Skip to content

Commit 5474d1b

Browse files
committed
fix(pr-x1): rename array_windows → array_chunks (collision with std)
The plural rename in 2a2dfbf collided with the std slice method `array_windows` already referenced in `src/simd.rs` (lines 137-142, the `// Preferred SIMD lane widths` block uses `data.array_windows::<N>()` in its examples). Renamed to `array_chunks`, which: - matches the actual non-overlapping semantics of the helper - aligns with std's `slice::array_chunks` / `slice::as_chunks` naming - avoids any collision with std's `array_windows` (overlapping) that the SIMD layer will use once it stabilises Also fixes a sed double-substitution bug from 2a2dfbf that left `array_windowss` (double-s) in three places in `src/simd.rs` — those are now back to the correct `array_windows` reference to std's method. Module doc now contrasts our non-overlapping `array_chunks` against std's overlapping `array_windows` so the naming choice is documented in-tree.
1 parent 9a5cb6a commit 5474d1b

3 files changed

Lines changed: 48 additions & 47 deletions

File tree

Lines changed: 43 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,46 @@
1-
//! Const-size sliding-window helpers over `&[T]` (PR-X1).
1+
//! Const-size non-overlapping chunk helpers over `&[T]` (PR-X1).
22
//!
33
//! Centralises the `&[T] → impl Iterator<Item = &[T; N]>` pattern that
44
//! SIMD-staged consumers use to walk a buffer N lanes at a time. Without
55
//! this helper, each consumer either calls `slice::as_chunks::<N>` directly
66
//! (fine but undiscoverable) or rolls a raw slice index without the
77
//! compile-time bounds check.
88
//!
9-
//! # Semanticsnon-overlapping (NOT std `array_windows`)
9+
//! # Naming`array_chunks`, not `array_windows`
1010
//!
11-
//! Despite the plural name, this is the **non-overlapping** chunk variant —
12-
//! consecutive windows do not share elements. The name follows std's
13-
//! plural iterator-type convention ([`std::slice::ArrayWindows`]), but the
14-
//! semantics match [`std::slice::ArrayChunks`] / `slice::as_chunks`.
11+
//! `std::slice::array_windows::<N>()` (nightly) already exists and is the
12+
//! **overlapping** iterator — `crate::simd::*` re-uses that name for the
13+
//! std method once it stabilises (see the `// Preferred SIMD lane widths`
14+
//! block at the top of `src/simd.rs`, which uses `data.array_windows::<N>()`
15+
//! in its examples).
1516
//!
16-
//! For an 8-element input walked at `N = 4`:
17-
//! - `array_windows` (this module): yields `[0..4]`, `[4..8]` — **2 windows**.
17+
//! This helper is the **non-overlapping** variant, matching
18+
//! [`std::slice::ArrayChunks`] / stable `slice::as_chunks`. For an 8-element
19+
//! input at `N = 4`:
20+
//! - `array_chunks` (this module): yields `[0..4]`, `[4..8]` — 2 windows.
1821
//! - `std::slice::array_windows` (overlapping): would yield 5 windows.
1922
//!
2023
//! Non-overlapping is the correct shape for SIMD-staged inner loops where
2124
//! each lane-register load consumes its N elements before advancing by N.
2225
//!
2326
//! # Layering
2427
//!
25-
//! Lives in `hpc::array_windows`, re-exported from `crate::simd::*` per the
28+
//! Lives in `hpc::array_chunks`, re-exported from `crate::simd::*` per the
2629
//! W1a consumer contract at
2730
//! `.claude/knowledge/vertical-simd-consumer-contract.md`.
2831
//!
2932
//! # Design reference
3033
//!
31-
//! `.claude/knowledge/pr-x1-design.md` § "3. `array_window`". This module
32-
//! ships the **iterator-shape** variant (whole-buffer walk yielding all
33-
//! const-size windows); the design doc's singular-window sketch
34-
//! (`array_window(slice, offset) -> &[T; N]`) was superseded by the
35-
//! iterator form here, which composes directly with SIMD-staged consumer
36-
//! loops and avoids per-call panic surface in tight inner loops. The name
37-
//! was pluralised to match the std iterator-type convention.
34+
//! `.claude/knowledge/pr-x1-design.md` § "3. `array_window`". The design
35+
//! doc's singular-window sketch (`array_window(slice, offset) -> &[T; N]`)
36+
//! was superseded by the iterator form here. The name landed as
37+
//! `array_chunks` to avoid collision with std's `array_windows` (overlapping)
38+
//! already referenced in the SIMD layer.
3839
3940
/// Walk `data` as a sequence of non-overlapping const-size windows.
4041
///
4142
/// Returns an iterator over `&[T; N]` references into `data`. The tail
42-
/// (`data.len() % N` items) is discarded; use [`array_windows_checked`] to
43+
/// (`data.len() % N` items) is discarded; use [`array_chunks_checked`] to
4344
/// fail-fast when the length is not a multiple of `N`.
4445
///
4546
/// Zero-cost: this is a thin wrapper around [`slice::as_chunks`] that pins
@@ -48,9 +49,9 @@
4849
/// # Examples
4950
///
5051
/// ```
51-
/// use ndarray::hpc::array_windows::array_windows;
52+
/// use ndarray::hpc::array_chunks::array_chunks;
5253
/// let data: Vec<u8> = (0..16).collect();
53-
/// let windows: Vec<&[u8; 4]> = array_windows::<u8, 4>(&data).collect();
54+
/// let windows: Vec<&[u8; 4]> = array_chunks::<u8, 4>(&data).collect();
5455
/// assert_eq!(windows.len(), 4);
5556
/// assert_eq!(windows[0], &[0, 1, 2, 3]);
5657
/// assert_eq!(windows[3], &[12, 13, 14, 15]);
@@ -59,43 +60,43 @@
5960
/// # Examples — tail discarded
6061
///
6162
/// ```
62-
/// use ndarray::hpc::array_windows::array_windows;
63+
/// use ndarray::hpc::array_chunks::array_chunks;
6364
/// let data: Vec<u8> = (0..7).collect();
64-
/// let windows: Vec<&[u8; 4]> = array_windows::<u8, 4>(&data).collect();
65+
/// let windows: Vec<&[u8; 4]> = array_chunks::<u8, 4>(&data).collect();
6566
/// // 7 / 4 = 1 window; the trailing 3 items are dropped.
6667
/// assert_eq!(windows.len(), 1);
6768
/// ```
6869
#[inline]
69-
pub fn array_windows<T, const N: usize>(data: &[T]) -> impl Iterator<Item = &[T; N]> + '_ {
70+
pub fn array_chunks<T, const N: usize>(data: &[T]) -> impl Iterator<Item = &[T; N]> + '_ {
7071
data.as_chunks::<N>().0.iter()
7172
}
7273

7374
/// Walk `data` as `&[T; N]` windows, returning `Err(())` if `data.len()`
7475
/// is not a multiple of `N`.
7576
///
76-
/// This is the strict variant of [`array_windows`]: the consumer asserts up
77+
/// This is the strict variant of [`array_chunks`]: the consumer asserts up
7778
/// front that the buffer is lane-aligned and the caller wants the error
7879
/// surfaced rather than silently truncating.
7980
///
8081
/// # Examples
8182
///
8283
/// ```
83-
/// use ndarray::hpc::array_windows::array_windows_checked;
84+
/// use ndarray::hpc::array_chunks::array_chunks_checked;
8485
/// let data: Vec<u8> = (0..16).collect();
85-
/// let it = array_windows_checked::<u8, 4>(&data).expect("16 is a multiple of 4");
86+
/// let it = array_chunks_checked::<u8, 4>(&data).expect("16 is a multiple of 4");
8687
/// assert_eq!(it.count(), 4);
8788
///
8889
/// let bad: Vec<u8> = (0..7).collect();
89-
/// assert!(array_windows_checked::<u8, 4>(&bad).is_err());
90+
/// assert!(array_chunks_checked::<u8, 4>(&bad).is_err());
9091
/// ```
9192
#[inline]
92-
pub fn array_windows_checked<T, const N: usize>(
93+
pub fn array_chunks_checked<T, const N: usize>(
9394
data: &[T],
9495
) -> Result<impl Iterator<Item = &[T; N]> + '_, ()> {
9596
if data.len() % N != 0 {
9697
return Err(());
9798
}
98-
Ok(array_windows::<T, N>(data))
99+
Ok(array_chunks::<T, N>(data))
99100
}
100101

101102
// ============================================================================
@@ -108,46 +109,46 @@ mod tests {
108109

109110
/// 16-element buffer yields four 4-wide windows.
110111
#[test]
111-
fn array_windows_4_over_16() {
112+
fn array_chunks_4_over_16() {
112113
let data: Vec<u8> = (0u8..16).collect();
113-
let windows: Vec<&[u8; 4]> = array_windows::<u8, 4>(&data).collect();
114+
let windows: Vec<&[u8; 4]> = array_chunks::<u8, 4>(&data).collect();
114115
assert_eq!(windows.len(), 4);
115116
assert_eq!(windows[0], &[0, 1, 2, 3]);
116117
assert_eq!(windows[1], &[4, 5, 6, 7]);
117118
assert_eq!(windows[2], &[8, 9, 10, 11]);
118119
assert_eq!(windows[3], &[12, 13, 14, 15]);
119120
}
120121

121-
/// Tail items are silently discarded by `array_windows`.
122+
/// Tail items are silently discarded by `array_chunks`.
122123
#[test]
123-
fn array_windows_drops_tail() {
124+
fn array_chunks_drops_tail() {
124125
let data: Vec<u8> = (0u8..7).collect();
125-
let windows: Vec<&[u8; 4]> = array_windows::<u8, 4>(&data).collect();
126+
let windows: Vec<&[u8; 4]> = array_chunks::<u8, 4>(&data).collect();
126127
assert_eq!(windows.len(), 1);
127128
assert_eq!(windows[0], &[0, 1, 2, 3]);
128129
}
129130

130131
/// Mismatched length surfaces as Err in the checked variant.
131132
#[test]
132-
fn array_windows_checked_rejects_mismatch() {
133-
assert!(array_windows_checked::<u8, 4>(&[0u8; 7]).is_err());
134-
assert!(array_windows_checked::<u8, 4>(&[0u8; 5]).is_err());
135-
assert!(array_windows_checked::<u8, 4>(&[0u8; 1]).is_err());
133+
fn array_chunks_checked_rejects_mismatch() {
134+
assert!(array_chunks_checked::<u8, 4>(&[0u8; 7]).is_err());
135+
assert!(array_chunks_checked::<u8, 4>(&[0u8; 5]).is_err());
136+
assert!(array_chunks_checked::<u8, 4>(&[0u8; 1]).is_err());
136137
}
137138

138139
/// Aligned length succeeds in the checked variant.
139140
#[test]
140-
fn array_windows_checked_accepts_aligned() {
141+
fn array_chunks_checked_accepts_aligned() {
141142
let data = [0u8; 16];
142-
let it = array_windows_checked::<u8, 4>(&data).expect("16 is a multiple of 4");
143+
let it = array_chunks_checked::<u8, 4>(&data).expect("16 is a multiple of 4");
143144
assert_eq!(it.count(), 4);
144145
}
145146

146147
/// Empty buffer yields zero windows (not an error in either variant).
147148
#[test]
148-
fn array_windows_empty_buffer() {
149-
assert_eq!(array_windows::<u8, 4>(&[]).count(), 0);
150-
let it = array_windows_checked::<u8, 4>(&[]).expect("0 % 4 == 0, should be Ok");
149+
fn array_chunks_empty_buffer() {
150+
assert_eq!(array_chunks::<u8, 4>(&[]).count(), 0);
151+
let it = array_chunks_checked::<u8, 4>(&[]).expect("0 % 4 == 0, should be Ok");
151152
assert_eq!(it.count(), 0);
152153
}
153154
}

src/hpc/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ pub mod fingerprint;
4242
// PR-X1 — multi-lane typed column substrate + const-size array windows.
4343
// Re-exported from crate::simd::* per the W1a consumer contract.
4444
pub mod column;
45-
pub mod array_windows;
45+
pub mod array_chunks;
4646
#[allow(missing_docs)]
4747
pub mod plane;
4848
#[allow(missing_docs)]

src/simd.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -134,12 +134,12 @@ fn tier() -> Tier {
134134
// function uses as_chunks::<16>() + as_chunks::<8>() for SIMD widths.
135135

136136
// ============================================================================
137-
// Preferred SIMD lane widths — compile-time constants for array_windowss
137+
// Preferred SIMD lane widths — compile-time constants for array_windows
138138
// ============================================================================
139139
//
140-
// Consumer code uses these to select array_windowss size at compile time:
140+
// Consumer code uses these to select array_windows size at compile time:
141141
//
142-
// for window in data.array_windowss::<{crate::simd::PREFERRED_F64_LANES}>() {
142+
// for window in data.array_windows::<{crate::simd::PREFERRED_F64_LANES}>() {
143143
// let v = F64x8::from_array(*window); // AVX-512: native 8-wide
144144
// // or
145145
// let v = F64x4::from_array(*window); // AVX2: native 4-wide
@@ -1723,7 +1723,7 @@ pub use crate::hpc::fingerprint::{
17231723
// through `crate::simd::*`; without these re-exports the cognitive-shader
17241724
// stack reaches for `crate::hpc::column::*` directly, breaking the contract.
17251725
pub use crate::hpc::column::MultiLaneColumn;
1726-
pub use crate::hpc::array_windows::{array_windows, array_windows_checked};
1726+
pub use crate::hpc::array_chunks::{array_chunks, array_chunks_checked};
17271727

17281728
pub use crate::hpc::quantized::{
17291729
dequantize_i2_to_f32, dequantize_i4_to_f32, dequantize_i8_to_f32, quantize_f32_to_i2, quantize_f32_to_i4,

0 commit comments

Comments
 (0)