| 12345678910111213141516171819202122232425262728293031323334353637383940 |
- //! Quality markers for collected recipes: bench-coverage stars and the
- //! per-category medal ranks.
- use super::render::latest_score;
- use super::{ReportEntry, ReportRow};
- /// Reports exist but none finished the full scenario pool.
- pub(crate) fn incomplete(reports: &[ReportEntry]) -> bool {
- !reports.is_empty() && !reports.iter().any(|e| e.done)
- }
- /// Gold/silver/bronze per (parent model, node count) category, ranked by
- /// latest score. Lanes of different node counts don't compete against each
- /// other (4x has more GPUs than 2x); recipes without any score don't take
- /// a medal. Ties break by recipe name (deterministic).
- pub(crate) fn award_medals(rows: &mut [ReportRow]) {
- use std::cmp::Ordering;
- let mut groups: std::collections::HashMap<(String, u32), Vec<usize>> =
- std::collections::HashMap::new();
- for (i, r) in rows.iter().enumerate() {
- groups
- .entry((r.parent.clone(), r.nodes.unwrap_or(1)))
- .or_default()
- .push(i);
- }
- for (_, mut idxs) in groups {
- idxs.sort_by(|&a, &b| {
- let pct = |i: usize| latest_score(&rows[i]).and_then(|e| e.pct);
- pct(b)
- .partial_cmp(&pct(a))
- .unwrap_or(Ordering::Equal)
- .then_with(|| rows[a].name.cmp(&rows[b].name))
- });
- for (rank, &i) in idxs.iter().enumerate().take(3) {
- if latest_score(&rows[i]).is_some() {
- rows[i].medal = Some(rank as u8 + 1);
- }
- }
- }
- }
|