SLURM Job Script Generator
Goal
Generate a correct, copy-pasteable SLURM job script (.sbatch) for running a simulation, and surface common configuration mistakes (bad walltime format, conflicting memory flags, oversubscription hints).
Requirements
- Python 3.10+
- No external dependencies (Python standard library only)
- Works on Linux, macOS, and Windows (script generation only)
Inputs to Gather
| Input |
Description |
Example |
| Job name |
Short identifier for the job |
phasefield-strong-scaling |
| Walltime |
SLURM time limit |
00:30:00 |
| Partition |
Cluster partition/queue (if required) |
compute |
| Account |
Project/account (if required) |
matsim |
| Nodes |
Number of nodes to allocate |
2 |
| MPI tasks |
Total tasks, or tasks per node |
128 or 64 per node |
| Threads |
CPUs per task (OpenMP threads) |
2 |
| Memory |
--mem or --mem-per-cpu (cluster policy dependent) |
32G |
| GPUs |
GPUs per node (optional) |
4 |
| Working directory |
Where the run should execute |
$SLURM_SUBMIT_DIR |
| Modules |
Environment modules to load (optional) |
gcc/12, openmpi/4.1 |
| Run command |
The command to launch under SLURM |
./simulate --config cfg.json |
Decision Guidance
MPI vs MPI+OpenMP layout
Does the code use OpenMP / threading?
├── NO → Use MPI-only: cpus-per-task=1
└── YES → Use hybrid: set cpus-per-task = threads per MPI rank
and export OMP_NUM_THREADS = cpus-per-task
Rule of thumb: if you see diminishing strong-scaling efficiency at high MPI ranks, try fewer ranks with more threads per rank (and measure).
Memory flag selection
- Use either
--mem (per node) or --mem-per-cpu (per CPU), not both.
- Follow your cluster’s documentation; some sites enforce one style.
- SLURM
--mem units are integer MB by default, or an integer with suffix K/M/G/T (and --mem=0 commonly means “all memory on node”).
Script Outputs (JSON Fields)
| Script |
Key Outputs |
scripts/slurm_script_generator.py |
results.script, results.directives, results.derived, results.warnings |
Workflow
- Gather cluster constraints (partition/account, GPU policy, memory policy).
- Choose a process layout (MPI-only vs hybrid MPI+OpenMP).
- Generate the script with
slurm_script_generator.py.
- Inspect warnings (conflicts, suspicious layouts).
- Save the generated script as
job.sbatch.
- Submit with
sbatch job.sbatch and monitor with squeue.
CLI Examples
# Preview a job script (prints to stdout)
python3 skills/hpc-deployment/slurm-job-script-generator/scripts/slurm_script_generator.py \
--job-name phasefield \
--time 00:10:00 \
--partition compute \
--nodes 1 \
--ntasks-per-node 8 \
--cpus-per-task 2 \
--mem 16G \
--module gcc/12 \
--module openmpi/4.1 \
-- \
./simulate --config config.json
# Write to a file and also emit structured JSON
python3 skills/hpc-deployment/slurm-job-script-generator/scripts/slurm_script_generator.py \
--job-name phasefield \
--time 00:10:00 \
--nodes 1 \
--ntasks 16 \
--cpus-per-task 1 \
--out job.sbatch \
--json \
-- \
/bin/echo hello
Conversational Workflow Example
User: I need an sbatch script for my MPI simulation. I want 2 nodes, 64 ranks per node, 2 OpenMP threads per rank, and 2 hours.
Agent workflow:
- Confirm partition/account and whether GPUs are needed.
- Generate a hybrid job script:
python3 scripts/slurm_script_generator.py --job-name run --time 02:00:00 --nodes 2 --ntasks-per-node 64 --cpus-per-task 2 -- -- ./simulate
- Explain the mapping:
- Total ranks = 128
- Threads per rank = 2 (
OMP_NUM_THREADS=2)
- If the user provides node core counts, sanity-check oversubscription using
--cores-per-node.
Error Handling
| Error |
Cause |
Resolution |
time must be HH:MM:SS or D-HH:MM:SS |
Bad walltime format |
Use 00:30:00 or 1-00:00:00 |
nodes must be positive |
Non-positive nodes |
Provide --nodes >= 1 |
Provide either --mem or --mem-per-cpu, not both |
Conflicting memory directives |
Choose one memory style |
Provide a run command after -- |
Missing launch command |
Add -- ./simulate ... |
Security
Input Validation
--time is validated against strict HH:MM:SS or D-HH:MM:SS format via regex
--nodes, --ntasks, --ntasks-per-node, --cpus-per-task, --gpus are validated as positive integers with upper bounds
--mem and --mem-per-cpu are validated against SLURM's accepted format (<int>[K|M|G|T]); providing both simultaneously is rejected
--job-name is validated against [a-zA-Z0-9_.-]+ (no shell metacharacters)
--partition and --account are validated against safe-character allowlists
--module values are validated to prevent shell injection (no ;, |, &, backticks, or $)
File Access
- The script reads no external files; all inputs are provided via CLI arguments
--out writes the generated sbatch script to a single specified file path
- The generated script is a plain-text shell script with
#SBATCH directives; it contains no dynamically generated code
Tool Restrictions
- Read: Used to inspect script source, references, and existing job scripts
- Bash: Used to execute
slurm_script_generator.py with explicit argument lists; the generated script itself is NOT executed by the agent
- Write: Used to save the generated
.sbatch file; writes are scoped to the user's working directory
- Grep/Glob: Used to locate existing scripts, configs, and cluster documentation
Safety Measures
- No
eval(), exec(), or dynamic code generation
- All subprocess calls use explicit argument lists (no
shell=True)
- The run command (after
--) is included verbatim in the generated script but is never executed by the skill itself
- Module names are sanitized to prevent injection into
module load directives
- Generated scripts use
set -euo pipefail for safe shell execution on the cluster
Limitations
- Does not query cluster hardware or site policies; it can only validate internal consistency.
- SLURM installations vary (GPU directives, QoS rules, partitions). Adjust directives for your site.
References
references/slurm_directives.md - Common #SBATCH directives and mapping tips
Version History
- v1.0.0 (2026-02-25): Initial SLURM job script generator
1---2name: slurm-job-script-generator3description: Generate correct, copy-pasteable SLURM sbatch job scripts and sanity-check HPC resource requests — configure nodes, MPI tasks, OpenMP threads, memory (per-node or per-cpu), GPUs, walltime, partitions, modules, and environment variables, with automatic detection of conflicting directives and oversubscription. Use when preparing a SLURM submission script, deciding between pure MPI and hybrid MPI+OpenMP layouts, standardizing #SBATCH directives across a team, debugging why a job won't launch or gets killed, or setting up GPU-accelerated simulation jobs, even if the user only says "I need to run this on the cluster" or "my job keeps getting killed."4---56# SLURM Job Script Generator78## Goal910Generate a correct, copy-pasteable SLURM job script (`.sbatch`) for running a simulation, and surface common configuration mistakes (bad walltime format, conflicting memory flags, oversubscription hints).1112## Requirements1314- Python 3.10+15- No external dependencies (Python standard library only)16- Works on Linux, macOS, and Windows (script generation only)1718## Inputs to Gather1920| Input | Description | Example |21|-------|-------------|---------|22| Job name | Short identifier for the job | `phasefield-strong-scaling` |23| Walltime | SLURM time limit | `00:30:00` |24| Partition | Cluster partition/queue (if required) | `compute` |25| Account | Project/account (if required) | `matsim` |26| Nodes | Number of nodes to allocate | `2` |27| MPI tasks | Total tasks, or tasks per node | `128` or `64` per node |28| Threads | CPUs per task (OpenMP threads) | `2` |29| Memory | `--mem` or `--mem-per-cpu` (cluster policy dependent) | `32G` |30| GPUs | GPUs per node (optional) | `4` |31| Working directory | Where the run should execute | `$SLURM_SUBMIT_DIR` |32| Modules | Environment modules to load (optional) | `gcc/12`, `openmpi/4.1` |33| Run command | The command to launch under SLURM | `./simulate --config cfg.json` |3435## Decision Guidance3637### MPI vs MPI+OpenMP layout3839```40Does the code use OpenMP / threading?41├── NO → Use MPI-only: cpus-per-task=142└── YES → Use hybrid: set cpus-per-task = threads per MPI rank43 and export OMP_NUM_THREADS = cpus-per-task44```4546**Rule of thumb:** if you see diminishing strong-scaling efficiency at high MPI ranks, try fewer ranks with more threads per rank (and measure).4748### Memory flag selection4950- Use **either** `--mem` (per node) **or** `--mem-per-cpu` (per CPU), not both.51- Follow your cluster’s documentation; some sites enforce one style.52- SLURM `--mem` units are integer MB by default, or an integer with suffix `K/M/G/T` (and `--mem=0` commonly means “all memory on node”).5354## Script Outputs (JSON Fields)5556| Script | Key Outputs |57|--------|-------------|58| `scripts/slurm_script_generator.py` | `results.script`, `results.directives`, `results.derived`, `results.warnings` |5960## Workflow61621. Gather cluster constraints (partition/account, GPU policy, memory policy).632. Choose a process layout (MPI-only vs hybrid MPI+OpenMP).643. Generate the script with `slurm_script_generator.py`.654. Inspect warnings (conflicts, suspicious layouts).665. Save the generated script as `job.sbatch`.676. Submit with `sbatch job.sbatch` and monitor with `squeue`.6869## CLI Examples7071```bash72# Preview a job script (prints to stdout)73python3 skills/hpc-deployment/slurm-job-script-generator/scripts/slurm_script_generator.py \74 --job-name phasefield \75 --time 00:10:00 \76 --partition compute \77 --nodes 1 \78 --ntasks-per-node 8 \79 --cpus-per-task 2 \80 --mem 16G \81 --module gcc/12 \82 --module openmpi/4.1 \83 -- \84 ./simulate --config config.json8586# Write to a file and also emit structured JSON87python3 skills/hpc-deployment/slurm-job-script-generator/scripts/slurm_script_generator.py \88 --job-name phasefield \89 --time 00:10:00 \90 --nodes 1 \91 --ntasks 16 \92 --cpus-per-task 1 \93 --out job.sbatch \94 --json \95 -- \96 /bin/echo hello97```9899## Conversational Workflow Example100101**User**: I need an `sbatch` script for my MPI simulation. I want 2 nodes, 64 ranks per node, 2 OpenMP threads per rank, and 2 hours.102103**Agent workflow**:1041. Confirm partition/account and whether GPUs are needed.1052. Generate a hybrid job script:106 ```bash107 python3 scripts/slurm_script_generator.py --job-name run --time 02:00:00 --nodes 2 --ntasks-per-node 64 --cpus-per-task 2 -- -- ./simulate108 ```1093. Explain the mapping:110 - Total ranks = 128111 - Threads per rank = 2 (`OMP_NUM_THREADS=2`)1124. If the user provides node core counts, sanity-check oversubscription using `--cores-per-node`.113114## Error Handling115116| Error | Cause | Resolution |117|-------|-------|------------|118| `time must be HH:MM:SS or D-HH:MM:SS` | Bad walltime format | Use `00:30:00` or `1-00:00:00` |119| `nodes must be positive` | Non-positive nodes | Provide `--nodes >= 1` |120| `Provide either --mem or --mem-per-cpu, not both` | Conflicting memory directives | Choose one memory style |121| `Provide a run command after --` | Missing launch command | Add `-- ./simulate ...` |122123## Security124125### Input Validation126- `--time` is validated against strict `HH:MM:SS` or `D-HH:MM:SS` format via regex127- `--nodes`, `--ntasks`, `--ntasks-per-node`, `--cpus-per-task`, `--gpus` are validated as positive integers with upper bounds128- `--mem` and `--mem-per-cpu` are validated against SLURM's accepted format (`<int>[K|M|G|T]`); providing both simultaneously is rejected129- `--job-name` is validated against `[a-zA-Z0-9_.-]+` (no shell metacharacters)130- `--partition` and `--account` are validated against safe-character allowlists131- `--module` values are validated to prevent shell injection (no `;`, `|`, `&`, backticks, or `$`)132133### File Access134- The script reads no external files; all inputs are provided via CLI arguments135- `--out` writes the generated sbatch script to a single specified file path136- The generated script is a plain-text shell script with `#SBATCH` directives; it contains no dynamically generated code137138### Tool Restrictions139- **Read**: Used to inspect script source, references, and existing job scripts140- **Bash**: Used to execute `slurm_script_generator.py` with explicit argument lists; the generated script itself is NOT executed by the agent141- **Write**: Used to save the generated `.sbatch` file; writes are scoped to the user's working directory142- **Grep/Glob**: Used to locate existing scripts, configs, and cluster documentation143144### Safety Measures145- No `eval()`, `exec()`, or dynamic code generation146- All subprocess calls use explicit argument lists (no `shell=True`)147- The run command (after `--`) is included verbatim in the generated script but is never executed by the skill itself148- Module names are sanitized to prevent injection into `module load` directives149- Generated scripts use `set -euo pipefail` for safe shell execution on the cluster150151## Limitations152153- Does not query cluster hardware or site policies; it can only validate internal consistency.154- SLURM installations vary (GPU directives, QoS rules, partitions). Adjust directives for your site.155156## References157158- `references/slurm_directives.md` - Common `#SBATCH` directives and mapping tips159160## Version History161162- **v1.0.0** (2026-02-25): Initial SLURM job script generator