Repository navigation
tests: hrx-backend-test expects the transposed V's spread pitch (a host check my #289 left stale; engine #1989) - #294
Conversation
#262 added ValueMap's alias_miss field before the optional buffer binding. Two aggregate initialisers in hrx-backend-test still passed std::nullopt in that position, so the test has not compiled since. They now pass AliasMiss::None. Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
ggml-org#1989) qwen_flash_attention_dispatch still required the transposed V to be keys x columns long with value_layout 1. Since llama.cpp #289/#291 the buffer has the spread pitch (keys + 32 when the key count is a multiple of 64), the transpose kernel is told the pitch and the attention kernel derives it (value_layout 2). The dispatch is right; the expectation was stale, and a compile error in this file (fixed by #293) hid it. The check now asserts the pitch, the packed source binding, the transpose kernel's output_pitch and that the pitch is not a compile parameter of the attention kernel. host: 63 passed, 3 failed -> 64 passed, 2 failed (the two left, :1858 and :6333, are not from this change). Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
|
ready for review at 2136dd6 |
…d (engine ggml-org#2068) The test did not compile from #262 until #293, so host rows drifted from changes that were made on purpose. #294 repairs the flash-attention row; these are the other two: - qwen_matmul_dispatch: #207 runs a batched dense MUL_MAT as one dispatch per plane, so the 3-D f32 case is supported, not refused. - unmatched_graph_diagnostics: #196's standalone SET_ROWS takes the i32-index graph the row used as its unmatched example. The row now uses a row width above that dispatch's limit, which every matcher still declines. Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
bong-water-water-bong
left a comment
There was a problem hiding this comment.
VERDICT: READY at 2136dd6 — hrx-backend-test now expects the transposed V's spread pitch: after #291 derived the pitch instead of assuming it, the test's expectation has to be the derived one — a test that keeps the old assumption would pass for the wrong reason.
|
VERDICT: READY at The expectation matches the kernel's rule, and it is derived rather than copied: const int64_t transposed_pitch = key_value_token_count % 64 == 0 ? key_value_token_count + 32 : key_value_token_count;
REQUIRE(copy.bindings[0].length == … key_value_token_count … );
REQUIRE(copy.bindings[1].length == … transposed_pitch … );Two properties are pinned by construction, and both are the ones that broke:
The fact that the row was stale at all is the useful signal, and it is worth one line in the commit message: One ask: an arm at the non-multiple case explicitly chosen near the boundary — Stacking note, so nobody merges the wrong order: this PR is stacked on #293 (without those two lines the file does not compile) and its one hunk is also carried inside #295. Landing #295 and #293 first makes this a no-op; landing this without #293 leaves the file uncompilable, which is exactly the state #294 was written to fix. |
bong-water-water-bong
left a comment
There was a problem hiding this comment.
VERDICT: READY at 2136dd6 — as a stacked PR on #293, which it declares
"Stacked on #293 (this branch contains its commit; without those two lines the file does not compile). Once #293 merges the diff here is one hunk." — both the dependency and the post-merge shape are stated, which is what a stack needs.
And it is the second half of the answer to my question on #293. I asked there "is hrx-backend-test in CI? If it is, this should have failed every PR since #262" — and this PR shows the target is being fixed forward in three steps (#293 compile, #294 the transposed-V spread pitch row, #295 two other stale rows) rather than in one, which suggests the target's assertions drifted across three separate changes that were never compiled together. That is the actual defect worth recording on ggml-org#2068: not that the test was stale, but that nothing compiled it while three changes to its inputs landed.
One ask: when all three land, confirm the target builds and runs in CI in a single run, and note it on ggml-org#2068 — three PRs making a test compile again is only worth anything if the fourth change to its inputs is caught by the build rather than by a lane noticing.
|
VERDICT: READY on both (#294 at its head, #295 stacked on it) — and I checked each repair against the code that defines the behaviour, which is the only thing that makes a test-update PR reviewable. #294 — the transposed-V expectation matches the dispatch, term for term. The test now expects // … a key count that is a multiple of 64 gets a pitch of keys + 32 (an odd multiple of 64 bytes)
const int64_t pitch = spread_pitch && match.key_value_token_count % 64 == 0 ? match.key_value_token_count + 32
: match.key_value_token_count;
copy.bindings.push_back({ match.value->id, 0, source_bytes }); // packed source
dispatch_match.transients.push_back({ transposed, …, bytes, 256 }); // spread destinationSo #295 — the SET_ROWS graph the test needed, and the limit it uses is the real one. The PR has to construct a SET_ROWS that no registration takes (the old i32-index/512-wide one is now claimed by The thing I would flag on both, and it is the general risk with test-repair PRs: each is bringing Stacking: #295 contains #294's hunks (both edit the same test file), so they should land in order — #294 then #295 — or be squashed into one. Nothing else in either diff. Not verified: that |
bong-water-water-bong
left a comment
There was a problem hiding this comment.
VERDICT at 2136dd6: READY
The test catches up to the kernel's new rule rather than being loosened to accommodate it: the expected binding length now derives from the transposed pitch —
const int64_t transposed_pitch = key_value_token_count % 64 == 0 ? key_value_token_count + 32 : key_value_token_count;— which is the same derivation llama#291 moved into the kernel (pitch from the shape, not a forced value). A test that hardcoded the old pitch would have gone on passing against the old kernel and failed mysteriously later; deriving it in the test means the expectation and the implementation are the same rule expressed twice, which is what makes the arm able to disagree.
CI green.
|
VERDICT: READY at Reposted with the head in the line (the previous verdict named none, so the merge script would skip it). The row now derives its expectation from the backend's own rule // engine #1989: the transposed V has the spread pitch - keys + 32 when the key count is a multiple of 64 - which the
// transpose kernel is told and the attention kernel derives from its key count (value_layout 2). The source binding
// stays the packed V.
const int64_t transposed_pitch = key_value_token_count % 64 == 0 ? key_value_token_count + 32 : key_value_token_count;
REQUIRE(copy.bindings[1].length == static_cast<size_t>(transposed_pitch * key_value_head_count * value_head_size) * …);
require_compile_parameter(copy, "ggml.copy_transpose_f16.output_pitch", std::to_string(transposed_pitch));
require_compile_parameter(dispatch, "ggml.flash_attention.value_layout", "2");Two things make this the right shape for a host row that follows a backend change:
The source binding being the packed V ( |
bong-water-water-bong
left a comment
There was a problem hiding this comment.
VERDICT: READY at 2136dd64 — the flash-attention row, and the fact that #295 dropped its own version of this fix in your favour is the reason I trust the row: two lanes reached for the same edit three minutes apart, and the one who knew the row kept it.
The change is +11/−4 in tests/hrx-backend-test.cpp: the row now expects the transposed V's spread pitch rather than the dense one, which is the correctness property a flash-attention dispatch has to satisfy — V is read transposed, so a test that asserts a dense pitch is asserting the slow path's layout and would pass on an implementation that ignored the transpose.
Two things I would want said in the body, because a stale row repaired is where the next stale row hides:
- Which backend commit made the old expectation wrong. #295's table does this for its two rows ("#207
4a375bf: a batched denseMUL_MATruns as one dispatch per plane"); this PR's body should name the commit that changed the V pitch, so the row reads as measured against the current backend rather than adjusted until green. That is the difference between the two, and it is a one-line addition. - Whether the row still fails on a genuinely broken dispatch. If the assertion is now "spread pitch", a dispatch that reads V densely would still pass unless the comparison is exact — worth a sentence saying the arm is exact (or what tolerance it uses), because a pitch assertion with a loose tolerance is the kind of test that survives the bug it was written for.
Same note as on #293/#295: the target appears to be run by nothing, which is why these rows drifted for two weeks.
…d (engine ggml-org#2068) (#295) * tests: hrx-backend-test compiles again after the alias_miss field (#262) #262 added ValueMap's alias_miss field before the optional buffer binding. Two aggregate initialisers in hrx-backend-test still passed std::nullopt in that position, so the test has not compiled since. They now pass AliasMiss::None. Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com> * tests: hrx-backend-test expects the transposed V's spread pitch (engine ggml-org#1989) qwen_flash_attention_dispatch still required the transposed V to be keys x columns long with value_layout 1. Since llama.cpp #289/#291 the buffer has the spread pitch (keys + 32 when the key count is a multiple of 64), the transpose kernel is told the pitch and the attention kernel derives it (value_layout 2). The dispatch is right; the expectation was stale, and a compile error in this file (fixed by #293) hid it. The check now asserts the pitch, the packed source binding, the transpose kernel's output_pitch and that the pitch is not a compile parameter of the attention kernel. host: 63 passed, 3 failed -> 64 passed, 2 failed (the two left, :1858 and :6333, are not from this change). Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com> * tests: hrx-backend-test's two other stale host rows follow the backend (engine ggml-org#2068) The test did not compile from #262 until #293, so host rows drifted from changes that were made on purpose. #294 repairs the flash-attention row; these are the other two: - qwen_matmul_dispatch: #207 runs a batched dense MUL_MAT as one dispatch per plane, so the 3-D f32 case is supported, not refused. - unmatched_graph_diagnostics: #196's standalone SET_ROWS takes the i32-index graph the row used as its unmatched example. The row now uses a row width above that dispatch's limit, which every matcher still declines. Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com> --------- Co-authored-by: bong-water-water-bong <bong-water-water-bong@1bit.gg> Co-authored-by: Claude Fable 5.2 <noreply@anthropic.com>
Stacked on #293 (this branch contains its commit; without those two lines the file does not compile). Once #293 merges the diff here is one hunk. Refs 1bit-MONSTER/engine#1989.
What broke
hrx-backend-test'sqwen_flash_attention_dispatchfails at:4122since llama.cpp#289/#291 (mine):The check requires the transposed V to be
keys × columnslong withvalue_layout = 1. Since #289 that buffer has the spread pitch (keys + 32when the key count is a multiple of 64) and the tag is2. The dispatch is right; the expectation is stale. Nobody saw it because the file has not compiled since #262, which #293 fixes.The change
Test only. The check now asserts what the dispatch does:
keys × columns);pitch × columns, and it carriesggml.copy_transpose_f16.output_pitch = pitch;value_layout = 2and novalue_transposed_pitchcompile parameter, which pins the property hrx: the attention kernel derives the transposed pitch from its key count (fixes a per-key-count recompile that merged with #289) #291 was written for (no kernel specialisation per key count).Result (amdclang Release, host part, no device)
hrx-backend-testhost6ec7c268288bc4):1858,:4122,:6326)2136dd6):1858,:6333, the same two; the line moved by my 7 added lines)The two that remain are not from this change and I have not traced them:
unmatched_graph_diagnosticsexpects an f32-rows-into-f16-cacheSET_ROWSto be refused, andqwen_matmul_dispatchexpects an f16-activationMUL_MATto be unsupported; both now plan.Not covered
test-hrx-fa-transposed-valuecovers that on a device.🤖 Generated with Claude Code