build_infra — stand up and verify the CP test environment
CP code cannot be developed or trusted without multi-GPU execution. This skill
proves the environment can run the collectives CP depends on, and decides which CP
configurations are testable here. Run the shipped scripts; do not hand-wave the
checks. All scripts live in scripts/ under this skill
(${CLAUDE_SKILL_DIR}/scripts).
Step 1 — Inventory the hardware
nvidia-smi -L # count + model
nvidia-smi --query-gpu=index,memory.total,memory.used --format=csv
nvidia-smi topo -m # NVLink / PCIe topology
Note which GPUs are free (other users may occupy a shared node — respect
manage_gpu hygiene if available: never use a GPU you did not claim).
Step 2 — Map free GPUs to testable 2D-CP configurations
| Free GPUs | 2D-CP | Integration |
|---|---|---|
| >=8 | yes — cp0=cp1=2 (+ dp>=2) |
full end-to-end |
| 4–7 | yes — cp0=cp1=2 |
limited |
| 0–3 | no (needs a perfect square >=4) | escalate to SLURM (Step 5) |
2D-CP requires size_cp to be a perfect square (cp0=cp1); the smallest is 4.
Record the chosen config(s).
Step 3 — Probe the software stack
python "${CLAUDE_SKILL_DIR}/scripts/probe_env.py"
It reports Python / PyTorch / CUDA / NCCL versions, torch.cuda.is_available(),
per-GPU compute capability and memory, free disk space, the NVIDIA driver
version, and a self-consistency verdict (see the next section), plus a
recommended CP-config JSON derived from the live GPU count. If PyTorch lacks a CUDA
backend, or versions are incompatible with the target model, stop and surface it to
the user. (Point the disk check at your real work dir with
FOLD_CP_WORKDIR=<path>; it defaults to the cwd.)
Resolve the ONE environment that satisfies BOTH constraints: a torch built for the
GPUs' arch (e.g. sm_120/Blackwell needs a recent CUDA) AND the target model importable
in it. The interpreter may not be on PATH (pixi/conda) and the model may not be
pip-installed — find the env where both import torch (right arch) and
python -c "import <model_pkg>" succeed, and record its absolute interpreter path
in docs/cp_infra.md. Also probe the multi-rank launch prerequisites and bake them
into the recorded recipe:
PYTHONPATH=<repo root>when the model is not pip-installed —mp.spawn(spawn start-method) workers don't inherit the parent's cwd, so they hitModuleNotFoundErrorwithout it.- Sandbox / seccomp can block NCCL. If the agent runtime sandboxes syscalls, the AF_UNIX sockets used by the NCCL / process-group bootstrap may be blocked → a silent deadlock; run multi-rank jobs with the sandbox disabled (or the runtime's escape hatch). Record the working invocation (interpreter, env vars, sandbox flag) so every downstream multi-rank run reuses it.
Resource prerequisites (info-only, model-agnostic) — R4 / R10
fold-cp's skills are model-agnostic: they do not prescribe a fixed GPU SKU or count, because a custom model may ship kernels that only run on certain GPUs (custom CUDA/Triton, an arch-gated attention) — unknowable ahead of time. So the requirement is not "have an H100"; it is a self-consistent stack. Treat this as a high-level guide, not a hard gate — the real gates are the smoke tests (Step 4).
- Self-consistency (the actual requirement). The user's hardware ⇄ their PyTorch
runtime ⇄ their model must be mutually compatible: a torch built for the GPUs' arch, an
NVIDIA driver new enough for that CUDA build, and the target model importable in that
interpreter.
probe_env.pygives the authoritative signal —torch.cuda.is_available()isTrueonly when driver + CUDA-build + GPU-arch agree — and reports the NVIDIA driver vs the CUDA build so a mismatch is legible. The two halves probe_env can't settle on its own: model import (Step 3 —python -c "import <model_pkg>"in the chosen interpreter) and DTensor /device_meshsupport (Step 4 smoke tests). The one hard software floor is that the runtime supportstorch.distributed.tensorDTensor +init_device_mesh— which is exactly what Step 4 proves. - Disk: recommend ≥ ~150 GB free for checkpoints + model containers + datasets + build
artifacts (a large model or many checkpoints can need more).
probe_env.pyreports free/total and warns under the threshold; it is a recommendation, not a hard stop. - Per-step hardware (R10) is runtime-derived, not a fixed table. GPU count → testable
configuration comes from Step 2 (2D needs a perfect square ≥4); per-module memory
budgets come from
/fold-cp:dtensor_modules(the O(N/cp0) / O(N²/(cp0·cp1)) backward budget) and are measured by/fold-cp:mem_profile; training vs inference differ only by fwd vs fwd+bwd+step, captured by/fold-cp:benchmarkon the same mesh. Record the SKU you actually ran on incp_infra.mdas provenance — do not prescribe one.
Step 4 — Run the communication smoke tests
These self-launch with mp.spawn (no torchrun needed) and must pass before any
CP work. Always timeout-wrap and tee the logs (Rule 16):
WS=<world size from Step 2>
timeout 120 python "${CLAUDE_SKILL_DIR}/scripts/test_collectives.py" --world-size $WS |& tee /tmp/$USER/cp_collectives.log
timeout 120 python "${CLAUDE_SKILL_DIR}/scripts/test_dtensor_smoke.py" --world-size $WS |& tee /tmp/$USER/cp_dtensor.log
test_collectives.py— verifiesbatch_isend_irecv(ring P2P),all_gather,all_reduce, andreduce_scatteragainst analytic expected values on every rank. A hang here means NCCL/IB misconfiguration — diagnose before proceeding.test_dtensor_smoke.py— builds aDeviceMesh,distribute_tensor, checksto_local()shapes and afull_tensor()round-trip for a 2D square-tile placement. This proves the DTensor substrate works here.
If a test hangs to the timeout, treat it as a hard failure (likely a deadlock or
transport problem), capture NCCL_DEBUG=INFO output, and resolve before moving on.
Step 5 — No local GPUs: escalate to a cluster (SLURM)
If Step 2 yields fewer than 4 GPUs, CP cannot be tested locally. Then:
- Ask the user for cluster access details: login/submission host, scheduler (SLURM assumed), partition/queue, account, time limit, the module/conda activation line, and how the repo is reached on compute nodes (shared FS vs rsync). Ask whether the agent may submit jobs on their behalf.
- Fill
scripts/slurm_probe.sbatchwith those values — it requests one node + N GPUs and runs the Step 3–4 probes undersrun. Submit withsbatch, then pollsqueue/sacctand read the captured log. Do not assume success — read the log. - Record the working launch recipe (sbatch header + activation) in
docs/cp_infra.mdso downstream skills reuse it for every multi-rank run.
Step 6 — Record the deliverable
Write docs/cp_infra.md with: the GPU inventory, the chosen testable 2D-CP config(s)
and world_size, software versions, the resource prerequisites (free disk vs the
~150 GB recommendation, NVIDIA driver vs torch's CUDA build, and the
self-consistency verdict from the section above), smoke-test results (paths to the
tee'd logs), and the canonical launch command (local mp.spawn/torchrun or the
SLURM recipe). Downstream skills read this file to know how to launch tests and
benchmarks.
Deadlock-hardening (set these once, before any multi-rank run)
Distributed CP runs hang silently without a few guards — bake them into the launch
recipe in docs/cp_infra.md:
- Per-collective timeouts on
init_process_group(separate NCCL/cuda vs Gloo/cputimedeltas) so a deadlock fails fast instead of hanging the session (also Rule 16). TORCH_NCCL_ASYNC_ERROR_HANDLING=1set beforeinit_process_group, so a rank that errors tears the group down instead of leaving peers blocked.- Free-port selection +
MASTER_PORTpropagation: pick an OS-assigned free port withSO_REUSEADDRon rank 0 and broadcast it; concurrent worktrees/CI that hardcode a port collide and rebind-race. - P2P parity ordering in any ring/transpose (Rule 7) — schedule send/recv by rank parity so paired ranks don't both block on send.
PYTORCH_CUDA_ALLOC_CONF=expandable_segments:Trueat the memory ceiling to fight fragmentation-drivencudaMallocretries / spurious OOMs.
Output contract
docs/cp_infra.mdexists and names the testable topology + world size and the exact launch recipe.- Both smoke tests passed (logs on disk) or a SLURM path is established and a probe job has been verified to pass.
- If neither local GPUs nor cluster access can be obtained, stop and tell the user exactly what is blocking CP development.