Repository navigation
tests: GGML_HRX_LOG_DISPATCH stays a logging switch, with the byte-identical A/B (Fixes #2143) - #2182
Conversation
Measurements are taken with the flag set (the dispatch profile, the #1536 close test), so it must not be able to change what the backend does. In the pinned fork it is read twice, both in static void functions of const arguments. The test fails when the flag is read anywhere else, or when a reader could return a decision or write through an argument. It skips the tree check, not its self-test, when the submodule is not checked out. Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
|
ready for review at fb5dc73 |
PR Reviewer Guide 🔍Here are some key observations to aid the review process:
|
bong-water-water-bong
left a comment
There was a problem hiding this comment.
VERDICT at fb5dc73: READY
This closes #2143 with a property rather than a measurement, and the reasoning is the review: "Measurements are taken with this flag set (the dispatch profile, the #1536 close test), so it must not be able to change what the backend does."
The test proves it structurally — in the pinned fork the flag is read in exactly two places, both static void taking const references and returning nothing, so they can print and cannot change which kernel is chosen. Asserting the call sites' shape is stronger than asserting one observed run: a future edit that gave either function a return value or a mutable argument would fail the test even if its behaviour happened to be unchanged that day.
That is the same idea as #1919 (the NPU_BATCH_CHECK oracle must leave the forward exactly as it found it) but applied to a flag that was found to be non-neutral by #2162's 18,782-token evidence. So the sequence is complete and in the right order: the finding was documented where the flag lives, the fork was fixed, and now the fix is pinned. A flag used for the dispatch profile and the #1536 close test is load-bearing for every measurement this fleet takes, which is why it deserves a permanent guard rather than a note.
Fixes #2143
What the issue says, and what is measured
#2143 reports that an 18.8k request failed with
GGML_HRX_LOG_DISPATCHunset and succeeded with it set, one run each, and concludes that the flag changes behaviour. It does not, on the source and on the device. The one-against-one difference is the intermittent long-prompt fault that is tracked on its own (#1536 on the build without the f16 fixes, and #2159): a fault that shows in 3 of 3 or 12 of 30 runs will split a single pair by chance.Source (the pinned fork): the flag is read in two places,
dispatch_log_requested_output()anddispatch_log_match()indispatch-registry.cpp. Both arestatic void, take their arguments by const reference, and onlyfprintf. Nothing that selects a registration or binds a value reads it.Device (strixhalo, one
gpu-holdticket, 12:40Z, the CI HRX build at204493d4, Qwen3-4B Q4_K_M,llama-server -c 16384 -np 1 --cache-reuse 256): 18 greedy requests per arm (6 x a 219-token prompt, 6 x a 9,300-token prompt, 6 x the same withcache_prompttrue, 128 tokens each), the replies concatenated in order and hashed.ggml_hrx dispatch:lines in the server logf7516b2f63deec75GGML_HRX_LOG_DISPATCH=1f7516b2f63deec75The flag was live in the second arm (23 log lines) and the output is byte-identical.
What this PR adds
tests/hrx_log_dispatch_neutral_test.py, registered as ctesthrx_log_dispatch_neutral: it fails when the flag is read anywhere but those two functions, when a reader is notstatic void, or when a reader takes an argument it could write through. So the flag cannot quietly become a selection input later, which matters because measurements are taken with it set (the dispatch profile of #2084, the #1536 close test).Its self-test (always run, also when the submodule is not checked out) covers: the two readers as they are; a comment naming the flag; a reader in another file; a reader that returns a value; a reader with a writable argument; a reader in another function. It uses a
check()helper, notassert.Not covered
Timing. Two
fprintfcalls (at most 8 + one per registration name per process) could shift a race by microseconds; a race that depends on that is a defect of the racing code (#2159 is looking for one), not of the flag.🤖 Generated with Claude Code