Skip to main content

vyre_driver/
benchmark_pass_selection.rs

1//! Benchmark-driven optimization pass selection.
2//!
3//! Expensive passes must not fire because a static list says so. They need
4//! graph/frontier/reuse evidence showing that the launch, memory, or readback
5//! cost they remove is larger than their own planning cost. This module makes
6//! that decision explicit and deterministic.
7
8use crate::accounting::{
9    checked_add_u64_count as checked_add, checked_add_usize_count as checked_add_usize,
10    ArithmeticOverflow,
11};
12use crate::numeric::checked_compose_basis_points_u64;
13use crate::reservation_policy::{
14    reserved_typed_vec as reserved_vec, ReservationPolicy, ReusableIndexScratch,
15};
16
17const BENCHMARK_PASS_SELECTION_RESERVATION: ReservationPolicy = ReservationPolicy::new(
18    "benchmark pass selection",
19    "shard the optimization candidate set before pass selection",
20);
21
22/// One optimization candidate with benchmark-derived thresholds.
23#[derive(Clone, Copy, Debug, Eq, PartialEq)]
24pub struct BenchmarkPassCandidate {
25    /// Registered optimization pass id.
26    pub pass_id: &'static str,
27    /// Minimum active frontier items required before this pass is profitable.
28    pub min_frontier_items: u64,
29    /// Minimum repeated graph executions required before this pass is profitable.
30    pub min_reuse_count: u64,
31    /// Minimum readback bytes avoided before this pass is profitable.
32    pub min_avoided_readback_bytes: u64,
33    /// Estimated planning/compile cost in nanoseconds.
34    pub planning_cost_ns: u64,
35    /// Scratch bytes needed by the pass while planning/executing.
36    pub scratch_bytes: u64,
37    /// Expected speedup in basis points from committed benchmark evidence.
38    pub expected_speedup_bps: u32,
39    /// Whether the pass is mandatory when its thresholds are met.
40    pub mandatory_when_profitable: bool,
41}
42
43/// Runtime benchmark sample used to select optimization passes.
44#[derive(Clone, Copy, Debug, Eq, PartialEq)]
45pub struct BenchmarkPassSelectionSample {
46    /// Active frontier items in the current graph/query batch.
47    pub frontier_items: u64,
48    /// Number of repeated executions over the same resident graph shape.
49    pub reuse_count: u64,
50    /// Readback bytes the workload can avoid with compaction/aggregation.
51    pub avoidable_readback_bytes: u64,
52    /// Maximum total planning cost allowed.
53    pub planning_budget_ns: u64,
54    /// Maximum scratch bytes allowed for selected passes.
55    pub scratch_budget_bytes: u64,
56}
57
58/// One skipped optimization with a stable reason.
59#[derive(Clone, Debug, Eq, PartialEq)]
60pub struct SkippedBenchmarkPass {
61    /// Registered optimization pass id.
62    pub pass_id: &'static str,
63    /// Stable reason.
64    pub reason: BenchmarkPassSkipReason,
65}
66
67/// Stable skip reason for an optimization candidate.
68#[derive(Clone, Copy, Debug, Eq, PartialEq)]
69pub enum BenchmarkPassSkipReason {
70    /// Frontier is too small for this pass to pay for itself.
71    FrontierBelowThreshold,
72    /// Graph reuse is too low for residency/cache/fusion work to amortize.
73    ReuseBelowThreshold,
74    /// Readback pressure is too low for compaction/aggregation to pay off.
75    ReadbackBelowThreshold,
76    /// Planning budget would be exceeded.
77    PlanningBudgetExceeded,
78    /// Scratch budget would be exceeded.
79    ScratchBudgetExceeded,
80}
81
82/// Pass-selection output.
83#[derive(Clone, Debug, Eq, PartialEq)]
84pub struct BenchmarkPassSelectionPlan {
85    /// Selected pass ids in benchmark-value order.
86    pub selected_pass_ids: Vec<&'static str>,
87    /// Skipped pass ids with stable reasons.
88    pub skipped_passes: Vec<SkippedBenchmarkPass>,
89    /// Total selected planning cost.
90    pub total_planning_cost_ns: u64,
91    /// Total selected scratch bytes.
92    pub total_scratch_bytes: u64,
93    /// Product of selected speedup multipliers in basis points.
94    pub projected_speedup_bps: u64,
95}
96
97/// Caller-owned scratch for repeated benchmark pass selection.
98#[derive(Debug, Default)]
99pub struct BenchmarkPassSelectionScratch {
100    index_scratch: ReusableIndexScratch<&'static str>,
101}
102
103impl BenchmarkPassSelectionScratch {
104    /// Allocate empty reusable pass-selection scratch.
105    #[must_use]
106    pub fn new() -> Self {
107        Self::default()
108    }
109
110    /// Allocate reusable pass-selection scratch for a known candidate count.
111    ///
112    /// # Errors
113    ///
114    /// Returns [`BenchmarkPassSelectionError`] when scratch storage cannot be reserved.
115    pub fn try_with_capacity(candidate_count: usize) -> Result<Self, BenchmarkPassSelectionError> {
116        let mut scratch = Self::default();
117        scratch.try_reserve_candidates(candidate_count)?;
118        Ok(scratch)
119    }
120
121    /// Reserve reusable pass-selection scratch for a known candidate count.
122    ///
123    /// # Errors
124    ///
125    /// Returns [`BenchmarkPassSelectionError`] when scratch storage cannot be reserved.
126    pub fn try_reserve_candidates(
127        &mut self,
128        candidate_count: usize,
129    ) -> Result<(), BenchmarkPassSelectionError> {
130        self.index_scratch.try_reserve_with(
131            BENCHMARK_PASS_SELECTION_RESERVATION,
132            candidate_count,
133            "scratch.seen",
134            "scratch.ordered_indices",
135            storage_reserve_failed,
136        )
137    }
138
139    /// Retained duplicate-detection capacity.
140    #[must_use]
141    pub fn seen_capacity(&self) -> usize {
142        self.index_scratch.seen_capacity()
143    }
144
145    /// Retained candidate-ordering capacity.
146    #[must_use]
147    pub fn ordered_index_capacity(&self) -> usize {
148        self.index_scratch.ordered_index_capacity()
149    }
150}
151
152/// Benchmark-driven pass-selection errors.
153#[derive(Clone, Debug, Eq, PartialEq)]
154pub enum BenchmarkPassSelectionError {
155    /// Candidate pass id is empty.
156    EmptyPassId,
157    /// Duplicate candidate pass id.
158    DuplicatePassId {
159        /// Duplicate pass id.
160        pass_id: &'static str,
161    },
162    /// Candidate has no benchmark speedup evidence.
163    MissingSpeedupEvidence {
164        /// Invalid pass id.
165        pass_id: &'static str,
166    },
167    /// Mandatory profitable pass could not fit the explicit budgets.
168    MandatoryProfitablePassOverBudget {
169        /// Pass id.
170        pass_id: &'static str,
171        /// Reason it could not fit.
172        reason: BenchmarkPassSkipReason,
173    },
174    /// Arithmetic overflowed.
175    CountOverflow {
176        /// Field being computed.
177        field: &'static str,
178    },
179    /// Scratch or result-vector storage reservation failed before pass selection.
180    StorageReserveFailed {
181        /// Field being reserved.
182        field: &'static str,
183        /// Requested total capacity.
184        requested: usize,
185        /// Allocator failure details.
186        message: String,
187    },
188}
189
190impl ArithmeticOverflow for BenchmarkPassSelectionError {
191    fn arithmetic_overflow(field: &'static str) -> Self {
192        Self::CountOverflow { field }
193    }
194}
195
196impl std::fmt::Display for BenchmarkPassSelectionError {
197    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
198        match self {
199            Self::EmptyPassId => write!(
200                f,
201                "benchmark pass selection received an empty pass id. Fix: register every pass before selection."
202            ),
203            Self::DuplicatePassId { pass_id } => write!(
204                f,
205                "benchmark pass selection received duplicate pass `{pass_id}`. Fix: keep one benchmark row per pass."
206            ),
207            Self::MissingSpeedupEvidence { pass_id } => write!(
208                f,
209                "benchmark pass `{pass_id}` has no positive speedup evidence. Fix: add committed benchmark evidence or remove the candidate."
210            ),
211            Self::MandatoryProfitablePassOverBudget { pass_id, reason } => write!(
212                f,
213                "mandatory profitable pass `{pass_id}` was blocked by {reason:?}. Fix: raise the explicit budget or shard before pass selection."
214            ),
215            Self::CountOverflow { field } => write!(
216                f,
217                "benchmark pass selection overflowed while computing {field}. Fix: shard the optimization candidate set."
218            ),
219            Self::StorageReserveFailed {
220                field,
221                requested,
222                message,
223            } => write!(
224                f,
225                "benchmark pass selection failed to reserve {field} for {requested} entries: {message}. Fix: shard the optimization candidate set before pass selection."
226            ),
227        }
228    }
229}
230
231impl std::error::Error for BenchmarkPassSelectionError {}
232
233/// Select optimization passes from benchmark evidence and workload stats.
234///
235/// # Errors
236///
237/// Returns [`BenchmarkPassSelectionError`] when candidates are invalid, budget
238/// accounting overflows, mandatory profitable passes cannot fit the budget, or
239/// planner storage cannot be reserved.
240pub fn select_benchmark_passes(
241    candidates: &[BenchmarkPassCandidate],
242    sample: BenchmarkPassSelectionSample,
243) -> Result<BenchmarkPassSelectionPlan, BenchmarkPassSelectionError> {
244    let mut scratch = BenchmarkPassSelectionScratch::try_with_capacity(candidates.len())?;
245    select_benchmark_passes_with_scratch(candidates, sample, &mut scratch)
246}
247
248/// Select optimization passes using caller-owned temporary storage.
249///
250/// # Errors
251///
252/// Returns [`BenchmarkPassSelectionError`] when candidates are invalid, budget
253/// accounting overflows, mandatory profitable passes cannot fit the budget, or
254/// planner storage cannot be reserved.
255pub fn select_benchmark_passes_with_scratch(
256    candidates: &[BenchmarkPassCandidate],
257    sample: BenchmarkPassSelectionSample,
258    scratch: &mut BenchmarkPassSelectionScratch,
259) -> Result<BenchmarkPassSelectionPlan, BenchmarkPassSelectionError> {
260    scratch.index_scratch.clear();
261    scratch.try_reserve_candidates(candidates.len())?;
262    for (index, candidate) in candidates.iter().enumerate() {
263        if candidate.pass_id.is_empty() {
264            return Err(BenchmarkPassSelectionError::EmptyPassId);
265        }
266        if !scratch.index_scratch.insert_seen(candidate.pass_id) {
267            return Err(BenchmarkPassSelectionError::DuplicatePassId {
268                pass_id: candidate.pass_id,
269            });
270        }
271        if candidate.expected_speedup_bps <= 10_000 {
272            return Err(BenchmarkPassSelectionError::MissingSpeedupEvidence {
273                pass_id: candidate.pass_id,
274            });
275        }
276        scratch.index_scratch.push_index(index);
277    }
278    scratch
279        .index_scratch
280        .ordered_indices_mut()
281        .sort_unstable_by(|&left, &right| {
282            candidates[right]
283                .mandatory_when_profitable
284                .cmp(&candidates[left].mandatory_when_profitable)
285                .then_with(|| {
286                    pass_value(&candidates[right])
287                        .cmp(&pass_value(&candidates[left]))
288                        .then_with(|| candidates[left].pass_id.cmp(candidates[right].pass_id))
289                })
290        });
291
292    let (selected_pass_capacity, skipped_pass_capacity) =
293        count_final_pass_buckets(candidates, sample, scratch.index_scratch.ordered_indices())?;
294    let mut selected_pass_ids =
295        reserved_selection_vec(selected_pass_capacity, "selected_pass_ids")?;
296    let mut skipped_passes = reserved_selection_vec(skipped_pass_capacity, "skipped_passes")?;
297    let mut total_planning_cost_ns = 0_u64;
298    let mut total_scratch_bytes = 0_u64;
299    let mut projected_speedup_bps = 10_000_u64;
300
301    for &index in scratch.index_scratch.ordered_indices() {
302        let candidate = candidates[index];
303        if sample.frontier_items < candidate.min_frontier_items {
304            skipped_passes.push(skipped(
305                candidate.pass_id,
306                BenchmarkPassSkipReason::FrontierBelowThreshold,
307            ));
308            continue;
309        }
310        if sample.reuse_count < candidate.min_reuse_count {
311            skipped_passes.push(skipped(
312                candidate.pass_id,
313                BenchmarkPassSkipReason::ReuseBelowThreshold,
314            ));
315            continue;
316        }
317        if sample.avoidable_readback_bytes < candidate.min_avoided_readback_bytes {
318            skipped_passes.push(skipped(
319                candidate.pass_id,
320                BenchmarkPassSkipReason::ReadbackBelowThreshold,
321            ));
322            continue;
323        }
324
325        let next_planning = checked_add(
326            total_planning_cost_ns,
327            candidate.planning_cost_ns,
328            "planning cost",
329        )?;
330        if next_planning > sample.planning_budget_ns {
331            handle_budget_skip(
332                candidate,
333                BenchmarkPassSkipReason::PlanningBudgetExceeded,
334                &mut skipped_passes,
335            )?;
336            continue;
337        }
338        let next_scratch = checked_add(
339            total_scratch_bytes,
340            candidate.scratch_bytes,
341            "scratch bytes",
342        )?;
343        if next_scratch > sample.scratch_budget_bytes {
344            handle_budget_skip(
345                candidate,
346                BenchmarkPassSkipReason::ScratchBudgetExceeded,
347                &mut skipped_passes,
348            )?;
349            continue;
350        }
351
352        selected_pass_ids.push(candidate.pass_id);
353        total_planning_cost_ns = next_planning;
354        total_scratch_bytes = next_scratch;
355        projected_speedup_bps = checked_compose_basis_points_u64(
356            projected_speedup_bps,
357            u64::from(candidate.expected_speedup_bps),
358        )
359        .ok_or(BenchmarkPassSelectionError::CountOverflow {
360            field: "projected speedup product",
361        })?;
362    }
363
364    Ok(BenchmarkPassSelectionPlan {
365        selected_pass_ids,
366        skipped_passes,
367        total_planning_cost_ns,
368        total_scratch_bytes,
369        projected_speedup_bps,
370    })
371}
372
373fn pass_value(candidate: &BenchmarkPassCandidate) -> u128 {
374    u128::from(candidate.expected_speedup_bps)
375        * (u128::from(candidate.min_frontier_items)
376            + u128::from(candidate.min_reuse_count)
377            + u128::from(candidate.min_avoided_readback_bytes))
378}
379
380fn count_final_pass_buckets(
381    candidates: &[BenchmarkPassCandidate],
382    sample: BenchmarkPassSelectionSample,
383    ordered_indices: &[usize],
384) -> Result<(usize, usize), BenchmarkPassSelectionError> {
385    let mut selected = 0usize;
386    let mut skipped = 0usize;
387    let mut total_planning_cost_ns = 0_u64;
388    let mut total_scratch_bytes = 0_u64;
389    for &index in ordered_indices {
390        let candidate = candidates[index];
391        if sample.frontier_items < candidate.min_frontier_items
392            || sample.reuse_count < candidate.min_reuse_count
393            || sample.avoidable_readback_bytes < candidate.min_avoided_readback_bytes
394        {
395            skipped = checked_add_usize(skipped, 1, "skipped pass count")?;
396            continue;
397        }
398        let next_planning = checked_add(
399            total_planning_cost_ns,
400            candidate.planning_cost_ns,
401            "planning cost",
402        )?;
403        if next_planning > sample.planning_budget_ns {
404            if candidate.mandatory_when_profitable {
405                return Err(
406                    BenchmarkPassSelectionError::MandatoryProfitablePassOverBudget {
407                        pass_id: candidate.pass_id,
408                        reason: BenchmarkPassSkipReason::PlanningBudgetExceeded,
409                    },
410                );
411            }
412            skipped = checked_add_usize(skipped, 1, "skipped pass count")?;
413            continue;
414        }
415        let next_scratch = checked_add(
416            total_scratch_bytes,
417            candidate.scratch_bytes,
418            "scratch bytes",
419        )?;
420        if next_scratch > sample.scratch_budget_bytes {
421            if candidate.mandatory_when_profitable {
422                return Err(
423                    BenchmarkPassSelectionError::MandatoryProfitablePassOverBudget {
424                        pass_id: candidate.pass_id,
425                        reason: BenchmarkPassSkipReason::ScratchBudgetExceeded,
426                    },
427                );
428            }
429            skipped = checked_add_usize(skipped, 1, "skipped pass count")?;
430            continue;
431        }
432        selected = checked_add_usize(selected, 1, "selected pass count")?;
433        total_planning_cost_ns = next_planning;
434        total_scratch_bytes = next_scratch;
435    }
436    Ok((selected, skipped))
437}
438
439fn skipped(pass_id: &'static str, reason: BenchmarkPassSkipReason) -> SkippedBenchmarkPass {
440    SkippedBenchmarkPass { pass_id, reason }
441}
442
443fn handle_budget_skip(
444    candidate: BenchmarkPassCandidate,
445    reason: BenchmarkPassSkipReason,
446    skipped_passes: &mut Vec<SkippedBenchmarkPass>,
447) -> Result<(), BenchmarkPassSelectionError> {
448    if candidate.mandatory_when_profitable {
449        return Err(
450            BenchmarkPassSelectionError::MandatoryProfitablePassOverBudget {
451                pass_id: candidate.pass_id,
452                reason,
453            },
454        );
455    }
456    skipped_passes.push(skipped(candidate.pass_id, reason));
457    Ok(())
458}
459
460fn reserved_selection_vec<T>(
461    capacity: usize,
462    field: &'static str,
463) -> Result<Vec<T>, BenchmarkPassSelectionError> {
464    reserved_vec(
465        BENCHMARK_PASS_SELECTION_RESERVATION,
466        capacity,
467        field,
468        storage_reserve_failed,
469    )
470}
471
472fn storage_reserve_failed(
473    field: &'static str,
474    requested: usize,
475    message: String,
476) -> BenchmarkPassSelectionError {
477    BenchmarkPassSelectionError::StorageReserveFailed {
478        field,
479        requested,
480        message,
481    }
482}
483
484#[cfg(test)]
485mod tests {
486    use super::*;
487
488    #[test]
489    fn benchmark_pass_selection_picks_profitable_passes_by_value() {
490        let plan = select_benchmark_passes(
491            &[
492                candidate(
493                    "device.adjacent-launch-fusion",
494                    1_000,
495                    4,
496                    0,
497                    100,
498                    64,
499                    18_000,
500                    true,
501                ),
502                candidate(
503                    "device.result-compaction",
504                    1,
505                    1,
506                    4_096,
507                    20,
508                    16,
509                    12_000,
510                    false,
511                ),
512                candidate(
513                    "device.megakernel-plan-cache",
514                    1,
515                    64,
516                    0,
517                    50,
518                    32,
519                    25_000,
520                    true,
521                ),
522            ],
523            BenchmarkPassSelectionSample {
524                frontier_items: 2_000,
525                reuse_count: 128,
526                avoidable_readback_bytes: 8_192,
527                planning_budget_ns: 200,
528                scratch_budget_bytes: 128,
529            },
530        )
531        .expect("Fix: profitable passes should select");
532
533        assert_eq!(plan.selected_pass_ids.len(), 3);
534        assert!(plan
535            .selected_pass_ids
536            .contains(&"device.megakernel-plan-cache"));
537        assert!(plan
538            .selected_pass_ids
539            .contains(&"device.adjacent-launch-fusion"));
540        assert!(plan.selected_pass_ids.contains(&"device.result-compaction"));
541        assert_eq!(plan.total_planning_cost_ns, 170);
542        assert_eq!(plan.total_scratch_bytes, 112);
543        assert!(plan.projected_speedup_bps > 50_000);
544    }
545
546    #[test]
547    fn benchmark_pass_selection_skips_unprofitable_passes_with_stable_reasons() {
548        let plan = select_benchmark_passes(
549            &[
550                candidate(
551                    "device.adjacent-launch-fusion",
552                    1_000,
553                    4,
554                    0,
555                    10,
556                    8,
557                    15_000,
558                    false,
559                ),
560                candidate(
561                    "device.result-compaction",
562                    1,
563                    1,
564                    4_096,
565                    10,
566                    8,
567                    11_000,
568                    false,
569                ),
570            ],
571            BenchmarkPassSelectionSample {
572                frontier_items: 10,
573                reuse_count: 1,
574                avoidable_readback_bytes: 128,
575                planning_budget_ns: 100,
576                scratch_budget_bytes: 100,
577            },
578        )
579        .expect("Fix: unprofitable optional passes should skip");
580
581        assert_eq!(plan.selected_pass_ids, Vec::<&'static str>::new());
582        assert_eq!(plan.skipped_passes.len(), 2);
583        assert!(plan.skipped_passes.contains(&SkippedBenchmarkPass {
584            pass_id: "device.adjacent-launch-fusion",
585            reason: BenchmarkPassSkipReason::FrontierBelowThreshold,
586        }));
587        assert!(plan.skipped_passes.contains(&SkippedBenchmarkPass {
588            pass_id: "device.result-compaction",
589            reason: BenchmarkPassSkipReason::ReadbackBelowThreshold,
590        }));
591    }
592
593    #[test]
594    fn benchmark_pass_selection_ranks_huge_values_without_saturation_ties() {
595        let plan = select_benchmark_passes(
596            &[
597                candidate(
598                    "device.a-lexicographic-low-value",
599                    u64::MAX,
600                    u64::MAX,
601                    u64::MAX - 1,
602                    1,
603                    1,
604                    11_000,
605                    false,
606                ),
607                candidate(
608                    "device.z-lexicographic-high-value",
609                    u64::MAX,
610                    u64::MAX,
611                    u64::MAX,
612                    1,
613                    1,
614                    11_000,
615                    false,
616                ),
617            ],
618            BenchmarkPassSelectionSample {
619                frontier_items: u64::MAX,
620                reuse_count: u64::MAX,
621                avoidable_readback_bytes: u64::MAX,
622                planning_budget_ns: 10,
623                scratch_budget_bytes: 10,
624            },
625        )
626        .expect("Fix: huge benchmark evidence should rank without saturating value ties");
627
628        assert_eq!(
629            plan.selected_pass_ids[0],
630            "device.z-lexicographic-high-value",
631            "Fix: pass ranking must use widened arithmetic; saturating u64 scoring would tie these candidates and incorrectly choose lexicographic order."
632        );
633    }
634
635    #[test]
636    fn benchmark_pass_selection_rejects_missing_evidence_and_blocked_mandatory() {
637        assert_eq!(
638            select_benchmark_passes(
639                &[candidate("device.bad", 1, 1, 0, 1, 1, 10_000, false)],
640                sample(),
641            )
642            .expect_err("zero speedup evidence should fail"),
643            BenchmarkPassSelectionError::MissingSpeedupEvidence {
644                pass_id: "device.bad",
645            }
646        );
647        assert_eq!(
648            select_benchmark_passes(
649                &[candidate("device.mandatory", 1, 1, 0, 101, 1, 11_000, true,)],
650                sample(),
651            )
652            .expect_err("mandatory profitable pass cannot exceed budget"),
653            BenchmarkPassSelectionError::MandatoryProfitablePassOverBudget {
654                pass_id: "device.mandatory",
655                reason: BenchmarkPassSkipReason::PlanningBudgetExceeded,
656            }
657        );
658    }
659
660    #[test]
661    fn benchmark_pass_selection_does_not_let_optional_passes_starve_mandatory_passes() {
662        let plan = select_benchmark_passes(
663            &[
664                candidate(
665                    "device.optional-high-value",
666                    1,
667                    1,
668                    1_000_000,
669                    100,
670                    1,
671                    20_000,
672                    false,
673                ),
674                candidate("device.mandatory-low-value", 1, 1, 1, 100, 1, 11_000, true),
675            ],
676            BenchmarkPassSelectionSample {
677                frontier_items: 1,
678                reuse_count: 1,
679                avoidable_readback_bytes: 1_000_000,
680                planning_budget_ns: 100,
681                scratch_budget_bytes: 8,
682            },
683        )
684        .expect("Fix: mandatory profitable pass must reserve budget before optional passes");
685
686        assert_eq!(plan.selected_pass_ids, vec!["device.mandatory-low-value"]);
687        assert_eq!(
688            plan.skipped_passes,
689            vec![SkippedBenchmarkPass {
690                pass_id: "device.optional-high-value",
691                reason: BenchmarkPassSkipReason::PlanningBudgetExceeded,
692            }]
693        );
694    }
695
696    #[test]
697    fn benchmark_pass_selection_avoids_tree_sets_and_candidate_vector_copies() {
698        let src = include_str!("benchmark_pass_selection.rs");
699        assert!(
700            !src.contains(concat!("BTree", "Set")),
701            "Fix: benchmark pass selection should hash pass ids and sort candidate indices by value."
702        );
703        assert!(
704            !src.contains(concat!("candidates", ".to_vec()")),
705            "Fix: benchmark pass selection should not copy all candidates before value ordering."
706        );
707        assert!(
708            src.contains("BenchmarkPassSelectionScratch::try_with_capacity(candidates.len())?"),
709            "Fix: benchmark pass selection must stage scratch with fallible release-path allocation."
710        );
711        assert!(
712            src.contains("scratch.try_reserve_candidates(candidates.len())?"),
713            "Fix: caller-owned benchmark pass-selection scratch must grow through fallible reservation."
714        );
715        assert!(
716            src.contains("ReusableIndexScratch"),
717            "Fix: benchmark pass-selection duplicate detection and ordering scratch must share the paired typed fallible reservation helper."
718        );
719        assert!(
720            src.contains("StorageReserveFailed"),
721            "Fix: benchmark pass-selection allocation failures must surface as actionable planning errors."
722        );
723        assert!(
724            !src.contains(concat!("FxHashSet::with_capacity", "_and_hasher")),
725            "Fix: benchmark pass-selection scratch hash storage must not allocate infallibly."
726        );
727        assert!(
728            !src.contains(concat!("Vec::with_capacity", "(candidate_count)"))
729                && !src.contains(concat!("Vec::with_capacity", "(candidates.len())")),
730            "Fix: benchmark pass-selection scratch/result vectors must not allocate infallibly."
731        );
732    }
733
734    #[test]
735    fn benchmark_pass_selection_reuses_caller_owned_candidate_scratch() {
736        let mut scratch =
737            BenchmarkPassSelectionScratch::try_with_capacity(64).expect("Fix: scratch capacity");
738        let names = [
739            "device.synthetic.00",
740            "device.synthetic.01",
741            "device.synthetic.02",
742            "device.synthetic.03",
743            "device.synthetic.04",
744            "device.synthetic.05",
745            "device.synthetic.06",
746            "device.synthetic.07",
747            "device.synthetic.08",
748            "device.synthetic.09",
749            "device.synthetic.10",
750            "device.synthetic.11",
751            "device.synthetic.12",
752            "device.synthetic.13",
753            "device.synthetic.14",
754            "device.synthetic.15",
755        ];
756        let mut wide = Vec::new();
757        wide.try_reserve_exact(names.len())
758            .expect("Fix: synthetic pass vector capacity");
759        for (index, name) in names.iter().copied().enumerate() {
760            wide.push(candidate(
761                name,
762                1,
763                1,
764                1,
765                1,
766                1,
767                11_000 + u32::try_from(index).expect("Fix: synthetic pass index fits in u32"),
768                false,
769            ));
770        }
771        let first = select_benchmark_passes_with_scratch(
772            &wide,
773            BenchmarkPassSelectionSample {
774                frontier_items: 64,
775                reuse_count: 64,
776                avoidable_readback_bytes: 64,
777                planning_budget_ns: 128,
778                scratch_budget_bytes: 128,
779            },
780            &mut scratch,
781        )
782        .expect("Fix: wide benchmark pass selection should plan with reusable scratch");
783        let seen_capacity = scratch.seen_capacity();
784        let ordered_index_capacity = scratch.ordered_index_capacity();
785
786        assert_eq!(first.selected_pass_ids.len(), names.len());
787
788        let second = select_benchmark_passes_with_scratch(
789            &[
790                candidate("device.reused.high", 1, 1, 1, 10, 8, 20_000, false),
791                candidate("device.reused.low", 1, 1, 1, 10, 8, 12_000, false),
792            ],
793            sample(),
794            &mut scratch,
795        )
796        .expect("Fix: smaller benchmark pass selection should reuse previous scratch");
797
798        assert_eq!(second.selected_pass_ids[0], "device.reused.high");
799        assert!(scratch.seen_capacity() >= seen_capacity);
800        assert!(scratch.ordered_index_capacity() >= ordered_index_capacity);
801    }
802
803    #[test]
804    fn generated_benchmark_pass_profiles_preserve_budget_priority_and_ordering_contracts() {
805        let mut scratch = BenchmarkPassSelectionScratch::default();
806        for candidate_count in 1usize..=64 {
807            for budget_multiplier in 1u64..=16 {
808                let mut candidates = Vec::new();
809                candidates
810                    .try_reserve_exact(candidate_count)
811                    .expect("Fix: generated candidate capacity");
812                for index in 0..candidate_count {
813                    let mandatory = index % 5 == 0;
814                    candidates.push(candidate(
815                        if mandatory {
816                            "device.generated.mandatory"
817                        } else {
818                            "device.generated.optional"
819                        },
820                        1,
821                        1,
822                        u64::try_from(index % 4).expect("Fix: index fits"),
823                        1 + u64::try_from(index % 3).expect("Fix: index fits"),
824                        1,
825                        11_000 + u32::try_from(index % 1_000).expect("Fix: index fits"),
826                        mandatory,
827                    ));
828                    candidates[index].pass_id = generated_pass_id(index);
829                }
830
831                let plan = select_benchmark_passes_with_scratch(
832                    &candidates,
833                    BenchmarkPassSelectionSample {
834                        frontier_items: 128,
835                        reuse_count: 128,
836                        avoidable_readback_bytes: 128,
837                        planning_budget_ns: budget_multiplier * 64,
838                        scratch_budget_bytes: budget_multiplier * 64,
839                    },
840                    &mut scratch,
841                )
842                .expect("Fix: generated benchmark pass selection profile should plan");
843
844                let mut used_planning = 0u64;
845                let mut used_scratch = 0u64;
846                for pass_id in &plan.selected_pass_ids {
847                    let candidate = candidates
848                        .iter()
849                        .find(|candidate| candidate.pass_id == *pass_id)
850                        .expect("Fix: selected pass must map to a generated candidate");
851                    used_planning += candidate.planning_cost_ns;
852                    used_scratch += candidate.scratch_bytes;
853                }
854                assert_eq!(plan.total_planning_cost_ns, used_planning);
855                assert_eq!(plan.total_scratch_bytes, used_scratch);
856                assert!(plan.total_planning_cost_ns <= budget_multiplier * 64);
857                assert!(plan.total_scratch_bytes <= budget_multiplier * 64);
858                assert!(plan.projected_speedup_bps >= 10_000);
859            }
860        }
861    }
862
863    fn generated_pass_id(index: usize) -> &'static str {
864        const IDS: [&str; 64] = [
865            "device.generated.00",
866            "device.generated.01",
867            "device.generated.02",
868            "device.generated.03",
869            "device.generated.04",
870            "device.generated.05",
871            "device.generated.06",
872            "device.generated.07",
873            "device.generated.08",
874            "device.generated.09",
875            "device.generated.10",
876            "device.generated.11",
877            "device.generated.12",
878            "device.generated.13",
879            "device.generated.14",
880            "device.generated.15",
881            "device.generated.16",
882            "device.generated.17",
883            "device.generated.18",
884            "device.generated.19",
885            "device.generated.20",
886            "device.generated.21",
887            "device.generated.22",
888            "device.generated.23",
889            "device.generated.24",
890            "device.generated.25",
891            "device.generated.26",
892            "device.generated.27",
893            "device.generated.28",
894            "device.generated.29",
895            "device.generated.30",
896            "device.generated.31",
897            "device.generated.32",
898            "device.generated.33",
899            "device.generated.34",
900            "device.generated.35",
901            "device.generated.36",
902            "device.generated.37",
903            "device.generated.38",
904            "device.generated.39",
905            "device.generated.40",
906            "device.generated.41",
907            "device.generated.42",
908            "device.generated.43",
909            "device.generated.44",
910            "device.generated.45",
911            "device.generated.46",
912            "device.generated.47",
913            "device.generated.48",
914            "device.generated.49",
915            "device.generated.50",
916            "device.generated.51",
917            "device.generated.52",
918            "device.generated.53",
919            "device.generated.54",
920            "device.generated.55",
921            "device.generated.56",
922            "device.generated.57",
923            "device.generated.58",
924            "device.generated.59",
925            "device.generated.60",
926            "device.generated.61",
927            "device.generated.62",
928            "device.generated.63",
929        ];
930        IDS[index]
931    }
932
933    fn sample() -> BenchmarkPassSelectionSample {
934        BenchmarkPassSelectionSample {
935            frontier_items: 10,
936            reuse_count: 10,
937            avoidable_readback_bytes: 10,
938            planning_budget_ns: 100,
939            scratch_budget_bytes: 100,
940        }
941    }
942
943    fn candidate(
944        pass_id: &'static str,
945        min_frontier_items: u64,
946        min_reuse_count: u64,
947        min_avoided_readback_bytes: u64,
948        planning_cost_ns: u64,
949        scratch_bytes: u64,
950        expected_speedup_bps: u32,
951        mandatory_when_profitable: bool,
952    ) -> BenchmarkPassCandidate {
953        BenchmarkPassCandidate {
954            pass_id,
955            min_frontier_items,
956            min_reuse_count,
957            min_avoided_readback_bytes,
958            planning_cost_ns,
959            scratch_bytes,
960            expected_speedup_bps,
961            mandatory_when_profitable,
962        }
963    }
964}