Repository navigation
fix(rocke): emit the gfx1250 DPP softmax reduce with update.dpp, not inline asm - #14613
Conversation
…inline asm IRBuilder.vop2_f32_dpp_xor emitted each softmax row-reduce stage as inline asm (v_max_f32_dpp / v_add_f32_dpp ... row_xmask:N). LLVM's hazard recognizer does not look inside inline asm, so on gfx1250 those asm VALU writes could overwrite a WMMA source operand before the required gap and LLVM added no wait states (checkWMMACoexecutionHazards only sees real instructions). Emit the stage as warp_shuffle_xor_dpp (llvm.amdgcn.update.dpp, row_xmask) followed by fmax/fadd. GCNDPPCombine folds the mov back into v_add_f32_dpp / v_max_num_f32_dpp, and the hazard recognizer now covers the DPP writes. The docstring's claim that GCNDPPCombine refuses to fold row_xmask movs on gfx1250 was wrong; the fold works. With upstream LLVM, decode_3d seg kernels keep all 128 fused DPP ops (112 with --wide-kv-load, where 16 fadds sit in a divergent block) and the modeled WMMA co-execution violations drop to 0 (4 in the fp8 configs with the asm). Compilers that quiet the shuffled value for llvm.maxnum keep the max stages as mov_dpp + v_max_num_f32 until they pick up upstream. The forced wmma_spacing=1 (v_nop) for use_dpp_softmax is left in place; removing it needs a hardware run. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
✅ All Checks Passed — Ready for Review
📖 Need help? See the Policy FAQ for details on every check and how to fix failures. |
|
🎉 All checks passed! This PR is ready for review. |
CongMa13
left a comment
There was a problem hiding this comment.
No new issues found. I agree with the following existing comments:
- PR description needs an issue reference —
therock-pr-bot[bot]— #14613 (comment) (repeated at #14613 (comment)) - Changed source needs an accompanying unit test —
therock-pr-bot[bot]— #14613 (comment)
CongMa13
left a comment
There was a problem hiding this comment.
No new P0 or P1 issues were identified during this review. The changes are approved.
Check that each softmax row-reduce step lowers to one in-row llvm.amdgcn.update.dpp (row_xmask, 0x160 | mask) followed by maxnum or fadd with the shuffled value as the first operand, and that no inline asm is emitted. The checks run on the Python lowering before the cross-engine comparison, so they also run where the C++ engine is not built. The unchanged argument checks of vop2_f32_dpp_xor are covered as well. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Automated review: Model - qwen3.6:35b-a3b-coding-mtp-q4_K_M, effort: max PR #14613 — emit the gfx1250 DPP softmax reduce with update.dpp, not inline asm (reble, AICK-2839) — 🟡 First-round: no closer look needed — exact rewrite; the WMMA hazard check now sees the DPP writes; ROCm clang leaves the max steps unfused
Utility: 🟢 Positive — closes an unguarded WMMA operand overwrite in gfx1250 decode; exact rewrite. Legend: 🔴 blocking · 🟠 should-fix · 🟡 minor nit · 🟢 info/good · ⚪ retracted First-round review: a local qwen3.6 model made the independent first pass, and the orchestrator (Claude Opus 5.5) verified it. On a clean merge with develop, it ran the native build and ctest, byte identity (every family at llvm22), the representative and differential goldens, and the PR's test file. It checked the new lowering against the old asm, lowered two gfx1250 decode_3d seg kernels on the merge and on develop, compared their ROCm clang 24 ISA, probed the max-step fusion, and read the four hipkernelprovider CI logs at head. The orchestrator owns this merge-worthiness call. It flags whether a closer look is needed; it is not an approval or a rejection. |
TheRock Submodule Bump ActivityNewest first
|
JIRA ID : AICK-2839
Motivation
On gfx1250 the decode attention softmax (
attention_tiled_3d, DPP softmax on by default) emits each row-reduce step throughIRBuilder.vop2_f32_dpp_xoras inline asm (v_max_f32_dpp/v_add_f32_dpp ... row_xmask:N). LLVM does not inspect inline asm for the gfx1250 WMMA co-execution hazard (GCNHazardRecognizer::checkWMMACoexecutionHazards), so an asm DPP write to a WMMA source register gets no wait states. As real instructions the DPP ops are covered by the hazard recognizer.Technical Details
core/ir.py::vop2_f32_dpp_xornow emitswarp_shuffle_xor_dpp(llvm.amdgcn.update.dpp,row_xmask:N) followed byfmax/fadd. Signature and callers (helpers/attention.py::wave_reduce_max/sum) are unchanged.v_mov_b32_dppback intov_add_f32_dpp/v_max_num_f32_dpp. The docstring claimed this fold does not happen on gfx1250; that is corrected.wmma_spacing=1foruse_dpp_softmaxis left in place; removing it needs a hardware run.Test Plan
rocke_ir_parity_harness.py --check) on llvm20, llvm22 and llvm23platform/tests/test_rocke.pyand the library attention testsdecode_3d_verifyseg kernel for 13 configurations (bf16/fp8 KV, kv 512-4096,--invariant-hoist,--num-waves 4,--dtla,--sw-pipeline,--plain,--ds-tr,--register-p,--wide-kv-load), compiled with upstream LLVM (d55a3fd2,-O3): fused DPP count and WMMA co-execution distances against LLVM's wait-state tableTest Result
test_rocke.py: 316 passed, 124 skipped. Attention tests: 138 passed, 51 skipped. Both unchanged by the patch (compared at the earlier base 7accefb).--wide-kv-load, where 16 adds run under a different EXEC mask than their DPP mov, which GCNDPPCombine does not fold across); hazard violations 4 -> 0 in fp8 kv 512/4096 and 0 everywhere else.--num-waves 4--plain --wide-kv-loadCompilers that quiet the shuffled value for
llvm.maxnum(a separatev_max_num_f32 v, v, v) leave the max steps unfused until they pick up upstream. Not run: GPU,tools/check_byte_identity.py,pre-commit.Submission Checklist
Co-Authored-By: Claude Opus 5.5 noreply@anthropic.com