Repository navigation
[FlyDSL] HGEMM: keep the C shuffle in fp32 for fp32 output; DSv4 wkv_gate fp32 rows - #6005
AMD-yanfeiwang wants to merge 1 commit into
Conversation
…gate fp32 rows The gfx950 A16W16 kernels rounded the fp32 accumulator to the 16-bit input dtype before the LDS C shuffle, so out_dtype=fp32 (and split-K partials) had bf16-level error (~2e-3 rel). Shared C now uses the output dtype; fp32 output matches torch.mm(out_dtype=fp32) (~1e-6). bf16/fp16 output is unchanged. The fp32 kernel is renamed (_fp32c): FlyDSL's disk-cache key does not cover @flyc.kernel bodies, so the new name keeps old lossy binaries from being served. Adds gfx950 fp32-out tuned rows for the DeepSeek-V4 compressor wkv_gate GEMM (N=1024/2560, K=7168, M<=32), where FlyDSL beats hipBLASLt by 1.2-2.5x. op_tests/test_flydsl_hgemm.py gains -o fp32.
🏷️ CI GuideRuns automatically on every PR:
Extended tests (opt-in via labels):
One backend per PR: PR title tags & labels: |
Motivation
The gfx950 FlyDSL HGEMM (
gemm_a16w16_gfx950) rounds the fp32 accumulator to bf16/fp16 before the LDS C shuffle. Without_dtype=fp32, the output (and every split-K partial) therefore has bf16-level error, about 2e-3 relative. That makes FlyDSL unusable for fp32-output GEMMs such as the DeepSeek-V4 compressorwkv_gate(bf16 x bf16 -> fp32, K=7168). hipBLASLt takes 11-16 us per call there, and a decode step runs 61 of these calls.Technical Details
gemm_a16w16_gfx950.py, ft and hti): the shared C tile and the r2g vectors use the output dtype. fp32 output is no longer rounded to 16 bits, and the LDS size check uses the output bytes. bf16/fp16 output is unchanged.hgemm_bf16_fp32c_.... FlyDSL's disk-cache key hashes the@flyc.jitlauncher and its helpers but not the@flyc.kernelbodies (checked on flydsl 0.3.2 and 0.3.4.1). Without the rename, a cache filled by the old kernel, such as a precompiled image cache, would keep serving the lossy binary.dsv4_bf16_tuned_gemm.csv): 12 gfx950 fp32-output FlyDSL rows for DSv4wkv_gate, N=1024 (HCA) and N=2560 (fused CSA, [ROCm][DSV4] Add opt-in C4 compressor GEMM fusion sgl-project/sglang#38920), K=7168, M in {1,2,4,8,16,32}. For M>32, FlyDSL loses to or ties hipBLASLt, so those shapes stay on torch.op_tests/test_flydsl_hgemm.py -o fp32runs the three DSv4 shapes. Its tolerance is 1e-2 atol / 1e-4 rtol, which any 16-bit rounding fails.linear_bf16_fp32to aitertgemm.mm(otype=fp32)when the tuned row is FlyDSL.Test Plan
python op_tests/test_flydsl_hgemm.py -o fp32andpython op_tests/test_flydsl_hgemm.py(default bf16 set). Run on this commit applied tolmsysorg/sglang-rocm:v0.5.20-rocm724-mi35x-20260927(flydsl 0.3.2, image cache present), 1x MI355X.Test Result
torch.mm(out_dtype=fp32)).Kernel.
wkv_gatebf16 x bf16 -> fp32, K=7168, 1x MI355X. Time per call in us: CUDA-graph replay, 8 rotating weights. The tuned FlyDSL config is compared with torch.mm (hipBLASLt):E2E. DSv4-Pro, TP8 on MI355X, 8k input / 1k output, T_step in ms (lower is better). Paired runs, 2 boots x 3 reps.
All 24 pairs are faster. gsm8k (1319 questions) accuracy per boot: 0.942 / 0.943 before and 0.944 / 0.945 after. DSpark c16/c64 (M>32) are unchanged by construction.