mirror of
https://github.com/deepseek-ai/DeepGEMM.git
synced 2026-11-05 00:47:26 +00:00
[PR #434] fix: derive the SM120 fp8 mqa_logits swizzle mode from head_dim #445
Labels
No labels
pull-request
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
deepseek-ai/DeepGEMM#445
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
📋 Pull Request Information
Original PR: https://github.com/deepseek-ai/DeepGEMM/pull/434
Author: @aganhui
Created: 9/10/2026
Status: 🔄 Open
Base:
nv_dev← Head:fix/sm120-fp8-mqa-swizzle📝 Commits (2)
184190bfix: match the SM120 fp8 mqa_logits read-side swizzle mode to the TMA descriptors (#433)5825212Address review: fix the fp8 paged variant too, add swizzle-mode static asserts (#433)📊 Changes
2 files changed (+14 additions, -2 deletions)
View changed files
📝
deep_gemm/include/deep_gemm/impls/sm120_fp8_mqa_logits.cuh(+8 -1)📝
deep_gemm/include/deep_gemm/impls/sm120_fp8_paged_mqa_logits.cuh(+6 -1)📄 Description
Fixes #433.
The SM120 fp8 MQA-logits readers un-swizzle shared memory with a hardcoded 128-byte pattern, while the host TMA descriptors and the
tma::copysites swizzle in head_dim-byte atoms (32B/64B/128B for D=32/64/128 — the fp8 row is head_dim bytes). For head_dim 32/64 the XOR bits don't match the write pattern, fragment loads address outside their row, and the kernel returns in-window logits that are silently wrong. D=128 is the only head_dim where the hardcoded value matches, which is why the main DSA path works.This derives the mode from
kHeadDim, matching the sibling kernels: SM90 (to_swizzle_cute_type<kHeadDim>()) and SM100 (kHeadDim / kPackFactor).Both fp8 variants are fixed (second commit, addressing the review finding): the fp8 paged dispatch has no
head_dim == 128restriction — only its fp4 sibling does — so the paged kernel had the same mismatch. Notably, in the paged variant the resulting garbage is deterministic (misreads land on deterministically-stale shared memory), so self-consistency passes and only the accuracy comparison against the reference exposes it.Validation on RTX 5090 D (CUDA 13.0, PyTorch 2.11.0+cu130, nv_dev @
2642b32):test_mqa_logits(20x bitwise + accuracy vs reference + bench): PASSED, all 384 configs, fp8 up to 411 TFLOPSAlso adds
DG_STATIC_ASSERT(kHeadDim ∈ {32, 64, 128})next to the derived constants (per review suggestion), so a future dispatch widening cannot silently instantiate an invalidCuTeSwizzle.Unaffected kernels (verified): dense fp4 and both fp4 paged variants are head_dim-128-only (
DG_HOST_ASSERT/DG_STATIC_ASSERT), where their constants already match. Dense fp8 and fp8 paged are the only instantiations whose dispatches allow multiple row widths, and both are now derived.Scan script and raw logs: https://gist.github.com/aganhui/f783450b212217284c062c3b46300649
🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.