metrale_bench/benchmarks/spec_cost/
table_input.rs1use std::collections::BTreeMap;
18
19use anyhow::{Context, Result, bail};
20
21use super::cell::{
22 KEY_DRAFT_J, KEY_DRAFT_MS, KEY_K, KEY_VACUOUS, KEY_VERIFY_J, KEY_WALL_MS, record_key,
23};
24
25#[derive(Clone, Copy, Debug, PartialEq)]
27pub struct MeasuredCell {
28 pub n: usize,
29 pub k: usize,
30 pub verify_ms: f64,
31 pub verify_j: f64,
32 pub draft_ms: f64,
33 pub draft_j: f64,
34}
35
36pub fn read(metrics: &BTreeMap<String, f64>) -> Result<Vec<MeasuredCell>> {
40 let k = *metrics
41 .get(KEY_K)
42 .context("not a spec-cost record: no `k`")?;
43 if !(k >= 0.0 && k.fract() == 0.0) {
44 bail!("spec-cost record: k = {k} is not a draft count");
45 }
46 let suffix = format!("_{KEY_VACUOUS}");
47 let mut widths: Vec<usize> = metrics
48 .keys()
49 .filter_map(|key| {
50 key.strip_prefix('n')?
51 .strip_suffix(suffix.as_str())?
52 .parse()
53 .ok()
54 })
55 .collect();
56 widths.sort_unstable();
57 if widths.is_empty() {
58 bail!("spec-cost record at k = {k}: no width");
59 }
60 let field = |n: usize, f: &str| -> Result<f64> {
61 metrics.get(&record_key(n, f)).copied().with_context(|| {
62 format!("spec-cost record at k = {k}: width {n} has no {f} (rail not sampled?)")
63 })
64 };
65 widths
66 .into_iter()
67 .map(|n| {
68 if field(n, KEY_VACUOUS)? != 0.0 {
69 bail!("spec-cost record at k = {k}: width {n} is vacuous; re-run it");
70 }
71 let (wall_ms, draft_ms) = (field(n, KEY_WALL_MS)?, field(n, KEY_DRAFT_MS)?);
72 if draft_ms > wall_ms {
73 bail!("spec-cost record at k = {k}: width {n} drafts {draft_ms} ms of a {wall_ms} ms step");
74 }
75 Ok(MeasuredCell {
76 n,
77 k: k as usize,
78 verify_ms: wall_ms - draft_ms,
79 verify_j: field(n, KEY_VERIFY_J)?,
80 draft_ms,
81 draft_j: field(n, KEY_DRAFT_J)?,
82 })
83 })
84 .collect()
85}
86
87#[cfg(test)]
88#[path = "table_input_tests.rs"]
89mod tests;