feat(KERNEL-QUANT-CIQ-GEMM-ROCM): keep-quant GEMM providers on kROCM - #1
Open
ghazni101 wants to merge 3 commits into
Open
feat(KERNEL-QUANT-CIQ-GEMM-ROCM): keep-quant GEMM providers on kROCM#1ghazni101 wants to merge 3 commits into
ghazni101 wants to merge 3 commits into
Conversation
…tion call site (mudler#1273) Closes the "Owed" item from mudler#1065: CheckKvCacheShape's production call site in GPUModelRunner::initialize_kv_cache now has a test. Building the runner with a non-multiple-of-16 block size (kBlockSize = 8) asserts the throw at construction, from the FLASH_ATTN backend's own get_kv_cache_shape — the executable statement of the contract the server's --block-size validation and the bench rounding exist to prevent at the entry points. Validated on gfx1151 (Strix Halo, ROCm 7.2.3) as part of the mudler#41 M3 battery: test_runner 20/20 cases, 544 assertions, on the current-main build with mudler#1056 + mudler#1065 merged. Issue: mudler#41 FOLLOWING_AGENTS_PROTOCOL Following-Agents-Protocol: true AI-Assisted: true Assisted-by: DeepSeekV4:Flash [Freebuff]
The ROCm backend registers no quantized-weight GEMM provider, so every GGUF k-quant weight on an AMD card computes off device. The spec scopes W1 as kMatmulBTQuant and kMatmulBTQuantGrouped providers mirroring the CUDA sibling, which the GGUF loader reaches automatically once they are registered, and owes the upstream csrc/rocm W4A16 family behind a loader consumer that does not exist yet. The issue index gains the three 2026-08-21 campaign issues: mudler#1586 toolchain adoption and optimization, mudler#1587 this row, mudler#1588 the Qwen3.5-0.8B numerics characterization. FOLLOWING_AGENTS_PROTOCOL Following-Agents-Protocol: true AI-Assisted: true Assisted-by: AGENT:ox-alpha [omp]
… kROCM The GGUF loader routes a block-typed weight to MatmulBTQuant whenever the running device has the provider, so registering these two ops lights up keep-quant compute on every ROCm board with no model-path change: the dense and grouped MoE towers stage once through ResidentWeight and dispatch to the new device GEMM. Coverage mirrors the CUDA sibling exactly — the ten Q8_K-family encodings plus a native Q8_0 arm. The integer dots are the portable scalar forms of the CPU reference bodies in the CPU accumulation order, because gfx1100 exposes no signed byte dot (v_dot4_i32_iu8 is unsigned-only; sdot4 needs a feature this target does not offer), and the gate is bit-exactness against the CPU tier at NMSE 1e-6 with the f64 dequant band at 5e-4. Unsupported dtypes throw naming the dtype instead of silently falling back to a host kernel that cannot follow device pointers; VT_GGUF_KEEP_QUANT=0 restores load-time expansion. Gates on gfx1100 / ROCm 7.14.0: test_rocm_quant_dot 132,094 assertions green across all ten encodings (decode through prefill shapes, broadcast and per-row grouped arms over a poisoned output buffer), focused ctest 'rocm|cross_device|quant' 20/21 with only the pre-existing MoeSiluMul bf16 exactness failure (mudler#1588) remaining, and an end-to-end Qwen3.5-0.8B Q4_K_M decode that is deterministic on device. FOLLOWING_AGENTS_PROTOCOL Following-Agents-Protocol: true AI-Assisted: true Assisted-by: AGENT:ox-alpha [omp]
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 changed
W1 of KERNEL-QUANT-CIQ-GEMM-ROCM (mudler#1587): the kROCM providers for
OpId::kMatmulBTQuantandOpId::kMatmulBTQuantGrouped, in the newsrc/vt/rocm/rocm_quant_dot.hip, plus the committed spec(
.agents/specs/kernel-quant-ciq-gemm-rocm.md) and a red-first gate(
tests/vt/test_rocm_quant_dot.cpp).Registering the providers flips
GgufQuantComputeAvailable()true onROCm, so every GGUF k-quant model now computes on the AMD GPU through
the existing seams (loader policy ->
vt::MatmulBT[Quant]->GetOp(kROCM)) with zero model-path edits. Towers stage once throughthe existing
ResidentWeightpath.Coverage mirrors the CUDA sibling exactly: ten Q8_K-family encodings
(Q2_K, Q3_K, Q4_K, Q5_K, Q6_K, IQ2_XXS, IQ3_XXS, IQ2_S, IQ1_S,
IQ1_XXXS) plus a native Q8_0 arm. The IQ codebooks reuse
cuda_quant_iq_tables.cuhas the single source — pure__device__syntax, no CUDA — so no transcription drift is possible.
Why
The ROCm backend had no quantized-weight GEMM provider: every GGUF
k-quant weight on an AMD card computed off device (bf16 expansion at
load). AGENTS.md makes quantized arms a standing requirement. Upstream
pins an RDNA3 W4A16 family in
csrc/rocm(gptq_gemm_rdna3gatedVLLM_ROCM_GFX1100) but nothing in this tree can reach it yet — noAWQ/GPTQ consumer exists — so that family stays under
## Owedin thespec (W2), per the reachability rule.
HIP delta that shaped the implementation (measured on gfx1100 /
ROCm 7.14.0)
gfx1100 exposes NO signed byte dot:
__dp4adoes not exist;__builtin_amdgcn_sdot4needs target featuredot1-insts, which clangrejects for this target ("not a recognized feature"); the one hardware
dot that assembles (
v_dot4_i32_iu8) is UNSIGNEDxUNSIGNED and computeswrong over signed Q8 activations (verified by device experiment:
byte 0xFD contributed +253x, not -3x). The integer dots therefore ship
as portable scalar loops in the CPU reference's exact accumulation
order — which is what makes the bit-exactness gate achievable. The ISA
dots are recorded as W2 levers with their own exactness arguments.
__shfl_down_syncalso requires a 64-bit mask on this target.Unsupported dtypes (Q4_0/MXFP4, Q8_0-activation) THROW naming the dtype
instead of falling back to a host kernel that cannot follow device
pointers on a discrete card;
VT_GGUF_KEEP_QUANT=0restores load-timebf16 expansion.
How to verify
On gfx1100 / ROCm 7.14.0 (container
rocm-dev:7.14.0):Measured on this tree:
test_rocm_quant_dot: 132,094 assertions green — all ten encodings xdecode/prefill shapes x broadcast/per-row grouped arms, output buffer
poisoned before every launch so a silent no-op fails (ENG-EXPERT-STREAM: the CUDA arm for IQ1_S and IQ1_XXXS, verified on GB10 mudler/vllm.cpp#967 class).
ctest -R 'rocm|cross_device|quant': 20 of 21 pass;the one failure is the PRE-EXISTING MoeSiluMul bf16 exactness case
tracked in Characterize Qwen3.5-0.8B CPU against ROCm numerics on gfx1100 mudler/vllm.cpp#1588 (present on main before this change).
deterministic across runs, coherent output, warm ~27.6 tok/s at 4B.
What remains unverified or out of scope
a recorded deviation (subagent runtime had no model configured). A
fresh review pass against the spec is still owed before merge.
win; the unsigned-dot/dot2 ISA levers are W2 with their own exactness
arguments.
the spec's
## Owed.riding the follow-up rather than widening this PR.
Closes mudler#1587
FOLLOWING_AGENTS_PROTOCOL
Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: AGENT:ox-alpha [omp]