You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
HIP Flash Next: WMMA sparse attention for prompt chunks on gfx11 #1597
On AMD Ryzen AI MAX+ 395, Radeon 8060S gfx1151 (40 CUs, 128 GB unified memory, measured 225.6 GB/s read), Ubuntu 26.04, archive HIP 7.1 (clang 21), TensorFold 7c068895, TensorFold/Qwen3.8-Flash-Next-MLX-4bit-MTP.
A cold prompt prefills at about 240 tok/s, flat from 8K to 262K tokens. A rocprofv3 kernel trace of one 7.9K-token prompt puts 33% of the window in tf_fn_sparse_parts12 (zig/kernels/hip/flashnext/sparse.hpp): 9.8 s over 1,669 calls, about 7 ms per 64-row slice once the indexer's selection is full. The kernel is scalar fp32: one block per (kv head, query row, part), each staging its own row's selected keys, so neighbouring query rows that select mostly the same blocks share nothing.
Proposal
A prompt-only kernel on gfx11 WMMA: 4 query rows x the kv head's 12 query heads as 48 WMMA columns, walking the union of those rows' selected blocks, with per-row block masks, the causal end per row, fp32 online softmax and the existing parts/merge layout. Decode keeps the scalar kernel. It changes the sums (bf16 Q.K and P.V fragments with fp32 accumulation instead of fp32 scalar), so it needs the agreed arithmetic gate.
A prototype behind an opt-in switch: the kernel matches an fp64 reference within 2.1e-3 absolute on served shapes (the scalar kernel 1.7e-7); prefill 231/260/241 -> 326/411/374 tok/s at 8K/32K/131K with needles found and decode unchanged; the sparse kernel's time per 8K prompt drops from 9.81 s to 0.73 s.
Gate to agree
FP64 error bound and teacher-forced top-token comparison against the scalar kernel on served shapes.
Kernel contract registration on the HIP runner (gates 1-5) and limits for every served RDNA chip.
Drafted equals plain, concurrent equals solo, resumed equals fresh, on the WMMA path.
Thanks @gilby. 9.8 s to 0.73 s for the sparse kernel on an 8k prompt is a big gain.
The WMMA path changes tokens: 2.1e-3 against FP64, where the scalar kernel is at 1.7e-7. So it can land as an opt-in
only, and it stays opt-in. The scalar kernel remains the default. The gate:
a measured quality check: teacher-forced top-token differences against the scalar kernel on served shapes, with
every difference and its margin recorded, and needle retrieval at 8k, 32k and 131k;
the FP64 error bound on served shapes, reported per column as well as overall;
the kernel contract on the HIP runner, with limits for every served chip;
drafted equal to plain, concurrent equal to solo and resumed equal to fresh, on the WMMA path itself;
tokens equal to main with the switch off.
If you can keep the products closer to fp32 (a high and low bf16 split, or P kept in fp32) and keep most of the gain,
that version could be held to the exact gate and become the default. Draft #1622 looks like this work, and the same
points apply there.
Activity
gilby commentedon Oct 29, 2026
/atc claim
gilby commentedon Oct 29, 2026
/atc presence 92c09e919a782d24ccd6e54e1270735b752a9eebbac6e2c5f15b15ba701cf795
ashhart commentedon Oct 30, 2026
Thanks @gilby. 9.8 s to 0.73 s for the sparse kernel on an 8k prompt is a big gain.
The WMMA path changes tokens: 2.1e-3 against FP64, where the scalar kernel is at 1.7e-7. So it can land as an opt-in
only, and it stays opt-in. The scalar kernel remains the default. The gate:
every difference and its margin recorded, and needle retrieval at 8k, 32k and 131k;
If you can keep the products closer to fp32 (a high and low bf16 split, or P kept in fp32) and keep most of the gain,
that version could be held to the exact gate and become the default. Draft #1622 looks like this work, and the same
points apply there.