Repository navigation
dr-isa-stream-lab: G2L falsifier — one witnessed translation reused across GEMMs (D-DT64-G2L-1) - #1994
Conversation
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
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
|
Important
This repository does not receive automatic reviews because it has fewer than 10 stars.
|
Codex Review Summary: ✅ CompletedThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
There was a problem hiding this comment.
💡 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".
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
|
CI: Locally, against #418's head ( Generated by Claude Code |
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XAqKMMWgnUU9g7Ldyn6sbk
#1992 (its former base) and AdaWorldAPI/ndarray#418 are both merged; this PR now targets
maindirectly. 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 DRMapTable. Reading across the two spaces directly is a gather and stays refused. Per ADMISSION B (#1640):translatelocates 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).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.Measured (one AMX VM, three runs; each quantity on its own)
64 fields × 64 columns, 200 global ids,
int8_tile_gemm_tier()= AMX TDPBUSD.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 innerBTablewas admitted, and packing indexed past the table (panic). It now reports the inner extent, andBValues::highest_rowmaps positions to identities, soadmit_operandrefuses withShapeRefusal::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 redTranslatedB::newremovedTranslatedB::highest_rowremovedTranslation::checkremoved55 lab tests pass in release mode; clippy
-D warningsclean.Still open: who owns the translation in production, and frames across a restore (#1993).
🤖 Generated with Claude Code
https://claude.ai/code/session_01XAqKMMWgnUU9g7Ldyn6sbk