onebrc/lane-j: wire GridBatch through ndarray MultiLaneColumn (D-DNV-1)#641
Conversation
The proven 64×64 gridlake batch table (E-1BRC-GRIDLAKE-SWEETSPOT-1) now renders its four accumulator columns as ndarray::simd::MultiLaneColumn gridlake carriers — min/max on the i32x16 lane, sum on i64x8, count (widened, non-negative) on u64x8, the integer lanes ndarray added for exactly this. GridBatch::as_gridlake_columns is a little-endian reading (zero re-layout), returning Err(()) on a mis-aligned grid to mirror MultiLaneColumn::new's own 64-byte contract. This is D-DNV-1 of the DeepNSM→V3 convergence plan: the batch table is not a bespoke struct, it is typed lanes over one carrier — the same MultiLaneColumn the COCA cognitive Cell (helix48/campq48/count/truth) composes from. Wire, don't invent. - Cargo.toml: lane-j feature pulls ndarray (default-features=false, std). - lane_j.rs: GridlakeColumns + as_gridlake_columns + 2 tests (LE roundtrip cell-for-cell against the source accumulators, incl. lane-boundary and tile-edge cells; unaligned-grid reject). Typed lanes exercised via len_i32x16/iter_i32x16 == grid/16, i64x8/u64x8 == grid/8. - STATUS_BOARD: deepnsm-v3-convergence-v1 section, D-DNV-1 In PR. Verified: cargo test --features lane-j (2/2 green); lane_j.rs fmt + clippy clean. Pre-existing fmt/clippy debt in sibling lanes (lane_s/lane_t) left untouched. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MLBnPuScZy6w9di2QEjsXM
📝 WalkthroughWalkthroughThis PR adds SIMD gridlake carrier support to onebrc-probe: the lane-j feature now pulls in the ndarray dependency, GridBatch becomes public and gains an as_gridlake_columns() method producing a new GridlakeColumns struct of MultiLaneColumn fields, with roundtrip and alignment tests. A status board entry documents related deliverables. ChangesGridlake SIMD Carrier and Status Board
Estimated code review effort: 2 (Simple) | ~12 minutes Sequence Diagram(s)sequenceDiagram
participant Test
participant GridBatch
participant MultiLaneColumn
Test->>GridBatch: as_gridlake_columns()
GridBatch->>GridBatch: encode mins/maxs/sums as LE i32/i64 bytes
GridBatch->>GridBatch: widen counts u32 to u64 LE bytes
GridBatch->>MultiLaneColumn: new(bytes) for each field
MultiLaneColumn-->>GridBatch: Ok(column) or alignment error
GridBatch-->>Test: Result<GridlakeColumns, ()>
Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (2)
crates/onebrc-probe/src/lane_j.rs (2)
218-238: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueThree near-identical serialization helpers — consider a generic implementation.
col_i32,col_i64, andcol_u64_from_u32differ only in element width/conversion. A small generic helper (e.g., overIntoIterator+ a byte-writer closure) would remove the duplication and reduce future drift risk if a fourth lane width is added.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@crates/onebrc-probe/src/lane_j.rs` around lines 218 - 238, The three serialization helpers col_i32, col_i64, and col_u64_from_u32 are near-identical and should be consolidated. Refactor the MultiLaneColumn byte-building logic into a shared generic helper used by these functions, with the type-specific conversion handled via a small closure or trait-based adapter. Keep the existing function names as thin wrappers if needed, but make the byte serialization and Arc::from/ MultiLaneColumn::new flow live in one place to prevent drift when adding more lane widths.
137-137: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueKeep
GridBatchcrate-private unless you add an external constructor.GridlakeColumnsis the only new public carrier here;GridBatchhas no downstream entry point, sopub(crate)would keep the API surface smaller.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@crates/onebrc-probe/src/lane_j.rs` at line 137, `GridBatch` is exposed as public without any external construction path, so reduce its visibility to crate-private in the `GridBatch` definition unless you also add a public constructor or other downstream entry point. Update the `GridBatch` item in `lane_j` to match the intended API surface, and keep `GridlakeColumns` as the only new public carrier.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.claude/board/STATUS_BOARD.md:
- Around line 1-11: The STATUS_BOARD.md update breaks the append-only ledger
convention by inserting a new section at the top and effectively reordering
prior status entries. Update the board by appending a dated correction or new
status entry at the end instead of changing the existing history in place, and
keep the existing entries and provenance in their original order; use the
STATUS_BOARD heading and the existing D-id rows as the anchors when making the
append-only fix.
In `@crates/onebrc-probe/src/lane_j.rs`:
- Line 217: The `as_gridlake_columns()` method currently returns
`Result<GridlakeColumns, ()>`, which bypasses the repo’s snafu error pattern and
forces a clippy allow. Replace the unit error with a proper `snafu`-derived
error type in the `lane_j` module, such as a `GridlakeCarrierError` variant that
captures the relevant alignment context (for example, the grid size or column
details) instead of propagating `MultiLaneColumn::new` as `Err(())`. Update the
`as_gridlake_columns` signature and its call sites to surface this richer error
consistently with the project’s Rust error conventions.
---
Nitpick comments:
In `@crates/onebrc-probe/src/lane_j.rs`:
- Around line 218-238: The three serialization helpers col_i32, col_i64, and
col_u64_from_u32 are near-identical and should be consolidated. Refactor the
MultiLaneColumn byte-building logic into a shared generic helper used by these
functions, with the type-specific conversion handled via a small closure or
trait-based adapter. Keep the existing function names as thin wrappers if
needed, but make the byte serialization and Arc::from/ MultiLaneColumn::new flow
live in one place to prevent drift when adding more lane widths.
- Line 137: `GridBatch` is exposed as public without any external construction
path, so reduce its visibility to crate-private in the `GridBatch` definition
unless you also add a public constructor or other downstream entry point. Update
the `GridBatch` item in `lane_j` to match the intended API surface, and keep
`GridlakeColumns` as the only new public carrier.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: a5b48c0e-3b7e-42a1-b2c7-ab57ee068968
📒 Files selected for processing (3)
.claude/board/STATUS_BOARD.mdcrates/onebrc-probe/Cargo.tomlcrates/onebrc-probe/src/lane_j.rs
| ## deepnsm-v3-convergence-v1 — DeepNSM is the encoder that fills reserved tenants | ||
|
|
||
| Plan: `.claude/plans/deepnsm-v3-convergence-v1.md` (`E-V3-DEEPNSM-IS-THE-ENCODER-NOT-A-MIGRATION-1`). Static convergence PROVEN by #624 P0–P5; the memory layer is the genuinely-unbuilt seam. Extends `v3-convergence-wiring-v1` (wire-don't-invent). | ||
|
|
||
| | D-id | Title | Crate(s) | Status | Evidence | | ||
| |---|---|---|---|---| | ||
| | D-DNV-1 | Gridlake carrier: `GridBatch::as_gridlake_columns` → `ndarray::simd::MultiLaneColumn` (i32 min/max, i64 sum, u64 count); the carrier the COCA `Cell` also rides | onebrc-probe (+ndarray) | In PR | lane-j feature pulls ndarray; 2 tests green (LE roundtrip cell-for-cell + unaligned-grid reject); lane_j.rs clippy-clean | | ||
| | D-DNV-2 | deepnsm `SpoTriple` → `CausalEdge64` S/P/O+freq/conf → `MaterializedEdges`; run `nars_engine.all_projections()` (2³) over the COCA distance matrix | deepnsm + planner | Queued | buildable; extends #624 P3b | | ||
| | D-DNV-3 | arm-discovery as the 2nd proposer leg into one SpoStore (shares palette256 oracle) | arm-discovery + deepnsm | Blocked (ARM-JIRAK-FLOOR) | D-ARM-7 Jirak noise floor is the hard prereq | | ||
| | D-DNV-4 | Episodic-witness tenant + `basin=family` wake (`witness_tombstone` calcify chain) | contract + arigraph | Blocked (own wave + probe) | no episodic-witness ValueTenant; calcify chain is `todo!()`; basin=family doc-only | | ||
|
|
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick win
Preserve the board's append-only history.
This new section is inserted at the top, which conflicts with the append-only ledger convention and weakens provenance. Please append a dated entry/correction instead of reordering prior status entries.
Based on learnings: files under .claude/board/*.md are append-only ledgers; do not rewrite or edit prior entries in place.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.claude/board/STATUS_BOARD.md around lines 1 - 11, The STATUS_BOARD.md
update breaks the append-only ledger convention by inserting a new section at
the top and effectively reordering prior status entries. Update the board by
appending a dated correction or new status entry at the end instead of changing
the existing history in place, and keep the existing entries and provenance in
their original order; use the STATUS_BOARD heading and the existing D-id rows as
the anchors when making the append-only fix.
Source: Learnings
| /// 64-byte aligned (i.e. `grid % 16 != 0`), mirroring | ||
| /// `MultiLaneColumn::new`'s own contract. | ||
| #[allow(clippy::result_unit_err)] // pass-through of MultiLaneColumn::new's Result<_, ()> alignment contract | ||
| pub fn as_gridlake_columns(&self) -> Result<GridlakeColumns, ()> { |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick win
Unit error type bypasses the repo's snafu convention.
as_gridlake_columns() returns Result<GridlakeColumns, ()> and needs a #[allow(clippy::result_unit_err)] to silence the resulting lint. The repo's Rust guideline calls for reusing snafu error patterns instead of a bare () error, which also loses diagnostic context (e.g., which column/grid size failed alignment) that a proper error variant could carry.
As per coding guidelines, "Format Rust code with cargo fmt --all; keep modules and functions snake_case, types PascalCase, and reuse snafu error patterns".
♻️ Suggested direction
- #[allow(clippy::result_unit_err)] // pass-through of MultiLaneColumn::new's Result<_, ()> alignment contract
- pub fn as_gridlake_columns(&self) -> Result<GridlakeColumns, ()> {
+ pub fn as_gridlake_columns(&self) -> Result<GridlakeColumns, GridlakeCarrierError> {with a snafu-derived GridlakeCarrierError (e.g., UnalignedGridSnafu { grid: usize }) surfaced instead of swallowing MultiLaneColumn::new's Err(()).
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@crates/onebrc-probe/src/lane_j.rs` at line 217, The `as_gridlake_columns()`
method currently returns `Result<GridlakeColumns, ()>`, which bypasses the
repo’s snafu error pattern and forces a clippy allow. Replace the unit error
with a proper `snafu`-derived error type in the `lane_j` module, such as a
`GridlakeCarrierError` variant that captures the relevant alignment context (for
example, the grid size or column details) instead of propagating
`MultiLaneColumn::new` as `Err(())`. Update the `as_gridlake_columns` signature
and its call sites to surface this richer error consistently with the project’s
Rust error conventions.
Source: Coding guidelines
Addresses the #641 review: as_gridlake_columns returned Result<_, ()> with a clippy allow, losing which grid failed alignment. Replace with a GridlakeCarrierError::UnalignedGrid { grid } that surfaces the offending grid size, drops the #[allow(clippy::result_unit_err)], and impls Display + std::error::Error. Kept a plain enum rather than a snafu type: onebrc-probe is a workspace-excluded standalone probe whose lanes A/C are dependency-free by design (its Cargo.toml), so a snafu type would drag a new dep into a crate that deliberately carries none — the enum gives the same diagnostic context without that cost. The unaligned-grid test now asserts the variant (grid=72). 2/2 gridlake tests green; lane_j.rs fmt + clippy clean. Not addressed: the STATUS_BOARD "append-only" comment is a false positive — the board's sections are newest-first and this prepended a NEW section without reordering or rewriting any prior entry. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MLBnPuScZy6w9di2QEjsXM
…n-review-o0yoxv onebrc/lane-j: typed GridlakeCarrierError (addresses #641 review)
What
First code step of the DeepNSM→V3 convergence plan (#640): D-DNV-1, the gridlake carrier foundation. The proven 64×64 gridlake batch table (
E-1BRC-GRIDLAKE-SWEETSPOT-1, #635) now renders its four accumulator columns throughndarray::simd::MultiLaneColumn— the SoA-contract carrier — instead of being an opaque set of parallelVecs.The insight this lands (from
E-V3-DEEPNSM-IS-THE-ENCODER-NOT-A-MIGRATION-1): the gridlake batch table is not a bespoke struct — it is typed lanes over one carrier, the sameMultiLaneColumnthe COCA cognitiveCell(helix48/campq48/count/truth,crates/deepnsm/examples/gridlake_coca_wire.rs) composes from. Wire, don't invent.Change
crates/onebrc-probe/Cargo.toml— thelane-jfeature now pullsndarray(default-features = false,std), the same fork dep lane-b already uses.crates/onebrc-probe/src/lane_j.rs—GridBatch::as_gridlake_columns() -> Result<GridlakeColumns, ()>: a little-endian reading (zero re-layout) of the four accumulators onto the integer lanes ndarray added for exactly this — min/max rideI32x16(iter_i32x16"min/max tile columns"), sum ridesI64x8(iter_i64x8"running sums"), count (non-negative accumulator) is widenedu32 → u64ontoU64x8. ReturnsErr(())on a mis-aligned grid, mirroringMultiLaneColumn::new's own 64-byte contract.Verification
cargo test --manifest-path crates/onebrc-probe/Cargo.toml --features lane-j— 2/2 green:gridlake_batch_rides_multilane_column_losslessly— the LE roundtrip is cell-for-cell exact against the sourcemins/maxs/sums/counts(populated across lane-boundary cells 15|16 and the tile edge 4095); typed-lane views wired (len_i32x16/iter_i32x16== grid/16,i64x8/u64x8== grid/8).gridlake_carrier_rejects_unaligned_grid— a grid not a multiple of 16 is refused, not silently mis-carried.lane_j.rsis fmt-clean and clippy-clean (the oneresult_unit_errcarries#[allow]mirroring theMultiLaneColumn::newcontract it passes through). Pre-existing fmt/clippy debt in sibling probe lanes (lane_s/lane_t) is left untouched — out of scope.Scope
Read-side carrier only — no hot-path change, no new tenant, no
ENVELOPE_LAYOUT_VERSIONbump.STATUS_BOARDcarries thedeepnsm-v3-convergence-v1section with D-DNV-1 = In PR and D-DNV-2..4 (SPO→CausalEdge64+2³ / arm-discovery leg / episodic-witness tenant) queued and gated per the plan.🤖 Generated with Claude Code
https://claude.ai/code/session_01MLBnPuScZy6w9di2QEjsXM
Generated by Claude Code
Summary by CodeRabbit
New Features
lane-jdata path to support an additional vectorized array backend.Tests