Skip to content

lgj-abi minor 12: the grouped sum that never builds a selection (fold-distillation wave 4) - #84

Merged
AdaWorldAPI merged 2 commits into
mainfrom
claude/fold-distillation-pr-wave-s57uj7
Sep 22, 2026
Merged

AdaWorldAPI merged 2 commits into
mainfrom
claude/fold-distillation-pr-wave-s57uj7

Conversation

@AdaWorldAPI

@AdaWorldAPI AdaWorldAPI commented Sep 22, 2026 •

Copy link
Copy Markdown
Owner

The Java → Panama → mask-risc proof of the fold-distillation wave (lance-graph #1256, ndarray #318, both merged): a GROUP BY … SUM crosses the membrane once and no selection exists at any point.

The gap it closes. Every reduction this ABI carried consumed a mask: lgj_plan_eval landed the plan in a mask handle, then a lgj_reduce_* read it. Java never held the selection, but it was still a population-sized intermediate that existed only to be consumed by the very next fold — and a GROUP BY paid for it once per group (bricks' sumBy() measured 32 crossings for 16 groups).

ABI minor 12 — one symbol, no new status, no manifest growth. lgj_plan_group_sum_i32(res, ops, n_ops, group_lane, val_lane, via_res, via_lane, out_sums, n_groups) lowers the plan exactly as plan_eval does (plan_lower::lower_group_sum: same prefix rewrite, same survivor skip) and ends in Terminal::GroupSumI32 over the accumulator instead of Keep. The executor runs it tile by tile; the accumulator is TILE_WORDS of scratch; the only answer-sized state is the caller's i64 per group, which is all that crosses back. via_res != 0 is the fk-keyed form (SUM(line.amount) GROUP BY partner.country, Terminal::GroupSumViaI32, the indirection fused — no partner-side mask, no remapped key lane). n_ops == 0 is legal and means every row: the one Pred::Range this crate emits, pinned to be 0..n_rows and nothing else so exec_error_to_status's RangeOutOfBounds arm stays an internal-bug mapping.

Java. View.sumByGroup(key, value, groups) → GroupTotals (addressed by key, exposes no array) and View.sumByGroupVia(key, via, viaKey, value, groups). Downcalls.Minor12 lazy holder, requireMinor(12), an OldAbiCompatTest leg, and the DoctrineFenceTest pin for the eighth named materialisation site (Engine.groupSumI32's toArray, sized by the key domain the caller typed, never by rows — root CLAUDE.md list updated).

Measured, not predicted:

  • sumByGroup: 1 crossing at 1,024 and at 65,536 rows for 16 groups; the per-group path measured 32 beside it in the same run. sumByGroupVia: 1.
  • Native 191 tests (+8: two-crossing-path parity over the {AND,OR}^n sweep on single- and multi-tile populations; empty/all-OR plans against a hand walk; n_groups as a sink bound; tiled executor vs scalar reference on both key shapes; the fk-keyed form against a hand-walked join incl. zero-fallback drops; every refusal leaving out_sums untouched; a lance-graph-quack convergence arm with Agg::GroupSumI32). Clippy -D warnings + fmt clean.
  • Java 612 checks (409 + GroupSumTest 203) under JDK 28 --enable-preview, abi 0.12, ndarray::simd avx512.
  • OldAbiCompatTest both ways: 13/13 against this library; against a minor-11 library built from 07e044f, View.sumByGroup throws AbiMismatchException naming minor 12, every minor-11 feature still working beside it.
  • Six disable arms red-then-green (docs/abi.md §20.6), each restored from the commit.

Docs/board: docs/abi.md §2 history, §7 (29 → 30 symbols), §20; LATEST_STATE entry; STATUS_BOARD D-LGJ-FOLD-4 done, D-LGJ-FOLD-5 (migrate bricks sumBy() onto sumByGroup, re-pin 32 → 1) queued.

CI here is expected green: lance-graph main already carries #1256.

🤖 Generated with Claude Code

https://claude.ai/code/session_01GXUahz73MZxtxWcfpHp9dG


Generated by Claude Code

Summary by CodeRabbit

  • New Features

    • Added grouped summation APIs for signed 32-bit values, returning totals for a requested number of groups.
    • Supports filtering, grouping by local keys, and grouping through related data.
    • Empty groups return zero; out-of-range or unmatched keys are excluded.
    • Added validation for invalid arguments and closed resources.
  • Documentation

    • Documented the expanded ABI and grouped-sum capability.
  • Compatibility

    • Added ABI version 12 support and compatibility verification.

`lgj_plan_group_sum_i32` lowers the fused plan and `GROUP BY key SUM(val)`
as ONE mask-risc program (`plan_lower::lower_group_sum`, the same prefix
rewrite and survivor skip as `plan_eval`, ending in `Terminal::GroupSumI32`
over the accumulator instead of `Keep`). The executor runs it tile by tile;
the only state sized by the answer is the caller's `i64` buffer, one per
group, and that is all that crosses back. Java's `View.sumByGroup` is
therefore one crossing for 16 groups at any row count, where the path it
replaces (plan_eval into a mask, then reduce per group) measured 32.

`via_res`/`via_lane` give the fk-keyed form: the group of a row is the
second table's `u32` lane read through this table's key lane, fused inside
`Terminal::GroupSumViaI32` — no partner-side mask, no remapped key lane.
`View.sumByGroupVia` is the Java spelling, still one crossing.

An empty plan is legal here (there is no destination mask a caller could
fill itself) and lowers to the whole-lane `Pred::Range { 0, n_rows }` — the
one Range this crate emits, pinned to be that range and nothing else so
`exec_error_to_status`'s RangeOutOfBounds arm stays an internal-bug mapping.

Native: 191 tests (8 new: two-crossing-path parity over the combine sweep
on single- and multi-tile populations, empty/all-OR plans against a hand
walk, n_groups as a sink bound, tiled executor vs scalar reference on both
key shapes, the fk-keyed form against a hand-walked join with zero-fallback
drops, every refusal leaving out_sums untouched, and a quack-lowering
convergence arm with Agg::GroupSumI32). Clippy -D warnings and fmt clean.

Java (JDK 28, --enable-preview): 612 checks (409 + GroupSumTest 203):
parity against per-group sumOf, one-crossing cost measured beside the
32-crossing path, the keyed form against an oracle that reads the second
resource's keys through the one named materialiser, argument checks before
any crossing. Minor12 lazy holder, requireMinor(12), an OldAbiCompatTest
gate, and the DoctrineFenceTest pin for the eighth named materialisation
site (Engine.groupSumI32's toArray, sized by groups, never rows).

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GXUahz73MZxtxWcfpHp9dG
…oard rows

`docs/abi.md`: minor 12 in the version history, the symbol count 29 → 30,
`lgj_plan_group_sum_i32` in §7's surface table, and §20 — why the grouped
sum exists (every reduction consumed a mask; a GROUP BY consumed one per
group), what it does (the plan lowered as `plan_eval` lowers it, ending in
a sum terminal over a tile-local accumulator), the contract, why one
symbol and no scalar twin, the Java spelling, and the six-arm disable
table with what each arm observed.

Root `CLAUDE.md`: `Engine.groupSumI32`'s `toArray` joins the exhaustive
materialisation-site list as the eighth site, sized by the key domain the
caller asked for, never by rows.

Board: LATEST_STATE entry (measured crossings, gates, what is still owed —
the bricks consumer still runs the 32-crossing path) and a STATUS_BOARD
section with D-LGJ-FOLD-4 done and D-LGJ-FOLD-5 (the bricks migration)
queued.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GXUahz73MZxtxWcfpHp9dG
@coderabbitai

coderabbitai Bot commented Sep 22, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

Navigate logical layers of code changes, visualize relationships, and explore their blast radius.

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Essentials

Run ID: dca941c2-3c17-4e2b-a9d2-a1458244b2dc

📥 Commits

Reviewing files that changed from the base of the PR and between 07e044f and 303c2cf.

📒 Files selected for processing (18)
  • .claude/board/LATEST_STATE.md
  • .claude/board/STATUS_BOARD.md
  • CLAUDE.md
  • docs/abi.md
  • java/src/main/java/com/adaworldapi/lancegraph/GroupTotals.java
  • java/src/main/java/com/adaworldapi/lancegraph/NativePattern.java
  • java/src/main/java/com/adaworldapi/lancegraph/View.java
  • java/src/main/java/com/adaworldapi/lancegraph/internal/ffm/Downcalls.java
  • java/src/main/java/com/adaworldapi/lancegraph/internal/ffm/Engine.java
  • java/src/test/java/com/adaworldapi/lancegraph/AllTests.java
  • java/src/test/java/com/adaworldapi/lancegraph/DoctrineFenceTest.java
  • java/src/test/java/com/adaworldapi/lancegraph/GroupSumTest.java
  • java/src/test/java/com/adaworldapi/lancegraph/OldAbiCompatTest.java
  • native/lgj-abi/src/abi.rs
  • native/lgj-abi/src/exports.rs
  • native/lgj-abi/src/exports/tests/group_sum.rs
  • native/lgj-abi/src/exports/tests/lowering_convergence.rs
  • native/lgj-abi/src/plan_lower.rs

Included review availability: 0 reviews are currently available. Your included PR review attempts over the past 7 days set your current allowance at 2 reviews per hour.


📝 Walkthrough

Walkthrough

Added ABI minor 12 grouped-sum execution for local and foreign keys. Added native lowering, Java APIs, GroupTotals, validation, compatibility checks, and native and Java tests.

Changes

Grouped sum execution

Layer / File(s) Summary
ABI contract and grouped lowering
native/lgj-abi/src/abi.rs, native/lgj-abi/src/plan_lower.rs, docs/abi.md
Defines lgj_plan_group_sum_i32, ABI minor 12 semantics, local and foreign-key grouping, empty-plan behavior, and grouped-sum lowering.
Native export and validation
native/lgj-abi/src/exports.rs, native/lgj-abi/src/exports/tests/*, native/lgj-abi/src/exports/tests/lowering_convergence.rs
Implements validation, tile-local grouped accumulation, optional foreign-resource lookup, output guarantees, and native differential and refusal tests.
Java binding and public API
java/src/main/java/com/adaworldapi/lancegraph/internal/ffm/*, java/src/main/java/com/adaworldapi/lancegraph/GroupTotals.java, java/src/main/java/com/adaworldapi/lancegraph/{NativePattern,View}.java
Adds the minor-12 downcall, Engine.groupSumI32, immutable GroupTotals, and local or foreign-key View aggregation methods.
Java validation and project records
java/src/test/java/com/adaworldapi/lancegraph/*, CLAUDE.md, .claude/board/*
Adds grouped-sum tests, ABI compatibility coverage, materialization census updates, and implementation status records.

Priority: ➖ Normal

Estimated code review effort: 4 (Complex) | ~60 minutes

Change: Feature

Sequence Diagram(s)

sequenceDiagram
  participant Caller
  participant View
  participant Engine
  participant NativeABI
  participant GroupTotals
  Caller->>View: call sumByGroup
  View->>Engine: pass plan, lanes, and group count
  Engine->>NativeABI: perform one grouped-sum crossing
  NativeABI-->>Engine: return i64 totals
  Engine-->>GroupTotals: materialize group-sized result
  GroupTotals-->>Caller: expose indexed totals
Loading

Suggested reviewers: claude

Merge Risk: ⚪ Minimal · up to 303c2

The ABI-12 grouped-sum APIs add local and foreign-key aggregation with validation and compatibility coverage; no current merge blocker is identified.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 75.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 44 functions across 14 files. (4 skipped:… Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly identifies ABI minor 12 and the main change: fused grouped summation without building a selection. The parenthetical wave label adds context but does not obscure the change.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Full details: Docstring Coverage

Explanation

Docstring coverage is 75.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 44 functions across 14 files. (4 skipped: 4 unsupported.)

  • Fix all pre-merge checks with AI
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Commit to this branch
  • Create a new PR

I hop through plans where group sums grow,
One crossing makes the totals flow.
Keys may join from tables far,
Empty groups keep zeros where they are.
The rabbit stamps the ABI bright,
And bounds the harvest just right.

Comment @coderabbitai help to get the list of available commands.

@cursor

cursor Bot commented Sep 22, 2026

Copy link
Copy Markdown

Bugbot couldn't run - usage limit reached

Bugbot 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_58fc4011-98ac-4ca6-baf8-0054dee02ea1)

@AdaWorldAPI
AdaWorldAPI marked this pull request as ready for review September 22, 2026 06:20
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, you can upgrade your account or add credits to your account and enable them for code reviews in your settings.

@cursor

cursor Bot commented Sep 22, 2026

Copy link
Copy Markdown

Bugbot couldn't run - usage limit reached

Bugbot 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_ed8ecc02-4978-49af-b2e1-3b464562aafc)

@AdaWorldAPI
AdaWorldAPI merged commit bb81d80 into main Sep 22, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants