training

Collective Communication

Who sends? Who receives? What does each rank own when communication finishes?

Published 2026-10-27 · Updated 2026-10-27
On this page

Start with ownership

A GPU computes values locally. The next training operation may need values from other GPUs. Choose a communication pattern from the required output: which values must each GPU own?

A rank identifies one participant in a process group. Here, each rank represents one GPU. The group has four ranks, numbered 0 through 3. A root is the selected source or destination for a rooted collective.

Three questions distinguish the patterns: Do values combine arithmetically? Does every rank receive the same result? Does each destination need a different piece?

The communication contract
PatternWhat happens to values?Who owns the output?
BroadcastCopy one root inputEvery rank: the same input
ReduceCombine matching positionsRoot: the full reduction
AllReduceCombine matching positionsEvery rank: the full reduction
AllGatherConcatenate source shardsEvery rank: all shards
ReduceScatterCombine matching positions; partition the resultEach rank: a different reduced shard
AllToAllExchange destination-specific piecesEach rank: pieces addressed to it
Send / ReceiveCopy between selected peersSelected receiver

Each scene separates input reference from result being built. A send step names both endpoints. The following receive step changes only the receiver. These are original conceptual schedules, not timings or descriptions of a particular library. Real implementations can forward data, use trees or rings, and overlap many transfers.

Broadcast: one input, every rank

Rank 0 owns a tensor. Broadcast gives every rank that same tensor. No values are added. The root also keeps the tensor.

Broadcast: follow the dataSynthetic integer example · one illustrative schedule
Step 0 / 7 · Inputs

Start. Local contributions are already present; no remote data has arrived.

Four ranks · follow one transfer at a time
Rank 0IDLE
Input A · reference
A01from rank 0A12from rank 0A23from rank 0A34from rank 0
Local starting state
A01from rank 0A12from rank 0A23from rank 0A34from rank 0
Rank 1IDLE
Input B · reference
None
Local starting state
None
Rank 2IDLE
Input C · reference
None
Local starting state
None
Rank 3IDLE
Input D · reference
None
Local starting state
None

Letters identify source inputs; the digit identifies a tensor position. Σ marks a sum. Sending keeps the source input. The input row is a reference, not extra physical storage. Scroll the rank diagram horizontally on narrow screens.

Final result on every rank
  • Rank 0: A0=1 · A1=2 · A2=3 · A3=4
  • Rank 1: A0=1 · A1=2 · A2=3 · A3=4
  • Rank 2: A0=1 · A1=2 · A2=3 · A3=4
  • Rank 3: A0=1 · A1=2 · A2=3 · A3=4

Training example. Initialize replicated parameters from one agreed state. Rank 0 starts with [1, 2, 3, 4]. After Broadcast, all four replicas start with those values. This synchronizes initialization; it does not synchronize future gradient updates. PyTorch DDP design ↗ describes initialization from rank 0.

Reduce: combine at one rank

Each rank owns a contribution to the same logical tensor. Reduce combines matching positions and places the result at one root. The examples use SUM. Other reductions include MIN and MAX.

Reduce: follow the dataSynthetic integer example · one illustrative schedule
Step 0 / 7 · Inputs

Start. Local contributions are already present; no remote data has arrived.

Four ranks · follow one transfer at a time
Rank 0IDLE
Input A · reference
A01from rank 0A12from rank 0A23from rank 0A34from rank 0
Local starting state
A01from rank 0A12from rank 0A23from rank 0A34from rank 0
Rank 1IDLE
Input B · reference
B05from rank 1B16from rank 1B27from rank 1B38from rank 1
Local starting state
None
Rank 2IDLE
Input C · reference
C09from rank 2C110from rank 2C211from rank 2C312from rank 2
Local starting state
None
Rank 3IDLE
Input D · reference
D013from rank 3D114from rank 3D215from rank 3D316from rank 3
Local starting state
None

Letters identify source inputs; the digit identifies a tensor position. Σ marks a sum. Sending keeps the source input. The input row is a reference, not extra physical storage. Scroll the rank diagram horizontally on narrow screens.

Final result on every rank
  • Rank 0: Σ0=28 · Σ1=32 · Σ2=36 · Σ3=40
  • Rank 1: No output
  • Rank 2: No output
  • Rank 3: No output

Here, rank 0 receives [28, 32, 36, 40]. At position 0, the contributions are 1 + 5 + 9 + 13 = 28. Ranks 1–3 still have their input references, but no defined reduction output.

Training example. Aggregate evaluation statistics at a logging coordinator. Reduce the loss sum and valid-token count to rank 0. Divide the global sum by the global count there. Averaging per-rank means gives the wrong global mean when valid-token counts differ.

AllReduce: combine for every rank

AllReduce computes a reduction and gives the full result to every rank. Each output position includes the corresponding contribution from all participants. The inputs need matching logical positions.

AllReduce: follow the dataSynthetic integer example · one illustrative schedule
Step 0 / 13 · Inputs

Start. Local contributions are already present; no remote data has arrived.

Four ranks · follow one transfer at a time
Rank 0IDLE
Input A · reference
A01from rank 0A12from rank 0A23from rank 0A34from rank 0
Local starting state
A01from rank 0A12from rank 0A23from rank 0A34from rank 0
Rank 1IDLE
Input B · reference
B05from rank 1B16from rank 1B27from rank 1B38from rank 1
Local starting state
None
Rank 2IDLE
Input C · reference
C09from rank 2C110from rank 2C211from rank 2C312from rank 2
Local starting state
None
Rank 3IDLE
Input D · reference
D013from rank 3D114from rank 3D215from rank 3D316from rank 3
Local starting state
None

Letters identify source inputs; the digit identifies a tensor position. Σ marks a sum. Sending keeps the source input. The input row is a reference, not extra physical storage. Scroll the rank diagram horizontally on narrow screens.

Final result on every rank
  • Rank 0: Σ0=28 · Σ1=32 · Σ2=36 · Σ3=40
  • Rank 1: Σ0=28 · Σ1=32 · Σ2=36 · Σ3=40
  • Rank 2: Σ0=28 · Σ1=32 · Σ2=36 · Σ3=40
  • Rank 3: Σ0=28 · Σ1=32 · Σ2=36 · Σ3=40

All four ranks finish with [28, 32, 36, 40]. The scene first reduces to rank 0, then broadcasts the complete sum. This is one way to demonstrate the contract. AllReduce does not require a central rank in its implementation.

Training example. In data parallelism, replicas compute gradients from different local batches. Gradient synchronization lets replicas apply the same update. Standard DDP averages gradients across ranks; the animation shows a SUM without division. For equal local batch sizes and local mean losses, divide the displayed sum by four to obtain the mean gradient. Unequal batches require an explicit weighting rule. DDP gradient synchronization ↗.

AllGather: collect all shards everywhere

AllGather starts with one shard per rank. Every rank receives the shards in rank order. Values remain separate; no reduction occurs.

AllGather: follow the dataSynthetic integer example · one illustrative schedule
Step 0 / 25 · Inputs

Start. Local contributions are already present; no remote data has arrived.

Four ranks · follow one transfer at a time
Rank 0IDLE
Input A · reference
A01from rank 0
Local starting state
A01from rank 0WaitingWaitingWaiting
Rank 1IDLE
Input B · reference
B16from rank 1
Local starting state
WaitingB16from rank 1WaitingWaiting
Rank 2IDLE
Input C · reference
C211from rank 2
Local starting state
WaitingWaitingC211from rank 2Waiting
Rank 3IDLE
Input D · reference
D316from rank 3
Local starting state
WaitingWaitingWaitingD316from rank 3

Letters identify source inputs; the digit identifies a tensor position. Σ marks a sum. Sending keeps the source input. The input row is a reference, not extra physical storage. Scroll the rank diagram horizontally on narrow screens.

Final result on every rank
  • Rank 0: A0=1 · B1=6 · C2=11 · D3=16
  • Rank 1: A0=1 · B1=6 · C2=11 · D3=16
  • Rank 2: A0=1 · B1=6 · C2=11 · D3=16
  • Rank 3: A0=1 · B1=6 · C2=11 · D3=16

The four input shards are A0=1, B1=6, C2=11 and D3=16. Every result is [1, 6, 11, 16]. A shard already local to its owner needs no network transfer.

Training example. With fully sharded data parallelism (FSDP), a layer’s parameter shards can be gathered before that layer computes. This temporarily increases local parameter storage. The full parameter values are reconstructed, rather than added together. FSDP sharding strategies ↗.

ReduceScatter: combine, then keep a shard

ReduceScatter combines matching tensor positions across ranks. It gives each rank only its assigned partition of the reduced result. The examples use four equal partitions, with one element per partition.

ReduceScatter: follow the dataSynthetic integer example · one illustrative schedule
Step 0 / 25 · Inputs

Start. Local contributions are already present; no remote data has arrived.

Four ranks · follow one transfer at a time
Rank 0IDLE
Input A · reference
A01from rank 0A12from rank 0A23from rank 0A34from rank 0
Local starting state
A01from rank 0
Rank 1IDLE
Input B · reference
B05from rank 1B16from rank 1B27from rank 1B38from rank 1
Local starting state
B16from rank 1
Rank 2IDLE
Input C · reference
C09from rank 2C110from rank 2C211from rank 2C312from rank 2
Local starting state
C211from rank 2
Rank 3IDLE
Input D · reference
D013from rank 3D114from rank 3D215from rank 3D316from rank 3
Local starting state
D316from rank 3

Letters identify source inputs; the digit identifies a tensor position. Σ marks a sum. Sending keeps the source input. The input row is a reference, not extra physical storage. Scroll the rank diagram horizontally on narrow screens.

Final result on every rank
  • Rank 0: Σ0=28
  • Rank 1: Σ1=32
  • Rank 2: Σ2=36
  • Rank 3: Σ3=40

Rank 0 gets position 0: 28. Rank 1 gets position 1: 32. Rank 2 gets position 2: 36. Rank 3 gets position 3: 40. Every result includes contributions from all four inputs, but no rank holds the full reduced vector.

FSDP: send each synchronized gradient to its parameter owner

Fully sharded data parallelism (FSDP) assigns each rank a parameter shard and the corresponding optimizer state. During a layer’s computation, ranks temporarily gather its parameters. Each rank processes a different local batch and produces gradient contributions for that gathered parameter group. FSDP parameter and gradient sharding ↗.

Follow a two-rank FSDP step

One layer, two ranks · time flows downward ↓Synthetic schedule · equal local batch sizes and local mean losses

Rank 0 processes batch A and owns W00. Rank 1 processes batch B and owns W01. W00 and W01 are two shards of the same layer. gA0 names batch A’s gradient contribution for W00.

Weights: AllGatherGradients: ReduceScatter
Rank 0Local batch A · owns W00
Rank 1Local batch B · owns W01
1Start: sharded storage
W00Optimizer state for W00
W01Optimizer state for W01
2Forward: AllGather weights
Rank 0Sender
W00 · weight shard
Rank 1Receiver
Rank 0Receiver
W01 · weight shard
Rank 1Sender
Full weights [W00, W01]Run forward on batch ASave activations, or recompute them later
Full weights [W00, W01]Run forward on batch BSave activations, or recompute them later
Reshard → keep W00Release temporary full-weight storage
Reshard → keep W01Release temporary full-weight storage
3Backward: AllGather weights again
Rank 0Sender
W00 · weight shard
Rank 1Receiver
Rank 0Receiver
W01 · weight shard
Rank 1Sender
Backward on batch AUses full weights [W00, W01]Produces [gA0, gA1]
Backward on batch BUses full weights [W00, W01]Produces [gB0, gB1]
4ReduceScatter gradients to their owners
Rank 0Sender
gA1 · gradient from batch A for W01
Rank 1Receiver
Rank 0Receiver
gB0 · gradient from batch B for W00
Rank 1Sender
Own gA0 + received gB0Mean: gA,0+gB,02\dfrac{g_{A,0}+g_{B,0}}{2}Synchronized gradient for W00 only
Received gA1 + own gB1Mean: gA,1+gB,12\dfrac{g_{A,1}+g_{B,1}}{2}Synchronized gradient for W01 only
5Local optimizer update
Update W00 locallyUse its mean gradient and optimizer stateRelease temporary full weights; retain updated W00
Update W01 locallyUse its mean gradient and optimizer stateRelease temporary full weights; retain updated W01
Next forward: AllGather reconstructs the layer from the updated weight shards. It does not gather gradients.

The arrows name the sender, payload and receiver. Transfers within a collective can run concurrently; this diagram separates them for readability. A larger model completes backward before the optimizer step. Averaging can occur before, during or after ReduceScatter. Global gradient-norm clipping can require an additional small reduction. Scroll horizontally on narrow screens.

In the four-rank animation above, use the four positions as four scalar parameters: w0, w1, w2 and w3. Rank 0 owns w0, rank 1 owns w1, and so on. Every input row is a gradient contribution from one local batch. A0=1 and B0=5 therefore contribute to the same parameter w0. They are gradients, not parameter values.

  1. Gather parameters for computation. Each rank obtains the parameters needed by the layer. Its local batch can depend on every parameter in that group.
  2. Compute local gradients. The example produces [1,2,3,4] on rank 0, [5,6,7,8] on rank 1, [9,10,11,12] on rank 2 and [13,14,15,16] on rank 3.
  3. Reduce matching gradient positions. For w0, add 1 + 5 + 9 + 13 = 28. Deliver that sum to rank 0. Repeat for the other parameter owners.
  4. Update each local shard. Each owner uses its synchronized gradient and local optimizer state to update its parameter shard.
  5. Gather updated parameters when needed. The next computation reconstructs parameters from the owners’ updated shards.
One FSDP optimizer step: four scalar parameter shards
OwnerParameter before updateSUM from ReduceScatterMean gradientParameter after SGD
Rank 0w0 = 102879.3
Rank 1w1 = 2032819.2
Rank 2w2 = 3036929.1
Rank 3w3 = 40401039.0

This synthetic update assumes equal local batch sizes, local mean losses and stochastic gradient descent (SGD) with learning rate 0.1. Divide each sum by four, then subtract 0.1 times that mean gradient from its parameter. The animation stops at the unscaled SUM. Frameworks can apply normalization around the collective.

After the update, a parameter AllGather reconstructs [9.3,19.2,29.1,39.0]. It gathers updated weights. The synchronized gradients remain sharded. With Adam, each owner also updates the first and second moment estimates for its parameter shard.

Each optimizer needs only the gradient positions it owns. ReduceScatter therefore stops with one synchronized gradient shard per rank. An AllReduce would additionally replicate the other owners’ gradient positions, which this local update does not need.

In full sharding, parameter gathers occur before forward and backward computation, with resharding between these phases. Temporary full parameter groups, gradient buffers and activations still contribute to peak memory. Actual shards contain many parameter elements; the scalar table isolates ownership. FSDP communication lifecycle ↗.

AllToAll: a different piece for each destination

Each rank splits its input by destination. Piece j goes to rank j. Each receiver assembles incoming pieces in source-rank order. AllToAll redistributes values; it does not add them.

AllToAll: follow the dataSynthetic integer example · one illustrative schedule
Step 0 / 25 · Inputs

Start. Local contributions are already present; no remote data has arrived.

Four ranks · follow one transfer at a time
Rank 0IDLE
Input A · reference
A01from rank 0A12from rank 0A23from rank 0A34from rank 0
Local starting state
A01from rank 0WaitingWaitingWaiting
Rank 1IDLE
Input B · reference
B05from rank 1B16from rank 1B27from rank 1B38from rank 1
Local starting state
WaitingB16from rank 1WaitingWaiting
Rank 2IDLE
Input C · reference
C09from rank 2C110from rank 2C211from rank 2C312from rank 2
Local starting state
WaitingWaitingC211from rank 2Waiting
Rank 3IDLE
Input D · reference
D013from rank 3D114from rank 3D215from rank 3D316from rank 3
Local starting state
WaitingWaitingWaitingD316from rank 3

Letters identify source inputs; the digit identifies a tensor position. Σ marks a sum. Sending keeps the source input. The input row is a reference, not extra physical storage. Scroll the rank diagram horizontally on narrow screens.

Final result on every rank
  • Rank 0: A0=1 · B0=5 · C0=9 · D0=13
  • Rank 1: A1=2 · B1=6 · C1=10 · D1=14
  • Rank 2: A2=3 · B2=7 · C2=11 · D2=15
  • Rank 3: A3=4 · B3=8 · C3=12 · D3=16

Read A2 as “from source A (rank 0), addressed to rank 2.” Rank 2 receives A2, B2, C2 and D2: [3, 7, 11, 15]. Rank 0 receives A0, B0, C0 and D0. The piece for the local rank stays local.

Training example. Expert parallelism assigns experts to different ranks. A mixture-of-experts (MoE) router groups token vectors by destination expert. Dispatch sends those groups to their owners. A return exchange sends expert outputs back to the original token owners for combination. Expert-parallel dispatch and return.

The equal-size scene makes ownership visible. Real routing can produce unequal counts or empty destinations. Variable-size exchanges need matching send/receive counts for each peer. Top-k routing can create several token-expert assignments per token. The combine operation must restore token order and apply the routing weights. AllToAll split semantics ↗.

Send / Receive: one peer exchange

Send / Receive transfers data between selected peers. It is point-to-point communication, rather than a collective over the whole group. The sender and receiver must match the payload and peer identities.

Send / Receive: follow the dataSynthetic integer example · one illustrative schedule
Step 0 / 3 · Inputs

Start. Local contributions are already present; no remote data has arrived.

Four ranks · follow one transfer at a time
Rank 0IDLE
Input A · reference
A01from rank 0A12from rank 0A23from rank 0A34from rank 0
Local starting state
A01from rank 0A12from rank 0A23from rank 0A34from rank 0
Rank 1IDLE
Input B · reference
None
Local starting state
None
Rank 2IDLE
Input C · reference
None
Local starting state
None
Rank 3IDLE
Input D · reference
None
Local starting state
None

Letters identify source inputs; the digit identifies a tensor position. Σ marks a sum. Sending keeps the source input. The input row is a reference, not extra physical storage. Scroll the rank diagram horizontally on narrow screens.

Final result on every rank
  • Rank 0: A0=1 · A1=2 · A2=3 · A3=4
  • Rank 1: A0=1 · A1=2 · A2=3 · A3=4
  • Rank 2: No output
  • Rank 3: No output

Only rank 1 receives rank 0’s [1, 2, 3, 4]. Ranks 2 and 3 do not participate. The source retains its data; a send does not imply deleting the source buffer.

Training example. In pipeline parallelism, a stage sends forward activations to the next stage. During backward, activation gradients travel in the opposite direction. Several microbatches can be in flight, so matching the stage and microbatch matters. PyTorch pipeline tutorial ↗.

Connect the patterns

AllReduce can be understood in two ways: Reduce followed by Broadcast, or ReduceScatter followed by AllGather. The first scene uses a root for clarity. The second factorization explains why gradient reduction can stop at sharded ownership.

x0=[1,2,3,4],x1=[5,6,7,8]x2=[9,10,11,12],x3=[13,14,15,16]s=∑r=03xr=[28,32,36,40]ReduceScatter⁡SUM:s0=[28], s1=[32], s2=[36], s3=[40]AllGather⁡(s0,s1,s2,s3):s on every rank\begin{aligned}x_0&=[1,2,3,4],\quad x_1=[5,6,7,8]\\x_2&=[9,10,11,12],\quad x_3=[13,14,15,16]\\s&=\sum_{r=0}^{3}x_r=[28,32,36,40]\\\operatorname{ReduceScatter}_{\rm SUM}&:\quad s_0=[28],\ s_1=[32],\ s_2=[36],\ s_3=[40]\\\operatorname{AllGather}(s_0,s_1,s_2,s_3)&:\quad s\text{ on every rank}\end{aligned}
Four ranks, elementwise SUM, equal contiguous partitions and the same rank order. Gathering the reduced shards gives the AllReduce result. Here r is a source rank and sᵣ is its assigned output shard.

The standalone AllGather scene starts from unreduced values [1], [6], [11], [16]. To compose it after ReduceScatter, replace those inputs with [28], [32], [36], [40]. AllGather copies whichever shards it receives; it never supplies the missing arithmetic.

These are equivalences of the required mathematical result. Different floating-point reduction orders can produce slightly different rounded values. Equal results do not imply equal traffic, latency or memory use. Collective contracts and compositions ↗.

Closely related operations
OperationDifference to remember
GatherCollect shards at one root; AllGather collects them everywhere
ScatterOne root distributes different pieces; Broadcast distributes the same tensor
BarrierCoordinate arrival of participants; it carries no model tensor result

Recognize the pattern in a training step

Start from the tensor layout required by the next computation. The same training method can use several patterns in one step.

From training dependency to communication
DependencyTypical patternRequired result
Replicas need the same initial parametersBroadcastIdentical initial state
Replica gradients must agreeAllReduceComplete synchronized gradients on every replica
A sharded layer needs its parametersAllGatherAll parameter shards needed for that computation
An optimizer updates only its parameter shardReduceScatterSynchronized gradient shard at its owner
An expert must receive its routed tokensAllToAllDestination-specific token batches
The next pipeline stage needs activationsSend / ReceiveActivations at the next stage
A coordinator logs global statisticsReduceGlobal sums and counts at one rank

Tensor parallelism can also use AllReduce for partial output sums, or ReduceScatter when the output stays partitioned. The layer layout determines which result is needed. Infer the collective from matrix ownership.

What must agree across ranks?

All members of a collective’s process group must participate in a compatible order. Agree on the group, root where applicable, reduction, data type and tensor layout. Counts must satisfy the chosen operation; variable-size exchanges must agree per peer.

“Same shape” is insufficient. Two tensors can have identical local dimensions while referring to different global positions. Summing those tensors would combine unrelated values. The rank-to-shard map is part of the contract.

Communication completion must also precede the consuming computation. An asynchronous API can return before the result is ready. Buffer reuse needs its own completion rule. The scenes show logical receipt, rather than GPU memory-order or stream semantics. PyTorch completion semantics ↗.

Once the result contract is clear, investigate scheduling and performance in GPU Communication. That note owns rings, trees, transports and readiness protocols.

Sources and connected notes

The diagrams and integer traces are original teaching models. They show one transfer at a time to expose sender, receiver and ownership. Playback speed and step counts are not performance measurements.

Continue with Distributed Training and Parallelism, MoE execution and GPU Communication.