Repository navigation
Conversation
8 of 9 tasks
This was referenced Nov 2, 2026
Merged
This was referenced Nov 3, 2026
… the scalar kernel's bits
tf_fn_sparse_lanes{6,12}_{f16,bf16} do the scalar kernel's fp32
operations in its order: a row's 32-key tiles, each score a sum over
the dims in order, the per-tile xor-shuffle max and sum, the running
max and sum folded tile by tile, and P.V key by key. Only the operands'
sources change: a lane holds a key and several heads, q is read four
dims at a time, K and V are staged in the cache type with 16-byte loads
and V is read from LDS, the cache kind is a template parameter, and one
tile in 31 KB of LDS lets two blocks share a CU.
The launcher takes it for 16-bit caches with head dims on 8 and keeps
tf_fn_sparse_parts for fp32 caches. A device test compares both
kernels' parts, maxima and merged rows word for word; the contract gets
records for both cache kinds and an fp64 runner.
gilby
force-pushed
the
strix/hip-sparse-lanes
branch
from
November 3, 2026 11:01
d719be1 to
14f04fe
Compare
Contributor
Author
|
Rebased onto current main (cfcbecb). The conflicts were the CHANGELOG, the record list and the kernel and contract registries, all resolved by keeping both sides. The merge took Receipts on the rebased head (14f04fe), one Strix Halo iGPU (gfx1151), ROCm 7.1 hipcc, zig 0.17.0:
Not run: gfx1030, gfx1100 and gfx1201 hardware, and any other family. Still waiting on a review. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What this changes
Flash Next's sparse attention on HIP gets a second kernel,
tf_fn_sparse_lanes{6,12}_{f16,bf16}(zig/kernels/hip/flashnext/sparse_lanes.hpp), that does the same fp32 operations in the same order astf_fn_sparse_parts{6,12}and so gives the same bits: the launcher takes it for 16-bit caches whose head dim is a multiple of 8, and keeps the scalar kernel for fp32 caches. Prompt rows, decode rows and MTP verify rows all go through it, as they did through the scalar kernel.The scalar kernel spends most of its time on LDS reads (two per multiply-add) and a cache-kind branch per element. The new kernel keeps each row's 32-key tiles, each (head, key) score as a sequential dim-by-dim sum, the per-tile xor-shuffle max and sum trees, the running max/sum update tile by tile and P·V key by key, and changes only where the operands come from:
Refs #1597.
Receipt
9e8c368bplus this change,zig build native-hip -Dhip-arch=gfx1151, Ubuntu archive HIP 7.1 (clang 21), AMD Ryzen AI MAX+ 395 with Radeon 8060Sgfx1151(128 GB unified memory). CheckpointTensorFold/Qwen3.8-Flash-Next-MLX-4bit-MTPrevision2b170fa6, MTP 3 drafts,--parallel 1 --context 131072 --prompt-cache-gib 0, base and candidate alternating on fresh servers on the same machine.hip/kernel_tests/flashnext_sparse.zig) runs both kernels on the same rows and compares the parts, the maxima and sums and the merged rows word for word: bf16 and fp16 caches, 12, 6 and 3 query heads a kv head, head dims 256 and 128, 1, 3, 5 and 16 parts, key counts 0, 1, 7, 31, 32, 33, 63, 64, 65, 97, 300, 650, 2,000 and 2,048, listed and dense rows. It needs the new launcher entry, so it fails to build on main.zig build hip-kernel-test110 passed, 1 skipped, 0 failed (run directly from the test binary); with two of the kernel's additions swapped, the new test fails.tf_fn_sparse_lanes12_{f16,bf16}and a runner (zig/tests/hip/contract_sparse_lanes.zig) against an fp64 reference:SUMMARY gfx1151 53 kernels: 53 pass gates 1-4, 0 fail, 2 known findings; 5 controls: 5 red as planted, 0 missed; 130 limit problems(main: 52 kernels, the same 2 known findings and 130 limit problems). The limit problems are the same register differences in existing kernels as on main; the new records pass their live limits. All four chips' records come fromzig build hip-kernel-contract-limits -Dhip-relax-branches=true(every new record current on gfx1030, gfx1100, gfx1151 and gfx1201); the live check passes on gfx1151.token_sha256oftools/bench_openai.py,tools/bench_concurrent.pyand bothtools/bench_cache.py --require-coldprompts identical to main;bench_concurrent --alone --serialevery cell equal, 0 failed.tools/bench_cache.py --require-cold --tokens 16on public 7,377- and 29,364-token arrays, cold requests after the first (fresh servers in the order main, this, ..., main): 7,377 tokens 19.51 / 19.52 s -> 12.24 / 12.28 s (-37%), 29,364 tokens 87.22 / 86.96 s -> 53.38 / 53.35 s (-39%). The first request after start: 45.4 / 45.0 -> 38.4 s and 97.7 / 97.2 -> 62.9 s.tools/bench_openai.py --tokens 256 --reps 3 --temperatures 0, median tok/s code / chat: main 49.87 / 43.85 and 50.06 / 44.02, this change 50.57 / 44.50 (unchanged); MTP acceptance unchanged (2.753 / 2.37 tokens a round), as the bits are.tf_fn_sparse_parts129.82 s →tf_fn_sparse_lanes12_bf161.96 s, at the same 1,614 launches; the whole GPU window 21.7 -> 13.7 s (profiled on maind377fcc6before the rebase).zig build test -Dhip=true --summary all485/485 steps, 0 failed;python3 tools/zig/lean_check.py424 on main and change;zig fmt --checkandgit diff --checkclean.Checklist
"draft": false, a resumed prompt equals a fresh one, and concurrent equals solo.SUMMARYline is in the receipt.