README.md
August 27, 2026 · View on GitHub
PrimusBench
PrimusBench is a set of scripts for multi-node system preflight checks and benchmarking. It supports both bare-metal (Ansible-driven) and SLURM-based runs, covering network connectivity, node health checks, I/O benchmarks, and key system metrics such as computation-communication overlap and kernel launch overhead.
Features
- Preflight: SSH reachability, node configuration, network connectivity
- I/O Benchmarks: fio, IOR (optional)
- System Benchmarks: Computation-Communication Overlap, Kernel Launch Overhead
- Three run modes: Bare metal via Ansible, SLURM cluster, or Kubernetes with PyTorchJob
Prerequisites
- Target nodes run a basic Linux environment (Ubuntu 22.04 or equivalent recommended)
- Nodes are mutually reachable; the control node can SSH to targets (passwordless or auto-configured by scripts)
- Bare-metal mode requires Ansible on the control node; SLURM mode requires
salloc/srun - ROCm/PyTorch dependencies are typically provided by the container image
Quick Start
Running on Bare Metal
- Prepare host inventory
Create or edit
hosts.iniat the repo root:
[all]
host1
host2
Hostnames or IPs are supported; ensure they resolve.
- Run The entry script will:
- Install Docker across nodes via Ansible
- Start preflight checks and benchmarks, writing logs to
outputs/<TIMESTAMP>
Common environment variables:
IMAGE: Benchmark image (default:primussafe/primusbench:202510210028)INVENTORY_FILE: Ansible inventory file (default:hosts.ini)IO_BENCHMARK_MOUNT: Enable and mount a directory for I/O benchmarks (optional)
Run:
bash run_bare_metal.sh
Key steps in run_bare_metal.sh:
- Install Docker:
playbooks/bare_metal/install_docker.yaml - Run benchmarks:
playbooks/bare_metal/bench.yaml - Logs directory:
outputs/<TIMESTAMP>(main logprimusbench.log)
Running on SLURM
The SLURM mode automatically handles resource allocation and benchmark execution. By default, run_slurm.sh will use salloc to allocate resources before running the benchmarks.
Default Usage (Automatic Allocation):
# Automatically allocate 2 nodes and run benchmarks (default behavior)
bash run_slurm.sh
# Allocate 4 nodes with custom settings
NNODES=4 PARTITION=gpu TIME=2:00:00 bash run_slurm.sh
Within Existing SLURM Allocation:
# If already in a SLURM job, skip auto-allocation
bash run_slurm.sh --no-allocate
Excluding Problem Nodes:
# Use default exclude list (configured in script)
bash run_slurm.sh
# Custom exclude list
EXCLUDE_NODES="chi[2770-2772]" bash run_slurm.sh
# Don't exclude any nodes
EXCLUDE_NODES="" bash run_slurm.sh
run_slurm.sh will:
- Automatically allocate nodes via
salloc(unless --no-allocate is used) - Display excluded nodes if configured
- Use
srunto execute containers on each node - Run node and network preflight checks
- Filter out unhealthy nodes and keep healthy ones for benchmarks
- Generate comprehensive health reports
- Write outputs to
outputs/<TIMESTAMP>
Environment variables (configured in config.sh, can be overridden):
NNODES: Number of nodes (default: 2)PARTITION: SLURM partition (default: configured in config.sh)TIME: Job time limit (default: 4:30:00)CPUS_PER_TASK: CPUs per task (default: 128)EXCLUDE_NODES: Nodes to exclude from allocationIMAGE: Container image for benchmarksMASTER_PORT: Master port for distributed operations- See
config.shfor complete configuration options
Running on Kubernetes with PyTorchJob
For Kubernetes clusters with Kubeflow PyTorchJob operator, you can run distributed benchmarks using the provided PyTorchJob specification.
Prerequisites:
- Kubernetes cluster with Kubeflow Training Operator installed
- Access to a shared storage (hostPath or PVC) for workspace and outputs
- Container image available in your cluster registry
Steps:
- Prepare the PyTorchJob manifest
Edit
kubernetes/pytorchjob.yamland replace the following placeholders:
<host_path to be replaced, shared directory>: Path to shared workspace directory on nodes<pvc_name to be replaced, io_benchmark_pvc>: Name of PVC for I/O benchmarks (if using PVC)- Adjust
replicascount for Master and Worker as needed - Update resource limits (GPUs, memory, CPU) according to your cluster
- Configure environment variables Key variables in the YAML (adjust as needed):
NCCL_SOCKET_IFNAME/GLOO_SOCKET_IFNAME: Network interface nameNCCL_IB_HCA: RDMA device names (comma-separated)IO_BENCHMARK_MOUNT: Mount point for I/O benchmarks- Container image: Update
imagefield with your image tag
- Deploy the PyTorchJob
kubectl apply -f kubernetes/pytorchjob.yaml
- Monitor the job
# Check job status
kubectl get pytorchjob network
# View logs from master pod
kubectl logs -f <master-pod-name>
# View logs from worker pods
kubectl logs -f <worker-pod-name>
- Collect results Results will be written to the shared workspace directory specified in the volumeMounts.
Important notes:
- The job uses
hostNetwork: truefor optimal RDMA performance - Privileged security context is required for device access
- Ensure all nodes have the necessary RDMA devices and drivers installed
- Worker replicas count determines the number of worker nodes (adjust based on cluster size)
Key scripts and directories
run_bare_metal.sh: bare-metal entrypoint; installs Docker, calls Ansible playbooks, streams logsrun_slurm.sh: SLURM execution with automatic resource allocationrun_slurm.sh: preflight and network checks inside the SLURM jobrun.sh: container entrypoint; runs I/O benchmarks, node/network preflight, system benchmarks, and collects resultsplaybooks/: Ansible playbooks (bare-metal install and benchmarks)kubernetes/: Kubernetes manifests including PyTorchJob specificationsbenchmarks/: benchmark implementations and build scriptspreflight/: SSH, node, and network preflight componentsbuild/:Dockerfileandbuild.sh, which build the images with the necessary dependencies and tools
Outputs and logs
Default output locations:
- Bare metal:
outputs/<TIMESTAMP> - SLURM:
output/<TIMESTAMP>(orSHARE_PATH/output/<TIMESTAMP>) - Kubernetes: Written to shared workspace volume specified in PyTorchJob manifest
Important files (examples):
primusbench.log: main runtime log (streamed by bare-metal entry)io_benchmarks.log: I/O benchmark log (when enabled)preflight_node.log/preflight_network.log: preflight resultsoverlap_results.json/kernel_overhead_results.json: system benchmark results
Container image
Default images are set via environment variables in the scripts:
- Benchmark image:
IMAGE(used byrun_bare_metal.sh/ Ansible playbooks) - Preflight images:
PREFLIGHT_NODE_IMAGE,PREFLIGHT_NETWORK_IMAGE(SLURM)
Build the image
- Build from this repo:
docker build -t primussafe/primusbench:{{TAG}} .
FAQ
- Ansible connection failures: Verify hostnames/IPs in
hosts.iniresolve; confirm SSH port and passwordless access; setINVENTORY_FILEto a custom inventory if needed. - Logs not generated: In bare-metal mode, main log is
outputs/<TIMESTAMP>/primusbench.log; if missing, check bare-metal or install phase logs first. - Nodes marked unhealthy: Inspect
preflight_node.logandpreflight_network.log; fix reported issues (ports, drivers, clocks, DNS, bandwidth/latency anomalies, etc.). - I/O benchmarks not running: Set
IO_BENCHMARK_MOUNTto the target mount point.
License
This project is licensed under the terms described in the LICENSE file.