Job Scripts¶
Complete guide to writing SLURM job scripts, common job types, and advanced tips.
Basic Job Script Structure¶
SLURM job scripts contain directives (lines starting with #SBATCH) and commands to run your workload.
#!/bin/bash
# Lines starting with #SBATCH are SLURM directives
#SBATCH --job-name=myjob
#SBATCH --nodes=1
#SBATCH --ntasks=1
#SBATCH --time=01:00:00
#SBATCH --output=myjob.out
# Regular shell commands follow
module purge
module load python
echo "Running job..."
python my_script.py
Essential Directives¶
Job Identification¶
#SBATCH --job-name=myjob # Job name (max 128 chars)
#SBATCH --output=output.out # Standard output file
#SBATCH --error=error.err # Standard error file
#SBATCH --mail-user=email@msu.edu # Email address
#SBATCH --mail-type=END,FAIL # When to email (NONE, START, END, FAIL, ALL)
Resources¶
#SBATCH --nodes=1 # Number of nodes
#SBATCH --ntasks=1 # Number of tasks (MPI processes)
#SBATCH --cpus-per-task=4 # CPUs per task
#SBATCH --mem=8G # Total memory
#SBATCH --mem-per-cpu=2G # Memory per CPU
#SBATCH --time=01:00:00 # Wall time (HH:MM:SS)
Partition and QoS¶
#SBATCH --qos=normal # Quality of Service
#SBATCH --account=myproject # Account to charge
Complete Examples by Workload Type¶
Most common type. Use for serial or multi-threaded CPU workloads.
#!/bin/bash
#SBATCH --job-name=cpu-job
#SBATCH --nodes=1
#SBATCH --ntasks=1
#SBATCH --cpus-per-task=8
#SBATCH --mem=16G
#SBATCH --time=02:00:00
module purge
module load python
python cpu_intensive.py
For distributed memory parallel computing.
#!/bin/bash
#SBATCH --job-name=mpi-job
#SBATCH --nodes=4
#SBATCH --ntasks-per-node=16
#SBATCH --cpus-per-task=1
#SBATCH --mem=32G
#SBATCH --time=04:00:00
module purge
module load openmpi
mpirun -np 64 ./mpi_program
See GPU Usage for details.
#!/bin/bash
#SBATCH --job-name=gpu-job
#SBATCH --nodes=1
#SBATCH --ntasks=1
#SBATCH --cpus-per-task=8
#SBATCH --gres=gpu:1
#SBATCH --mem=32G
#SBATCH --time=02:00:00
#SBATCH --partition=<valid_gpu_partition>
module purge
module load cuda
python gpu_training.py
#!/bin/bash
#SBATCH --job-name=big-mem
#SBATCH --nodes=1
#SBATCH --ntasks=1
#SBATCH --cpus-per-task=8
#SBATCH --mem=256G
#SBATCH --time=12:00:00
#SBATCH --partition=bigmem
#SBATCH --output=big-mem.out
module purge
module load python
python process_large_dataset.py
Run many similar jobs efficiently without creating separate scripts.
#!/bin/bash
#SBATCH --job-name=array-job
#SBATCH --array=1-100
#SBATCH --nodes=1
#SBATCH --ntasks=1
#SBATCH --cpus-per-task=2
#SBATCH --mem=4G
#SBATCH --time=01:00:00
# $SLURM_ARRAY_TASK_ID ranges from 1 to 100
python process_sample.py --id $SLURM_ARRAY_TASK_ID
Key features:
Each array task gets a unique ID (
$SLURM_ARRAY_TASK_ID)Use
%Afor master job ID,%afor array task ID in output filesLimit concurrent tasks:
#SBATCH --array=1-100%10(10 at a time)
Example with unique output files:
#SBATCH --output=output_%A_%a.txt # Each task writes to separate file
Use cases:
Parameter sweeps
Batch simulations
Processing multiple files in parallel
Get a shell on a compute node for testing or debugging.
# Basic interactive session
srun --pty --time=02:00:00 /bin/bash
# With resources
srun --pty --nodes=1 --ntasks=1 --cpus-per-task=4 --mem=8G --time=02:00:00 /bin/bash
# Interactive GPU session
srun --pty --partition=<valid_gpu_partition> --gres=gpu:1 --time=04:00:00 /bin/bash
Quick tests or small computations.
#!/bin/bash
#SBATCH --job-name=burst
#SBATCH --nodes=1
#SBATCH --ntasks=1
#SBATCH --time=00:10:00 # 10 minutes
python quick_test.py
Cluster-Specific Job Examples¶
Different clusters have different partition names and resource options:
Standard CPU Job:
#!/bin/bash
#SBATCH --job-name=orion-cpu
#SBATCH --nodes=1
#SBATCH --ntasks=1
#SBATCH --cpus-per-task=4
#SBATCH --mem=16G
#SBATCH --time=04:00:00
#SBATCH --output=orion-job.out
module purge
module load python
python analysis.py
Big Memory Job:
#!/bin/bash
#SBATCH --job-name=orion-bigmem
#SBATCH --nodes=1
#SBATCH --mem=300G
#SBATCH --partition=bigmem
#SBATCH --time=04:00:00
python memory_intensive.py
Standard CPU Job:
#!/bin/bash
#SBATCH --job-name=hercules-cpu
#SBATCH --nodes=1
#SBATCH --ntasks=1
#SBATCH --cpus-per-task=8
#SBATCH --mem=32G
#SBATCH --time=04:00:00
#SBATCH --output=hercules-job.out
module purge
module load python
python analysis.py
GPU Job (A100):
#!/bin/bash
#SBATCH --job-name=ptolemy-gpu
#SBATCH --nodes=1
#SBATCH --ntasks=1
#SBATCH --cpus-per-task=8
#SBATCH --mem=32G
#SBATCH --gres=gpu:a100:1
#SBATCH --time=04:00:00
#SBATCH --partition=gpu-a100
#SBATCH --output=ptolemy-job.out
module purge
module load cuda pytorch
python train_model.py
MIG GPU Job:
#!/bin/bash
#SBATCH --job-name=ptolemy-mig
#SBATCH --nodes=1
#SBATCH --gres=gpu:mig:1g.10gb
#SBATCH --partition=gpu-a100-mig7
#SBATCH --time=04:00:00
python mig_job.py
V100 GPU Job:
#!/bin/bash
#SBATCH --job-name=gpu-v100
#SBATCH --nodes=1
#SBATCH --gres=gpu:v100:1
#SBATCH --partition=gpu-v100
#SBATCH --time=04:00:00
#SBATCH --output=gpu-v100.out
module purge
module load cuda
python tensorflow_job.py
A100 GPU Job:
#!/bin/bash
#SBATCH --job-name=gpu-a100
#SBATCH --nodes=1
#SBATCH --gres=gpu:a100:1
#SBATCH --partition=gpu-a100
#SBATCH --time=04:00:00
module purge
module load cuda
python pytorch_job.py
L40S GPU Job:
#!/bin/bash
#SBATCH --job-name=gpu-l40s
#SBATCH --nodes=1
#SBATCH --gres=gpu:l40s:1
#SBATCH --partition=gpu-l40s
#SBATCH --time=04:00:00
python inference_job.py
CPU Job:
#!/bin/bash
#SBATCH --job-name=morrill-cpu
#SBATCH --nodes=1
#SBATCH --cpus-per-task=8
#SBATCH --mem=32G
#SBATCH --time=04:00:00
#SBATCH --output=morrill-cpu.out
python analysis.py
GPU Job (A100):
#!/bin/bash
#SBATCH --job-name=morrill-gpu
#SBATCH --nodes=1
#SBATCH --gres=gpu:a100:1
#SBATCH --partition=gpu-a100
#SBATCH --time=04:00:00
#SBATCH --output=morrill-gpu.out
module purge
module load cuda
python train_model.py
Choosing the Right Job Type¶
Workload Type |
Job Type |
Key Directives |
|---|---|---|
Serial script |
CPU-only |
|
Multi-threaded |
CPU-only |
|
MPI parallel |
Multi-node |
|
Deep learning |
GPU |
|
Many similar tasks |
Array |
|
Testing/Debugging |
Interactive |
|
Best Practices¶
Always specify resources - Don’t rely on defaults
Use meaningful job names - Easier to identify in queue
Redirect output - Capture stdout and stderr with
--outputand--errorLoad modules explicitly - Don’t rely on environment
Request only what you need - Helps scheduler be more efficient
Test with small jobs first - Verify before scaling up
Use job arrays for batch processing - More efficient than individual jobs
Common Mistakes¶
Wrong shebang¶
#!/bin/bash # Correct
#!/bin/sh # May not work for all scripts
Missing output redirection¶
#SBATCH --output=myjob.%j.out # %j = job ID
Requesting too much memory¶
#SBATCH --mem=1000G # Too much, will fail
#SBATCH --mem=128G # Better
Wrong time format¶
#SBATCH --time=24:00:00 # Correct (24 hours)
#SBATCH --time=24:00 # Wrong format