repeat: split cols against every constraint the BD imposes, and add test coverage - #161
Open
atassis wants to merge 3 commits into
Open
repeat: split cols against every constraint the BD imposes, and add test coverage#161atassis wants to merge 3 commits into
atassis wants to merge 3 commits into
Conversation
The CSV reporting hook requires a [...] suffix on every nodeid and raises otherwise. A test with no parameters has none, and the iteration parametrize that would otherwise supply one is only added when --iterations > 1. On devel today, `pytest iron/tests/stream/names.py --iterations 1` aborts the whole session with an INTERNALERROR on test_module_parameters_cover_the_golden_weights.
verify_buffer thresholds on `diff >= max(abs_tol, rel_tol * norm)`. At rel_tol=abs_tol=0 the threshold is 0, so `diff >= 0` holds for every element and a bit-identical buffer scores 100% errors. That makes exact equality inexpressible, which is the gate an operator that does no arithmetic wants and none can currently ask for. Compare strictly, matching what np.isclose means by its tolerances: the new mask is a subset of the old one, so no result that passes today can start failing.
The taps split cols as sizes [..., cols // cols_split, cols_split] with strides [..., cols_split, 1], so the innermost dim counts chunks and the contiguous run sits one dim out. In the unsplit case that is a 1-element innermost dim: at bf16 two bytes, not a whole 32-bit word, and the BD verifier rejects it -- rows=8 cols=512 repeat=4 does not build at all. Swapping the two inner dims gives a byte-identical address sequence (the nested (outer, inner) walk of a linear range is the same walk either way) while making the innermost dim the contiguous run. The swap moves cols_split onto the next dim out, which carries the SAME 10-bit wrap field, so bounding the chunk length alone is not enough -- and the old assert, which bounded cols_split, was the only thing checking it. Rather than move the assert, the selection loop now searches for a divisor satisfying all three constraints at once: chunk <= 1023, chunk a whole number of 32-bit words, and count <= 1023. Where no divisor satisfies them -- an odd cols, a prime above 1023, or 2 x such a prime -- it raises instead of emitting a tap the verifier will reject less legibly. Every cols that worked before selects the same cols_split, llama's 131072 included. Adds the operator's first test coverage: five device arms at exact equality spanning cols_split 1, 2, 4 and 256 (the llama shape), plus three rejection arms. 8/8.
atassis
force-pushed
the
pr/repeat-tests
branch
from
August 27, 2026 00:38
3b4bd5e to
26747d7
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Stacked on #157: the new tests gate at exact equality, which #157 is what makes
expressible. Its two commits are in this diff and drop out when it merges.
repeathas no tests, and could not have had:rows=8, cols=512, repeat=4does notbuild.
Both taps split
colsasso the innermost dim counts chunks and the contiguous run sits one dim out.
cols_splitis 1 whenever no split is needed, which makes the innermost dim one element. At bf16
that is two bytes, not a whole 32-bit word, and
verifyStridesWrapsrejects it:The 512-element stride-1 run the transfer is actually made of is right there in dim 2.
The reason this survived:
llama_npu.pypassescols = prompt_len * head_dim, far above1023, so it lands at
cols_split = 256and its innermost dim is a healthy 256 elements.The only caller in the tree never trips it; every small-
colsshape does, which is what atest would use.
Added
iron/operators/repeat/test.py. Five device arms atrel_tol=abs_tol=0(repeat movesdata and computes nothing) spanning
cols_split1, 2, 4 and 256 -- the last being theshape
llama_npu.pyactually dispatches -- plus three arms pinning the shapes that haveno legal split. 8/8.
Changed
iron/operators/repeat/design.py: swap the two inner dims so the innermost carriescols // cols_splitat stride 1. The address sequence is byte-identical either way --the nested (outer, inner) walk of a linear range is the same walk regardless of which
factor is outer -- so the change is only in which dim the hardware sees as innermost.
The swap moves
cols_splitonto the next dim out, which carries the same 10-bit wrapfield, so bounding the chunk length alone is not sufficient. The selection loop now
searches for a divisor satisfying all three constraints at once: chunk <= 1023, chunk a
whole number of 32-bit words, and count <= 1023. Where no divisor satisfies them -- an
odd
cols, a prime above 1023, or twice such a prime -- it raises rather than emitting atap the BD verifier rejects less legibly. Every
colsthat worked before selects thesame
cols_split, including llama's 131072.Removed
Evidence
8/8 on device, run without the
not extensivefilter so both extensive arms -- includingthe llama shape -- actually executed. The emitted BD for the llama arm is
sizes = [4, 8, 256, 512] strides = [0, 131072, 512, 1].