simd: keyed-reduction family — group count/min/max over resident or VIA keys - #320
Conversation
…IA keys
Every keyed reduction is the same walk: visit the rows a mask selects,
resolve each row's group through a key address, fold the row into the
group's slot. That walk now exists once (`group_walk`) with one address
type (`GroupKeyAddr::{Resident, Via}`), and each public function is a
named instance — the facade shape `simd.rs` uses over its backends.
New, surfaced through `ndarray::simd`:
- masked_group_count_u32 / _via COUNT(*) GROUP BY
- masked_group_min_i32 / _via MIN GROUP BY (caller seeds i64::MAX)
- masked_group_max_i32 / _via MAX GROUP BY (caller seeds i64::MIN)
MIN/MAX fold into an i64 sink seeded outside the i32 range, so a slot that
still holds its seed is exactly an empty group — SQL NULL — recoverable
without a second counting pass.
masked_group_sum_i32 and masked_group_sum_i32_via are rebased onto the same
walker; their contracts, panic messages and doctests are unchanged.
Tests compare all eight members against an independent longhand scalar
reference over lengths 0..1000, with anti-vacuity asserting the fixture
really hits out-of-universe keys, both VIA drops, i32::MIN and a dirty
mask tail.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GXUahz73MZxtxWcfpHp9dG
|
Navigate logical layers of code changes, visualize relationships, and explore their blast radius. Note Currently processing new changes in this PR. This may take a few minutes, please wait... ⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Essentials Run ID: 📒 Files selected for processing (1)
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Essentials Run ID: 📒 Files selected for processing (1)
Included review availability: 1 review is currently available. Your included PR review attempts over the past 7 days set your current allowance at 3 reviews per hour. 📝 WalkthroughWalkthroughThe change adds a shared walker for masked keyed sums and adds count, minimum, and maximum reductions for resident and indirect keys. It re-exports the new reductions and tests boundary cases, invalid keys, accumulation, and input-length errors. ChangesMasked Group Reductions
Priority: ➖ Normal Estimated code review effort: 3 (Moderate) | ~20 minutes Change: Feature Suggested reviewers: Merge Risk: ⚪ Minimal · up to No actionable merge-blocking issue is identified; proceed after normal checks. 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches📝 Generate docstrings
A rabbit counts the rows in flight, Comment |
Bugbot couldn't run - usage limit reachedBugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit. A user or team admin can review and increase usage limits in the Cursor dashboard. (requestId: serverGenReqId_f469144e-04f5-419d-a15c-91a57adb8fca) |
|
The workflow header already notes that the runner pool mixes AVX-512 and non-AVX-512 machines per job. This row's cache key ( - name: cpu tier for the cache key
id: tier
run: echo "t=$(grep -q avx512f /proc/cpuinfo && echo v4 || echo v3)" >> "$GITHUB_OUTPUT"
- uses: Swatinem/rust-cache@v2
with:
key: nightly-${{ steps.tier.outputs.t }}The same key gap exists on the other unpinned Generated by Claude Code |
Bugbot couldn't run - usage limit reachedBugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit. A user or team admin can review and increase usage limits in the Cursor dashboard. (requestId: serverGenReqId_b95c1598-eb36-44e1-a5a6-26829c195a80) |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 040b5109c1
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
masked_group_count_u32 and masked_group_count_u32_via accumulated with `+= 1`. On a slot the caller seeded at i64::MAX (allowed by the accumulate-into-caller-state contract) that panicked in a debug build and wrapped in release, so behavior depended on the build profile. The sum family the count claims to share its contract with uses wrapping_add. Both count variants now use wrapping_add, and the doc states it. Test counts_wrap_like_sums_at_the_i64_boundary seeds i64::MAX and checks both count variants (and the sum, for parity) land on i64::MIN. It panicked at the old `+= 1` before the fix. Reported by the Codex review on #320. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GXUahz73MZxtxWcfpHp9dG
Doc comments for the group_family_tests fixture, oracle and the three tests that lacked one. Documentation only; no behavior change. Brings the PR's docstring coverage over the reviewer's 80% threshold (was 79.17%). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GXUahz73MZxtxWcfpHp9dG
What
This adds the keyed-reduction family that DuckDB-style
GROUP BYneeds, as T0 masking primitives surfaced throughndarray::simd:masked_group_count_u32/_viaCOUNT(*) … GROUP BY kmasked_group_min_i32/_viaMIN(v) … GROUP BY ki64::MAXmasked_group_max_i32/_viaMAX(v) … GROUP BY ki64::MINThe resident variant reads the group of row
iaskeys[i]. The_viavariant reads it astable[index[i]], with the zero-fallback at both hops thatmasked_group_sum_i32_viaalready has.One walk, named instances
Every keyed reduction is the same walk: visit the rows the mask selects, resolve each row's group through a key address, and fold the row into its slot. Only the fold and the address vary. So the walk now exists once:
group_walk: the bit loop, the tail clamp and the caller-named panic message;GroupKeyAddr::{Resident, Via}: resolving a row to its group, including both drops.Each public function is a named closure over the walker. This is the same facade-over-mechanics shape
simd.rsuses for its backends.masked_group_sum_i32andmasked_group_sum_i32_viaare rebased onto it with unchanged contracts, panic messages and doctests. A new keyed reduction is now one closure, not another copy of the loop.Why MIN/MAX use an i64 sink seeded outside the i32 range: a slot that still holds its seed is exactly an empty group, which is SQL
NULL. That's recoverable without a second counting pass.Tests
i32::MIN;Each check was deliberately broken against the committed code, then restored:
maxcargo test --lib simd_masking_ops: 122 passed. The new doctests pass, and clippy with-D warningsandfmt --checkare clean.Consumer
Next is lance-graph: mask-risc gets one grouped-reduce terminal, and quack folds
GROUP BYCOUNT/MIN/MAX to one program instead of K. That runs under the DuckDB differential harness.🤖 Generated with Claude Code
https://claude.ai/code/session_01GXUahz73MZxtxWcfpHp9dG
Summary by CodeRabbit