Conversation
🤖 ds-review-bot Code Reviewv6未发现本次变更新引入的明确缺陷。清理范围保持不变,新增屏障覆盖全部 CTA 线程且不与数学线程屏障冲突,FP8 与 paged 路径保持原有行为。当前环境未找到 CUDA 编译器或 GPU 工具,未复跑正确性和性能测试。 v5The change moves the MXFP8/MXFP4 Verified (no action needed):
No blocking issues found; approve. Two non-blocking suggestions are attached. Performance claims (1.6-2.3x on GB200 for MX clean_logits=True, FP8 within 0.2%) could not be re-run in this environment and are taken from the PR description; the change is low-risk with respect to output semantics. v4Reviewed the single-file scheduling change in deep_gemm/include/deep_gemm/impls/sm100_mqa_logits.cuh (30 insertions / 16 deletions vs baseline 66081d4). The patch is correct and semantics-preserving. It (1) hoists the existing logits cleaner into a local lambda Files reviewed: 1 |
|
Continued in #436 using the intended source branch name. The implementation and validation are unchanged; this PR retains the earlier review discussion. |
On GB200 with NVCC 13.3.33, placing MXFP8/MXFP4 MQA-logits cleanup after the CTA's main computation improves
clean_logits=Trueperformance by about 1.6–2.3x for the H64/D128 cases below, with identical complete outputs. This PR proposes that scheduling change for the SM100 MX paths.Move the MX cleaner after the CTA's producer/consumer work and TMEM release. Reuse the existing cleaner through a local lambda, and synchronize with a separate named barrier (ID 1) so it cannot overlap the math-only barrier (ID 0). The grid-stride cleanup ranges, in-coverage masks, metadata layout, and public API are unchanged. FP8 retains concurrent cleanup; moving FP8 cleanup as well caused a 5–8% slowdown in some exploratory cases. The lambda's
kCleanLogitsguard also avoids instantiating contiguous-only cleaner methods for paged schedulers.Performance
Baseline:
66081d4c9c7d7c44f13fea402e5b622aa0f409c2. Same GB200 GPU (152 SMs), NVCC 13.3.33, default DeepGEMM JIT flags targetingsm_100f, driver 580.167.08, PyTorch 2.13.0+cu130; PDL disabled.H=64, D=128, FP32 weights/output, uncompressed logits. Q/K/weights are all zero, MX scales are one, and each row uses
[0, KV-Q+row). These are CUDA Graph GPU timings of the completeclean_logits=Truecall, including all cleaning. Metadata is precomputed outside timing. Five calls per graph with distinct retained output buffers; 40 samples, rotating/reversing variant order, immediate warmup before each timed replay; median per-call latency. The timing runs use normal GPU clocks. Separate Nsight captures below use controlled base clocks.The
clean_logits=Falsecontrol stays within 0.2% between builds for these eight points. A further 18-shape screen (both metadata modes) includes H=8/32/64, Q=KV=8192, CP windows, and BF16 weights/output: MX latencies improve in every screened case; FP8 is within 0.2% of baseline. The improvement also appears with random inputs. The table uses an all-zero workload to reduce input-dependent power effects.Timing data, including p10/p90 (microseconds)
Investigation notes
A few local ablations helped distinguish cleanup bandwidth costs from sensitivity to code placement. These use H64/D128, Q=2048, KV=32768:
clean_logits=False. The cleaner-loop unrolling and inline-PTX store variants showed similar timings to baseline.With the final patch, a controlled-clock Nsight Compute 2026.2 comparison for MXFP8, Q=2048, KV=32768, no metadata shows:
per_issue_activeratio)Exploratory PC samples place much of the additional wait around the math-side TMEM-result barrier check. Together, these results suggest that cleaner placement affects main-loop execution; memory traffic and resource allocation are largely unchanged, and neither binary has register spills. The precise low-level dependency remains to be investigated. The proposed change avoids this sensitivity on the tested configuration while retaining the existing output semantics.
Validation
test_mqa_logits: 32 sampled configurations pass (including its 20-repeat bitwise checks, scheduled-path equality, full mask checks, and reference comparisons).test_paged_mqa_logits: 4 sampled configurations pass, exercising the shared core with paged schedulers.No permanent test-matrix or benchmark-file additions. Existing upstream tests can be run from a built checkout with:
Standalone performance reproducer (writes every timing sample to JSON)
Save as
pr-reproduce.pyand run it once with each built revision, using the same GPU and NVCC. Both builds and all JIT compilations must finish before timed sampling; the script warms every specialization before capture. It verifies the zero output and complete negative-infinity mask before timing.