///|
pub(all) struct BenchmarkRecord {
name : String
cells : Int
particles : Int
steps : Int
work_units : Int
final_particles : Int
charge_error : Double
energy_drift : Double
} derive(Debug, ToJson)
///|
pub(all) struct BenchmarkSuite {
records : Array[BenchmarkRecord]
} derive(Debug, ToJson)
///|
pub fn benchmark_scenario(scenario : SimulationScenario) -> BenchmarkRecord {
let diagnostics = scenario_trace(scenario)
let final_particles = if diagnostics.length() == 0 {
0
} else {
diagnostics[diagnostics.length() - 1].particles
}
let charge_error = scenario_charge_error(scenario)
let energies = diagnostics.map(fn(item) { item.total_energy() })
{
name: scenario.name,
cells: scenario.grid.cells,
particles: scenario.particles,
steps: scenario.steps,
work_units: scenario_work_units(scenario),
final_particles,
charge_error,
energy_drift: if energies.length() == 0 {
0.0
} else {
relative_change(energies[0], energies[energies.length() - 1])
},
}
}
///|
pub fn benchmark_suite() -> BenchmarkSuite {
let records = [
benchmark_scenario(standard_scenario("tiny", 8, 16, 2)),
benchmark_scenario(standard_scenario("medium", 32, 128, 4)),
benchmark_scenario(standard_scenario("large", 64, 256, 6)),
]
{ records, }
}
///|
pub fn BenchmarkSuite::total_work(suite : BenchmarkSuite) -> Int {
suite.records.fold(init=0, fn(acc, record) { acc + record.work_units })
}
///|
pub fn BenchmarkSuite::maximum_charge_error(suite : BenchmarkSuite) -> Double {
let mut maximum = 0.0
for record in suite.records {
maximum = maximum.max(record.charge_error)
}
maximum
}
///|
pub fn BenchmarkSuite::maximum_energy_drift(suite : BenchmarkSuite) -> Double {
let mut maximum = 0.0
for record in suite.records {
maximum = maximum.max(record.energy_drift)
}
maximum
}
///|
pub fn benchmark_suite_to_csv(suite : BenchmarkSuite) -> String {
let output = StringBuilder()
output.write_string(
"name,cells,particles,steps,work_units,final_particles,charge_error,energy_drift\n",
)
for record in suite.records {
output.write_string(
"\{record.name},\{record.cells},\{record.particles},\{record.steps},\{record.work_units},\{record.final_particles},\{record.charge_error},\{record.energy_drift}\n",
)
}
output.to_string()
}
///|
pub fn benchmark_suite_summary(suite : BenchmarkSuite) -> String {
"records=\{suite.records.length()}\nwork_units=\{suite.total_work()}\nmax_charge_error=\{suite.maximum_charge_error()}\nmax_energy_drift=\{suite.maximum_energy_drift()}\n"
}
///|
pub fn benchmark_record_to_json_like(record : BenchmarkRecord) -> String {
"{name:\"\{record.name}\",cells:\{record.cells},particles:\{record.particles},steps:\{record.steps},work_units:\{record.work_units},charge_error:\{record.charge_error},energy_drift:\{record.energy_drift}}"
}