Skip to content

dr-isa-stream-lab: G2L falsifier — one witnessed translation reused across GEMMs (D-DT64-G2L-1) - #1994

Merged
AdaWorldAPI merged 12 commits into
mainfrom
ccr-8062bcc7-l7lkz9-g2l-lab
Nov 10, 2026
Merged

AdaWorldAPI merged 12 commits into
mainfrom
ccr-8062bcc7-l7lkz9-g2l-lab

Conversation

@AdaWorldAPI

@AdaWorldAPI AdaWorldAPI commented Nov 10, 2026 •

Copy link
Copy Markdown
Owner

#1992 (its former base) and AdaWorldAPI/ndarray#418 are both merged; this PR now targets main directly. Persistence of the map table is #1993.

What

The consumer names a selection in global ids; the source holds its u8 lanes in its own row order (SPACE_B), described by a DR MapTable. Reading across the two spaces directly is a gather and stays refused. Per ADMISSION B (#1640):

  1. translate locates every selected id once, under one map-table frame (counted lookups), and expresses the selection in the source's order. A map whose coordinate revision is not the source's is refused (stale mapping).
  2. The object is bound on the source, in the source's space.
  3. B is prepared once through TranslatedB. Admission resolves every selected position to the identity it reads (BValues::highest_row) and checks it against the inner operand's extent; packing then makes one map read per row. The operand identity names the translation.
  4. Every run reads the source's lanes with zero G2L lookups and zero map reads.

Measured (one AMX VM, three runs; each quantity on its own)

64 fields × 64 columns, 200 global ids, int8_tile_gemm_tier() = AMX TDPBUSD.

Step Time Movement
translate once 83–85 µs 3200 G2L lookups
prepare B once (admit + pack) 46–48 µs 200 admission + 200 packing map reads; 16,384 B bytes packed
stage A, per warm run 11–14 µs 12,800 useful bytes into a 16,384-byte padded buffer
GEMM only 0.71–0.86 µs —
warm run (resolve + stage A + GEMM) 20–24 µs 0 lookups, 0 map reads, 12,800 A bytes staged
re-translate per operation 157–186 µs 3200 lookups + 400 map reads + B pack + A stage

Zero lookups is not zero data movement. The selection is scattered in the source's order, so every warm run still gathers it into a dense K-padded A, at about 15× the cost of the GEMM. The translation removes the global → local resolution, not the gather.

K order. Translation reorders K. That is validated here only for exact integer GEMM (the sum does not depend on order, absent overflow). It is not a result for order-sensitive operators: floating-point reductions, saturation, scans, or anything that reads K by position.

Operand extent (review fix)

TranslatedB::extent() used to report the source's position range. An identity past a short inner BTable was admitted, and packing indexed past the table (panic). It now reports the inner extent, and BValues::highest_row maps positions to identities, so admit_operand refuses with ShapeRefusal::OperandShape { last: 3000, rows: 100, .. } before packing reads anything (#1990's contract). Test: a_translated_identity_past_the_inner_table_is_refused_before_packing, with a silence twin where every identity fits.

A translation is also refused when it was made on another source in the same order (G2lRefusal::Foreign): a_translation_from_another_source_in_the_same_order_is_refused.

Falsifiers (tests/integration/g2l.rs), each disable-verified red

Test Disable that turns it red
exact vs an oracle in global ids alone; 5 runs, 0 further lookups or map reads per-row packing cache removed
a source reorder refuses the old binding, translation and operand staleness check in TranslatedB::new removed
a stale mapping (lanes reordered, map not) is refused map-vs-source coordinate check removed
a prepared B from one translation is refused under another translated identity ignoring the translation
an identity past the inner B table is refused before packing TranslatedB::highest_row removed
a translation from another source in the same order is refused the frame check in Translation::check removed
the untranslated cross-space read stays refused; unknown and repeated ids refused —

55 lab tests pass in release mode; clippy -D warnings clean.

Still open: who owns the translation in production, and frames across a restore (#1993).

🤖 Generated with Claude Code

https://claude.ai/code/session_01XAqKMMWgnUU9g7Ldyn6sbk

Adds int8::direct and int8::PreparedI8B. A is read in place at the u8
lanes' pitch and B is prepared once as PackedI8B bands, through
ndarray::simd::int8_gemm_packed_strided (AdaWorldAPI/ndarray#418). The
prepared-B reuse rule moves into shape::ReuseKey, shared by the BF16 and
INT8 prepared operands so the two cannot drift.

Measured on one AMX VM (median of 41 warm runs, three runs), 256 fields x
256 columns: the direct GEMM takes 45.5-48.1 us against 78.3-78.8 us for
backend::gemm_i8, end to end 47.5-57.9 us against 88.9-92.2 us; at 64
fields 0.98-1.01 us against 3.4-3.6 us. No A copied, no allocation.

Needs ndarray#418.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XAqKMMWgnUU9g7Ldyn6sbk
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XAqKMMWgnUU9g7Ldyn6sbk
The benchmark's pack-timing row called ndarray::hpc::amx_matmul::vnni_pack_i8
directly. hpc is reached only through the ndarray::simd polyfill, so the row
now times PackedI8B::pack_from, which packs into the same VNNI layout. The
measured share is unchanged (23.1 us, 39% of the gemm_i8 row at 256 fields).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XAqKMMWgnUU9g7Ldyn6sbk
…n reused across GEMMs

D-DT64-G2L-1. A selection named in global ids is translated once under one
frame of the source's DR MapTable into the source's own row order (counted
lookups). The object is bound in the source's space, B is prepared once
through the translation (one map read per row), and every run reads the
source's lanes in place with zero lookups. Cross-space reads without a
translation stay refused (ADMISSION B, #1640).

One AMX VM, three runs: translate once 68-85 us (3200 lookups), prepare B
37-47 us, warm run 16-22 us with 0 lookups; re-translating per operation
128-166 us (about 8x). Six falsifiers in tests/integration/g2l.rs, four
disable runs red. Contract doc G2L row moves from OPEN to measured (lab).

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

coderabbitai Bot commented Nov 10, 2026 •

Copy link
Copy Markdown

Important

  • Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

Run configuration

  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: ce354266-566f-4b49-8dcd-9d1758b8e46d
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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

@AdaWorldAPI
AdaWorldAPI marked this pull request as ready for review November 10, 2026 18:26
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Nov 10, 2026 •

Copy link
Copy Markdown
Codex Review Summary: ✅ Completed

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

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-11-10T18:27:45.347802Z 041ca3a 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.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 041ca3a405

ℹ️ 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".

Comment thread crates/dr-isa-stream-lab/src/g2l.rs Resolved
Comment thread crates/dr-isa-stream-lab/src/g2l.rs Resolved
TranslatedB::extent() reported the source's position range, so an identity
past the inner table passed admit_operand and packing indexed past the
table. extent() now reports the inner operand's own extent, and BValues
gains highest_row(selection), which TranslatedB overrides to resolve each
selected position to the identity it reads. admit_operand then refuses
with ShapeRefusal::OperandShape before any packing (#1990's contract).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XAqKMMWgnUU9g7Ldyn6sbk
The G2L bench now reports separately: G2L lookups and translation time;
admission and packing map reads during B preparation; B bytes packed and
preparation time; A staging bytes and time per warm run; GEMM-only time;
and the complete warm run. GEMM alone is 0.71-0.86 us; staging the sparse
selection into a padded A is 11-14 us of a 20-24 us warm run, so zero
lookups is not zero data movement. BENCH-SHAPE, the board entry and the
contract doc record that K order changes under translation and is
validated only for exact integer GEMM.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XAqKMMWgnUU9g7Ldyn6sbk
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XAqKMMWgnUU9g7Ldyn6sbk
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XAqKMMWgnUU9g7Ldyn6sbk
Two sources built in the same order have equal coordinate digests, so
Translation::check admitted a translation from the other one and packing
then panicked reading a table with a frame it never issued (Codex, #1994).
check now asks the source's own map table whether it issued the
translation's frame, and refuses with G2lRefusal::Foreign before packing.

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

Copy link
Copy Markdown
Owner Author

CI: excluded-crate fmt, clippy and tests is red until ndarray#418 merges. The only error is E0432: unresolved imports ndarray::simd::{int8_gemm_packed_strided, PackedI8B} in src/int8.rs. CI builds the lab against ndarray master, and both items arrive with #418. #1992 is blocked by the same thing.

Locally, against #418's head (4b87d85), all 55 lab tests pass in release mode and clippy -D warnings is clean. Once #418 merges, a re-run of this check should go green with no change here.


Generated by Claude Code

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XAqKMMWgnUU9g7Ldyn6sbk
@AdaWorldAPI
AdaWorldAPI changed the base branch from ccr-8062bcc7-l7lkz9-int8-direct to main November 10, 2026 19:15
@AdaWorldAPI
AdaWorldAPI merged commit 5ffca72 into main Nov 10, 2026
13 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