DSA backward SM100: support zero-length top-k rows in the kernel - #439
Conversation
📝 WalkthroughWalkthroughThe SM100 sparse-attention backward kernel now handles zero or negative ChangesSM100 empty sparse-row handling
Estimated code review effort: 3 (Moderate) | ~20 minutes Suggested labels: Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
|
Thanks @jiayus-nvidia — this is a better resolution than the interface guard in #433. Handling the empty row inside the kernel avoids the per-call D2H sync, keeps CUDA-graph capture behavior consistent, and the early exit before any pipeline/TMEM setup addresses the deadlock at its root. I also looked at the sm100 Closing #433 in favor of this. |
|
@cudnn-ci-bot run |
|
🚀 Running mirror pipeline Branch: cudnn-gh/pr-439-ed665d8 |
Summary
Add native SM100 kernel support for sparse-attention backward rows whose
topk_lengthis zero.The kernel now detects an empty row before initializing any asynchronous
pipeline or allocating TMEM. All threads in the CTA cooperatively write zero
to the corresponding
dQrow and then exit. The row contributes nothing todKVord_sink, matching the mathematical gradient of a query attendingto no KV entries.
Malformed negative lengths take the same defensive early-exit path so they
cannot enter the zero-tile pipeline path.
Why
The SM100 backward kernel previously computed:
For topk == 0, this produces zero tiles, but the warp-specialized pipeline
assumes that at least one tile is handed between its producer and consumer
stages. On B200 this can deadlock the launch at 100% SM utilization. If
execution reached the epilogue, dQ could also be written from TMEM
accumulators that no MMA instruction had initialized.
Handling the row inside the kernel:
Implementation
For each query-token/head-block CTA, the kernel reads the CTA-uniform
topk_length before setting up pipelines or TMEM.
When the value is nonpositive, it:
The normal path reuses the same topk value, so positive rows do not incur
an additional load.
API and compatibility impact
allowed to enter the deadlocking pipeline path.
Related work
This is an alternative kernel-side resolution for #433.
Thanks to @zkyue for identifying the zero-tile failure mode, providing the
B200 hang reproducer, and analyzing the likely pipeline deadlock. That
investigation directly motivated this implementation.
Unlike the interface guard proposed in #433, this change supports empty rows
without adding a host synchronization or capture-specific behavior.
Testing
Tested on an NVIDIA B200 (SM100):
PYTHONPATH=/code/github/cudnn-frontend/python
pytest -q -rs
fe_api/dsa/test_DSA_sparse_attention_backward.py
-k sm100_zero_topk_length
Result:
2 passed, 6 deselected
Coverage includes:
Summary by CodeRabbit
Bug Fixes
Tests