Skip to content

Commit 417131b

Browse files
committed
fix(lints+docs): clippy clean on graduated modules + rustdoc examples
Two CI / review-feedback fixes on PR #194: 1) Clippy (`-D warnings`, --features rayon / approx,serde,rayon): 10 errors surfaced because the graduated modules are no longer under hpc/mod.rs's `#![allow(clippy::all, ...)]` umbrella. Fixed each at the canonical Rust idiom rather than re-applying the umbrella — graduated modules hold to the higher standard: - `bitwise.rs:110,155` — `acc = acc + (x + y);` → `acc += x + y;` (assign_op_pattern; bare without parens). - `distance.rs:99` — `for j in i..n { points[j] }` → `for p in &points[i..n] { p[0]..p[2] }` (needless_range_loop). - `byte_scan.rs:38,71` — `for j in i..n { if haystack[j] == needle { result.push(j); }}` → `for (offset, &byte) in haystack[i..n] .iter().enumerate() { if byte == needle { result.push(i + offset); }}` (needless_range_loop with index preservation). - `byte_scan.rs:101,129` — same pattern but counting via `total += 1`; switched to `for &byte in &haystack[i..n]` (no index needed at all). - `spatial_hash.rs:334` — `for lane in 0..8 { d2_arr[lane] }` → `for (lane, &d2_lane) in d2_arr.iter().enumerate()`. - `spatial_hash.rs:342` — `for i in (chunks*8)..candidates.len() { candidates[i] }` → `let tail_start = chunks * 8; for (offset, &cand) in candidates[tail_start..].iter() .enumerate() { result.push((tail_start + offset, d2)) }`. 2) CodeRabbit + CLAUDE.md hard rule ("All public APIs need /// doc comments with examples"): Added `# Example` rustdoc blocks to each of the five new `pub mod` declarations in `src/lib.rs`. Each example uses only the actual public API of the target module (verified by running the doctests): - `bitwise` — popcount + hamming over [0xFF; 16]/[0x00; 16] - `heel_f64x8` — cosine_f64_simd + dot_f64_simd over [1.0; 32] - `distance` — l1/l2/linf_f64_simd over pythagorean (3,0)/(0,4) - `byte_scan` — byte_find_all over a 23-char fixture - `spatial_hash` — SpatialHash::new + insert + len All five doctests pass under `cargo test --doc`. `cargo clippy --features rayon --lib -- -D warnings` and `cargo clippy --features approx,serde,rayon -- -D warnings` both green.
1 parent ca2fc14 commit 417131b

5 files changed

Lines changed: 74 additions & 23 deletions

File tree

src/bitwise.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ unsafe fn hamming_avx512bw(a: &[u8], b: &[u8]) -> u64 {
107107
let hi = xor.shr_epi16(4) & low_mask;
108108
let popcnt_lo = lookup.shuffle_bytes(lo);
109109
let popcnt_hi = lookup.shuffle_bytes(hi);
110-
acc = acc + (popcnt_lo + popcnt_hi);
110+
acc += popcnt_lo + popcnt_hi;
111111

112112
i += 64;
113113
inner_count += 1;
@@ -152,7 +152,7 @@ unsafe fn popcount_avx512bw(a: &[u8]) -> u64 {
152152
let hi = va.shr_epi16(4) & low_mask;
153153
let popcnt_lo = lookup.shuffle_bytes(lo);
154154
let popcnt_hi = lookup.shuffle_bytes(hi);
155-
acc = acc + (popcnt_lo + popcnt_hi);
155+
acc += popcnt_lo + popcnt_hi;
156156

157157
i += 64;
158158
inner_count += 1;

src/byte_scan.rs

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,9 @@ pub(crate) mod simd_impl {
3535
i += 32;
3636
}
3737
// Scalar tail
38-
for j in i..n {
39-
if haystack[j] == needle {
40-
result.push(j);
38+
for (offset, &byte) in haystack[i..n].iter().enumerate() {
39+
if byte == needle {
40+
result.push(i + offset);
4141
}
4242
}
4343
result
@@ -68,9 +68,9 @@ pub(crate) mod simd_impl {
6868
i += 64;
6969
}
7070
// Scalar tail
71-
for j in i..n {
72-
if haystack[j] == needle {
73-
result.push(j);
71+
for (offset, &byte) in haystack[i..n].iter().enumerate() {
72+
if byte == needle {
73+
result.push(i + offset);
7474
}
7575
}
7676
result
@@ -98,8 +98,8 @@ pub(crate) mod simd_impl {
9898
}
9999
i += 32;
100100
}
101-
for j in i..n {
102-
if haystack[j] == needle {
101+
for &byte in &haystack[i..n] {
102+
if byte == needle {
103103
total += 1;
104104
}
105105
}
@@ -126,8 +126,8 @@ pub(crate) mod simd_impl {
126126
total += mask.count_ones() as usize;
127127
i += 64;
128128
}
129-
for j in i..n {
130-
if haystack[j] == needle {
129+
for &byte in &haystack[i..n] {
130+
if byte == needle {
131131
total += 1;
132132
}
133133
}

src/distance.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -96,10 +96,10 @@ pub(crate) mod simd_impl {
9696
}
9797

9898
// Scalar tail
99-
for j in i..n {
100-
let dx = query[0] - points[j][0];
101-
let dy = query[1] - points[j][1];
102-
let dz = query[2] - points[j][2];
99+
for p in &points[i..n] {
100+
let dx = query[0] - p[0];
101+
let dy = query[1] - p[1];
102+
let dz = query[2] - p[2];
103103
out.push(dx * dx + dy * dy + dz * dz);
104104
}
105105
}
@@ -211,7 +211,7 @@ pub fn l1_f64_simd(a: &[f64], b: &[f64]) -> f64 {
211211
for i in 0..chunks {
212212
let va = F64x8::from_slice(&a[i * 8..]);
213213
let vb = F64x8::from_slice(&b[i * 8..]);
214-
acc = acc + (va - vb).abs();
214+
acc += (va - vb).abs();
215215
}
216216
let mut sum = acc.reduce_sum();
217217
let offset = chunks * 8;

src/lib.rs

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -276,28 +276,78 @@ pub mod simd_caps;
276276
/// Graduated from `crate::hpc::bitwise::*` (substrate-tier; uses
277277
/// `crate::simd::U64x8` polyfill internally). Back-compat re-export in
278278
/// `crate::hpc::*` preserves existing import paths.
279+
///
280+
/// # Example
281+
///
282+
/// ```
283+
/// use ndarray::bitwise::{hamming_distance_raw, popcount_raw};
284+
/// let a = [0xFFu8; 16];
285+
/// let b = [0x00u8; 16];
286+
/// assert_eq!(hamming_distance_raw(&a, &b), 128);
287+
/// assert_eq!(popcount_raw(&a), 128);
288+
/// ```
279289
#[cfg(feature = "std")]
280290
pub mod bitwise;
281291

282292
/// F64x8 HEEL distance kernels — 8-plane weighted Hamming, f64 SIMD
283293
/// dot / cosine / sum-of-squares. Graduated from `crate::hpc::heel_f64x8::*`.
294+
///
295+
/// # Example
296+
///
297+
/// ```
298+
/// use ndarray::heel_f64x8::{cosine_f64_simd, dot_f64_simd};
299+
/// let a = vec![1.0_f64; 32];
300+
/// let b = vec![1.0_f64; 32];
301+
/// assert!((cosine_f64_simd(&a, &b) - 1.0).abs() < 1e-10);
302+
/// assert!((dot_f64_simd(&a, &b) - 32.0).abs() < 1e-10);
303+
/// ```
284304
#[cfg(feature = "std")]
285305
pub mod heel_f64x8;
286306

287307
/// Batch distance computations — spatial 3D-point queries +
288308
/// slice-shape L1 / L2 / L∞ (PR-X10 A6). Graduated from
289309
/// `crate::hpc::distance::*`.
310+
///
311+
/// # Example
312+
///
313+
/// ```
314+
/// use ndarray::distance::{l1_f64_simd, l2_f64_simd, linf_f64_simd};
315+
/// let a = vec![3.0_f64, 0.0];
316+
/// let b = vec![0.0_f64, 4.0];
317+
/// assert!((l1_f64_simd(&a, &b) - 7.0).abs() < 1e-12);
318+
/// assert!((l2_f64_simd(&a, &b) - 5.0).abs() < 1e-12);
319+
/// assert!((linf_f64_simd(&a, &b) - 4.0).abs() < 1e-12);
320+
/// ```
290321
#[cfg(feature = "std")]
291322
pub mod distance;
292323

293324
/// SIMD-accelerated byte-scan utilities — needle search, delimiter
294325
/// finding, parallel byte comparison. Graduated from
295326
/// `crate::hpc::byte_scan::*`.
327+
///
328+
/// # Example
329+
///
330+
/// ```
331+
/// use ndarray::byte_scan::byte_find_all;
332+
/// let haystack = b"hello world, hello rust";
333+
/// let hits = byte_find_all(haystack, b'l');
334+
/// assert_eq!(hits, vec![2, 3, 9, 15, 16]);
335+
/// ```
296336
#[cfg(feature = "std")]
297337
pub mod byte_scan;
298338

299339
/// SIMD-accelerated spatial hash — bucketing, candidate gather, hash
300340
/// collision detection. Graduated from `crate::hpc::spatial_hash::*`.
341+
///
342+
/// # Example
343+
///
344+
/// ```
345+
/// use ndarray::spatial_hash::SpatialHash;
346+
/// let mut grid = SpatialHash::new(1.0);
347+
/// grid.insert(0, 0.0, 0.0, 0.0);
348+
/// grid.insert(1, 10.0, 10.0, 10.0);
349+
/// assert_eq!(grid.len(), 2);
350+
/// ```
301351
#[cfg(feature = "std")]
302352
pub mod spatial_hash;
303353

src/spatial_hash.rs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -331,18 +331,19 @@ pub(crate) unsafe fn batch_sq_dist_avx2(query: [f32; 3], candidates: &[[f32; 3]]
331331

332332
// Compare: d2 <= radius_sq (scalar array comparison — no F32x8 cmp polyfill)
333333
let d2_arr = d2.to_array();
334-
for lane in 0..8 {
335-
if d2_arr[lane] <= radius_sq {
336-
result.push((base + lane, d2_arr[lane]));
334+
for (lane, &d2_lane) in d2_arr.iter().enumerate() {
335+
if d2_lane <= radius_sq {
336+
result.push((base + lane, d2_lane));
337337
}
338338
}
339339
}
340340

341341
// Scalar tail
342-
for i in (chunks * 8)..candidates.len() {
343-
let d2 = sq_dist_f32(query, candidates[i]);
342+
let tail_start = chunks * 8;
343+
for (offset, &cand) in candidates[tail_start..].iter().enumerate() {
344+
let d2 = sq_dist_f32(query, cand);
344345
if d2 <= radius_sq {
345-
result.push((i, d2));
346+
result.push((tail_start + offset, d2));
346347
}
347348
}
348349

0 commit comments

Comments
 (0)