Skip to content
Free tool · runs in your browser

NCCL Topology Linter

The failures that burn the most GPU-hours are the ones that were guaranteed before step 0: a NIC on the wrong side of the root complex, ACS silently killing GPUDirect, an NCCL_IB_HCA that matches nothing. Paste your node's topology bundle and get every one of them flagged, with the exact fix, before the job gang-schedules.

GPU→NIC affinity & NUMA PCIe ACS detection NCCL env vs. real fabric
1. Run this on a compute node (10 seconds, read-only)
nvidia-smi topo -m
env | egrep "NCCL|FI_|UCX"
ibstat
ip -br addr
ulimit -l
sudo lspci -vvv | grep -B1 ACSCtl
Runs locally in your browser. Nothing is uploaded.
Free CLI · runs on your cluster

Benchmark it, don't just lint it

The linter above reads your configuration. This runs the actual collectives your job will run: NCCL all-reduce, all-gather and reduce-scatter across a size sweep. It reports bus bandwidth against what your fabric should deliver, and times every rank individually, so the straggler that would have set your step time gets named before you spend the allocation finding it.

Run the benchmark

One line, no account. Installs a single stdlib-only Python file and runs it against the GPUs it can see. It needs torch with CUDA for the collectives; everything else is standard library.

curl -fsSL https://denpex.com/preflight.sh | sh
torchrun --nnodes=$NNODES --nproc_per_node=8 \
  --rdzv_backend=c10d --rdzv_endpoint=$MASTER_ADDR:29500 \
  -m denpex_preflight run

One task per GPU. The rendezvous itself is part of the test: if ranks cannot find each other here, they will not find each other at step 0.

NCCL busbw
all-reduce, all-gather and reduce-scatter across a size sweep, with the correct per-collective bus factors
Straggler spread
per-rank timings compared against the cohort median, so the slow rank is named before the job starts
GPU health under load
HBM and PCIe bandwidth, plus ECC counters and throttle reasons sampled during the run, not at idle

Score a result

Runs in your browser · nothing uploaded

The CLI prints its own verdict. Paste the JSON from --json preflight.json here to see the full breakdown. Useful for a result carried off an air-gapped cluster on a USB stick.

Frequently asked questions

What does the topology linter check?

Five layers: (1) GPU↔GPU fabric: NVLink islands vs pairs crossing the CPU interconnect; (2) GPU↔NIC affinity: ranks whose nearest NIC sits behind the CPU root complex, where GPUDirect RDMA silently disables itself; (3) PCIe ACS: bridges with Access Control Services enabled, which redirect P2P through the root complex and break or throttle GDR; (4) NCCL environment: NCCL_IB_HCA validated against your actual HCAs and port states, NCCL_SOCKET_IFNAME against real interfaces, plus typo detection across 60+ documented NCCL variables; (5) limits: RLIMIT_MEMLOCK ceilings that make ibv_reg_mr fail under load.

Does my data leave my machine?

No. The linter runs entirely in your browser as compiled JavaScript. The paste box contents are never transmitted. Scale+ customers can run the identical engine server-side via POST /api/preflight/topology for CI gates.

How is this different from denpex preflight-cluster?

denpex preflight-cluster (the agent command) validates the runtime: rendezvous, ring bandwidth, port sanity, GPU/driver uniformity, ulimits, clock skew. This linter validates the configuration underneath: it reads the actual PCIe/NVLink/NIC topology and checks your NCCL settings against it. Run both. Use the agent before every gang-schedule, and the linter whenever the fabric, drivers, or NCCL env change.

Why do PCIe ACS settings matter for NCCL?

With ACS enabled on a bridge, every peer-to-peer transaction is forced up to the root complex for access validation. GPU↔GPU P2P bandwidth collapses and GPUDirect RDMA breaks or throttles, which NCCL surfaces as mysterious slow all-reduce or 'peer access not supported' errors. On bare metal the fix is disabling ACS in BIOS or via setpci; on virtualized hosts it may be required for isolation, in which case you disable P2P deliberately instead of debugging ghosts.

Gate your CI on it

The same engine runs server-side at POST /api/preflight/topology (Scale+), and the Denpex GitHub Action / GitLab template can block a merge on a blocker-level finding.

CI/CD integration docs