1. Problem and Motivation
Curriculum Bridge (AI-C01-001 AI-C02-001): Whereas Step 81 (AI-C01-001) established how 3D Parallelism (DP, TP, PP) and ZeRO stages (ZeRO-1/2/3) partition model states across GPU HBM, this deep dive deconstructs the physical GPU interconnect and collective communication layer underneath those sharding primitives: the Hockney - latency-bandwidth model, Ring vs. Double-Binary Tree All-Reduce, NCCL channel topology discovery, and PyTorch DDP backward-pass gradient bucketing.
In modern distributed deep learning, training multi-billion parameter foundation models (Llama 3, GPT-4, Gemini) requires orchestrating clusters consisting of thousands of accelerator chips (such as NVIDIA H100, B200, or AMD MI300X).
While modern tensor accelerators deliver staggering computational power—an NVIDIA H100 SXM5 yields dense FP16/BF16 Tensor Core throughput ( with 2:4 structured sparsity) and HBM3 bandwidth—their real-world distributed training efficiency is fundamentally governed by interconnect communication bandwidth:
+---------------------------------------------------------------------------------------------------+
| THE COMMUNICATION BOTTLENECK |
+---------------------------------------------------------------------------------------------------+
| 1. Massive Gradient Payloads: A 70B parameter model produces 140 GB of FP16 gradients every |
| single forward-backward training step. |
| 2. Centralized Ingestion Collapse: A naive parameter server receiving 140 GB from 512 worker |
| GPUs must ingest 71.6 Terabytes of network data every step, saturating any physical switch. |
| 3. The Physical Interconnect Hierarchy Gap: |
| - Intra-Node NVLink 4: 900 GB/sec bidirectional per GPU (sub-microsecond crossbar latency). |
| - Inter-Node InfiniBand NDR: 400 Gbps (~50 GB/sec per GPU) (18x bandwidth drop!). |
| - Commodity PCIe Gen5: 64 GB/sec (14x slower than NVLink). |
| 4. Synchronization Latency: If GPUs must stall their tensor cores while waiting for network |
| gradient exchanges, GPU compute utilization drops below 30%, wasting millions of dollars in |
| data center capital expenditure. |
+---------------------------------------------------------------------------------------------------+
To eliminate central server bottlenecks, modern AI infrastructure relies exclusively on decentralized collective communication algorithms, primarily the Ring All-Reduce and Double-Binary Tree primitives orchestrated by the NVIDIA Collective Communications Library (NCCL).
2. Mental Model & Architectural Overview
Collective communication describes algorithms where a group of participating processes (GPUs) collectively exchange, reduce, or broadcast data arrays of size bytes.
1. Step 0: Tensor Chunk Partitioning & Phase A: Scatter-Reduce (P - 1 = 3 Steps)
Establishes the ingress and structural boundary across Step 0: Tensor Chunk Partitioning & Phase A: Scatter-Reduce (P - 1 = 3 Steps): Divide tensor of size M into P = 4 equal chunks; GPU i holds: [C0_i, C1_i, C2_i, C3_i]; Chunk size = M / 4 bytes.
2. Intra-Node: NVLink & NVSwitch & PCIe Gen5 Comparison
Coordinates core data-plane execution and state transitions through Intra-Node: NVLink & NVSwitch & PCIe Gen5 Comparison: NVIDIA H100 / B200 SXM Chassis (8 GPUs); 4th Gen NVLink: 900 GB/sec bidirectional; NVSwitch crossbar: Full all-to-all crossbar.
3. Hierarchical / 2D Collectives & NCCL Channel Multiplexing
Enforces durability, state convergence, and output verification across Hierarchical / 2D Collectives & NCCL Channel Multiplexing: To hide the 18x network bandwidth gap; 1. Intra-node Reduce-Scatter via NVLink (900 GB/s); 2. Inter-node All-Reduce via InfiniBand (50 GB/s).
The Core Primitives
- All-Reduce: Every GPU starts with an array of size . All arrays are element-wise summed (or averaged), and every GPU finishes with the complete, identical reduced array.
- Reduce-Scatter: Every GPU starts with an array of size . The arrays are element-wise summed, but the final reduced array is partitioned equally among the GPUs, such that GPU receives a unique chunk of size .
- All-Gather: Every GPU starts with a distinct local chunk of size . Every GPU gathers all chunks from all peers, such that all GPUs finish with the full concatenated array of size .
- Broadcast: One root GPU sends an array of size to all other GPUs.
3. Terminology & Core Mechanics
- NCCL (NVIDIA Collective Communications Library): The de facto standard library providing high-performance collective communication primitives multi-threaded and multi-GPU aware for CUDA.
- NVLink: NVIDIA’s high-speed, direct GPU-to-GPU point-to-point interconnect. On H100 (NVLink 4), each GPU provides 18 links yielding 900 GB/s bidirectional bandwidth.
- NVSwitch: An on-board physical crossbar switch allowing all 8 GPUs within an HGX/DGX chassis to communicate with any other GPU at full 900 GB/s NVLink line rate.
- InfiniBand NDR (Next Data Rate): A high-throughput, low-latency cluster networking standard providing 400 Gbps (50 GB/s) per port with hardware Remote Direct Memory Access (RDMA).
- GPUDirect RDMA: A hardware mechanism that allows network interface cards (NICs) to directly access GPU High-Bandwidth Memory (HBM) over the PCIe/NVLink bus without staging data through host CPU DRAM.
- Hockney Communication Model: An analytical model that decomposes communication time into network startup latency and per-byte transfer cost :
4. Internal Workings & Algorithms: Ring All-Reduce Step-by-Step
In a ring topology, GPUs are logically arranged in a circular ring:
Every GPU connects only to its immediate successor (sending data) and immediate predecessor (receiving data). The tensor of size bytes is divided into equal chunks: , where each chunk has size:
Phase 1: The Scatter-Reduce Phase ( Steps)
The objective of Scatter-Reduce is to calculate the global sum of each chunk such that each GPU ends up holding the full global sum of exactly one chunk.
Initial State (P = 4 GPUs, 4 Chunks):
GPU 0: [C0_0, C1_0, C2_0, C3_0]
GPU 1: [C0_1, C1_1, C2_1, C3_1]
GPU 2: [C0_2, C1_2, C2_2, C3_2]
GPU 3: [C0_3, C1_3, C2_3, C3_3]
At each step :
- GPU sends chunk to its successor GPU .
- Simultaneously, GPU receives chunk from its predecessor GPU .
- GPU performs an in-memory element-wise addition:
After exactly steps:
- GPU 0 holds the complete global sum:
- GPU 1 holds the complete global sum:
- GPU 2 holds the complete global sum:
- GPU 3 holds the complete global sum:
Phase 2: The All-Gather Phase ( Steps)
Now that each GPU holds the complete sum of one chunk, that sum must be shared with all other GPUs.
At each step :
- GPU sends its fully reduced chunk to its successor.
- GPU receives the fully reduced chunk from its predecessor and overwrites its local partial chunk (no summation required).
- The chunk travels one hop around the ring per step.
After exactly steps: All GPUs hold the identical, fully reduced chunks !
5. Mathematical Derivations & Performance Model
Let us mathematically prove the bandwidth optimality and asymptotic invariance of Ring All-Reduce.
1. Data Volume Transmitted per GPU
In each step of the Scatter-Reduce phase:
- Each GPU sends a single chunk of size bytes.
- Number of steps = .
In each step of the All-Gather phase:
- Each GPU sends a single chunk of size bytes.
- Number of steps = .
Adding both phases together:
The Asymptotic Limit:
The total data transmitted by each GPU is completely independent of the cluster size ! Whether training on 8 GPUs or 8,192 GPUs, every GPU transmits at most bytes. Furthermore, all physical links in the ring are 100% saturated simultaneously, achieving optimal theoretical bandwidth utilization.
2. Time Complexity under the Hockney Model
Let:
- : Latency of initiating a network transmission (hop latency in seconds)
- : Per-byte transfer time, where is link bandwidth (bytes/sec)
- : Computational time to perform element-wise floating-point addition per byte
The total time for Ring All-Reduce is:
For large payloads (e.g., hundreds of megabytes of gradients), the bandwidth term completely dominates the latency term .
3. Design Alternatives & Collective Comparison Matrix: Ring vs. Tree vs. NVLS
+---------------------------------------------------------------------------------------------------+
| RING vs. TREE ALL-REDUCE COMPARISON |
+---------------------------------------------------------------------------------------------------+
| Metric | Ring All-Reduce | Double-Binary Tree All-Reduce |
+------------------------+----------------------------------------+---------------------------------+
| Network Latency Steps | 2(P - 1) (Linear in P) | ~ 2 * log2(P) (Logarithmic in P)|
| Bandwidth Factor | 2 * (P - 1) / P (Optimal: -> 2M) | ~ 2M (two complementary trees) |
| Optimal Payload Size | Large tensors (> 100 MB) | Small/Medium tensors (< 10 MB) |
| Straggler Sensitivity | High: 1 slow link stalls entire ring | Medium: Isolated to sub-tree |
+------------------------+----------------------------------------+---------------------------------+
When GPUs:
- Ring latency requires .
- Balanced binary-tree reduction + broadcast requires ( fewer serial startup latencies!).
In NCCL 2.20+ on Hopper/Blackwell systems, a third alternative—NVLink SHARP (NVLS) / InfiniBand SHARP—delegates floating-point summation directly into the NVSwitch3 / Quantum-2 switch silicon, cutting intra-node traffic from down to read + multicast write with switch hops. NCCL dynamically selects Tree, Ring, or NVLS/CollNet per collective based on payload bytes , communicator size , and detected fabric topology.
6. Hardware Interconnect Realities: NVLink vs. InfiniBand
A critical error in naive distributed systems models is treating all GPU-to-GPU links as uniform. In reality, modern AI clusters feature a two-tier non-uniform bandwidth hierarchy:
[ DGX / HGX Chassis: 8 x H100 GPUs ]
+-------------------------------------------------------------------------+
| GPU 0 <======== NVLink 4 Crossbar (900 GB/sec) ========> GPU 1 ... GPU 7|
+-------------------------------------------------------------------------+
| | | | |
PCIe PCIe PCIe PCIe PCIe
v v v v v
[CX7 NIC 0] [CX7 NIC 1] [CX7 NIC 2] [CX7 NIC 3] [CX7 NIC 4] ...
400 Gbps 400 Gbps 400 Gbps 400 Gbps 400 Gbps
(50 GB/s) (50 GB/s) (50 GB/s) (50 GB/s) (50 GB/s)
\ \ | / /
+-------------------------------------------------------------------------+
| InfiniBand Quantum-2 NDR Inter-Node Leaf/Spine Fabric |
+-------------------------------------------------------------------------+
The 18x Bandwidth Gap:
- Intra-Chassis (NVLink 4 + NVSwitch): bidirectional bandwidth per GPU. Latency .
- Inter-Chassis (InfiniBand NDR 400G): per GPU. Latency .
Hierarchical 2D All-Reduce
To avoid running a slow global ring through 50 GB/s InfiniBand links for every step, NCCL employs Hierarchical All-Reduce:
- Intra-Node Reduce-Scatter: The 8 GPUs within each node reduce their chunks using the blisteringly fast 900 GB/s NVLink bus.
- Inter-Node All-Reduce: Only 1 reduced chunk per GPU is sent over the 50 GB/s InfiniBand network to peer GPUs on other chassis.
- Intra-Node All-Gather: The fully reduced chunks are broadcast locally inside each node over NVLink.
7. Production Code Engine: Ring All-Reduce Simulator
The following TypeScript implementation provides a working simulation of the Ring All-Reduce algorithm, verifying numerical correctness, chunk splitting, scatter-reduce accumulation, and all-gather distribution:
/**
* Production-Grade Ring All-Reduce Simulator
* Demonstrates Scatter-Reduce and All-Gather phases with verification.
*/
export class GPUWorker {
public data: Float64Array;
constructor(
public readonly id: number,
initialValues: number[]
) {
this.data = new Float64Array(initialValues);
}
public getChunk(chunkIndex: number, chunkSize: number): Float64Array {
const start = chunkIndex * chunkSize;
return this.data.slice(start, start + chunkSize);
}
public setChunk(chunkIndex: number, chunkSize: number, source: Float64Array): void {
const start = chunkIndex * chunkSize;
this.data.set(source, start);
}
public reduceChunk(chunkIndex: number, chunkSize: number, received: Float64Array): void {
const start = chunkIndex * chunkSize;
for (let i = 0; i < chunkSize; i++) {
this.data[start + i] += received[i];
}
}
}
export class RingAllReducer {
private readonly numGPUs: number;
private readonly tensorSize: number;
private readonly chunkSize: number;
constructor(public readonly gpus: GPUWorker[]) {
this.numGPUs = gpus.length;
this.tensorSize = gpus[0].data.length;
if (this.tensorSize % this.numGPUs !== 0) {
throw new Error(`Tensor size ${this.tensorSize} must be divisible by GPU count ${this.numGPUs}`);
}
this.chunkSize = this.tensorSize / this.numGPUs;
}
/**
* Executes full Ring All-Reduce: Scatter-Reduce followed by All-Gather.
*/
public execute(): { totalTransferredPerGPU: number; stepsExecuted: number } {
const P = this.numGPUs;
const M = this.tensorSize;
let transferredBytes = 0;
// ==========================================
// PHASE 1: SCATTER-REDUCE (P - 1 steps)
// ==========================================
for (let step = 0; step < P - 1; step++) {
// Temporary buffers to simulate parallel synchronous ring transfers
const sendBuffers: Float64Array[] = [];
for (let i = 0; i < P; i++) {
// GPU i sends chunk: (i - step + P) % P
const sendChunkIdx = (i - step + P) % P;
sendBuffers[i] = this.gpus[i].getChunk(sendChunkIdx, this.chunkSize);
}
for (let i = 0; i < P; i++) {
// GPU i receives from predecessor GPU (i - 1 + P) % P
const recvChunkIdx = (i - step - 1 + P) % P;
const predecessorId = (i - 1 + P) % P;
const receivedData = sendBuffers[predecessorId];
// Sum received data into local chunk
this.gpus[i].reduceChunk(recvChunkIdx, this.chunkSize, receivedData);
}
transferredBytes += this.chunkSize * 8; // Float64 = 8 bytes
}
// ==========================================
// PHASE 2: ALL-GATHER (P - 1 steps)
// ==========================================
for (let step = 0; step < P - 1; step++) {
const sendBuffers: Float64Array[] = [];
for (let i = 0; i < P; i++) {
// GPU i sends its fully reduced chunk: (i - step + 1 + P) % P
const sendChunkIdx = (i - step + 1 + P) % P;
sendBuffers[i] = this.gpus[i].getChunk(sendChunkIdx, this.chunkSize);
}
for (let i = 0; i < P; i++) {
// GPU i receives and overwrites local chunk
const recvChunkIdx = (i - step + P) % P;
const predecessorId = (i - 1 + P) % P;
const receivedData = sendBuffers[predecessorId];
this.gpus[i].setChunk(recvChunkIdx, this.chunkSize, receivedData);
}
transferredBytes += this.chunkSize * 8;
}
return {
totalTransferredPerGPU: transferredBytes,
stepsExecuted: 2 * (P - 1),
};
}
}
function runDemo(): void {
console.log("=== GPU Interconnect: Ring All-Reduce Simulation ===");
const numGPUs = 4;
const tensorSize = 8;
const gpus = Array.from({ length: numGPUs }, (_, id) =>
new GPUWorker(id, Array.from({ length: tensorSize }, (_, i) => (id + 1) * 10 + i))
);
console.log(`Cluster: ${numGPUs} GPUs, Tensor size: ${tensorSize} elements (${tensorSize * 8} bytes)`);
console.log(`GPU 0 Initial: [${Array.from(gpus[0].data).join(", ")}]`);
console.log(`GPU 3 Initial: [${Array.from(gpus[3].data).join(", ")}]`);
const reducer = new RingAllReducer(gpus);
const result = reducer.execute();
console.log(`Ring All-Reduce executed: ${result.stepsExecuted} communication steps`);
console.log(`Transferred per GPU: ${result.totalTransferredPerGPU} bytes`);
console.log(`GPU 0 Synchronized: [${Array.from(gpus[0].data).join(", ")}]`);
console.log(`GPU 3 Synchronized: [${Array.from(gpus[3].data).join(", ")}]`);
const match = Array.from(gpus[0].data).every((val, idx) => val === gpus[3].data[idx]);
console.log(`All GPUs bitwise synchronized: ${match}`);
}
runDemo();
8. Compute-Communication Overlapping & Gradient Bucketing
In a synchronous distributed training step, executing backpropagation sequentially followed by collective communication leaves the GPU cores completely idle during network transfers:
Sequential Execution (No Overlap):
[ Forward Pass (60ms) ] -> [ Backward Pass (120ms) ] -> [ All-Reduce (45ms) ] -> [ Optimizer (15ms) ]
Total Step Time = 240ms (GPU Idle for 45ms!)
Pipelined Overlapping in PyTorch DDP
PyTorch DDP overcomes this through Gradient Bucketing:
Overlapped Execution (Pipelined Bucketing):
Layer 4 Compute (30ms) ---> Layer 4 Gradients Ready
|
Layer 3 Compute (30ms) +---> NCCL Async All-Reduce(Bucket 2) [CUDA Stream 1]
| (Transfers concurrently over InfiniBand!)
Layer 2 Compute (30ms) +---> NCCL Async All-Reduce(Bucket 1) [CUDA Stream 1]
|
Layer 1 Compute (30ms) v
All-Reduce finishes almost simultaneously with the final layer computation!
Total Step Time = 198ms (Hides ~90% of All-Reduce latency!)
- Bucket Partitioning: Model parameters are assigned to contiguous memory buckets (default 25 MB).
- Reverse Autograd Hook: During backpropagation, as soon as all parameters in a bucket receive their gradients, DDP immediately schedules an asynchronous non-blocking
ncclAllReducecall on a dedicated communication CUDA stream. - Stream Synchronization: The primary compute stream only synchronizes with the communication stream at the very end of the backward pass, just before the optimizer step.
9. Failure Modes, Network Stragglers & Diagnostics
| Operational Issue | Root Cause | Engineering Diagnostic & Mitigation |
|---|---|---|
| The Straggler Effect | A single GPU with thermal throttling or a degraded InfiniBand cable slows the entire ring. | NCCL Perf Test (all_reduce_perf): Identify which specific node has lower bus bandwidth; configure automated health checks to drain straggler nodes. |
| Silent Data Corruption (SDC) | Defective PCIe switches or optic transceivers flip bits in gradient tensors without crashing. | Hardware CRC checks; periodic gradient checksum verification across rank 0 and peer ranks. |
| InfiniBand PFC Deadlock | Buffer exhaustion triggers Priority Flow Control (PFC) pause frames in a cyclic dependency across spine switches. | Enable Explicit Congestion Notification (ECN) with dynamic queue management (RED) to drop packets before PFC triggers. |
| CUDA Stream Deadlock | NCCL kernel launched on Stream A waits for an event on Stream B that is waiting on Stream A. | Enforce strict single-direction CUDA stream synchronization; set NCCL_DEBUG=INFO to inspect collective launch order. |
10. Knowledge Check
Review the core collective communication principles, then complete the 4-question interactive assessment quiz at the end of this lesson:
- Parameter Server Bottleneck: Articulate why centralized parameter servers scale as , while Ring All-Reduce scales as .
- Ring Volume Derivation: Prove step-by-step why the total data transferred per GPU in Ring All-Reduce equals .
- Double-Binary Trees: Explain why Tree collectives provide latency steps and when they should be favored over Ring collectives.
- Compute-Communication Overlap: Describe how PyTorch DDP uses gradient bucketing and CUDA streams to hide network latency during backpropagation.
11. Practical Exercises & Deliverables
Exercise 1: Implement Bidirectional Ring All-Reduce
Problem: The single ring implementation in Section 7 transfers data only in the clockwise direction, utilizing only 50% of full-duplex network links.
Deliverable:
- Extend the
RingAllReducerTypeScript class to maintain two concurrent rings: Ring 0 (clockwise) and Ring 1 (counter-clockwise). - Divide the tensor into chunks, routing half through Ring 0 and half through Ring 1 simultaneously.
- Verify that both rings complete without data races and that all GPU tensors match the exact ground truth sum.
Exercise 2: Benchmark NCCL All-Reduce Bus Bandwidth
Problem: Measure the real-world bus bandwidth of a multi-GPU system and compare it to theoretical line rate.
Deliverable:
- Run
nccl-tests(all_reduce_perf -b 8M -e 1G -f 2 -g 8) on an 8-GPU node. - Record the reported Algorithm Bandwidth () and Bus Bandwidth (), where is tensor size in bytes and is collective wall-clock time.
- Plot achieved bus bandwidth against message size from 8 MB to 1 GB. Identify the inflection point where bus saturation transitions from latency-bound ( dominant) to bandwidth-bound ( dominant).
View Reference Architecture & Worked Solutions (AI-C02-001)
1. Worked Solution — Exercise 1: Bidirectional Dual-Ring All-Reduce Implementation
- Architectural Design: Partition the tensor of size into disjoint sub-chunks of size .
- Ring 0 (Clockwise,
next = (i + 1) % P,prev = (i - 1 + P) % P): Reduces and gathers chunks . - Ring 1 (Counter-Clockwise,
next = (i - 1 + P) % P,prev = (i + 1) % P): Simultaneously reduces and gathers chunks over the reverse full-duplex physical lane. - Because Ring 0 exclusively mutates indices and Ring 1 exclusively mutates indices , zero lock contention or data races occur, and full-duplex serialization time is cut by .
- Ring 0 (Clockwise,
export function executeBidirectionalRingAllReduce(gpus: GPUWorker[]): void {
const P = gpus.length;
const subChunkSize = gpus[0].data.length / (2 * P);
// Scatter-Reduce (P - 1 steps): Ring 0 clockwise on [0..P-1], Ring 1 counter-clockwise on [P..2P-1]
for (let step = 0; step < P - 1; step++) {
const cwSend = gpus.map((g, i) => g.getChunk((i - step + P) % P, subChunkSize));
const ccwSend = gpus.map((g, i) => g.getChunk(P + ((i + step) % P), subChunkSize));
for (let i = 0; i < P; i++) {
const cwRecvChunk = (i - step - 1 + P) % P;
const ccwRecvChunk = P + ((i + step + 1) % P);
gpus[i].reduceChunk(cwRecvChunk, subChunkSize, cwSend[(i - 1 + P) % P]);
gpus[i].reduceChunk(ccwRecvChunk, subChunkSize, ccwSend[(i + 1) % P]);
}
}
// All-Gather (P - 1 steps)
for (let step = 0; step < P - 1; step++) {
const cwSend = gpus.map((g, i) => g.getChunk((i - step + 1 + P) % P, subChunkSize));
const ccwSend = gpus.map((g, i) => g.getChunk(P + ((i + step - 1 + P) % P), subChunkSize));
for (let i = 0; i < P; i++) {
const cwRecvChunk = (i - step + P) % P;
const ccwRecvChunk = P + ((i + step) % P);
gpus[i].setChunk(cwRecvChunk, subChunkSize, cwSend[(i - 1 + P) % P]);
gpus[i].setChunk(ccwRecvChunk, subChunkSize, ccwSend[(i + 1) % P]);
}
}
}
2. Worked Solution — Exercise 2: NCCL all_reduce_perf Bus Bandwidth & Hockney Inflection Point
- Bus Bandwidth Formula ( GPUs):
- Representative 8x H100 SXM5 (NVLink 4.0, unidirectional peak) Benchmark Profile:
| Payload Size () | Step Time () | Algorithm BW () | Bus BW () | Dominant Hockney Regime |
|---|---|---|---|---|
| Latency-affected ( significant) | ||||
| Transition knee () | ||||
| Bandwidth-dominated | ||||
| ( of line rate) | Asymptotic NVLink saturation |
- Hockney Inflection Point Derivation:
Latency and bandwidth contributions are equal when . For , effective per-hop latency (including kernel launch + LL128 protocol synchronization), and , the inflection payload is , explaining why PyTorch DDP defaults to gradient buckets (
bucket_cap_mb=25) to operate safely above the latency knee.
12. Summary & Architectural Decision Guide
| Workload & Cluster Regime | Recommended Collective & Tuning | Engineering Rationale |
|---|---|---|
| Intra-node ( GPUs on NVSwitch) | NVLS (Hopper/Blackwell) or Multi-Channel Ring | Saturates bidirectional NVLink 4 with sub-microsecond latency. |
| Multi-node large buckets (, ) | Hierarchical 2D Ring All-Reduce | Bandwidth-optimal transfer; confines of local reductions to NVLink. |
| Ultra-large clusters () or small tensors () | Double-Binary Tree (NCCL_ALGO=Tree) | Replaces linear hop latency with tree depth while preserving full link utilization. |
| PyTorch DDP / FSDP backward pass | 25–50 MB Buckets + Dual CUDA Streams | Balances Hockney startup overhead against early first-bucket launch to overlap of network time. |
13. Authoritative References & Version Context
- Version & Hardware Baseline: Verified against NVIDIA NCCL 2.20+,
nccl-testsv2.13+, PyTorch 2.3+ (DistributedDataParallel&ProcessGroupNCCL), NVIDIA H100 SXM5 (NVLink 4.0 @ 900 GB/s bidirectional, NVSwitch3), and NVIDIA Quantum-2 InfiniBand NDR (400 Gbps / 50 GB/s per port). - Patarasuk & Yuan (JPDC 2009) — Bandwidth Optimal All-reduce Algorithms for Clusters of Workstations: Formal proof that Ring All-Reduce achieves the theoretical lower bound on homogeneous ring networks.
- Sanders, Speck & Träff (Parallel Computing 2009) — Two-Tree Algorithms for Full Bandwidth Broadcast, Reduction and Scan: Mathematical foundation for NCCL’s complementary Double-Binary Tree collectives.
- Thakur, Rabenseifner & Gropp (IJHPCA 2005) — Optimization of Collective Communication Operations in MPICH: Hockney complexity analysis comparing Ring, Recursive Halving-Doubling, and Rabenseifner algorithms.
- Li et al. (VLDB ‘20) — PyTorch Distributed: Experiences on Accelerating Data Parallel Training: Architecture of reverse-order gradient bucketing and compute-communication stream overlapping in PyTorch DDP.
- NVIDIA NCCL Documentation — NVIDIA Collective Communications Library (NCCL) User Guide & Bus Bandwidth Formula and
NVIDIA/nccl-testsPerformance Specification.