Skip to content

relalg/r2il: width costs no scratch slots - #1634

Merged
AdaWorldAPI merged 3 commits into
mainfrom
ccr-d3ce1263-ied9yh
Oct 20, 2026
Merged

AdaWorldAPI merged 3 commits into
mainfrom
ccr-d3ce1263-ied9yh

Conversation

@AdaWorldAPI

@AdaWorldAPI AdaWorldAPI commented Oct 20, 2026 •

Copy link
Copy Markdown
Owner

Follow-up to #1633. The first two commits were pushed after #1633 had been merged. The third adds a lab probe.

Problem

relalg lowered Or(a1..ak), And and Not through FoldDialect::call. That gives every atom and every operator a new scratch slot, so a chain of k atoms took 2k - 1 slots. A fold may use MAX_SLOTS = 8, so a disjunction of 5 atoms was refused with ScratchBufferTooSmall. Because of this, crepe-plan-probe built its semijoin mask through relalg only up to 4 centers and fell back to a scalar test above that.

What changes

  • r2il: FoldDialect::call_owned. It runs the unchanged call, then releases the slots of the operands it consumed, except the result. fresh() hands released slots out before minting new ones, and the free list is cleared at every fold.

    • Contract: the caller guarantees that no copy of a consumed Val survives. The dialect cannot check this, because Val is Copy.
    • Plain call is unchanged and is still refused past MAX_SLOTS; a test pins that.
  • relalg: Or, And, Not and the ne/ge/le negations inside atoms are lowered through call_owned. relalg consumes every subexpression's value exactly once, so the contract holds by construction. A chain of any width needs 3 slots; depth still costs slots.

  • crepe-plan-probe: SEMIJOIN_ATOMS_MAX and the scalar fallback are removed. The relalg mask is exact for any number of centers.

  • CI: the probe workflow now also runs relalg's own fmt, tests and clippy. relalg is its own workspace with a sibling ndarray patch, and no other job ran its tests. The workflow also triggers on r2il changes now.

  • crepe-plan-probe, lab only (examples/walk_mask.rs): crepe's graph_walking benchmark program, run twice:

    • once through crepe!'s generated code;
    • once as one n × n bit plane per path length, with ndarray::simd mask ops.

    The tuple counts must match crepe's. The mask form uses two facts the macro does not know: node ids are dense in 0..n, and path lengths are bounded (0..=50). No production path changes.

Tests

  • relalg:
    • a disjunction of 1, 4, 5, 64 and 1,000 atoms keeps exactly the right rows, as written and rewritten, in ≤ 3 slots;
    • a conjunction of negations up to 1,000 atoms gives the exact count;
    • the paired test depth_still_costs_slots checks that depth still costs slots.
  • The relalg test that pinned the as-written refusal now pins the rewrite's gain: 1 pass rewritten, 10 as written.
  • r2il: call_owned_reuses_consumed_slots_and_call_does_not runs a chain of 32 ranges. It takes exactly 3 slots with call_owned and is refused with call.
  • Totals: relalg 14, r2il dialect 9, crepe-plan-probe 38. The crates that depend on r2il also pass: r2il-mask-abi-probe, lance-graph-nal and holo-h14d-probe.
  • Disable run: with call_owned releasing nothing, 4 relalg tests and the r2il test go red.
  • walk_mask: the counts are identical to crepe at n = 128, 256 and 512. Disable run: dropping length-50 paths fails the count assertion.
    • Removing the semi-naive subtraction does not change the counts. It is a performance step only: each step adds 5 to the length, so the loop reaches the same fixpoint.

Measurement (walk_mask, release, median of 9)

n crepe bench (Fnv) bit planes Walk NoWalk
128 7.6 ms 0.30 ms 21,508 10,310
256 41.2 ms 1.1 ms 85,601 41,090
512 290.6 ms 1.3–2.3 ms 341,517 163,702

The crepe column is crepe's own criterion bench. The example's in-process crepe run uses the default hasher and is slower (11.5 / 67–77 / 580 ms). The gain comes from the dense domain and the bounded length, not from SIMD. Neither macro can use it without a domain annotation.


Generated by Claude Code

An Or, And or Not chain in relalg took one scratch slot per atom and one
per operator (2k - 1). The dialect allows 8, so a disjunction of 5 atoms
was refused with ScratchBufferTooSmall.

- r2il: FoldDialect::call_owned. It runs the unchanged call, then
  releases the slots of the operands it consumed, except the result.
  fresh() hands released slots out first, and the free list is cleared
  at every fold. The caller guarantees that no copy of a consumed Val
  survives, since Val is Copy and the dialect cannot check it. Plain
  call is unchanged and still refused past MAX_SLOTS; a test pins that.
- relalg: Or, And and Not are lowered through call_owned. Every
  subexpression's value is consumed exactly once, so the contract holds
  by construction. A chain of any width now needs 3 slots; depth still
  costs.
- relalg test a_wide_conjunction_runs_only_after_the_rewrite pinned the
  as-written refusal. That refusal is gone, so the test now pins the
  rewrite's gain instead: 1 pass rewritten, 10 as written.
- crepe-plan-probe: SEMIJOIN_ATOMS_MAX and the scalar membership
  fallback are removed; the relalg mask is exact for any number of
  centers.

Tests: relalg 14, r2il dialect 9, crepe-plan-probe 38. The crates that
depend on r2il (r2il-mask-abi-probe, lance-graph-nal, holo-h14d-probe)
also pass.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VncKoyG6JkpsoqhqTGTv3f
…nges

relalg is its own workspace, so no other job ran its tests; it now
needs them, because its lowering depends on FoldDialect::call_owned.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VncKoyG6JkpsoqhqTGTv3f
@coderabbitai

coderabbitai Bot commented Oct 20, 2026 •

Copy link
Copy Markdown

Important

Draft PR not reviewed

Draft PRs are not automatically reviewed by default.

  • Trigger a manual review

To automatically review draft PRs, update your CodeRabbit configuration:

reviews:
  auto_review:
    drafts: true
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Warning

Billing warning: we have not been able to collect payment for this subscription for more than 72 hours. Please update the payment method or pay any pending invoices in Billing to avoid service interruption.

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.

❤️ Share

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

crepe's graph_walking benchmark program, run twice in one example: once
through crepe!'s generated code, once as one n x n bit plane per path
length, using ndarray::simd mask ops. The tuple counts must match crepe's.

The mask form uses two facts the macro does not know: node ids are dense
in 0..n, and path lengths are bounded (0..=50).

Disable run: dropping length-50 paths makes the count assertion fail.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VncKoyG6JkpsoqhqTGTv3f
@AdaWorldAPI
AdaWorldAPI marked this pull request as ready for review October 20, 2026 21:33
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 20, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-20T21:36:23.712057Z f842d00 Draft marked ready
ℹ️ 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" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@coderabbitai

coderabbitai Bot commented Oct 20, 2026

Copy link
Copy Markdown

Add Carrot credits or activate Agent usage billing to use Autofix

@AdaWorldAPI
AdaWorldAPI merged commit abfa9e2 into main Oct 20, 2026
13 checks passed
AdaWorldAPI pushed a commit that referenced this pull request Oct 20, 2026
Maps 43 merged PRs onto the recovery ledger (revision c ended at #1591).
Read through ten Haiku substrate-mapper maps, checked against main abfa9e2.
Closes C39-C52; merges the gather ruling and ISS-ADMISSION-PREP-BINDING
into one ADMISSION item with Arm B as its measured example; narrows the
slot budget to nesting depth after call_owned; records stale STATUS rows,
git branch refs in the default build and two cards without frontmatter.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013z2e1YXkm6o6HNrDn5BPWA
AdaWorldAPI pushed a commit that referenced this pull request Oct 20, 2026
Maps 43 merged PRs onto the recovery ledger (revision c ended at #1591).
Read through ten Haiku substrate-mapper maps, checked against main abfa9e2.
Closes C39-C52; merges the gather ruling and ISS-ADMISSION-PREP-BINDING
into one ADMISSION item with Arm B as its measured example; narrows the
slot budget to nesting depth after call_owned; records stale STATUS rows,
git branch refs in the default build and two cards without frontmatter.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013z2e1YXkm6o6HNrDn5BPWA
AdaWorldAPI pushed a commit that referenced this pull request Oct 20, 2026
Maps 43 merged PRs onto the recovery ledger (revision c ended at #1591).
Read through ten Haiku substrate-mapper maps, checked against main abfa9e2.
Closes C39-C52; merges the gather ruling and ISS-ADMISSION-PREP-BINDING
into one ADMISSION item with Arm B as its measured example; narrows the
slot budget to nesting depth after call_owned; records stale STATUS rows,
git branch refs in the default build and two cards without frontmatter.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013z2e1YXkm6o6HNrDn5BPWA
AdaWorldAPI added a commit that referenced this pull request Oct 20, 2026
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