Skip to content

Commit cb5caad

Browse files
committed
chore(ndarray): migrate benches off nightly #![feature(test)] to criterion 0.5 + Tier A clippy fixes
User directive: stable Rust 1.94.1 only — no nightly features anywhere. The bench tests used #![feature(test)] + extern crate test + #[bench] (unstable libtest_bench framework), blocking CI on stable. Migrated all 13 benches to criterion 0.5 (already established workspace pattern via crates/p64 + crates/phyllotactic-manifold). Files migrated (10 source files; append.rs/construct.rs/numeric.rs were already criterion-based; Cargo.toml + ndarray-rand/Cargo.toml had the [[bench]] + criterion dev-dep prep already in working tree): benches/bench1.rs (1106 LOC, ~80 #[bench] fns + mat_mul! macro) benches/iter.rs (436 LOC, ~30 #[bench] fns) benches/par_rayon.rs (182 LOC, rayon-feature-gated) benches/zip.rs (133 LOC) benches/to_shape.rs (95 LOC) benches/higher-order.rs (93 LOC) benches/chunks.rs (87 LOC) benches/gemv_gemm.rs (75 LOC) benches/reserve.rs (31 LOC) ndarray-rand/benches/bench.rs (31 LOC) Mechanical conversion pattern: BEFORE: #[bench] fn name(b: &mut Bencher) { b.iter(|| ...); } AFTER: fn name(c: &mut Criterion) { c.bench_function("name", |b| b.iter(|| ...)); } criterion_group!(benches, name1, name2, ...); criterion_main!(benches); Bench function names preserved exactly so `cargo bench --bench foo name` keeps working. Wrapped inputs with criterion's black_box where the original used test::black_box. Special handling: - bench1.rs's mat_mul! macro now generates pub fn $name(c: &mut Criterion) inside each module + a pub fn group(c) that calls them all. Top-level criterion_group!(matmul_benches, mat_mul_f32::group, ...) registers all 30 generated benches. - bench1.rs split into 11 criterion_groups (iter/sum/add/scalar/ add_strided/iadd_scalar/iter_misc/dot/dimensionality/matmul/std) for readability; criterion_main! aggregates them all. - iter.rs splits #[cfg(feature = "std")] benches into a separate criterion_group with conditional criterion_main! inclusion. Tier A clippy fixes (per user request to ship clean): - examples/life.rs:1 + tests/assign.rs:1 + tests/array.rs:1 + benches/bench1.rs:1 + benches/iter.rs:1 — added #[allow(clippy::reversed_empty_ranges)] for the s![1..-1, ..] Python-style negative-indexing macro pattern (false positive — clippy can't see through s! macro). - tests/oper.rs:300 — replaced unsafe Vec::with_capacity + set_len uninit pattern with proper MaybeUninit<A>::uninit + write per slot + ManuallyDrop transmute. SAFETY comments document each unsafe block. Verification (per user "use clippy not check"): cargo clippy --benches --tests --examples --features rayon --no-deps → 0 errors in benches/tests/examples (down from 18+). 5 pre-existing lib code errors remain (NOT introduced here, NOT in scope for this commit): - src/hpc/quantized.rs:431 + src/hpc/blackboard.rs:484-485 + src/hpc/jitson/parser.rs:487 — clippy::approx_constant (literal PI values; should use std::f{32,64}::consts::PI) - src/hpc/renderer.rs:428 — clippy::absurd_extreme_comparisons These are lib-level tech debt visible to `cargo clippy --lib` and require separate fix commits.
1 parent 130aa8d commit cb5caad

20 files changed

Lines changed: 1387 additions & 955 deletions

Cargo.lock

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,56 @@ quickcheck = { workspace = true }
7171
approx = { workspace = true, default-features = true }
7272
itertools = { workspace = true }
7373
ndarray-gen = { workspace = true }
74+
criterion = { version = "0.5", features = ["html_reports"] }
75+
76+
[[bench]]
77+
name = "append"
78+
harness = false
79+
80+
[[bench]]
81+
name = "bench1"
82+
harness = false
83+
84+
[[bench]]
85+
name = "chunks"
86+
harness = false
87+
88+
[[bench]]
89+
name = "construct"
90+
harness = false
91+
92+
[[bench]]
93+
name = "gemv_gemm"
94+
harness = false
95+
96+
[[bench]]
97+
name = "higher-order"
98+
harness = false
99+
100+
[[bench]]
101+
name = "iter"
102+
harness = false
103+
104+
[[bench]]
105+
name = "numeric"
106+
harness = false
107+
108+
[[bench]]
109+
name = "par_rayon"
110+
harness = false
111+
required-features = ["rayon"]
112+
113+
[[bench]]
114+
name = "reserve"
115+
harness = false
116+
117+
[[bench]]
118+
name = "to_shape"
119+
harness = false
120+
121+
[[bench]]
122+
name = "zip"
123+
harness = false
74124

75125
[features]
76126
default = ["std"]

benches/append.rs

Lines changed: 16 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,30 @@
1-
#![feature(test)]
2-
3-
extern crate test;
4-
use test::Bencher;
5-
1+
use criterion::{black_box, criterion_group, criterion_main, Criterion};
62
use ndarray::prelude::*;
73

8-
#[bench]
9-
fn select_axis0(bench: &mut Bencher)
10-
{
4+
fn select_axis0(c: &mut Criterion) {
115
let a = Array::<f32, _>::zeros((256, 256));
126
let selectable = vec![0, 1, 2, 0, 1, 3, 0, 4, 16, 32, 128, 147, 149, 220, 221, 255, 221, 0, 1];
13-
bench.iter(|| a.select(Axis(0), &selectable));
7+
c.bench_function("select_axis0", |b| {
8+
b.iter(|| black_box(&a).select(Axis(0), black_box(&selectable)))
9+
});
1410
}
1511

16-
#[bench]
17-
fn select_axis1(bench: &mut Bencher)
18-
{
12+
fn select_axis1(c: &mut Criterion) {
1913
let a = Array::<f32, _>::zeros((256, 256));
2014
let selectable = vec![0, 1, 2, 0, 1, 3, 0, 4, 16, 32, 128, 147, 149, 220, 221, 255, 221, 0, 1];
21-
bench.iter(|| a.select(Axis(1), &selectable));
15+
c.bench_function("select_axis1", |b| {
16+
b.iter(|| black_box(&a).select(Axis(1), black_box(&selectable)))
17+
});
2218
}
2319

24-
#[bench]
25-
fn select_1d(bench: &mut Bencher)
26-
{
20+
fn select_1d(c: &mut Criterion) {
2721
let a = Array::<f32, _>::zeros(1024);
2822
let mut selectable = (0..a.len()).step_by(17).collect::<Vec<_>>();
2923
selectable.extend(selectable.clone().iter().rev());
30-
31-
bench.iter(|| a.select(Axis(0), &selectable));
24+
c.bench_function("select_1d", |b| {
25+
b.iter(|| black_box(&a).select(Axis(0), black_box(&selectable)))
26+
});
3227
}
28+
29+
criterion_group!(benches, select_axis0, select_axis1, select_1d);
30+
criterion_main!(benches);

0 commit comments

Comments
 (0)