Single-Allocation Mode
Experimental Feature
Single-allocation mode is experimental. It may contain bugs or undergo breaking changes in future releases. Please report any issues you encounter.
Single-allocation mode runs all tests within a single SLURM allocation instead of submitting separate jobs for each test.
Table of Contents
Overview
By default, IOPS submits a separate SLURM job for each test (per-test mode). Single-allocation mode changes this behavior:
| Mode | How it works |
|---|---|
per-test (default) | Each test = separate sbatch job |
single | One allocation, all tests run sequentially in bash |
Compatibility:
- Supported search methods:
exhaustiveandrandom.bayesianandadaptiveare rejected at config validation because single-allocation mode pre-generates all tests upfront, leaving no feedback loop for the optimizer or probe. - The
parallelsetting is ignored (with a warning); tests run sequentially inside the allocation.
When to Use
Single-allocation mode helps when your HPC system limits jobs per user, queue wait times are long, you have many small tests, or you want to reduce scheduler load.
Warning: Resource efficiency considerations
Single-allocation mode requires allocating resources for your largest test. When sweeping over variable resource counts (e.g.,
nodes: [1, 2, 4, 8]), smaller tests leave resources idle: allocate 8 nodes, run a 2-node test, and 6 nodes sit unused while consuming core-hours.Best suited for: Tests that all use the same (or similar) amount of resources. Consider per-test mode (
mode: "per-test") when tests have highly variable resource requirements and queue wait times are acceptable.
Basic Configuration
benchmark:
executor: "slurm"
slurm_options:
allocation:
mode: "single"
test_timeout: 300 # Per-test timeout in seconds (default: 3600)
allocation_script: |
#SBATCH --nodes=8
#SBATCH --time=02:00:00
#SBATCH --partition=batch
#SBATCH --account=myaccount
#SBATCH --exclusive
The allocation_script contains your SBATCH directives and setup commands (module loads, environment variables). The job completes automatically when all tests finish.
How It Works
- IOPS generates a complete execution script (
__iops_kickoff.sh) containing the shebang (#!/bin/bash), your SBATCH directives plus--job-name=iops_single_allocand output/error paths, your setup commands, arun_test()dispatcher function that runs each test with timeout handling, and sequentialrun_testcalls for every test. - IOPS submits
__iops_kickoff.shviasbatch. - Tests run sequentially inside the allocation:
run_test "exec_0001/rep_001" "script.sh" ... run_test "exec_0001/rep_002" "script.sh" ... - Each test writes its status to
__iops_status.json:RUNNINGthenSUCCEEDED/FAILED/TIMEOUT. - The IOPS runner monitors the status files and collects results.
Running MPI Programs
In single-allocation mode, your script runs directly on the first allocated node. For MPI programs, you need to launch processes to other nodes using srun or mpirun.
With PMI Support (Recommended)
If your MPI installation has SLURM PMI support, use srun directly in your script:
script_template: |
#!/bin/bash
module load openmpi
srun --nodes={{ nodes }} \
--ntasks={{ nodes * ppn }} \
{{ command.template }}
How to check for PMI support:
- Run
srun --mpi=listto see SLURM’s supported PMI versions - Run
ompi_info | grep pmito see OpenMPI’s PMI support - Both must match: If SLURM has
pmi2but OpenMPI haspmix3x, they may not be compatible. Test withsrun --mpi=pmi2 --ntasks=2 hostnameinside an allocation.
Without PMI Support
Most HPC systems have OpenMPI compiled without SLURM PMI support. In this case, use mpirun instead.
The problem: Unlike srun, mpirun doesn’t automatically limit processes to a subset of your allocation. If you allocate 8 nodes but a test only needs 2, mpirun -np 8 will spread processes across all 8 nodes instead of concentrating them on 2.
The solution: Build an explicit host list to control which nodes mpirun uses:
script_template: |
#!/bin/bash
module load openmpi
# Get all nodes in the allocation
ALLOC_NODES=$(scontrol show job $SLURM_JOB_ID | grep -oP 'NodeList=\K[^\s]+')
# Build host list: node1:slots,node2:slots,...
NODELIST=$(scontrol show hostnames $ALLOC_NODES \
| head -n {{ nodes }} \
| sed 's/$/:{{ ppn }}/' \
| tr '\n' ',')
NODELIST=${NODELIST%,} # Remove trailing comma
# Launch with explicit host list
mpirun --host $NODELIST \
-np {{ nodes * ppn }} \
--map-by ppr:{{ ppn }}:node \
--mca plm rsh \
--oversubscribe \
{{ command.template }}
Key flags explained:
| Flag | Purpose |
|---|---|
--host $NODELIST | Specify which nodes to use (format: node1:slots,node2:slots) |
-np N | Total number of processes |
--map-by ppr:N:node | Place N processes per node |
--mca plm rsh | Use SSH to launch on remote nodes (bypasses SLURM) |
--oversubscribe | Bypass slot detection (safe with --exclusive) |