ReduceScatter and AllGather decomposition
Track shard ownership, element counts, and layout when a full reduction is separated into distributed and replicated result phases.
On this page
The question for today
What you’ll understand
- Explain how ReduceScatter followed by compatible AllGather implements AllReduce.
- Calculate full and sharded buffer sizes with explicit count conventions.
- Identify when a training algorithm can consume a shard without immediately reconstructing the full result.
A full AllReduce leaves the same reduced tensor on every participant. Some training designs need only one shard on each rank for part of their work. Separating ReduceScatter from AllGather exposes that distinction: arithmetic combines contributions, ownership partitions the result, and a later gathering step decides when replication is necessary. Correct layout and buffer counts matter as much as the communication schedule.
Reduction and placement are separate parts of the result
For p ranks, split an N-element input into p equal blocks under a common layout. ReduceScatter reduces corresponding input elements across all ranks and leaves one reduced block with each rank. AllGather can then collect those reduced blocks in rank order so every rank holds the complete reduced tensor. Under compatible reduction, partitioning, and layout rules, that composition has the logical effect of AllReduce. It is not a promise of identical floating-point rounding or performance to a separately selected AllReduce implementation.
NCCL 2.32.3's ReduceScatter receive count denotes the per-rank reduced block, while each input buffer contains p such blocks. Its AllGather send count denotes one rank's contribution and the receive buffer holds the p-rank concatenation. Do not reuse one numeric count without checking which side of the operation it describes. MPI provides both equal-block and variable-count interfaces with their own rules. Zero or uneven partitions, padding, and alignment must be handled explicitly; a library cannot infer a missing element from a buffer that happens to be large enough.
A shard can be sufficient for one phase of training
A sharded optimizer may update its assigned parameter state using its reduced gradient shard, retaining less replicated gradient or optimizer memory during that phase. Which tensors need gathering afterwards depends on the training algorithm, parameter partition, and next computation. Do not assume that splitting a collective automatically shards every parameter, activation, or optimizer state. A complete memory plan records which buffers remain full, which are partitioned, and when temporary gathered views overlap with the retained shards.
Rank ownership is an explicit indexing contract. A change in communicator rank order can change which tensor slice a rank receives or where its AllGather contribution appears. Checkpoint metadata and optimizer ownership must agree with that mapping after restart or resharding. A buffer with the right number of elements but the wrong slice can silently corrupt training without causing a count mismatch. Validate values and offsets using a small identifiable tensor before benchmarking an anonymous array of random numbers.
Avoid reconstructing data before its consumer needs it
Decomposition can support overlap or memory savings when useful shard-local work occurs between phases. It can also add launch overhead, force a less efficient algorithm choice, or create extra buffers if applied without a dependency plan. The correct question is which consumer needs a full tensor and at what time. Preserve stream dependencies from reduction completion through shard consumption to gathering, and do not overwrite a shard while an AllGather still reads it. A memory estimate taken between phases must not be advertised as the peak for the whole training step.
The modular lab shows an ownership-order contrast only. Reset, set both m=8 and a=1, predict residue one after one Step and period eight, then Step. Separately Reset, set both m=8 and a=3, predict residue three after one Step and the same period eight, then Step. Both additive orbits visit every residue but in different orders. They perform no reduction or gathering. Explain why a real AllGather must place values according to its rank-layout contract rather than simply append chunks in whichever physical arrival order happens first.
Work it through
Price the reduced shard and later replication
Eight ranks reduce a logical tensor containing 1,048,576 four-byte elements, partitioned equally. Assume the input and output layouts are compatible and count only the result-buffer payload after each phase.
The complete tensor is 1,048,576×4=4,194,304 bytes, or 4 MiB. Each rank supplies that complete logical input to the equal-block ReduceScatter operation.
Each reduced shard contains 1,048,576/8=131,072 elements, or 524,288 bytes, exactly 0.5 MiB. Rank seven's block covers zero-based indices 917,504 through 1,048,575 under the stated consecutive layout.
A subsequent AllGather of 131,072 elements per rank reconstructs 1,048,576 elements, or 4 MiB, on every rank. An intermediate half-MiB shard therefore does not imply that the whole execution never retains a full tensor or additional scratch storage.
The count convention and slice identity define the operation. Memory savings depend on when the full result is actually required and which buffers coexist.
The living notebook
Explore the model
Interactive lab · modular
Coverage does not fix the ownership order
Reset, set both m=8 and a=1, predict residue one after one Step and period eight, then Step. Separately Reset, set both m=8 and a=3, predict residue three and period eight, then Step. This additive ordering exercise performs no reduction or gathering and does not determine an actual arrival schedule.
- Residue r0
- 0
- Orbit period · m/gcd(m,a)
- 12
- Distinct residues visited
- 1 of 12
Addition modulo m starts at zero: rₙ = na mod m. Playback advances two additions per second. The orbit has period m/gcd(m,a), including period one for a = 0. This is not a cryptographic security test or a primality algorithm. 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 completed set of chunks still needs the correct rank-to-slice layout; physical arrival order is not a substitute.
Pause & reason
Check your understanding
Your turn
Try it yourself
Four ranks AllGather 256 two-byte elements each. How many elements and payload bytes are in each full receive buffer? What additional layout fact must be verified?
Take a moment to make a prediction or work it out on paper. Open a hint when you need one.
Give me a hint
The receive concatenation contains one equally sized contribution per rank.
Compare with the solution
Each receive buffer contains 4×256=1,024 elements and 2,048 payload bytes. Verify that the expected tensor slices correspond to the communicator's rank order, including any rank-to-device remapping. Correct byte size alone does not prove that the gathered values occupy the intended logical positions.
Keep the idea
Take it with you
- Track reduction semantics separately from shard placement and replication.
- Check operation-specific send and receive count conventions.
- Budget the whole lifetime of sharded, gathered, input, and scratch buffers.
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.