Repository navigation
[Bugfix][Kernel] Sync cluster before DSMEM stores in ll_bf16 split-K router GEMM - #61463
Conversation
The split-K epilogue stores partials into peer CTAs' shared memory via st.shared::cluster before any cluster barrier, so a peer that has not started yet raises Xid 13 (CTA Not Present). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Matthew Bonanni <mbonanni@redhat.com>
There was a problem hiding this comment.
Perf verified on B300. Cost is ~0.06 µs/call on this setup with with PDL enabled.
nit: splitting the barrier so it stays out of the PDL prologue seems to recover about half of that (+0.035 vs +0.063 µs vs main), and all of it at:
cute.arch.cluster_arrive_relaxed() # keep; drop the cluster_wait() here
...
mainloop_pipeline.producer_commit(producer_state) # first stage
cute.arch.cluster_wait() # after B prefetch + griddepcontrol_wait
...
else:
cute.arch.cluster_wait() # MMA warps idle until stage 0 lands anyway
cute.arch.setmaxregister_increase(232)Note: I couldn't reproduce the bug you report. Can you check this alternative also fixes it?
|
@MatthewBonanni We have an independent single-GPU reproduction that may help with validation here. It reproduces without model weights, a connector SDK, RDMA, or a P/D deployment. The trigger is running the ll_bf16 split-K router concurrently with ordinary CUDA kernels that write directly to mapped pinned host memory on another stream. The copy kernels do not use clusters, and their buffers are separate from the router's buffers. Environment:
The unpatched _ll_bf16_splitk.py is byte-identical to upstream main at fa75d34 (SHA256 f282d0c1c4649d3affb19d694b7edf66cecf7764946b4effe57737830ec7a3ad). The rest of the environment is not a pristine-main build. Reproduction procedure (sources and logs are in the attached ZIP):
From the extracted directory, in an existing vLLM environment: mkdir -p results
nvcc -O3 -shared -Xcompiler -fPIC -arch=sm_103 copy.cu -o libhostcopy.so
unset CUDA_LAUNCH_BLOCKING
export CUTE_DSL_DISABLE_FILE_CACHING=1
export CUDA_DEVICE_WAITS_ON_EXCEPTION=0
.venv/bin/python -u router_probe.py --tag baseline --mode direct --seconds 10
# Apply this PR's patch, then use a fresh process:
.venv/bin/python -u router_probe.py --tag pr61463 --mode direct --seconds 120Please select an isolated GPU with CUDA_VISIBLE_DEVICES. The README includes environment and patching instructions. Compare dmesg before/after each run for new Xid lines. On 2026-10-16 we tested exactly the patch in this PR, with no other router changes:
The final recorded elapsed time is 130.383 seconds, including correctness checks after the loop. Generated PTX confirms the new arrive/wait precedes the first st.shared::cluster. This validates our isolated reproduction; we have not yet run a full-model serving soak test with this exact patch. Detailed results are in VALIDATION.txt in the attached ZIP. This is a timing-sensitive reproduction established on B300 with the environment above; we have not established reproduction on Hopper. Hopefully it provides a smaller validation workload than a full P/D deployment. |
Arrive at kernel start; DMA warps wait after priming the first stage (past griddepcontrol_wait), MMA warps wait before the mainloop. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Matthew Bonanni <mbonanni@redhat.com>
|
/ci run |
|
✅ Triggered Buildkite CI #99931 for commit |
Purpose
The
ll_bf16split-K router GEMM (#42562, M >= 8) stores partials into peer CTAs' shared memory (st.shared::cluster) before any cluster barrier. If a peer CTA hasn't started yet, the GPU raises Xid 13CTA Not Present, which surfaces asCUDA error: unspecified launch failure.Fix: all threads
cluster_arrive_relaxed()after pipeline init. DMA warpscluster_wait()after committing stage 0, and MMA warps wait at the start of their branch. So every peer is resident before the epilogue'sst.shared::cluster, and the wait stays out of the PDL prologue (split suggested by @LopezCastroRoberto).Reproduction
This uses @Skyseaee's single-GPU harness (comment). It runs the router GEMM in a CUDA graph, concurrent with non-cluster copy kernels that write to mapped pinned host memory:
main(a12e122206)unspecified launch failurein the first batch, 4/4 runsac5c06ee4b)The harness does not trigger the fault on H200. In serving, the same Xid hit GLM-5.3 HiSparse P/D decode (2x 8xH200, TP4) within minutes. The first revision of this fix (arrive+wait at kernel start) ran 6/6 passes clean there; the current revision has not been run in serving.
No regression test: the race depends on hardware CTA scheduling, so it can't be made deterministic.
test_ll_bf16_gemm.pycovers numerics only.Test results
All on
ac5c06ee4b.pytest tests/kernels/test_ll_bf16_gemm.py: 144 passed on B300 and on H200.Latency is µs per call: the median of 30 replays of a CUDA graph holding 200 back-to-back PDL
ll_bf16_gemmcalls, N=256.main🤖 Generated with Claude Code