metrale_bench/
registry.rs

1// SPDX-License-Identifier: MIT OR Apache-2.0
2
3//! 2026-09-26: The benchmark suite, in the order the Benchmarks pane lists
4//! it, and lookup by id.
5//!
6//! Owner: bench (registry).
7//! Invariants: none beyond the types; the tests below check that ids are
8//! unique and filename-safe and that every descriptor's defaults validate.
9
10use crate::benchmark::BenchmarkDescriptor;
11use crate::benchmarks::{
12    agentic, bfcl, concurrency, contamination, decode_floor, default_tier_boot, kat_equality,
13    mlperf_agentic, quick_speed, scheduler_equivalence, serve_matrix, spec_cost, ssm_poison, ttft,
14    video, vision,
15};
16
17/// 2026-09-26: Every benchmark, in list order. A compile-time table of
18/// `&'static` descriptors: registration is a compile-time decision.
19const ALL: &[&BenchmarkDescriptor] = &[
20    // 2026-09-26: A measurement tool with no baseline and no thresholds,
21    // excused from the PR gate set in `gate::coverage::NOT_REQUIRED`.
22    &quick_speed::DESCRIPTOR,
23    // 2026-09-26: The gate counterpart of the probe above, judged against a
24    // BENCH.toml floor and listed in `gate::coverage::REQUIRED`.
25    &decode_floor::DESCRIPTOR,
26    // 2026-10-04: A measurement tool for the speculative cost model, excused from the PR gate
27    // set in `gate::coverage::NOT_REQUIRED`.
28    &spec_cost::DESCRIPTOR,
29    &concurrency::DESCRIPTOR,
30    &concurrency::DFLASH2_DESCRIPTOR,
31    // 2026-09-26: The MoE flagship's concurrency ladder, listed in
32    // `gate::coverage::REQUIRED`; see `concurrency::MOE_DESCRIPTOR`.
33    &concurrency::MOE_DESCRIPTOR,
34    &ttft::WARM_DESCRIPTOR,
35    &ttft::COLD_DESCRIPTOR,
36    // 2026-09-27: Listed in `gate::coverage::REQUIRED`: the 32k-prompt pair on
37    // the dense flagship, then on the 35B MoE.
38    &ttft::HIGH_ISL_COLD_DESCRIPTOR,
39    &ttft::HIGH_ISL_WARM_DESCRIPTOR,
40    &ttft::HIGH_ISL_COLD_MOE_DESCRIPTOR,
41    &ttft::HIGH_ISL_WARM_MOE_DESCRIPTOR,
42    &contamination::DESCRIPTOR,
43    // 2026-09-26: Listed in `gate::coverage::REQUIRED`. Coverage has no
44    // per-model dimension: the checkpoints it measures are the BENCH.toml
45    // entries that declare `gate = "vision-fidelity"`
46    // (`gate::bench::baseline_for`).
47    &vision::DESCRIPTOR,
48    // 2026-09-26: The same, for the entries that declare
49    // `gate = "video-fidelity"`.
50    &video::DESCRIPTOR,
51    &ssm_poison::DESCRIPTOR,
52    // 2026-09-26: Beside the poisoning gate: both check whether one request's
53    // state reaches another. That one asks whether a replay changes; this one
54    // whether the order matters.
55    &kat_equality::DESCRIPTOR,
56    // 2026-10-03: The cheap correctness suite of the Nemotron-3 models, one gate id per model
57    // (`kat_equality::nemotron`, `bfcl::mini_descriptors`). Listed in
58    // `gate::coverage::PROMOTION_CANDIDATES` until their BENCH entries are measured.
59    &kat_equality::NEMOTRON_NANO_DESCRIPTOR,
60    &kat_equality::NEMOTRON_SUPER_DESCRIPTOR,
61    &bfcl::MINI_NEMOTRON_NANO_DESCRIPTOR,
62    &bfcl::MINI_NEMOTRON_SUPER_DESCRIPTOR,
63    // 2026-10-03: The mini draw itself, a measurement draw (`gate::coverage::NOT_REQUIRED`).
64    &bfcl::SUBSET_MINI_DESCRIPTOR,
65    // 2026-09-26: The same family: does the router matter? The same draw
66    // under the synchronous and the asynchronous device router. Listed in
67    // `gate::coverage::PROMOTION_CANDIDATES`.
68    &scheduler_equivalence::DESCRIPTOR,
69    // 2026-10-01: The serve's memory plan at its default precision tier, read after one
70    // warmup wave. Listed in `gate::coverage::PROMOTION_CANDIDATES`.
71    &default_tier_boot::DESCRIPTOR,
72    &agentic::DESCRIPTOR,
73    &bfcl::SUBSET_DESCRIPTOR,
74    &bfcl::SUBSET_ECHOLP_DESCRIPTOR,
75    &bfcl::FULL_DESCRIPTOR,
76    // 2026-09-26: The two subset gates above are also benchmark groups
77    // (`gate::group::GROUPS`): a shard is the group's benchmark run with
78    // `--param shard=i/n`, not a benchmark of its own. The MLPerf entry below
79    // is unrunnable (its dataset is not published) and is listed so the pane
80    // shows it exists.
81    &mlperf_agentic::SUBSET_DESCRIPTOR,
82    // 2026-09-26: Last: it replaces the model the box is serving (its
83    // `detail`), so it sits furthest from an accidental start.
84    &serve_matrix::DESCRIPTOR,
85];
86
87pub fn all() -> &'static [&'static BenchmarkDescriptor] {
88    ALL
89}
90
91/// 2026-09-26: Look one up by its stable id.
92pub fn find(id: &str) -> Option<&'static BenchmarkDescriptor> {
93    all().iter().copied().find(|d| d.id == id)
94}
95
96#[cfg(test)]
97mod tests {
98    use super::*;
99
100    #[test]
101    fn ids_are_unique_and_filename_safe() {
102        let mut seen = std::collections::BTreeSet::new();
103        for d in all() {
104            assert!(!d.id.is_empty(), "benchmark ids address history files");
105            assert!(seen.insert(d.id), "duplicate benchmark id {}", d.id);
106            assert!(
107                d.id.chars()
108                    .all(|c| c.is_ascii_lowercase() || c.is_ascii_digit() || c == '-'),
109                "{} is not filename-safe",
110                d.id
111            );
112        }
113    }
114
115    #[test]
116    fn find_round_trips_every_descriptor() {
117        for d in all() {
118            assert_eq!(find(d.id).unwrap().name, d.name);
119        }
120        assert!(find("nope").is_none());
121    }
122
123    /// 2026-09-26: A zero `expected_secs` would make the certification
124    /// planner (`bench_certify/plan.rs`) treat a runnable benchmark as free.
125    /// Zero is permitted only for benchmarks whose hint says they cannot run.
126    #[test]
127    fn every_runnable_benchmark_declares_an_expected_duration() {
128        for d in all() {
129            if d.duration_hint.starts_with("unrunnable") {
130                assert_eq!(
131                    d.expected_secs, 0,
132                    "{}: unrunnable but has a duration",
133                    d.id
134                );
135                continue;
136            }
137            assert!(d.expected_secs > 0, "{}: expected_secs is 0", d.id);
138        }
139        // 2026-09-26: Pin the required gates and the groups by name, so a new
140        // entry cannot slip in with the field left at zero.
141        for id in crate::gate::REQUIRED_GATES {
142            assert!(find(id).unwrap().expected_secs > 0, "{id}");
143        }
144        for g in crate::gate::group::GROUPS {
145            assert!(find(g.id).unwrap().expected_secs > 0, "{}", g.id);
146        }
147    }
148
149    #[test]
150    fn every_benchmark_declares_defaults_that_validate() {
151        for d in all() {
152            let b = d.build();
153            let specs = b.parameters();
154            let values = crate::params::ParamValues::defaults(&specs);
155            values
156                .validate_against(&specs)
157                .unwrap_or_else(|e| panic!("{}: {e}", d.id));
158        }
159    }
160}