Skip to content

QSA select: RDNA3 (gfx1100) WMMA block-scores arm on #337's arch dispatch (opt-in STRATA_SELECT_WMMA=1) - #368

Closed
xyzzing wants to merge 1 commit into
Niko1221:mainfrom
xyzzing:pr-qsa-select-wmma-rdna3
Closed

xyzzing wants to merge 1 commit into
Niko1221:mainfrom
xyzzing:pr-qsa-select-wmma-rdna3

Conversation

@xyzzing

@xyzzing xyzzing commented Oct 1, 2026

Copy link
Copy Markdown
Contributor

QSA select: RDNA3 (gfx1100) WMMA block-scores arm on #337's arch dispatch (opt-in STRATA_SELECT_WMMA=1)

Rebase of #312 as requested ("rebase this onto #337's HIP scorer entry point (it dispatches by arch) and keep it
opt-in under STRATA_SELECT_WMMA=1"). Stacked on #337: it merges that branch first, then adds the gfx1100 arm.

What the dispatch looks like now

qsa_block_scores_tc on HIP dispatches by architecture, one arm per card family:

  1. gfx12 (RDNA4) — hip: gfx12 (RDNA4) QSA select - WMMA block scorer, prompt-aware top-k dispatch #337's block_scores_wmma_kernel (bf16 three-way split), unchanged.
  2. gfx1100 (RDNA3) — this PR's block_scores_wmma_gfx11_kernel: rocWMMA 16x16x16 FP16 operands, FP32
    accumulation, wave32; keys and queries converted to FP16 per call into an internal scratch (the conversion is
    part of the arm's cost). Opt-in: STRATA_SELECT_WMMA=1 — its scores are FP16-input with another summation
    order, so they can change selection. STRATA_SELECT_OLD=1 still forces the warp kernel above all of this.
  3. anything else — return false, the warp kernel (unchanged default behavior; no card sees a new arm by default).

The arm that ran is printed once (strata select: prompt scorer arm = ...), so an opt-in that quietly fell back
cannot masquerade as the fast path.

Evidence (all measured on the card the PR targets)

  • Parity, 5/5 cases incl. adversarial fixtures (re-run on this branch's own 0.1.31 build) (qsa_select_wmma_parity, registered with ctest): the warp arm
    is bitwise == its host model; the tail block is bitwise == the warp arm (shared tail kernel — no new tail
    arithmetic); every score inside the pre-derived bound B(qi,b) = 2^-9.5 * S(qi,b) + 8 * 2^-24 * |score| vs a
    FP64 oracle (worst utilisation 0-11%); selection ids agree wherever the gap > 2B; the +2.5B negative control
    correctly FAILS the suite (the harness can detect a defect of the size the bound claims to cover).
  • Kernel bench @128k ctx (nq=256): warp 2.735 ms → wmma 0.235 ms = 11.64x on the kernel, re-measured on this branch's 0.1.31 build (the 0.1.24-base campaign measured 11.05x — same kernel, new base); the
    same kernel measured paired end-to-end at +8.7% at 128K (1K +0.2% ... 64K +3.8%; 123 paired cells,
    STRATA_SELECT_WMMA=1 vs default; decode within the protected cap) - that full table is in QSA select: ROCWMMA block-scores arm (opt-in STRATA_SELECT_WMMA=1, gfx1100) #312's description
    and carries over: the kernel is byte-identical through the 0.1.29/0.1.30/0.1.31 rebases, only the base moved.
  • The bench (qsa_select_bench) gains an FP64 accuracy gate sampled against all present arms and returns non-zero
    on a failed gate or a register-top-k mismatch (addressing the Copilot review items on hip: gfx12 (RDNA4) QSA select - WMMA block scorer, prompt-aware top-k dispatch #337's bench for our arm).

Files

CMakeLists.txt (parity + bench registration, rocWMMA detection), include/strata/kernels/qsa_select.hpp,
src/kernels/cuda/qsa_select.cu, src/kernels/qsa_select_bench.cpp (merged with #337's capacity-arg + FP64-gate
form), src/kernels/qsa_select_wmma_parity.cpp, src/prefill/prefill.cpp (call site unchanged from #337's —
the dispatch is internal to qsa_block_scores_tc).

We have no RDNA4 card, so the gfx12 arm is #337's and theirs to carry; on our RX 7900 XTX every number above is
personally reproduced. Default behavior on every architecture is unchanged unless STRATA_SELECT_WMMA=1.


Validated on this branch's own 0.1.31 build (gfx1100): parity 5/5, bench 128K 11.64x kernel with the wmma arm at worst 0.09 of its pre-declared bound, register top-k ids identical 256/256. The bench's FP64 gate applies each arm's own declared contract (4x-warp for the FP32-level arms; the 2^-9.5*S fp16-conversion bound for this arm - the same bound the parity suite enforces).

@xyzzing

xyzzing commented Oct 2, 2026

Copy link
Copy Markdown
Contributor Author

Rebased onto current main (0.1.35, d9ab843) — the PR is now exactly the gfx1100 arm: #337's content is upstream, so the branch is one clean commit on main (+629/−67 across the 6 files): the FP16 WMMA kernel as the second branch of the existing AMD dispatch (gfx12 first, gfx1100 under the same STRATA_SELECT_WMMA=1 opt-in, else the warp kernel), the parity suite, and the bench with #337's capacity arg + FP64 gate extended per-arm (each arm gated by its own declared contract — 4x-warp for the FP32-level arms, the 2^-9.5·S conversion bound for this one; the same bound its parity suite enforces with adversarial fixtures and a failing negative control).

Fresh numbers, measured on this branch's exact source on an RX 7900 XTX / gfx1100 / ROCm 7.1.1, paired per the frozen contract (5 interleaved pairs × 2 slots, one-shot runs, the tuned AMD config):

  • Parity: 5/5 incl. one-hot/coordinate-coded adversarial fixtures vs the pre-declared bound; the +2.5B negative control correctly FAILS the suite.
  • Kernel @128k: 11.64x (warp 2.735 ms → wmma 0.235 ms), wmma at worst 0.09 of its bound.
  • End-to-end (0.1.33/0.1.35 engine): +9.82% at 128K (n=10 paired), +4.24% at 64K holdout — the prompt path's qsa-select phase halves (12.4 s → 5.4 s at 128K).
  • Decode: −3.77% (paired median), beyond our predeclared 3% protection → by our own gates this arm KEEPS its opt-in status: it is a long-prompt tool, not a default-flip candidate. That matches the opt-in you chose for hip: gfx12 (RDNA4) QSA select - WMMA block scorer, prompt-aware top-k dispatch #337.

Byte-identity note: this branch's five source files are byte-identical to the tree that produced those parity/bench/e2e numbers (validated before the rebase packaging).

…h (opt-in STRATA_SELECT_WMMA=1)

Rebased onto 0.1.35 main (d9ab843). The gfx1100 FP16 WMMA arm (rocWMMA 16x16x16,
FP32 accumulation, wave32) plugs into qsa_block_scores_tc's AMD dispatch as the
second branch: gfx12 (RDNA4, Niko1221#337) first, then gfx1100 under the same
STRATA_SELECT_WMMA=1 opt-in, else false -> the warp kernel. STRATA_SELECT_OLD=1
still wins. The arm that ran is printed once, so a silent fallback cannot pass
as the fast path. The kernel is renamed block_scores_wmma_gfx11_kernel (Niko1221#337's
gfx12 kernel keeps its name). The bench carries Niko1221#337's capacity arg + FP64 gate
with each arm gated by its OWN declared contract (4x-warp for the FP32-level
arms; the 2^-9.5*S fp16 conversion bound for this arm - the same bound its
parity suite enforces with adversarial fixtures and a failing negative control).

Validated on this exact source (gfx1100, ROCm 7.1.1): qsa_select_wmma_parity 5/5
incl. adversarial fixtures; kernel bench 11.64x at 128K (wmma at worst 0.09 of
its bound); paired e2e on 0.1.33: +9.82% at 128K and +4.24% at 64K (gate 1/3
pass) with decode -3.77% (gate 2, cap 3%) -> the opt-in default is correct; the
measured table is in the PR thread.
@xyzzing
xyzzing force-pushed the pr-qsa-select-wmma-rdna3 branch from 6bbb1c5 to ae3e1b7 Compare October 2, 2026 16:41
@Niko1221

Niko1221 commented Oct 3, 2026

Copy link
Copy Markdown
Owner

Thank you for the careful parity work and the numbers. We can't maintain a second architecture-specific scorer arm without an AMD card to test it on, and even as an opt-in it costs decode (-3.8% in your runs). Please keep it in your fork for long-prompt work; closing here.

@Niko1221 Niko1221 closed this Oct 3, 2026
xyzzing added a commit to xyzzing/Strata that referenced this pull request Oct 4, 2026
Niko1221#368 content)

Carried from the pr-qsa-select-wmma-rdna3 branch (0.1.38 rebase 7e8adda) onto the
current line (0.1.39 + the RDNA3 WMMA prompt-attention arm). The gfx11 kernel keeps
its rename (block_scores_wmma_gfx11_kernel; the gfx12 kernel keeps the plain name),
the arch dispatch inside qsa_block_scores_tc routes gfx12 -> gfx1100-under-opt-in ->
false (warp fallback), and the arm prints once so no fallback can masquerade.
Parity + bench re-registered in CMake.
@xyzzing

xyzzing commented Oct 4, 2026

Copy link
Copy Markdown
Contributor Author

Rebased onto current main (0.1.39, 6f32ec0) — two commits, strata + both select test binaries compile- and run-gated on gfx1100. Fresh measurements on an RX 7900 XTX (ROCm 10.2 nightly SDK, gfx1100 hipBLASLt-100500 table, production-mirrored config, paired A/B arms alternating, env STRATA_SELECT_WMMA=1 on/off, same binary):

  • parity (qsa_select_wmma_parity): all cases PASS — FP64-oracle bound (worst utilisation 11.0%), selection ids agree wherever the gap exceeds 2B (differing queries 0), tail bitwise vs the warp arm, canaries + negative controls. One test-harness note: the warp-kernel contraction pin no longer fits on the nightly toolchain (the newer clang interleaves the four head-accumulators through v_fmac, so no single host-emulable pattern matches bitwise anymore) — demoted to a loud diagnostic in the second commit, since the arm's gates are the bound/selection/tail checks, not the pin.
  • kernel bench: scores @128k (ctx 131072, 256 queries × 32769 blocks): warp 2.862 ms → wmma 0.245 ms = 11.69×; register top-k identical 256/256.
  • paired e2e (5 pairs × 1K/32K/128K, 30/30 cells): prefill @128k +11.2% median, 5/5 pair wins (1514 → 1683 tok/s vs the PA-arm baseline of hip: RDNA3 (gfx1100) WMMA kernel for the int8-KV QSA prompt attention (opt-in STRATA_HIP_WMMA, gfx12/gfx11) #786 — the two arms compose); @32k +4.7% (4/5); decode flat-to-positive (the scorer was ~0.1% of decode). Mechanism confirmed in-engine: the qsa-select phase drops 12.2% → 2.4% of prefill GPU time.

The rebase surface is unchanged (6 files). gfx1100 currently runs the warp kernel on 0.1.39 (the only WMMA select in main is gfx12-gated), so this arm is the whole gap.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants