///|
pub(all) struct VerificationBundle {
scenario : SimulationScenario
manifest : ReproducibilityManifest
fingerprint : ResultFingerprint
metrics : Array[QualityMetric]
invariants : Array[InvariantCheck]
} derive(Debug, ToJson)
///|
pub fn build_verification_bundle(
scenario : SimulationScenario,
toolchain : String,
) -> VerificationBundle {
let state = scenario_run(scenario)
let initial_charge = total_particle_charge(
scenario_initial_state(scenario).particles,
)
{
scenario,
manifest: manifest_from_scenario(scenario, toolchain),
fingerprint: fingerprint_from_scenario(scenario),
metrics: scenario_quality_metrics(scenario),
invariants: pic_invariants(state, initial_charge),
}
}
///|
pub fn VerificationBundle::passed(bundle : VerificationBundle) -> Bool {
all_metrics_pass(bundle.metrics) &&
invariant_all(bundle.invariants) &&
result_is_well_formed(bundle.scenario, bundle.fingerprint)
}
///|
pub fn VerificationBundle::work_units(bundle : VerificationBundle) -> Int {
manifest_work_units(bundle.manifest)
}
///|
pub fn VerificationBundle::summary(bundle : VerificationBundle) -> String {
"name=\{bundle.manifest.name}\npassed=\{bundle.passed()}\nwork_units=\{bundle.work_units()}\nchecksum=\{bundle.fingerprint.checksum}\n"
}
///|
pub fn VerificationBundle::to_csv(bundle : VerificationBundle) -> String {
let output = StringBuilder()
output.write_string("section,key,value\n")
output.write_string("manifest,name,\{bundle.manifest.name}\n")
output.write_string("manifest,seed,\{bundle.manifest.seed}\n")
output.write_string("manifest,cells,\{bundle.manifest.cells}\n")
output.write_string("manifest,particles,\{bundle.manifest.particles}\n")
output.write_string("manifest,steps,\{bundle.manifest.steps}\n")
output.write_string("manifest,dt,\{bundle.manifest.dt}\n")
output.write_string("manifest,shape,\{bundle.manifest.shape}\n")
output.write_string("manifest,boundary,\{bundle.manifest.boundary}\n")
output.write_string(
"fingerprint,sample_count,\{bundle.fingerprint.sample_count}\n",
)
output.write_string(
"fingerprint,work_units,\{bundle.fingerprint.work_units}\n",
)
output.write_string(
"fingerprint,charge_error,\{bundle.fingerprint.charge_error}\n",
)
output.write_string(
"fingerprint,energy_drift,\{bundle.fingerprint.energy_drift}\n",
)
output.write_string("fingerprint,checksum,\{bundle.fingerprint.checksum}\n")
output.write_string(
"quality,metrics_pass,\{all_metrics_pass(bundle.metrics)}\n",
)
output.write_string(
"quality,invariants_pass,\{invariant_all(bundle.invariants)}\n",
)
output.to_string()
}
///|
pub fn VerificationBundle::metric_report(bundle : VerificationBundle) -> String {
quality_report(bundle.metrics)
}
///|
pub fn VerificationBundle::invariant_report(
bundle : VerificationBundle,
) -> String {
invariant_report(bundle.invariants)
}
///|
pub fn VerificationBundle::reproducibility_report(
bundle : VerificationBundle,
) -> String {
reproducibility_report(bundle.scenario, bundle.manifest.toolchain)
}
///|
pub fn verification_bundle_to_text(bundle : VerificationBundle) -> String {
let output = StringBuilder()
output.write_string(bundle.summary())
output.write_string("\n")
output.write_string(bundle.metric_report())
output.write_string("\n")
output.write_string(bundle.invariant_report())
output.write_string("\n")
output.write_string(bundle.reproducibility_report())
output.to_string()
}
///|
pub fn verification_bundle_records(
bundle : VerificationBundle,
) -> Array[QualityMetric] {
bundle.metrics.copy()
}
///|
pub fn verification_bundle_check_count(bundle : VerificationBundle) -> Int {
bundle.metrics.length() + bundle.invariants.length()
}
///|
pub fn verification_bundle_checksum(bundle : VerificationBundle) -> Int {
let metrics_hash = fingerprint_values(
bundle.metrics.map(fn(item) { item.value }),
)
let invariant_hash = fingerprint_values(
bundle.invariants.map(fn(item) { item.observed }),
)
(metrics_hash * 31 + invariant_hash + bundle.fingerprint.checksum) %
2147483647
}
///|
pub fn verification_bundle_schema() -> String {
"section,key,value"
}
///|
pub fn verification_bundle_is_deterministic(
scenario : SimulationScenario,
toolchain : String,
) -> Bool {
let first = build_verification_bundle(scenario, toolchain)
let second = build_verification_bundle(scenario, toolchain)
verification_bundle_checksum(first) == verification_bundle_checksum(second)
}
///|
pub fn verification_bundle_passes_thresholds(
bundle : VerificationBundle,
charge : Double,
energy : Double,
) -> Bool {
bundle.fingerprint.charge_error <= charge &&
bundle.fingerprint.energy_drift <= energy
}
///|
pub fn verification_bundle_expected_work(bundle : VerificationBundle) -> Int {
bundle.scenario.grid.cells * bundle.scenario.particles * bundle.scenario.steps
}
///|
pub fn verification_bundle_matches_work(bundle : VerificationBundle) -> Bool {
bundle.work_units() == verification_bundle_expected_work(bundle)
}
///|
pub fn verification_bundle_status(bundle : VerificationBundle) -> String {
if bundle.passed() && verification_bundle_matches_work(bundle) {
"pass"
} else {
"review"
}
}