Repository navigation
perf(hip): a skewed-row matrix tile, three blocks a WGP on gfx1151 for prompts up to 8192 codes deep - #2087
perf(hip): a skewed-row matrix tile, three blocks a WGP on gfx1151 for prompts up to 8192 codes deep#2087AbrahamCete wants to merge 4 commits into
Conversation
|
Thanks @AbrahamCete, a careful piece of work: the same sums in the same order, one more block a WGP, byte-identical logits, and the 27B's cold first token 3 to 4% sooner, with the depth cut-off measured instead of guessed. Two things before it lands. Main gained #1938's records and contract imports in the same two lists, so it needs a rebase. And our HIP records hold the release hipcc (ROCm 10.1, HIP 7.16), while this tile's come from the system compiler. Please regenerate the four |
…rows tuning.build compares every Row field name for each row at comptime, and the default quota of 1000 backward branches stops a table near 30 rows. The quota now scales with the rows and fields.
…r prompts up to 8192 codes deep affine_wmma_gemm stages x and the codes in rows padded to 20 words (45,056 bytes of LDS), so gfx1151 holds two blocks a WGP. affine_wmma_skew is the same tile with unpadded rows, each pair 16 bytes on in an 8-row group: 39,936 bytes, 230 VGPRs, three blocks a WGP, eight readers on eight bank groups, and the same sums in the same order. The registry takes it on gfx1151 (cost 9.5, between item64 and matrix) for products up to skew_k = 8192 codes deep; deeper, three blocks a WGP outgrow the caches and the padded tile stays faster. Its bytes equal the padded tile's: the order test, the routed row sweep and the kernel contract check them.
… layout comment fits 120 columns A routed launch passes the shape an item's rows (128 at prefill), not the chunk's, so the routed case the test built did not match what the engine sends. The test now covers plain prompts on both sides of skew_k and gfx1100's table.
566e7d1 to
de38a34
Compare
|
Thanks @ashhart. Both are done.
I've updated the description to match. The column-block bound will come as a follow-up. One more thing that hipcc showed: 8 of main's 22 are the planned-walk records of |
|
Thanks @AbrahamCete, both done: the rebase keeps logits byte-identical, and the skew tile's records now read current against the release hipcc. This is ready to land. And yes please to the separate PR re-deriving #1961's |
What this changes
On gfx1151 the prompt GEMM tile (
affine_wmma_gemm) holds two blocks a WGP (rocprofv3: 316 resident waves). Its 45,056 bytes of LDS are the limit: LDS goes out in 1 KB granules here, so three blocks need at most 43,008 bytes (a timed probe kernel fits three at 43,008 and two at 43,520). The extra bytes are the padding of the staging rows: each row of 16 words is padded to 20, so that eight 16-byte readers hit eight bank groups. Dropping the padding alone isn't enough: an XOR-swizzled layout came out at 250 VGPRs, which the compiler holds at five waves a SIMD.This PR adds
affine_wmma_skew: the same tile (wmma_gemm_tilewithSKEW = true), with unpadded rows where each pair of rows sits 16 bytes on in an 8-row group.Three blocks a WGP don't win everywhere.
skew_k = 8192codes deep (fitsPrefillSkew), at cost 9.5, betweenitem64andmatrix. Deeper products keep the padded tile, and other GPUs' tables have no row for it.Where it loses: shapes with few column blocks (the 35B's n = 2048, k = 4096 and n = 512 products) run 3% to 8% slower on the skewed tile, inside the totals below. A bound on column blocks could keep them on the padded tile; I left that for a follow-up.
It builds on #1658's
gfx1151.zon.skewpast 1,024 rows instead ofmatrix.tuning.build's comptime branch quota now grows with a table's rows. The default stoppedgfx1151.zonnear 30 rows with "evaluation exceeded 1000 backwards branches".Receipt
Environment: Ryzen AI Max+ 395 (gfx1151), Ubuntu 26.04, Zig 0.17.0, hipcc with HIP 7.1.52801 and Ubuntu clang 21.1.8 (rocprofv3 from ROCm 7.13). Checkpoints: Qwen3.8-27B-MLX-4bit and Qwen3.6-35B-A3B-MLX-4bit-MTP. Base: main 70ede48. I first measured on hip: a 64-row routed prompt tile for many-expert plans on gfx1151 #1658's head e3ea8e7 and rebased once it landed; the served runs below are from that base. The branch is now rebased onto main c2aa0fe (after dots.mocr on HIP: the publisher's BF16 OCR checkpoint, token-exact against its model card #1938), where the exactness, contract and test lines below were run again. Both sides were built from
git archivetrees.tf-qwen35-test prefill, one prefill after a warm-up, alternated B C B C, seconds:On hip: a 64-row routed prompt tile for many-expert plans on gfx1151 #1658's head, three rounds gave the same picture: 27B -3.7% at 2048 and 8192 and -2.5% at 32768; 35B -1.9%, -2.2% and -1.6%.
Which tile runs (rocprofv3, 2048 tokens): every 27B prompt product except down launches
affine_wmma_skew, and down keepsaffine_wmma_gemm. The 35B's dense products launchaffine_wmma_skew. Its routed products launchaffine_wmma_item, because hip: a 64-row routed prompt tile for many-expert plans on gfx1151 #1658's chunk cap doesn't bind there (see my note on hip: a 64-row routed prompt tile for many-expert plans on gfx1151 #1658). Where the skewed tile runs them instead, they take 5.06 / 2.98 ms a call against 5.76 / 3.36.Served, on hip: a 64-row routed prompt tile for many-expert plans on gfx1151 #1658's head (the logits hashes are the same on both bases, and the gains above reproduce on main), one fresh server a run, alternated B1 C1 B2 C2:
tools/bench_cache.py --require-cold --tokens 16,--context 34816 --parallel 1 --prompt-cache-gib 0,ttft_s:Every cold request's
token_shais the same on both sides, with 0 cached tokens.tools/bench_concurrent.py --levels 1,4 --tokens 256 --reps 3 --temperatures 0 --alone --serial,--parallel 4: token hashes are equal on every server (35B code9f2923ac14d0, chata8c28b8297b4; 27B code2b28aa2108de, chata06fab348fbe), 0 failed. Decode is unchanged: code at 4 streams 229.5 / 230.9 on hip: a 64-row routed prompt tile for many-expert plans on gfx1151 #1658 and 230.7 / 231.7 here on the 35B; 43.8 / 43.8 and 44.0 / 44.1 on the 27B.Exactness:
--f32, on 70ede48 and again on c2aa0fe (27Bdcc85692582d/232dd4cf1fcd, 35B18bee11563f1/84fbaeb871d7).--f32. So are the 64-step decode logits.Kernel contract, built with ROCm 10.1's hipcc (HIP 7.16.26385) on c2aa0fe:
SUMMARY gfx1151 95 kernels: 95 pass gates 1-4, 0 fail, 2 known findings; 11 controls: 11 red as planted, 0 missed; 6 limit problems. Main has 93 kernels and the same 6 limit problems.affine_wmma_skewat groups 32 and 64 passes nonfinite, repeat, shapes (18 shapes bit-equal toaffine_wmma_gemm) and sums.FAIL kernel-contract-limits: 22 problems, the same 22 as main. The tile's lines readrecord currenton gfx1100 and gfx1151 andN/Aon the other two.Tests run:
zig build test -Dhip=true --summary all: 570/570 steps.zig build hip-kernel-test --summary all: 132/136 passed, 4 skipped, 0 failed.tools/zig/lean_check.py: 425 problems, the same as main.zig fmt --checkis clean.contract_wmma_skew.zig); a selection test forskew_k's edges on gfx1151 and for gfx1100 keepingmatrix.Not run, and why: gfx1030, gfx1100, gfx1150 and gfx1201, because I have no card. gfx1100's table has no row for the tile, and gfx1150 (RDNA3.5, 1024 VGPRs) would read gfx1151's table but hold the same two blocks a WGP.