Skip to content

cleanup(rocm): build only the launched W4A8 sdot4 config - #89

Merged
BlivionIaG merged 2 commits into
rdna_extrasfrom
cursor/trim-w4a8-dead-configs-5089
Nov 12, 2026
Merged

BlivionIaG merged 2 commits into
rdna_extrasfrom
cursor/trim-w4a8-dead-configs-5089

Conversation

@BlivionIaG

@BlivionIaG BlivionIaG commented Oct 12, 2026 •

Copy link
Copy Markdown

Purpose

The production dense W4A8 sdot4 GEMM only builds the config it launches.

w4a8_gemm_rdna2 calls find_config(kDefaultConfigId) with kDefaultConfigId = 8 (a8_lds_k32_ag: 256 threads, NPT 4, K_STEP 32, M_TILE 8, LDS A, per-group activation scales) at group sizes 32, 64, and 128. The translation unit still instantiated the other eight explore configs at those three group sizes (24 kernel copies with no launch path), plus an uninstantiated probe kernel and an instantiate macro with no users. The header banner also claimed the file was not in the build.

This drops configs 0–7 from W4A8_EXPLORE_CONFIGS, deletes w4a8_probe_kernel (gfx1030 body and non-gfx stub) and W4A8_EXPLORE_INSTANTIATE_GEMM, and replaces the banner. find_config / kConfigs stay a one-entry lookup, so id 8 still resolves the same way. There is no env that selects a config id: the only getenv on this path is VLLM_RDNA2_W4A8_DEBUG. docs/rdna2/tuning.md documents VLLM_RDNA2_W4A8_SDOT4 (path on/off) and the two shape loggers, not a config picker, so the lookup for id 8 is unchanged.

Kept: config 8 at group sizes 32/64/128, the w4a8_gemm_kernel and w4a8_act_quant_kernel bodies, and VLLM_RDNA2_W4A8_DEBUG / VLLM_RDNA2_W4A8_MOE_DEBUG.

Not touched: csrc/rocm/moe_w4a8_rdna2.cu, CMakeLists.txt, ops.h, torch_bindings.cpp, _custom_ops.py (open PRs #51 and #57 edit those), and tests/kernels/quantization/test_rdna2_w4a8.py / test_rdna2_moe_w4a8.py.

This supersedes #41. That draft did the same trim on the stale base rdna_extra/v0.28.0 and cannot land. This PR is against rdna_extras (tip 64d59b89) and does not modify #41. No other open PR on rdna_extras removes these unlaunched copies.

AI assistance was used (Cursor Grok 4.7). A human should review every changed line.

Test Plan

No gfx1030 GPU on this VM, and hipcc is not installable here (hipcc is not on PATH; apt-cache search for hipcc and rocm-dev returns no packages). A gfx1030 build plus tests/kernels/quantization/test_rdna2_w4a8.py is required before merge.

Local checks, against rdna_extras at 64d59b8942:

  • Byte-compare w4a8_gemm_kernel (device body and non-gfx stub) and w4a8_act_quant_kernel (both copies) extracted from HEAD and this branch. Both real bodies match (w4a8_gemm_kernel 6484 bytes, w4a8_act_quant_kernel 3436 bytes). git diff hunks are only the banner, the probe kernel, the probe stub, and the config/instantiate macros.
  • rg for w4a8_probe_kernel, W4A8_EXPLORE_INSTANTIATE_GEMM, enum class Probe, and the dropped config names (a16_lds_k32, a16_lds_k16, a16_smem_k16, a8_smem_k32, a32n2_lds_k32, c16_lds_k32, a16_lds_k32_ag): no matches.
  • clang-format 21.1.2 --style=file --dry-run --Werror on the two edited files.

No model eval. The launched instantiation is unchanged (Cfg<256, 4, 32, MT=8, GROUP, kLds, A_GROUP=true> for GROUP in {32, 64, 128}), so numerics should not move. That still needs a gfx1030 run of test_rdna2_w4a8.py before merge.

Test Result

Kernel-body compare: identical, as above. Removed symbols: no remaining references in the tree. clang-format 21.1.2: clean. hipcc --offload-arch=gfx1030 -fsyntax-only of w4a8_sdot4_rdna2.cu: not run; ROCm/hipcc is not in this image and not in the default apt repos.

Left for later

  • docs/rdna2/w4a8-wiring.md still describes the header as a verbatim copy of /tmp/pr9_branch/csrc/rocm/explore/w4a8_sdot4.cuh and says W4A8_EXPLORE_CONFIGS is the full explore sweep.
  • The Cfg comment still cites isa_check.py. Left as-is so that struct source stays byte-for-byte.
  • The shared GEMM template still has kSmem, NPT=2, and M_TILE 16/32 branches. Config 8 does not take them. Stripping them would edit the kernel source, so they stay.
  • kBadConfig in the .cu error enum is unused. That was already true before this change.

Re-evaluation 2026-11-11

Verdict: ready to merge. The branch is pure subtraction. The gfx1030 build and test_rdna2_w4a8.py that the test plan above asked for were run on a V620 and everything the PR keeps is bit-identical to rdna_extras. Not merged; waiting for the merge decision.

Branch state

Base rdna_extras 1136bb952b (the body above was written against 64d59b8942)
Head e7ee449c78 = bab3c17ecb + merge of rdna_extras (clean). moe_w4a8_rdna2.cu gained large v2-kernel changes on rdna_extras since the PR base; none of it touches the removed items.
Net diff vs base 2 files, +9 / -117 (csrc/rocm/w4a8_sdot4_rdna2.cu, csrc/rocm/w4a8_sdot4_rdna2.cuh)
Authorship bab3c17ecb is authored by BlivionIaG with the Cursor Grok co-author trailer: no agent-authored commit, nothing to re-author. Supersedes the closed #41.
pre-commit passes on the two C++ files (clang-format and the generic hooks)

Nothing uses what is removed

Searched the whole tree (excluding bench_results) at e7ee449c78:

  • w4a8_probe_kernel, enum class Probe / Probe::k*, W4A8_EXPLORE_INSTANTIATE_GEMM, the names of configs 0-7 (a16_lds_k32, a16_lds_k16, a16_smem_k16, a8_smem_k32, a8_lds_k32, a32n2_lds_k32, c16_lds_k32, a16_lds_k32_ag), w4a8_sdot4_capi, w4a8_sdot4_isa_shim: no remaining references.
  • W4A8_EXPLORE_CONFIGS is used only by w4a8_sdot4_rdna2.cu (kConfigs, find_config(kDefaultConfigId = 8)). moe_w4a8_rdna2.cu includes the header but uses only primitives that stay (sdot4, load_w, load_group, f16_t, u32x2_t, kLoMask, thread_x, block_x/y/z). docs/rdna2/w4a8-wiring.md mentions the macro name, which stays.
  • No env var picks a config id (the only getenv calls on these paths are VLLM_RDNA2_W4A8_DEBUG and VLLM_RDNA2_W4A8_MOE_DEBUG). The probe was never registered in torch_bindings.cpp, so no op is removed.
  • Not touched by this PR, as before: moe_w4a8_rdna2.cu, CMakeLists.txt, ops.h, torch_bindings.cpp, _custom_ops.py.

Evidence on a V620 (gfx1030), HIP 0, ROCm 7.14, torch 2.12.0+rocm7.14.0

_rocm_C built for gfx1030 from the exact trees (rdna_extras 1136bb952b and this branch's merge e7ee449c78), same tree path and build dir so code objects are comparable.

check rdna_extras this PR
test_rdna2_w4a8.py, test_rdna2_moe_w4a8.py, test_rdna2_moe_deterministic.py, test_rdna2_moe_fp32_scratch.py, test_rdna2_dense_deterministic_dispatch.py on GPU 114 passed, 0 skipped 114 passed, 0 skipped
CPU-only: test_rdna3_compile_guards.py, tests/tools/rdna/test_mono_w4a8_plan.py, tests/models/qwen4_exp/test_amd_mono_rdna2_w4a8.py 97 passed, 7 skipped (need gfx1100 hardware) 97 passed, 7 skipped
dense W4A8 output hash, 210 cases (w4a8_gemm_rdna2 over M in {1, 8, 32, 33, 64, 200, 513} x K in {512, 2048, 4096} x N in {256, 1024, 4096} x G in {32, 64, 128}, plus w4a8_act_quant_rdna2 over the same M x G) reference all 108 cases that take the W4A8 kernel (M >= 33) and all 21 act-quant cases are bit-identical (SHA-256). The 81 cases with M < 33 take the W4A16 fallback, which is not bit-reproducible even between two runs of the same build (81 of 81 differ run-to-run on rdna_extras and on this PR, run twice each); that path is not touched by the PR
registered _rocm_C ops 172 172, schemas identical

Device code, gfx1030, per function (disassembled and compared instruction for instruction):

translation unit rdna_extras this PR
w4a8_sdot4_rdna2.hip.o 28 functions: 27 w4a8_gemm_kernel (9 configs x G 32/64/128) + w4a8_act_quant_kernel 4 functions: w4a8_gemm_kernel config 8 at G 32/64/128 + w4a8_act_quant_kernel, identical to rdna_extras (5,411 instructions); 24 w4a8_gemm_kernel removed
moe_w4a8_rdna2.hip.o (recompiled against the new header) 44 functions 44 functions, identical (82,877 instructions)
skinny_gemms.hip.o 478 functions identical
all 64 _rocm_C objects (fingerprint of .text, .rodata, .note) 63 identical; only w4a8_sdot4_rdna2.hip.o changed

Size and build time (gfx1030-only _rocm_C):

rdna_extras this PR delta
_rocm_C.abi3.so 91,695,992 B 91,152,640 B -543,352 B (-0.59 %)
.hip_fatbin 22,475,748 B 22,062,052 B -413,696 B (-1.84 %)
host .text 6,829,684 B 6,800,372 B -29,312 B
gfx1030 machine code of w4a8_sdot4_rdna2.hip.o 336,496 B 26,224 B -310,272 B (24 w4a8_gemm_kernel: 307,076 B)
w4a8_sdot4_rdna2.hip.o 2,037,176 B 1,468,480 B -568,696 B (-27.9 %)
compile time of that TU (MAX_JOBS=8, nice 19) 48.8 s 37.6 s -11.2 s

Fat build: w4a8_sdot4_rdna2.cu and moe_w4a8_rdna2.cu also compile (rc=0) for gfx1030;gfx942;gfx1100;gfx1200 from this branch; the non-gfx1030 device passes of the dense TU are the existing stub (772 B of .text), so the production fat build is unaffected. The two C++ files pass clang-format.

Risk

  • gfx1030 only, and only code that nothing launched: the kept config and everything else compiled for gfx1030 (MoE, skinny, all other objects) is instruction-identical, and outputs are bit-identical where the kept kernel runs.
  • Not run: a serving A/B. Nothing in a serving run can reach what was removed (it had no launch path), so there is no performance claim beyond the size and compile-time numbers above.

Notes, not blocking

  • "Left for later" above: the docs/rdna2/w4a8-wiring.md item no longer applies (the file now says the tree has no csrc/rocm/explore/ directory, and W4A8_EXPLORE_CONFIGS is still the name of the macro). The isa_check.py comment in the Cfg struct and the test_rdna2_w4a8.py docstring pointing at benchmarks/kernels/w4a8_sdot4_explore/test_reference.py refer to files that are not in the tree; they were not touched.
Open in Web Open in Cursor 

w4a8_gemm_rdna2 launches config 8 (a8_lds_k32_ag) only. Stop
instantiating the other eight explore configs, and drop the
uninstantiated probe kernel and the unused instantiate macro.

Co-authored-by: Cursor Grok 4.7 <cursoragent@cursor.com>
Signed-off-by: BlivionIaG <kev29lt@gmail.com>
Refresh the branch onto the current rdna_extras tip (1136bb9) before re-evaluating the W4A8 sdot4 config trim on gfx1030.

Signed-off-by: BlivionIaG <kev29lt@gmail.com>
@BlivionIaG
BlivionIaG merged commit a63a6b0 into rdna_extras Nov 12, 2026
4 checks passed
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.

1 participant