Cooperative grids: synchronize only within a supported launch
Calculate a hypothetical all-resident grid limit and explain why ordinary inter-block spinning can deadlock.
On this page
The question for today
What you’ll understand
- Distinguish an ordinary grid from a cooperatively launched grid group.
- Compute a residency-based launch bound under explicit assumptions.
- Explain uniform collective participation and resource-dependent validity.
An ordinary CUDA kernel cannot assume every block is resident simultaneously. A grid-wide barrier built by spinning on a global counter can therefore wait for blocks that have not been scheduled because the waiting blocks occupy their resources. Cooperative execution supplies a documented mechanism for certain grid-wide coordination, but it also imposes launch, support, and residency constraints. It is a different contract, not permission to insert a global wait into any kernel.
Ordinary block independence prevents hidden global waits
If a kernel launches more blocks than can reside, some blocks wait for earlier ones to release SM resources. Suppose every resident block spins until a counter says all grid blocks arrived. The unscheduled blocks cannot increment that counter, and the resident blocks never leave to make room. Correct atomic increments do not fix this scheduling deadlock. A fence also does not allocate missing residency. Use separate correctly ordered kernel phases or a supported cooperative protocol rather than relying on a favorable scheduling accident.
CUDA Cooperative Groups can represent a grid group whose sync operation is valid under the documented cooperative launch requirements. Use the cooperative launch API and query device support. Every participating group member must follow the collective contract; an early return by some required participants can invalidate the synchronization. Do not infer support for multi-device or newer cluster collectives from single-device grid support. These are distinct features with architecture, runtime, and launch requirements of their own.
Use the actual kernel allocation in the bound
B_active depends on block dimensions, compiled registers, static and dynamic shared memory, and other device constraints. Increasing a tile’s shared memory can reduce the maximum legal cooperative grid even when the ordinary launch would remain valid. Use the occupancy query for the specific kernel and dynamic shared-memory amount, then apply the cooperative launch requirements. A remembered device-wide thread count is not enough. Another build or kernel attribute can change the answer without any change to the application’s logical problem size.
An all-resident cooperative grid can process more data than its thread count by assigning multiple elements to threads or iterating over tiles. That changes the work mapping, not the residency limit. Ensure all participants still reach each grid synchronization in the required order while guarding data accesses. Tail handling that causes some blocks to exit before a grid barrier can break correctness. Measure whether the saved phase launches justify longer-lived blocks, additional synchronization, and the constrained scheduling footprint.
Compare with a simpler phase boundary
Separate kernels ordered within one stream provide a natural phase dependency without requiring all blocks from both phases to reside together. They also add launch and intermediate-state costs. A cooperative kernel can preserve some state across phases and synchronize internally, but is more constrained. Choose based on correctness, queried support, resource budgets, and measured application behavior. Include the smallest and largest supported problem shapes in tests, especially when dynamic shared-memory requirements change with shape.
The reliability lab illustrates only finite simultaneous availability. Reset, set n=6 and k=2, predict four available replicas, then Step. These are replica counts and a majority readout, not SMs or resident blocks. The lab has no cooperative launch, spinning kernel, or grid barrier, and its majority rule does not determine GPU validity. Use the explicit residency formula and API queries for the cooperative grid. The analogy simply warns against assuming that every nominal participant is simultaneously available to make progress.
Work it through
A changed tile reduces the legal toy grid bound
A hypothetical supported device has 20 identical SMs. The actual kernel configuration is known to permit three active cooperative blocks per SM after every resource limit. Compute the bound, then suppose larger dynamic shared memory reduces that to one.
The initial bound is 20×3=60 cooperative blocks. A proposed grid of 72 exceeds this declared all-resident bound even if an ordinary noncooperative grid of 72 could run in waves.
With 128 threads per block, 60 blocks provide a grid-stride span of 60×128=7,680 elements. Threads can iterate over a larger input while preserving the group’s collective participation.
After the resource change, the bound becomes 20×1=20 blocks, with a span of 2,560 threads at the same block size. Reusing the old cooperative grid size is invalid under these assumptions; query and validate the new configuration.
The residency contract depends on the compiled kernel and its requested resources, not only on the device name or input length.
The living notebook
Explore the model
Interactive lab · reliability
Nominal participants need simultaneous availability
Reset, set n=6 and k=2, predict four available replicas, then Step. This replica-availability model does not represent SM residency, cooperative launch support, grid barriers, or GPU scheduling. Its majority threshold is unrelated to cooperative-grid validity.
- Available replicas
- 4 of 5
- Majority needed
- 3
- Majority available?
- Yes
A replica count and a majority threshold, without a consensus protocol. Playback highlights fixed replica states. Having a majority alone does not establish linearizability, durability or failure independence. Parameter changes pause playback and recompute the model at the current elapsed time. Reset restores both parameters and returns time to zero. Playback starts paused. Adjust either parameter, then choose Play or Step.
Look forA global coordination assumption needs a real progress and resource guarantee for every required participant.
Pause & reason
Check your understanding
Your turn
Try it yourself
A supported hypothetical configuration has 12 SMs and permits two active cooperative blocks per SM. Is a 25-block grid within the stated residency bound? What is the span for 24 blocks of 256 threads?
Take a moment to make a prediction or work it out on paper. Open a hint when you need one.
Give me a hint
Multiply the actual active-block count by SMs, then count threads for the valid toy grid.
Compare with the solution
The bound is 12×2=24, so 25 exceeds it. A 24-block grid has span 24×256=6,144 threads for the one-dimensional grid-stride mapping. Valid launch support, all other constraints, and correct collective participation must still be checked.
Keep the idea
Take it with you
- Ordinary block independence does not support an implicit all-grid spin barrier.
- Cooperative synchronization requires a supported correctly sized launch.
- Kernel resource changes can alter the valid cooperative grid limit.
Read further
Original sources and deeper explanations to follow at your own pace.
Optional progress, saved in this browser when available. Revisit any lesson at any time.
Lesson not marked complete.