Drop cooperative launch from the CTA-independent local kernels - #34
Open
philippguevorguian wants to merge 3 commits into
Open
philippguevorguian wants to merge 3 commits into
philippguevorguian wants to merge 3 commits into
Conversation
The combine prologue's CTAs are independent: each block owns the dedup groups `blockIdx.x + j * num_sms`, reads read-only duplicate rows, and writes only its own primary row. All synchronization is block-local (warp shuffles and the block-local PipelineTmaAsync mbarriers); the kernel never calls grid_sync or cross_rank_barrier. PDL does not add a whole-grid requirement either. griddepcontrol's launch_dependents lets dependents be scheduled once all other CTAs issue the same instruction *or have completed*, so producer CTAs may run in waves and exit. Cooperative launch only imposes an occupancy-bounded whole-grid residency constraint here, so drop it. CombineKernel keeps its cooperative launch: its cross_rank_barrier spins in grid_sync until every local CTA arrives. Not GPU-tested.
philippguevorguian
marked this pull request as ready for review
September 20, 2026 04:13
Collaborator
|
this is solved in the latest release. see 33327eb |
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.
Drop cooperative launch from the CTA-independent local kernels
What changes
cooperative=Trueis removed from two launches,CombinePrologueKernelinmoonep/combine_prologue.pyandDispatchEpilogueKernelinmoonep/dispatch_epilogue.py. A new single-GPU test,tests/test_local_kernel_waves.py, pins the property both kernels now rely on. Grid dimensions, shared-memory geometry, PDL behavior, and stream ordering are untouched. Transport and planning kernels that own real grid-wide barriers keep their cooperative launches.Why it's worth doing
A cooperative launch tells CUDA the entire grid must be co-resident before any block starts. These two kernels have no use for that guarantee. Each CTA walks its own round-robin slice of dedup groups, writes only rows it owns, and synchronizes only inside its block through
PipelineTmaAsyncmbarriers and warp shuffles. Neither file containsgrid_syncorcross_rank_barrier. Cross-rank publication is handled byCombineKernelon entry and by dispatch on exit. PDL imposes no whole-grid requirement either, becausegriddepcontrol.launch_dependentsis issued per CTA andgriddepcontrol.waitis satisfied by the predecessor grid rather than by peer CTAs.The cost of the flag is real. Both kernels launch with
grid = num_sms, which defaults to all 132 SMs on H100, and at H=7168 each CTA reserves about 224 KiB of shared memory, so only one block fits per SM. A cooperative grid then cannot begin until the GPU fully drains. That has two consequences: the kernel queues behind co-resident work instead of filling in around it, and any grid larger than the occupancy bound is rejected outright by the driver.Measured impact (8xH100, S=4096, K=8, H=7168, 100 launches timed against a saturating GEMM stream)
combine_prologuedispatch_epilogueStandalone latency is unchanged. Under contention each kernel is roughly 24x faster, which is the regime a real training step runs in.
New test
tests/test_local_kernel_waves.pybuilds duplicate groups and a CPU oracle directly, so it needs one GPU and no torchrun. It sweeps both kernels across 4 hidden sizes, both PDL settings, and 5 group counts covering empty work, a partial batch, and pipeline reuse, for 80 cases. Grids are deliberately oversubscribed, and the largest case asserts that it exceeds the shared-memory residency bound before launching. Dispatch destinations are poisoned with a sentinel so a skipped copy cannot pass as success, and results are compared bit-exactly. Each launch carries a 10 second event deadline inside a spawned worker, so a hung launch is killed instead of hanging the session.The test discriminates. Against the current
masterlaunches it fails at the first case withCUDA_ERROR_COOPERATIVE_LAUNCH_TOO_LARGE(error 720). On this branch all 80 cases pass in 36 s.Tests and validations
nvidia-cutlass-dsl==4.4.2, andcuda-python==12.9(the default 13.x bindings fail against the 570.x driver withcudaErrorInsufficientDriver).master@2bd860b against this branch.torchrun --nproc_per_node=8 -m pytestper file:test_combine14 passed,test_e2e1 passed,test_dispatch12 passed,test_planning18 passed with 1 skipped,test_grad_reduce12 passed,test_prefetch14 passed. The pre-change baseline on the same machine gave identical counts fortest_combine,test_e2e, andtest_dispatch.master.test_combine14 passed,test_e2e1 passed.grid_sync, nocross_rank_barrier, and no cluster-wide synchronization. What remains is block-local mbarrier and shuffle traffic plus the per-CTA PDL calls.Not covered: multi-node runs, and PDL chains where the predecessor grid has not completed.