metrale_bench/benchmarks/serve_matrix/
report.rs1use super::plan::Plan;
12use super::score::{Outcome, RoundResult, Signal, Tally};
13use crate::result::{Cell, CellStyle, Column, Stat};
14use crate::result::{ResultTable, Verdict};
15
16fn style_of(signal: &Signal) -> CellStyle {
17 match signal {
18 Signal::Pass => CellStyle::Good,
19 Signal::Fail(_) => CellStyle::Bad,
20 Signal::NotApplicable(_) => CellStyle::Warn,
21 Signal::NotRun => CellStyle::Dim,
22 }
23}
24
25fn signal_cell(signal: &Signal) -> Cell {
26 Cell::styled(signal.text(), style_of(signal))
27}
28
29pub fn table(plan: &Plan, results: &[RoundResult]) -> ResultTable {
31 let mut t = ResultTable::new(
32 "SERVE MATRIX",
33 vec![
34 Column::left("Model × quant", 40),
35 Column::left("Serving", 8),
36 Column::left("Coherence", 10),
37 Column::left("Codegen", 8),
38 Column::left("Tools", 6),
39 Column::left("Long ctx", 9),
40 Column::right("tok/s", 8),
41 Column::left("Verdict", 28),
42 ],
43 );
44 for round in &plan.rounds {
45 let label = round.label();
46 if let Some(why) = round.skipped {
47 t.push(skipped_row(&label, why.reason()));
48 continue;
49 }
50 if round.excluded {
51 t.push(skipped_row(&label, "outside the filter"));
52 continue;
53 }
54 let found = results.iter().find(|r| r.label == label);
55 match found {
56 Some(r) => t.push(result_row(&label, r)),
57 None => t.push(missing_result_row(&label)),
58 }
59 }
60 t
61}
62
63fn skipped_row(label: &str, why: &str) -> Vec<Cell> {
64 let mut row = vec![Cell::new(label)];
65 row.extend((0..6).map(|_| Cell::styled("—", CellStyle::Dim)));
66 row.push(Cell::styled(format!("SKIP · {why}"), CellStyle::Dim));
67 row
68}
69
70fn missing_result_row(label: &str) -> Vec<Cell> {
71 let mut row = vec![Cell::new(label)];
72 row.extend((0..6).map(|_| Cell::styled("—", CellStyle::Dim)));
73 row.push(Cell::styled(
74 "FAIL · no result — did not run",
75 CellStyle::Bad,
76 ));
77 row
78}
79
80fn result_row(label: &str, r: &RoundResult) -> Vec<Cell> {
81 let bars = r.bars();
82 let verdict = if bars.is_empty() {
83 Cell::styled("PASS", CellStyle::Good)
84 } else {
85 Cell::styled(format!("FAIL · {}", bars.join(", ")), CellStyle::Bad)
86 };
87 let Some(s) = r.signals() else {
88 let mut row = vec![Cell::new(label)];
89 row.extend((0..6).map(|_| Cell::styled("—", CellStyle::Dim)));
90 row.push(verdict);
91 return row;
92 };
93 let coherence = format!("{}/{}", s.coherence_pass, s.coherence_total);
94 let coherence_style = if s.coherence_pass == s.coherence_total {
95 CellStyle::Good
96 } else {
97 CellStyle::Bad
98 };
99 let tps = match s.tps {
100 Some(v) if v > 0.0 => Cell::styled(format!("{v:.1}"), CellStyle::Accent),
101 Some(_) => Cell::styled("0", CellStyle::Bad),
102 None => Cell::styled("—", CellStyle::Dim),
103 };
104 vec![
105 Cell::new(label),
106 signal_cell(&s.identity),
108 Cell::styled(coherence, coherence_style),
109 signal_cell(&s.codegen),
110 signal_cell(&s.tool_call),
111 signal_cell(&s.long_ctx),
112 tps,
113 verdict,
114 ]
115}
116
117pub fn summary(tally: &Tally) -> Vec<Stat> {
118 vec![
119 Stat::new(
120 "Verified",
121 format!("{}/{}", tally.verified, tally.planned),
122 "planned",
123 )
124 .with_style(match (tally.planned, tally.passed()) {
127 (0, _) => CellStyle::Dim,
128 (_, true) => CellStyle::Good,
129 (_, false) => CellStyle::Bad,
130 }),
131 Stat::new("Below bar", tally.failures.len().to_string(), "").with_style(
132 if tally.failures.is_empty() {
133 CellStyle::Dim
134 } else {
135 CellStyle::Bad
136 },
137 ),
138 Stat::new("Not runnable", tally.skipped.to_string(), "on this box")
139 .with_style(CellStyle::Dim),
140 Stat::new("Filtered out", tally.excluded.to_string(), "").with_style(CellStyle::Dim),
141 ]
142}
143
144pub fn verdict(tally: &Tally, plan: &Plan) -> Verdict {
146 let text = super::score::verdict_text(tally, plan);
147 if tally.planned == 0 {
148 return Verdict::info(format!(
149 "no checkpoint on this box is runnable — nothing was measured. {text}"
150 ));
151 }
152 if tally.passed() {
153 Verdict::pass(text)
154 } else {
155 Verdict::fail(text)
156 }
157}
158
159pub fn round_line(r: &RoundResult) -> String {
161 match &r.outcome {
162 Outcome::BootFailed(why) => format!("{}: DID NOT BOOT — {why}", r.label),
163 Outcome::NotReached => format!("{}: not reached", r.label),
164 Outcome::Probed(s) => {
165 let bars = r.bars();
166 let mut line = format!(
167 "{}: serving {} · coherence {}/{} · codegen {} · tools {} · long-ctx {} · {}",
168 r.label,
169 s.identity.text(),
170 s.coherence_pass,
171 s.coherence_total,
172 s.codegen.text(),
173 s.tool_call.text(),
174 s.long_ctx.text(),
175 match s.tps {
176 Some(v) => format!("{v:.1} tok/s"),
177 None => "tok/s unmeasured (one SSE delta)".into(),
178 }
179 );
180 if let Some(note) = r.tps_note() {
181 line.push_str(&format!(" ({note})"));
182 }
183 if !bars.is_empty() {
184 line.push_str(&format!(" → FAIL {}", bars.join(", ")));
185 let why: Vec<&str> = [&s.identity, &s.codegen, &s.tool_call, &s.long_ctx]
188 .iter()
189 .filter(|sig| sig.is_fail())
190 .filter_map(|sig| sig.detail())
191 .collect();
192 if !why.is_empty() {
193 line.push_str(&format!(" — {}", why.join("; ")));
194 }
195 }
196 line
197 }
198 }
199}
200
201#[cfg(test)]
202#[path = "report_tests.rs"]
203mod tests;