Multi-node networking guide#
Multi-node training depends on high-bandwidth, low-latency communication between GPUs. On AMD systems, RCCL (ROCm Collective Communications Library) provides GPU collectives with an API aligned to NCCL, so most NCCL-prefixed environment variables apply to RCCL as well.
This guide summarizes how Primus configures networking, how InfiniBand, RoCE, and AINIC (AMD AI NIC) fit in, and how to validate and troubleshoot cluster connectivity.
Primary sources in this repository
Topic |
File |
|---|---|
Default NCCL/RCCL and socket setup |
|
IB HCA detection |
|
Socket / interface detection |
|
AINIC hook (container/CLI integration) |
|
AINIC CLI defaults |
|
ANP / |
|
1. Overview#
Goal: Keep gradient and parameter exchanges from becoming the bottleneck when scaling across nodes.
Stack: PyTorch distributed uses the ROCm NCCL backend name in many configs; the implementation is RCCL on AMD GPUs.
Transports: Common fabrics include InfiniBand (IB), RoCE (RDMA over Converged Ethernet), and AINIC on supported AMD platforms. Primus scripts set or detect HCAs, socket interfaces, and optional AINIC tuning.
2. InfiniBand configuration#
These variables are standard in NCCL/RCCL deployments. Primus seeds several from runner/helpers/envs/base_env.sh when that script is sourced.
Variable |
Role |
|---|---|
|
Selects InfiniBand Host Channel Adapters (device:port list). |
|
GID index for the active port (RoCE and IB differ; see vendor docs). |
|
Traffic class for InfiniBand. |
|
Traffic class for FIFO traffic. |
|
Retry count for IB operations (tune with vendor guidance). |
|
Timeout for IB operations. |
|
Queue pairs per connection. |
|
GPUDirect RDMA level for NIC/GPU transfers. |
|
Use DMA-BUF path where supported. |
Auto-detection in Primus#
If NCCL_IB_HCA is unset, base_env.sh runs runner/helpers/envs/get_nccl_ib_hca.sh, which enumerates /sys/class/infiniband/, skips bonded/storage-style devices, and builds a comma-separated device:port list for NCCL_IB_HCA.
Default in base_env.sh:
export NCCL_IB_GID_INDEX=${NCCL_IB_GID_INDEX:-3}
AINIC-oriented configs often override NCCL_IB_GID_INDEX to 1 (see runner/use_ainic.yaml and 03_enable_ainic.sh).
3. RoCE (RDMA over converged ethernet)#
RoCE reuses much of the IB verb stack; the same NCCL_IB_* knobs apply.
Variable |
Typical use |
|---|---|
|
RoCE version (commonly 2 for RoCE v2). |
GID selection (NCCL_IB_GID_INDEX) and traffic classes (NCCL_IB_TC, NCCL_IB_FIFO_TC) remain important on RoCE fabrics. Follow your network team’s mapping (often GID index 1 for RoCE v2 vs 3 for some IB fabrics—your site might differ).
4. AINIC (AMD AI NIC)#
AINIC refers to AMD’s AI-optimized NIC path (for example, the AMD Pensando™ Pollara 400 AI NIC) used in some clusters. Enabling it is a combination of environment, container image, and device pass-through.
Enable AINIC#
Set
USING_AINIC=1. The hookrunner/helpers/hooks/03_enable_ainic.shruns when this is set and exports AINIC-related variables back to the caller (env.VAR=VALUElines).Use container images built for AINIC when required by your site. Examples in this repository use tags such as
docker.io/tasimage/primus:<version>-ainic(seeexamples/customer_package/and.github/workflows/ci.yaml). Match the image to your ROCm and ANP bundle.
runner/use_ainic.yaml#
Primus CLI system defaults for AINIC-oriented runs include:
Container
devicemounts:/dev/kfd,/dev/dri,/dev/infiniband(required for GPU and IB access in the container).Environment entries such as
USING_AINIC=1,NCCL_PXN_DISABLE=0, andNCCL_IB_GID_INDEX=1.
Adjust NCCL_IB_GID_INDEX and container.options.image to match your cluster; comments in runner/use_ainic.yaml call this out explicitly.
AINIC hook#
runner/helpers/hooks/03_enable_ainic.sh is the supported hook path: it sets ANP/RCCL/MPI home directories, IB QoS, RoCE version, P2P channel counts, GDR flush behavior, LD_LIBRARY_PATH (including libibverbs and RCCL/ANP/MPI build paths), and related flags. Default NCCL_IB_FIFO_TC in the hook is 192; align this value with your fabric.
RCCL network plugin (ANP)#
For ANP-based networking, clusters often set NCCL_NET_PLUGIN to librccl-anp.so when that library is present under ANP_HOME_DIR, falling back to librccl-net.so otherwise—see the logic in examples/run_pretrain.sh. This complements the library paths from 03_enable_ainic.sh.
Variables commonly set for AINIC#
From 03_enable_ainic.sh (non-exhaustive):
Variable |
Purpose |
|---|---|
|
Install roots for ANP, RCCL, and Open MPI. |
|
Traffic classes for IB/RoCE. |
|
Often 1 for AINIC-oriented configs in Primus examples. |
|
RoCE v2. |
|
Stricter GDR flush ordering (set to |
|
Prepends |
5. Socket configuration#
CPU-side and fallback socket traffic uses interface selection:
Variable |
Role |
|---|---|
|
Interface name or pattern for NCCL socket transport (e.g. |
|
Interface for Gloo process groups (CPU barriers and related). |
Primus behavior: base_env.sh sets IP_INTERFACE via runner/helpers/envs/get_ip_interface.sh (fallback: first address from hostname -I). Both NCCL_SOCKET_IFNAME and GLOO_SOCKET_IFNAME default to IP_INTERFACE when unset.
Requirement: All nodes must agree on a reachable address family and interface choice; mismatched bindings are a frequent source of hangs.
6. PCIe cross-NIC (PXN)#
Variable |
Default in |
Meaning |
|---|---|---|
|
|
PXN disabled by default (saves GPU memory per comment in |
When NCCL_PXN_DISABLE=0, PCIe cross-NIC is enabled: GPUs might use NICs attached to other PCIe switches, which can improve multi-rail bandwidth at the cost of higher GPU memory use. runner/use_ainic.yaml sets NCCL_PXN_DISABLE=0 for AINIC-oriented runs.
7. Network diagnostics#
Preflight#
primus-cli direct -- preflight --network
For multi-node (Slurm example):
primus-cli slurm srun -N 4 -- preflight --host --gpu --network
See docs/02-user-guide/preflight.md for flags, output locations (output/preflight by default), and interpretation.
Set PRIMUS_EXPECT_IB=1 when InfiniBand is required for validation; preflight uses this in primus/tools/preflight/network/network_standard.py.
RCCL benchmark#
primus-cli slurm srun -N 4 -- benchmark rccl --op all_reduce --min-bytes 1M --max-bytes 128M
This exercises collective bandwidth and latency across a message-size sweep. See docs/02-user-guide/benchmarking.md and primus/tools/benchmark/rccl_bench_args.py for options (dtypes, operations, output files).
Verbose RCCL logs#
export NCCL_DEBUG=INFO
Use for short, controlled runs; TRACE can be extremely verbose.
8. Multi-node setup checklist#
ROCm version matches across all nodes (driver and container image).
NCCL_SOCKET_IFNAME/GLOO_SOCKET_IFNAME(or auto-detectedIP_INTERFACE) identify the same logical network on every node.InfiniBand or RoCE is up (
ibstat,/dev/infiniband, kernel modules such asib_core/mlx5_coreas appropriate).Firewall allows ports required by your launcher and collective tests (
MASTER_ADDR/MASTER_PORTreachable).MASTER_ADDRresolves and is reachable from all nodes.GPUS_PER_NODEmatches physical GPUs per node.Containers mount
/dev/kfd,/dev/dri, and/dev/infinibandwhen using IB/RoCE/AINIC (seerunner/use_ainic.yaml).
9. Troubleshooting network issues#
Symptom |
What to check |
|---|---|
Timeout or hang at init |
|
Slow collectives |
IB vs Ethernet path, |
IB not detected |
|
Wrong interface |
Restrict with |
GID / RoCE issues |
|
For a consolidated list of NCCL_* / RCCL_* variables, see docs/03-configuration-reference/environment-variables.md and the upstream RCCL environment variables documentation.