Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 46 additions & 1 deletion strided-basic/benches/support/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,13 +73,23 @@ pub struct CaseResult {
b_allocs: f64,
threshold: Option<f64>,
attempts_exceeded: usize,
report_ratio: bool,
}

impl CaseResult {
/// Report the ratio but retain the allocation gate.
#[allow(dead_code)] // Used by the fused bench, not the basic bench.
pub fn report_ratio(mut self) -> Self {
self.report_ratio = true;
self
}

fn failed(&self) -> bool {
match self.threshold {
Some(_) => {
self.attempts_exceeded == ATTEMPTS || self.a_allocs > 0.0 || self.b_allocs > 0.0
(!self.report_ratio && self.attempts_exceeded == ATTEMPTS)
|| self.a_allocs > 0.0
|| self.b_allocs > 0.0
}
None => false,
}
Expand Down Expand Up @@ -145,6 +155,7 @@ pub fn measure_case(
b_allocs: max_b_allocs,
threshold,
attempts_exceeded,
report_ratio: false,
}
}

Expand All @@ -157,6 +168,8 @@ pub fn print_table(cases: &[CaseResult], title: &str) {
.push_str("|----|------|--------:|--------:|------:|------------:|------------:|------|\n");
for case in cases {
let gate = match case.threshold {
Some(_) if case.report_ratio && case.failed() => "FAIL (alloc)".to_string(),
Some(threshold) if case.report_ratio => format!("report (ref {threshold}; alloc=0)"),
Some(threshold) if case.failed() => format!("FAIL (>{threshold})"),
Some(threshold) => format!("<= {threshold}"),
None => "report".to_string(),
Expand Down Expand Up @@ -191,3 +204,35 @@ pub fn exit_if_failed(cases: &[CaseResult]) {
std::process::exit(1);
}
}

#[cfg(test)]
mod tests {
#[allow(unused_imports)] // The harness-free bench enables cfg(test) without running tests.
use super::*;

#[test]
fn ratio_report_still_gates_allocations() {
let mut case = CaseResult {
id: "S2",
description: "test",
a_ns: 2.0,
b_ns: 1.0,
ratio: 2.0,
a_allocs: 0.0,
b_allocs: 0.0,
threshold: Some(1.5),
attempts_exceeded: ATTEMPTS,
report_ratio: false,
};
assert!(case.failed());
case = case.report_ratio();
assert!(!case.failed());
case.a_allocs = 1.0 / ALLOC_ITERS as f64;
assert!(case.failed());
case.a_allocs = 0.0;
case.b_allocs = 1.0 / ALLOC_ITERS as f64;
assert!(case.failed());
case.threshold = None;
assert!(!case.failed());
}
}
14 changes: 8 additions & 6 deletions strided-fused/benches/overhead_smoke.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,15 @@
//! every ratio.
//!
//! Run with `OVERHEAD_GATE=1` to make a failed gate exit non-zero; without it
//! the table is printed and the process succeeds. The gate is deliberately
//! forgiving: it fails only when all [`support::ATTEMPTS`] attempts exceed the
//! threshold, and the per-round timing is the minimum of [`support::ROUNDS`]
//! rounds.
//! the table is printed and the process succeeds. A ratio gate fails only when
//! all [`support::ATTEMPTS`] attempts exceed the threshold; gated allocations
//! must be zero. Each timing is the minimum of [`support::ROUNDS`] rounds.
//!
//! Rows (see `#306`):
//! - S1: erased fused `execute` under `Exec::serial()` vs a
//! budget-one `Exec::new(&pool, 1)` for a two-op DAG, `8x8x8`; guards #305.
//! - S2: typed fused single `Add` vs `zip_map2_into` add, contiguous `8x8x8`;
//! guards per-element dispatch in the single-op specialization.
//! reports the ratio and gates on zero allocations for both paths.
//! - S5: unspecialized replay vs the specialized `add`-then-`multiply` DAG,
//! `8x8x8` (reported only).
//!
Expand All @@ -44,6 +43,8 @@ use support::{measure_case, print_table, CaseResult};

const SIDE: usize = 8;
const LEN: usize = SIDE * SIDE * SIDE;
// Shared runners have machine-dependent ratios, so this is a reference, not a gate.
const S2_RATIO_REFERENCE: f64 = 1.5;

fn two_op_dag() -> FusedPlan {
FusedPlan::new(
Expand Down Expand Up @@ -148,7 +149,7 @@ fn s2_case() -> CaseResult {
"S2",
"fused single add vs zip_map2_into add",
5_000,
Some(1.5),
Some(S2_RATIO_REFERENCE),
|| {
fused_elementwise_into(
std::slice::from_mut(&mut fused_view),
Expand All @@ -171,6 +172,7 @@ fn s2_case() -> CaseResult {
black_box(map_view.as_mut_ptr());
},
)
.report_ratio()
}

/// S5: unspecialized replay vs the recognized `add`-then-`multiply` shape.
Expand Down
4 changes: 4 additions & 0 deletions strided-fused/tests/overhead_smoke_support.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#![allow(dead_code)]

#[path = "../../strided-basic/benches/support/mod.rs"]
mod support;
Loading