perf(ds4): extend sparse prefill scheduling to 10K

Merged
DU
1mo ago
+1335-309

September 12: fix adaptive quality regression; keep draft

Current head: cd02cdbab2a433097f1148b4758fd9339050a4a0.
Quality fix: a628ceaf731828cdc95dfd8e8a4644a5d6532a59.

Full-model workflow testing found repeated tool tags and truncated responses
with fused adaptive verification. Controlled tests ruled out F16 precision,
incremental mask uploads, graph replay and custom ROCmFPx expert fusion.
The failure followed ordinary dense gate/up fusion: at widths two and
three it could select paired MMQ while the ordinary operator selected MMVQ,
silently changing activation quantization and accumulation. Fusion admission
now shares the actual default/environment/override ceiling with normal dispatch.
Custom expert fusion, wide paired MMQ, six experts, attention optimizations
and adaptive width remain enabled. No fusion kill switch is needed.

Verified on LB8 / gfx1151

  • New graph regression: Q4_0 and ROCmFP4, widths 2/3/4/8, default and explicit
    four-column ceilings, eager execution and replay with changing inputs.
    Old library fails; corrected library passes byte-identical fused/unfused
    output and matching kernel-dispatch checks.
  • 531/531 affected tests pass in 36.26 seconds.
  • Two failing agent prompts: 512/512 truncated tokens before, 304/184 tokens
    with normal completion after
    . Reproduced with all production fusions enabled.
  • Broader matched AR/adaptive: both score 4/4 GSM and 4/4 maths; all four
    adaptive agent responses finish and contain the intended fixes (manual
    inspection, not executed upstream repository tests).
Four-prompt suiteAR mean wallAdaptive mean wall
GSM5.389 s4.596 s
Maths9.931 s8.367 s
Coding agent15.652 s16.200 s

Adaptive generates longer explanations/patches on two agent cases. Its
per-token output is faster, but that suite's completed-request latency is
3.5% worse. Do not claim identical decoding or a universal workflow win.

Review follow-up e496fbbda fixes the short maskless split-KV null dereference
(exit 139 before; both dtypes pass after), strengthens the ratio-4 oracle,
adds deterministic worker-race coverage and preserves the four-worker fallback.
The callback failure check now runs on the test thread. Full native/TSan/
ASan+UBSan stress validation passes; the normal five-test suite also passes
under a two-CPU affinity limit in 5.02 seconds. The separate host-only CppUnit
target avoids mixing hook-enabled and production class definitions.

Current-head release check, September 12

All current-head CI jobs pass: Linux, Windows, uv, Strix, R9700 and DGX.
The paused 3090 speed job is skipped. Cubic reports no issues across 16 files.
The source worktree is clean; there are no unpushed runtime fixes.

Fresh LB8 comparison, identical 9133-token five-key retrieval, two requests
per process, 59-token answers, all strict 5/5 and expected-hash checks pass:

Engine / modePrefill tok/sDecode tok/sMean request s
Nathan Vulkan v0.7.5 AR245.21617.67840.629
Corrected Luce ROCm AR253.48320.00038.988
Corrected Luce ROCm adaptive, cap four243.11025.12039.933

These use total stage tokens / total native stage time, including all 59
completion tokens for both engines. Vulkan's printed rate excludes its first
token, so its roughly 17.39 printed rate is not substituted in this table.
The comparison uses the respective ROCmFPX MIX and UD-IQ3_XXS artifacts, not
identical weight bytes. Six experts, cold prefix/prefill caches, C1 throughout.
Vulkan source is dff60048744f99cb0af68d02be2314456b3269dc, Q8 KV,
batch2048/microbatch1024, FA_WAVE32=1 and all bundled MMID switches enabled.

AR wins this fixture by 3.37% prefill and 13.14% decode. Adaptive is not
yet compared against fresh Vulkan adaptive. Its first/second request decode
rates are 19.8/34.2 tok/s, respectively, with identical answers and 90%
acceptance / 16 rounds. The warm result must not replace the aggregate or
be claimed as universal first-request speed.

Unused GPU page-cache retention was confirmed on LB8: about 61 GiB remained
cached after Vulkan exited. Idle-only reclaim restored 119.55 GiB available,
without reboot or persistent driver-setting changes. This resolves the
observed cross-backend load blockage, not the entire long-context limit:
120K adaptive runs at chunks10240 and8192 still hit the unchanged swap-out
guard after reclaim. No speed is claimed for those incomplete runs.

The chunk4096 120K workload returned all five keys and the expected hash at
150.801 prefill / 24.3 native decode tok/s, but its supervisor failed after
the answer because a running benchmark script was overwritten. It remains
provisional, not a clean release-qualification run. New supervisors use
immutable hash-named paths; no failed receipt or exit status was rewritten.

Remaining: long-context memory/performance qualification, cold adaptive
overhead, the explicitly unrecovered historical four-domain inputs, and a
fresh adaptive-versus-adaptive Vulkan comparison. Keep draft. No
all-context ROCm-over-Vulkan claim, merge, deployment or publication.


September 12: fix the DS4 CPU worker-pool lifetime race

Fix pushed in 4d84b1d77c6f869fa8c51804ba6ac428898aa71e; keep draft.

The previous pool waited only for active workers. A delayed inactive worker could observe the next job under the old generation, execute a callback twice and let its caller return while workers still accessed borrowed stack state. Normal full-model snapshot/teacher captures crashed twice; an extracted original-pool stress test reproduced duplicate/missing rows at job 193, and ThreadSanitizer separately reported the data race.

The replacement waits for every worker to acknowledge every generation. It retains static row partitions, the same F16 dot arithmetic, spin/park policy, and allocation-free callbacks. GPU kernels, model/quantization, six-expert routing, adaptive width and quality thresholds are unchanged. The host-only regression test is wired into hosted CI.

Verification

  • 100,000 mixed-width jobs across 1/2/4/8 workers plus 4,000 concurrent-client jobs pass; ThreadSanitizer and ASan/UBSan pass.
  • Production rebuild on LB8 succeeds; 522/522 affected CTests pass.
  • Four normal full-model Q2048/Q8192/Q8192/Q2048 captures complete: 1,024 teacher-forced full-vocabulary rows and 256 greedy tokens.
  • Two NEW frozen source-document diagnostics pass the preregistered mean-KL limit of 0.006:
DiagnosticCross-width mean KLSame-width replay KLTop-1 agreementGreedy common prefix
Technical prose0.004807960096.09375%32/32
Attention kernel code0.000964731099.21875%32/32

Same-width full float32 logit files are byte-identical. Cross-width logits are not byte-identical. These new tapes are explicitly not the missing historical four-domain gate, nor a task-accuracy or adaptive-verification qualification.

Performance preservation

Same frozen 9,133-token retrieval, 32K allocation, cold caches, six experts, two measured requests per configuration. Adaptive DSpark enabled with cap four, not fixed width. Same GPU library as parent baf0b5448.

ModeParent prefillFixed prefillParent decodeFixed decode
AR254.707255.65219.99820.020
Adaptive DSpark252.639250.71434.30134.710

Rates are tok/s using full server-stage time. All eight outputs retain 59 tokens, strict 5/5 retrieval and the identical expected response hash. All runs finish without memory-guard intervention. Small timing changes support preservation, not a new speed gain; controls had differing swap activity and this is not collectively swap-free.

Current-head CI is running. No merge, deployment or publication has occurred. The original missing four-domain gate, broader adaptive/task-quality validation and fresh matched optimized-Vulkan comparisons at short/long context remain publication gates. Earlier figures below must not be combined into an all-context win.

Evidence: LB8 /data/pr684-quality-20260911.a9yucl/; local RND/pr684-quality-20260911/. Frozen diagnostic tape SHA256: 3543e15aae9a2d1b1f2a29071aead6904bb0bd1e5b0c9e06ae373af594528fd4.

Previous changes, measurements and historical quality failure (preserved)

September 11: exact-order ROCm prefill overhead reduction

Fix pushed; keep draft. Commit baf0b54485884a1aff394266452f364bb0148e19 narrows the prefill regression while preserving restored adaptive acceptance. It does not close the full historical prefill gap or qualify the outstanding original prose-quality gate.

Change

  • Bound the existing eight-head HIP F32 dot-loop unrolling; keep sequential FMAs.
  • Replace contended per-weight envelope atomics with one wave's integer min/max scan per head. Keep the compact softmax tree and ascending-row value sums.
  • Add a byte-identical differential case covering all-zero value envelopes and head-dependent softmax underflow at a 133-token tail starting at 122,880.
  • No change to weights, quantization, six-expert routing, adaptive width, verifier precision, CUDA or F16 policy. No new global scratch.

Matched LB8 result

ROCm 7.2.4, gfx1151 Radeon 8060S, installed ROCmFPX MIX Strix target and Q4RMFP4 DSpark draft. Same 9,133-token five-key retrieval, 32K allocation, one wide frontier, cold prefix/prefill caches, concurrency one, natural 59-token responses (cap 128). Adaptive mode enabled with cap four, not fixed width. Rates use complete API stage time.

ModeBaseline prefillFix prefillBaseline decodeFix decode
Adaptive DSpark250.766255.288 (+1.80%)34.56734.744
AR253.592256.731 (+1.24%)19.99220.046

All rates tok/s. The sub-1% decode deltas are not claimed as decode gains.

Adaptive qualification used control–candidate–candidate–control processes, two measured requests each, four per arm. Every request retained 98% acceptance, 15 rounds, strict 5/5 retrieval and the same response hash. AR used two requests per arm with identical output checks. All completed under the unchanged memory/swap guards; runs are not collectively claimed swap-free.

Verification

  • 533/533 affected tests passed, including server units, MMQ, grouped MMID, fused combine, DS4, maskless F16/F32 and meta layout.
  • F32 attention fixtures are byte-identical to compact, including the added zero/underflow case. This is not a full-model byte-identity claim.
  • Restoring the selected variant after experiments reproduced the tested HIP library byte-for-byte; all six focused tests passed again.
  • HIP library SHA256: a2232acb6b506932bf7e2b05715733b0be865fcdf4c1da769d372238f6d391ae.
  • Delivered patch SHA256: 3e373d6bbc5cc14c7ae22789277058b2ec1aa2be578d3f11b611fc668f4ab162.
  • New-head CI is running. Speed profile is skipped; previous-head green CI is not substituted for this head.

Fresh LuceGraph baseline captures attribute 227639/227976 dispatches, all on verified Strix Agent 2, with complete/zero-drop capture. Attention accounted for 21.043 s, including 15.871 s in the targeted eight-head kernel. Legacy DS4 has no SeqEngine rounds: native kernel reports are valid, the generic host/round join is not. Instrumentation remains outside the PR; the disposable local checkout was removed only after its patch was preserved.

Remaining gates

  • The historical streaming receipt was 261.522 prefill tok/s, but only 90% acceptance and 31.820 adaptive decode. The selected fix remains roughly 2.4% below that historical prefill rate; that receipt is not a fresh same-session control.
  • Original prose-quality gate: KLD 0.011536, frozen limit 0.011216. Its frozen four-domain harness/tapes have not been located; kernel/retrieval tests do not replace it.
  • No new matched Vulkan run, all-context win, merge, deployment or publication is claimed.

The eight-way unroll experiment passed focused tests and was slightly faster in an attention microbenchmark, but has no matched full-model qualification and is not shipped in place of the measured four-way variant. The interrupted sixteen-way experiment produced no result.

Evidence: LB8 /data/pr684-prefill-20260911.3FvmOg/; local /private/tmp/pr684-prefill-20260911.F19VlC/RESULTS.md.

Earlier fixes, measurements and unresolved quality history (preserved)

September 10 regression fix — 64463db74

Partial fix; keep draft. The observed adaptive-acceptance regression is fixed.
The previous head's full prefill speed is not preserved, and the original
prose-quality gate remains unqualified. This is not merge-ready or a Vulkan
parity claim.

What changed

  • HIP F32 prefill now shares KV loads across eight attention heads, with
    quad key loads, while preserving compact attention's sequential dot
    products, softmax tree, and ascending-row value sums.
  • F32 fixtures now require byte-identical outputs against the compact
    reference, including all 64 model heads at a late-context tail. The old
    tolerance missed this regression.
  • The adaptive controller, draft cap, fused verification, verifier F16 KV,
    expert count, weights, quantization, and CUDA/F16 attention policies are
    unchanged. Eight attention heads does not mean eight drafted tokens.
  • No extra global scratch buffer or experimental profiler code is included.

Measured result on lucebox8

Same frozen 9,133-token five-key retrieval prompt, one wide prefill frontier,
six experts, 32K allocation, cold caches, concurrency one, two requests per
arm, natural 59-token outputs (cap 128). Adaptive DSpark is enabled with cap
four, not fixed width. Rates use full API stage time.

ModePrevious-head prefillFixed prefillPrevious-head decodeFixed decode
AR269.103253.78019.97619.993
Adaptive DSpark261.522249.88231.82034.423

All rates are tok/s. Previous-head values are earlier same-day production
receipts for 8c9faa374, retained below; they are not a fresh main or Vulkan
benchmark. A fresh matched normal/ROCprof capture also reproduced that
head's 90% acceptance / 16 rounds.

The fix restores 98% acceptance / 15 rounds in both repeats, versus
90% / 16 before. All final AR and adaptive responses pass strict 5/5
retrieval and the fixed response hash. AR decode is preserved.
Prefill is still about 4–6% below the previous head; do not combine the
old prefill rate with the new decode rate to claim a full win.

At 4K chunks, the same HIP kernel before the CUDA-scope/documentation cleanup
measured 228.754 prefill / 34.622 decode, also 98% / 15 rounds.
The cleaned AR 4K check measured 228.883 / 19.909.

Verification and remaining gates

  • 533/533 selected CTests pass on gfx1151, including DS4, MMQ, grouped
    MMID, fused combine, maskless F16/F32, dispatch controls, and server units.
  • F32 attention is byte-identical to compact at 10,240 tokens and a 129-token
    tail starting at 122,880, with three submissions and 16/64-head coverage.
    These are kernel fixtures, not full-model 128K qualification.
  • Six focused tests pass again after restoring the final build; its HIP
    library is byte-identical to the artifact used for the full suite and final
    workflow checks:
    660e95f3c2f4649740a74f842a75f9cee1b68ac9e1c6228bde1d4e96230c2476.
  • All completed model arms obey the unchanged 4 GiB headroom / 262144-page
    swap-out guard and 600-second timeout. No failed arm is counted as a gain.
  • Tiled-score, transposed-key, 16-head, and barrier-reduction experiments
    were discarded because they did not improve the combined result. Their
    code and receipts remain retained outside the PR.
  • Original prose quality is still an open gate: KLD 0.011536 versus frozen
    limit 0.011216. The original four-domain frozen tapes/harness have not
    been located; kernel/retrieval tests do not replace them.
  • New-head CI has started and is not yet fully green. No merge, deployment,
    article publication, broad-workflow win, or new matched Vulkan claim.

Commit: 64463db74a861b4cf8428c65e88cec1b27627715.
Evidence: LB8 /data/pr684-regression-20260910.YPAP3H/; local
/private/tmp/pr684-regression-20260910.eA2qDz/REGRESSION-RESULTS.md.
The LuceGraph baseline has complete/zero-drop v1 output and native DS4 scope
attribution of 312077/312414 GPU dispatches, all on gfx1151 Agent 2.
Legacy DS4 emits no SeqEngine rounds, so the generic host HTML join is
unavailable; native GPU reports are retained without fabricated round IDs.

Previous-head results and original PR history (retained unchanged)

September 10 follow-up — current head 8c9faa374

Conflicts are resolved against main 7ad10a703; GitHub reports MERGEABLE, but this PR remains draft, not approved for merge. Fresh-head CI: run 34527436416, in progress at this update.

Fixes delivered

  • Preserve both sides of the CI conflict: maskless/fused-combine tests and main's draft-top-K coverage.
  • Share byte-identical immutable F32 mask inputs within their layer-major graph cache. The reusable owner-local pool removes per-layer quadratic host duplication without changing mask values, GPU tensor identities, or lifetime boundaries.
  • Preserve main's F32 current-row prefill KV; extend the existing wave32 streaming kernel to F32 input instead of introducing an extra F16 rounding step. The verifier's independent F16 path is unchanged.
  • Retain the already-integrated #658/#664/#667/#683 correctness and performance work. No expert-count, weight-format, adaptive-controller, machine, or service change. No profiler instrumentation is in this PR.

Commits: 76e44ecc5, 4095c738f, 8c9faa374. Normal non-force push to the actual fork branch dusterbloom/lucebox-hub:perf/ds4-sparse-prefill-wide.

Fresh LB8 validation

ROCm 7.2.4, physical Radeon 8060S Strix Halo gfx1151, wave32; not R9700. Release HIP, graphs ON, affine OFF, four build workers.

533/533 selected CTests pass with no CTest skips. Five new immutable-pool tests also pass with ASan/UBSan. F32 compact/streamed oracle maximum errors: 8.3446503e-7 at 10,240 tokens and 4.1723251e-7 at a 129-token tail after position 122,880. Masked/analytical streaming outputs are byte-identical across three submissions. Tolerances are unchanged. These are kernel fixtures, not full-model 128K qualification.

Same-task model results

Same installed ROCmFPX MIX target and Q4RMFP4 DSpark draft, native six experts, 32K allocation, cold prefix/prefill caches, concurrency 1. Same frozen 9,133-token five-key retrieval prompt; two measured requests per arm, each naturally stops at 59 output tokens. Adaptive width is enabled with cap 4, not fixed width. Rates use total API stage tokens / total API stage time.

Current-head configurationPrefill tok/sDecode tok/sAcceptance / rounds
AR, 4K chunks242.20619.931—
AR, one wide batch269.10319.976—
Adaptive, 4K chunks242.51932.13190% / 16
Adaptive, one wide batch261.52231.82090% / 16
Adaptive, compact control, 4K216.72034.59898% / 15
Adaptive, compact control, wide231.86934.50998% / 15
Adaptive, precise-exp control, 4K236.46732.03690% / 16

4K means 4,096 + 4,096 + 941 tokens. Wide requests chunk 10,240 but actually processes one 9,133-token batch. Compact changes only GGML_CUDA_MLA_STREAM_TOPK=0; precise-exp changes only GGML_CUDA_MLA_STREAM_FAST_EXP=0. All seven arms exit zero without triggering the unchanged 4 GiB memory guard. All 14 measured responses pass strict 5/5 retrieval and the same fixed output hash.

The reproduced wide-batch memory failure is fixed for this task. Minimum MemAvailable is 5.495 GiB for wide AR (zero swap-out), 4.951 GiB for wide adaptive (18,377 swap-out pages), and 4.888 GiB for wide compact (34,972 pages). The previous candidate's same-task wide AR/spec attempts crossed the guard before producing output. No limit was lowered. This does not qualify every 10K or long-context memory shape.

Default adaptive performance is not yet fixed. The retained earlier-main 2f0eff051 receipt used 98% acceptance / 15 rounds and 33.900 tok/s; it is not a fresh timing of main 7ad10a703. Preserving F32 inputs alone or disabling fast-exp does not recover acceptance. F32 + compact attention does recover 98% / 15 rounds at both tested chunk sizes, but gives back prefill throughput. No default was changed to hide this tradeoff. Do not combine one configuration's prefill with another's decode and call it a single win.

Profiling and evidence boundary

A separate fresh LuceGraph/ROCprof build of merge-only 76e44ecc5+profile attributes 311,995 / 312,332 dispatches (99.89%) to five native DS4 scopes, all on verified gfx1151. One measured prefill contains 21.885 s GEMM and 7.499 s attention; one measured decode scope contains only ~44 ms attention. The old cache retained 1,486,880,768 bytes of F32 inputs at a 4K frontier, motivating immutable mask sharing.

Legacy DS4 produces complete/zero-drop JSONL but no SeqEngine scheduler rounds. Native DS4 trace scopes use trace-order IDs, not JSONL-correlated IDs; a generic host-round HTML join is unavailable. The valid reports are kernels.json/kernels.md and native Perfetto. Normal-run timings, not ROCprof overhead, supply throughput.

An initial incremental build reused stale graph/test objects after timestamp-preserving transfer. No model run used that build. Explicitly rebuilding all changed units produced the passing suite; both failed and successful build/test logs are retained.

Full receipts and exact runner on LB8:
/data/pr684-followup-20260910.emWWWR/.
Local report:
/private/tmp/pr684-followup-20260910.oPVHd0/FOLLOWUP-RESULTS.md.

Still required before merge/publication

  • Resolve or qualify the default streaming/adaptive acceptance tradeoff across representative tasks.
  • Requalify the historical frozen prose gate: KLD 0.011536 versus 0.011216. Its original frozen tapes/harness were not located in the inspected evidence; kernel/retrieval checks do not replace it. The failure remains recorded.
  • Fresh matched Vulkan and full-model 128K+ measurements before any broad Vulkan-win or full-model byte-identity claim.
  • Complete new-head CI/review. No merge or article publication was performed.
Earlier PR description and historical receipts — superseded by the current-head results above

Summary

  • integrate current main 2f0eff051 including #658/#664/#667/#683, retaining fused-combine alignment admission, MLA scratch barriers, saved verifier rows, runtime RoPE positions, and model-local mixed-MMQ policy
  • keep main's already-merged fused MoE combine and its existing disable/trace controls; this is not an additional gain over current main
  • extend current main's DS4 prefill schedule from two to five independent
    2,048-token numerical bands, admitting one physical frontier up to 10,240
    tokens
  • derive long ratio-4 causal visibility in the HIP attention path instead of
    retaining and uploading its quadratic score mask
  • pass authoritative long-prefill top-k rows directly, keep selected
    raw/compressed KV transport in F16, and stream each selected latent row once
    across sixteen wave32 heads
  • preserve native top-6 routing, selected-row order, per-row reduction order,
    independent 2K attention bands, and chronological state commit
  • preserve mrciffa's authorship on the three extracted streaming-attention
    commits from #683
  • preserve cheese-cakee's authorship on the fused-combine implementation and
    correctness commits from #658

Routing, expert matrix multiplies, sparse/exact prefill admission, and state
commit retain main's policies. Maskless ratio-4 prefill selects streaming
attention automatically when eligible, while other indexed shapes keep the
existing opt-in policy. Existing streaming, FP32 staging, fast-exp and fused
combine overrides are preserved; no new serving flag or private BWS policy
is added. GGML_CUDA_MLA_STREAM_TOPK=0 retains the compact maskless fallback.

September 10 integration fix

The old PR head predates important merged correctness fixes. This update
retains them, removes the duplicate fused-combine CMake target produced by
the overlap, and adds permanent HIP regression coverage:

  • compact versus streamed attention at 10,240 tokens and a 129-token tail
    starting at position 122,880, with pinned inputs and three submissions;
  • explicit-mask versus analytical-mask outputs and numerical tolerance
    against the compact reference, with no loosened tolerances;
  • default streaming dispatch and the explicit disable switch;
  • rejection of runtime-position or oversized (>512) top-k contracts on the
    fixed-position maskless path; masked verification keeps its wider support;
  • fused-combine alignment and new maskless tests included in both HIP CI jobs.

Fresh integrated LB8 validation: Release HIP gfx1151, graphs ON, 504/504
selected CTests passed
. At 10,240 tokens the compact/streamed maximum
absolute error is 1.2218952e-6; at the 129-token tail starting at 122,880 it
is 3.4272671e-7. Explicit-mask and analytical-mask streaming outputs are
byte-identical on all three submissions of each fixture. These are kernel
fixtures, not full-model long-context measurements.

Wide-batch memory qualification did not pass. On the same 9,133-token
retrieval task with the current main optimizations and installed target,
candidate AR and adaptive runs at requested chunk 10,240 both crossed the
unchanged 4 GiB host-headroom guard before producing output. Candidate AR at
chunk 8,192 also crossed the guard while handling the tail. The runner
terminated these attempts; no actual OOM was observed. Their partial timings
are not counted as gains. The safe-chunk regression check is reported
separately, not substituted for 10K qualification.

The older model timings and quality results below are historical receipts,
not measurements of this merged head. The recorded prose quality miss and
wider-batch memory qualification remain open. Keep this PR draft; no matched
Vulkan parity or full-model byte-identity claim is made.

Fresh matched 4K-chunk model regression

Same 9,133-token cold-prefix retrieval task, installed ROCmFPX MIX target,
six experts, same input token IDs, 32K context allocation, caches off, two
measured requests per arm. Both use effective chunks 4,096 + 4,096 + 941.
Rates use API-reported full stage time, not client decode windows.

Metric (tok/s)Current mainFixed #684Change
AR prefill225.073246.246+9.41%
AR decode19.95619.950-0.03%
Adaptive prefill223.143247.476+10.90%
Adaptive decode33.90031.779-6.26%

All eight responses pass strict 5/5 retrieval, contain 59 tokens, and have
the same output hash. Mean request wall time improves from 43.541 to 40.054
seconds in AR and from 42.680 to 38.779 seconds in adaptive mode.

Adaptive decode is not preserved in this check. Adaptive width is enabled
with q cap 4. Main uses 15 rounds with 98% draft acceptance; the candidate
uses 16 with 90% in both repeats. Round wall times are similar, but the extra
round lowers decode throughput. The precise numerical cause of the acceptance
change is not isolated. This regression, wider-batch memory headroom, and the
historical prose-quality miss remain open before merge-readiness. No fixed
high-acceptance or unmatched Vulkan win is claimed.

Fix head 431721f1e; engine/test code 1b91332f6 (last commit is documentation
only), integrated main 2f0eff051. Full receipts on LB8:
/data/pr684-fix-20260910.HsTxSi/, including model-summary.json, the four
completed arms, three aborted candidate attempts, regression-tests.log,
and the exact scripts. The initial main/adaptive arm requested chunk 10,240;
main's 4,096 cap gives the same effective shape as the candidate's explicit
4,096 setting.

Historical fused-combine discriminator (already merged in #658)

A frozen F-C-F-C process bracket used the same full model, prompts, runtime
shape, and machine state. Four warm observations per arm produced:

PromptLegacy combineFused combineChange
2,563 tokens194.594 tok/s202.578 tok/s+4.103%
9,133 tokens239.201 tok/s250.925 tok/s+4.901%

The exact same-binary comparison measured +3.270% at 2K and +4.923% at 8K.
The final flag-free build independently reached 204.044 and 252.362 tok/s.
Its server SHA-256 is
cc21d9f4257492f5ae46758088baaa0b459f43c0dcd3cfe280c13bd7cbf9c0dd.

The focused HIP microbenchmark improved from 1.876 to 0.240 ms at 401 rows
(7.807x), and from 10.374 to 1.158 ms at 2,048 rows (8.962x). Decode remained
within noise, so no decode gain is claimed.

That historical A/B used #658's selector before the old branch removed it.
The current integration retains main's selector and trace support.

Historical production workflow (before current-main integration)

Strix Halo gfx1151, 98.3 GB ROCmFPX MIX artifact, target-only sparse
prefill, native top-6 routing, fused autoregressive decode, Q4_0 K/V cache,
caches off, 9,133-token SWE-bench-shaped prompt, and up to 128 generated
tokens:

BuildPhysical prefillWarm prefill medianWarm decode medianMatched 128-token warm wall
Previous PR head 619413c8,192 + 941231.365 tok/s19.005 tok/s46.319 s
Scheduling-only receipt d6471f1one 9,133-token step252.175 tok/s19.220 tok/s42.797 s
Changetail removed+8.99%+1.13%-7.60%

The final two warm prefill samples were 252.09 and 252.26 tok/s. The matched
128-output-token warm sample saved 3.522 seconds. Decode code is unchanged;
its small movement is reported, not claimed as a decode optimization. Sparse
replay produced 47 tokens in one warm sample and 128 in the other, so whole
wall is compared only between matched 128-token samples.

The earlier clean-head 7,680-token receipt remains 254.921 tok/s, nominally
0.335% above the cited 254.07 tok/s Vulkan result at the same token count. The
prompts, artifacts, and quality protocols are not proven identical, so this PR
does not claim a cross-runtime record from that comparison.

Memory and execution shape

The ratio-4 analytic path removes retained masks from 21 attention layers:

  • 6.562 GiB at 8,192 tokens
  • 8.157 GiB at 9,133 tokens

That memory headroom permits the five-band frontier without a runtime memory
guard. The four full-vocabulary quality processes reported zero swaps; the
end-to-end runs had no OOM, managed-memory cliff, or system-manager failure.

Failure found by the real workflow

The first maskless implementation passed units but segfaulted on the real
9,133-token request. A GDB hardware watchpoint found the generic ring-mask
writer overwriting the layer-2 graph header: after omitting the layer-major
score mask, control incorrectly fell through to old-row logic that assumes a
saved ring unavailable in layer-major prefill.

The root-cause correction restricts that branch to
causal_batch && !layer_major_batch. It adds no fallback, allocation, flag,
or defensive guard. The corrected source crosses the former crash point and
passes the real workflow.

Historical qualification (before current-main integration)

Release HIP gfx1151, build concurrency capped at four. The full pinned-Halo
test_deepseek4_unit passes, including the ratio-4 boundary formula and a
focused explicit-mask versus analytic-mask GPU oracle with bit-identical
streaming-attention output. The fused-combine qualification also passes all
2x4 top-k/row/shared-output HIP cases, meta allocation/layout contracts, CPU/HIP
parity, legacy differential tolerance (1e-6), and a byte-exact signed-zero
case. test_ggml_meta_split_layout passes 17/17 checks.

The unchanged Q2048/Q8192/Q8192/Q2048 ABBA harness used four frozen real-domain
token tapes, 128 teacher-forced full-vocabulary rows, and 32 greedy rows per
arm:

DomainCross mean KLDSame-arm noiseCross top-1Greedy prefixResult
Prose/reasoning0.0115360.00897392.97%2KL-only miss
Code/kernel0.0012570.00132998.44%25pass
Tool/agent0.0012930.00135397.66%32pass
Multilingual/structured0.0035370.00392397.66%21pass

Code, tool, and multilingual passed the preregistered limits. Prose passed its
top-1 and greedy rules but measured KLD 0.011536 against the frozen
max(0.006, 1.25 * noise) limit of 0.011216, a 0.000320 miss. This is
consistent with the inherited sparse replay noise, but the sample remains
reported as failed: no threshold was changed and it was not rerun until
passing. The focused attention-kernel oracle is bit-identical.

Known limitation

Sparse prefill remains approximate and nondeterministic across identical
same-arm replays. State and logit hashes differ even within equal-width
controls. These results do not claim bitwise full-model determinism.

The 9,133-token timing fixture carries an agent-shaped coding transcript but
no actual tool schema and only a 128-token output budget. It directly exercises
the changed path; it is not a complete agent-task quality proof.

Scope

This PR contains public scheduling, selected-row dataflow, F16 transport,
generic HIP attention-kernel work, tests, and the narrow ring-mask root-cause
fix. It contains no private Behavioural Working Set mask, calibration, expert
reuse, slab, or placement policy. Temporary attribution telemetry was removed
before the final commit.