[Kernel] Optimize CuTeDSL DCP top-k merge - #47348
Draft
LucasWilkinson wants to merge 2 commits into
Draft
LucasWilkinson wants to merge 2 commits into
LucasWilkinson wants to merge 2 commits into
Conversation
LucasWilkinson
force-pushed
the
codex/cutedsl-topk-merge-improvements
branch
from
July 9, 2026 04:57
62838c0 to
9098107
Compare
Co-authored-by: OpenAI Codex <codex@openai.com> Signed-off-by: Lucas Wilkinson <lwilkins@redhat.com>
Replace the NCCL all-gather in the DCP sparse-indexer top-k merge with a one-shot all-gather over torch symmetric memory: each rank packs its (score, global_id) candidates into its slice of every rank's peer-mapped inbox, a device-side flag handshake orders the exchange, and the existing CuTeDSL selector then runs unchanged on the (now local, contiguous) gathered layout. Selection semantics are identical - each rank still exchanges its full local top-K, so the merge remains exact - and the selector kernel is untouched. The exchange is five small kernels (wait-writable, pack, push, publish- and-wait, ack) with sequence flags and sys-scope acquire/release; there are no host branches, so the chain is FULL-cudagraph capturable and replaces the per-layer NCCL RING_LL all-gather launch (~19us at decode sizes, latency-bound). Falls back to the all-gather path automatically when symmetric memory is unavailable. On the development branch this transport measured +3.8-4.0% output tok/s (GLM-5.1 NVFP4, TP4/DCP4, c64 ISL8192/OSL1024, B300, with a reduced candidate configuration), halving per-layer all-gathers. GSM8K-64 smoke on that branch: accuracy 0.9531, invalid 0. Tests: tests/distributed/test_dcp_topk_symm_mem.py asserts the fused exchange selects identical sets to the all-gather reference at 2 and 4 ranks across varying row counts, including under CUDA-graph capture and replay. The existing localize suite passes unchanged (38/38). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: Lucas Wilkinson <lwilkins@redhat.com>
LucasWilkinson
force-pushed
the
codex/cutedsl-topk-merge-improvements
branch
from
July 9, 2026 20:05
9098107 to
a317949
Compare
This was referenced Jul 27, 2026
Closed
Leoyzen
reviewed
Aug 11, 2026
| if tid == Int32(0): | ||
| committed_count_smem.store(Int32(0)) | ||
| prefix_smem.store(Uint64(0)) | ||
| prefix_smem.store(Uint32(0)) |
There was a problem hiding this comment.
Missing sync_threads() between score_threshold = prefix_smem.load() above and this store(0) — warps that haven't loaded yet capture score_threshold = 0, so the phase-2 key == score_threshold predicate drops every tied candidate. Adding one barrier before this store makes 20/20 heavy-tie trials match the 64-bit reference bit-exactly.
Contributor
|
This pull request has merge conflicts that must be resolved before it can be |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Two commits optimizing the DCP sparse-indexer top-k merge (each rank holds the local top-K of its 1/DCP KV shard; the merge selects the global top-K from the gathered candidates).
Commit 1 — CuTeDSL selector optimization.
StableTopKFromGatheredCandidatesKernelruns a radix pass over 32-bit score keys first and only runs the token-id tie-break pass when the score threshold actually ties, instead of always sorting 64-bitscore<<32 | ~idkeys. Selection semantics are unchanged and deterministic: score descending, then lowest global token id.Commit 2 — symmetric-memory candidate exchange. Replaces the NCCL all-gather of packed
(score, global_id)candidates with a one-shot all-gather overtorch.distributed._symmetric_memory: each rank packs its candidates into its slice of every peer's symmetric "inbox" with a Triton remote-write kernel, synchronized by device-side write/read sequence flags (sys-scope acquire/release atomics). No NCCL launch, no host branches, fully CUDA-graph capturable; the selector then runs on the local inbox unchanged.get_dcp_topk_symm_mem_workspacereturnsNoneon unsupported configurations (no device group, unaligned candidate counts, rendezvous failure) and the code falls back to the existing all-gather path.Duplicate-work check
Related DCP/sparse-MLA PRs (#46514, #45426) exist but none touch the CuTeDSL gathered-candidate selector or the candidate exchange transport. The side-stream indexer overlap work is separate in #47355.
Benchmarks
Selector microbenchmark (
stable_topk_from_gathered_candidates_cutedsl, median µs, 7×200 launches, JIT warmup excluded):The symm-mem exchange replaces an NCCL all-gather launch + copy with two flag kernels and one push kernel on the capture stream; on GLM-5.1-NVFP4 B200 TP=4/DCP=4 decode it was worth ~4% end-to-end output throughput measured back-to-back against the NCCL merge path.
Tests
tests/distributed/test_dcp_topk_symm_mem.pyis new: multi-rank exactness of the symm-mem merge against the all-gather reference (including tie-heavy scores and empty shards) and replay correctness under CUDA graph capture.AI assistance
AI assistance (Claude) was used to implement, benchmark, and prepare this PR. The human submitter has reviewed the changed lines and run the tests above.