mirror of
https://github.com/deepseek-ai/DeepGEMM.git
synced 2026-11-05 00:47:26 +00:00
[PR #343] [MERGED] Fix a race condition in contiguous k-grouped GEMM where in-flight tensormaps are updated in-place #377
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#377
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/343
Author: @dfyz
Created: 5/29/2026
Status: ✅ Merged
Merged: 7/6/2026
Merged by: @zheanxu
Base:
main← Head:main📝 Commits (1)
a6a9339Fix a race condition where in-flight tensormaps are updated in-place📊 Changes
2 files changed (+10 additions, -1 deletions)
View changed files
📝
deep_gemm/include/deep_gemm/impls/sm90_fp8_gemm_1d1d.cuh(+9 -0)📝
tests/generators.py(+1 -1)📄 Description
The weight gradient kernel for SM90 modifies the A/B tensormaps stored in GMEM when the scheduler decides to switch groups, but it doesn't make sure that previous TMA loads have already finished reading the tensormaps at that point. A TMA load reading from a tensormap being modified concurrently corrupts the output for obvious reasons.
A reliable way to reproduce this corruption (at least on an H200) is to run the
test_k_grouped_gemm_contiguoustest a couple of times with the shape added in this PR. Eventually the corruption will be large enough to make the test fail:Even when the test doesn't fail, the corruption still happens. You can see that by printing the
torch.norm()of the result here and seeing that it differs between the test runs:The fix for this is conceptually straightforward: section 9.7.9.26.5.2 from the PTX docs says that bulk async-group based completion mechanism can be used "for the completion of reading of the tensormap object" in (otherwise mbarrier-based) TMA loads. So running
cp.async.bulk.commit_group+cp.async.bulk.wait_group.read 0before modifying GMEM ensures all in-flight TMA loads have finished reading their tensormaps, which fixes the race condition.The only catch is that writing to a TMA descriptor from a single thread generates multiple
STG.E.128instructions, andptxasdecides to move some of them before theDEPBAR.LE SB0, 0x0generated bycp.async.bulk.wait_group.read 0, which re-introduces the race condition. CUTLASS does a__syncwarp()before updating tensormaps in GMEM, and inserting a warp sync indeed preventsptxasfrom reordering instructions, but this seems more like a coincidence, since we only have one thread from the warp anyway and I don't see a good way to explain this in term of the PTX memory model. In other words, this is an ugly hack, so if you have better solutions, I will gladly implement them. :)🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.