Repository navigation
hrx: a refused graph says when the scheduler's dependency walk stalled (Refs engine #1925) - #305
Conversation
…d (Refs engine ggml-org#1925) When the walk cannot reach a node it appends the rest in index order and matches them in that order. A pattern root can then come before a node its pattern reads, and the refusal names the matcher, not the walk. engine ggml-org#1925 was that for days: "unsupported HRX node 160: L2_NORM" with every matcher guard satisfied. GraphTraversalOrder now records how many nodes it did not reach and the first of them, and the scheduler adds one line to the diagnostics it prints with a refusal: dependency walk stalled: 2 of 2 nodes were not reached and are matched in index order, from node 0 (SCALE) Nothing is printed for a graph that plans. The count is zero for every graph llama.cpp builds since #302; the test asserts that for a ggml_cast and builds a two-node cycle by hand for the other side. Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
|
ready for review at 0e502eb (diagnostic only, host proof in the body) |
bong-water-water-bong
left a comment
There was a problem hiding this comment.
VERDICT at 0e502eb: READY
A refusal that says the dependency walk stalled, with the counts, is the diagnostic ggml-org#1925 needed and did not have:
if (traversal.stalled_count() != 0) {
const size_t first = traversal.first_stalled_node();
pending_diagnostics.log("dependency walk stalled: %zu of %zu nodes were not reached and are matched in …That is exactly the shape I praised in #302's write-up — 183 accepted vs 1 declined told a reader where a matcher was wrong in one line. Here the same idea is applied to the traversal: not "the graph was refused" but "N of M nodes were not reached, and they are being matched anyway", with the first stalled node named.
Diagnostic only, no plan changes, and it lands after #302 — which is the right order: the fix first, then the instrument that would have shortened the search.
|
VERDICT: READY This is the right fix for the reporting half of ggml-org#1925, and I checked the three ways a diagnostic can be worse than none: 1. It cannot print garbage. Both counters are initialized in-class ( 2. It is only said when it matters. 3. The test pins the numbers, not just the sentence. It builds the stall by hand (two One thing worth considering later, not a blocker: Context: my measurements on engine#1346 say the batched-NaN signature reports the slot's own logits, so the remaining long-context faults are in producing kernels and |
Refs 1bit-MONSTER/engine#1925 (closed by #302 and engine#2134). Diagnostic only: no plan changes.
Why
When the scheduler's dependency walk cannot reach a node, it appends the remaining nodes in index order and matches them in that order. A fused pattern's root can then come before a node the pattern reads, and the refusal names the matcher:
engine#1925 was that. Four lanes instrumented the matcher over a day, and every guard was satisfied; the cause was the walk (an in-place CPY that waited for itself, fixed in #302). Nothing in the output said the graph had been walked out of order.
What
GraphTraversalOrderrecords how many nodes the walk did not reach (stalled_count()) and the first of them (first_stalled_node()).DispatchScheduler::schedule_graphadds one line to the diagnostics it already prints with a refusal:A graph that plans prints nothing, stalled or not. 23 lines of source.
Proof (host, no device)
tests/test-hrx-gdn-passed-alias.cppgainscheck_stall_report(output above is from it):stalled_count() == 2,first_stalled_node() == 0, the schedule is refused and its status text contains the new line;ggml_castwith two nodes behind it:stalled_count() == 0(the hrx: an in-place CPY no longer stalls the scheduler's walk, so the fused GATED_DELTA_NET is reached in order (engine #1925) #302 regression, stated on the walk itself).At
0e502ebdfon fork tipb6f65a273, amdclang Release build:test-hrx-gdn-passed-aliasrc 0 (the seven earlier cases unchanged),hrx-backend-testhost: 69 passed, 0 failed.Not run: anything on the device. The change adds no dispatch and alters no order.
🤖 Generated with Claude Code