1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
//! Root of the `perf` integration-test binary: `#[ignore]`d throughput benchmarks, meant
//! to be run and read by hand, not correctness gates
//!
//! Native benches (`bandwidth`, `batched`, `dtypes`, `prepack`, `sgemm`, `small_mn`)
//! compare gemmkit against the `gemm` crate and/or `matrixmultiply`; those dev-dependencies
//! are excluded on wasm, so those modules are too. The wasm bench (`simd128`) has no
//! external crate to compare against on that target, so it instead measures gemmkit's
//! `simd128` token against its own scalar token. This whole file is `cfg(not(miri))`:
//! Miri cannot execute the target-feature-gated SIMD intrinsics these benches drive
//!
//! Every bench saturates all available cores, so each takes the shared `BENCH_GUARD` lock
//! as its first line to keep 2 from corrupting each other's numbers. Run with:
//! cargo test -p gemmkit --release --test perf -- --ignored --nocapture
//! Run the wasm benchmark (compile-time `+simd128`) under a wasm runtime:
//! RUSTFLAGS="-C target-feature=+simd128" CARGO_TARGET_WASM32_WASIP1_RUNNER=wasmtime \
//! cargo test -p gemmkit --release --target wasm32-wasip1 \
//! --no-default-features --features std --test perf -- --ignored --nocapture
// Shared harness (BENCH_GUARD, fill, measure/measure_gbps, Stat, the native-ISA token)
// Bandwidth-bound shapes: STREAM Triad/Copy ceilings, gemv (axpy/dot/mixed), gevv, small-k
// Batched GEMM (gemm_batched) vs naive gemm() loops, serial and parallel
// Fused-epilogue overhead vs plain gemm, same shape and ISA; asserts a ratio bound
// f16 / bf16 / i8 / c32 element-type throughput, each vs its available external baseline
// Prepacked-RHS/LHS reuse, prepack buffer setup cost, shared-LHS gate sweep
// f32 sgemm vs gemm crate / matrixmultiply, thread-scaling, per-call latency
// wasm simd128 vs the scalar token, single-threaded
// Small-m,n horizontal (inner-product) route benches