Skip to main content

Getting started with slurm

This guide will walk you through how to use SLURM on our FSE CSlab HPC cluster.

It covers:

  1. the most useful Slurm commands;
  2. how to write a Slurm batch script;

Important:

  • Replace placeholders such as <JOBID> and <NODENAME> with the values you want to use.
  • The examples below are designed to be easily understandeable, this does mean that they might not be maximally optimized.

Exploring the available nodes​

The first step in planning a job is investigating what resources are available. The HPC server is built up of multiple different nodes. A node is an individual compute server on which jobs run. Our server currently has 3 work nodes. You can observe this by running the following command:

sinfo -N

This will show you exactly what nodes are available on the server. You may notice that there is also a partition parameter. In our HPC server we currently only have 1 partition available, therefore you do not have to worry about it. You can intepret a partition as follows: A partition is a named queue in Slurm that contains a set of compute nodes and defines the conditions under which jobs can run on them.

With the names of the nodes found using sinfo -N you can find out how much computation power is available on a specific node:

scontrol show node <NODENAME>

you will most likely get an output like this:

NodeName=dacsgpu0002.fse-cslab.nl Arch=x86_64 CoresPerSocket=32
CPUAlloc=0 CPUEfctv=64 CPUTot=64 CPULoad=0.00
AvailableFeatures=(null)
ActiveFeatures=(null)
Gres=gpu:nvidia_l40:4(S:0)
NodeAddr=dacsgpu0002.fse-cslab.nl NodeHostName=dacsgpu0002.fse-cslab.nl Version=24.11.5
OS=Linux 6.12.69+deb13-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.12.69-1 (2026-02-08)
RealMemory=773352 AllocMem=0 FreeMem=754307 Sockets=1 Boards=1
State=IDLE ThreadsPerCore=2 TmpDisk=0 Weight=1 Owner=N/A MCS_label=N/A
Partitions=partition01
BootTime=2026-02-23T11:20:33 SlurmdStartTime=2026-03-12T15:56:16
LastBusyTime=2026-03-20T09:34:01 ResumeAfterTime=None
CfgTRES=cpu=64,mem=773352M,billing=64
AllocTRES=
CurrentWatts=0 AveWatts=0

From this you can find out the following information:

  • CoresPerSocket indicates how many physical cores there are in the node for each socket. then Sockets indicates how many sockets there are in total. In this example, the node has 32 * 1 = 32 physical cores
  • ThreadsPerCore indicates how many logical cores there are per physical core. In this case that is 2 thus in total there are 64 logical cpus in the node. Later, when you specify how many CPUs you want for your job, you should indicate the number of logical CPUs.
  • Gres=gpu:nvidia_l40:4(S:0) indicates how many gpus there are in the node. It follow this pattern: name[:type]:count. In this case there are 4 nvidia L40 GPUs.
  • RealMemory indicates how much ram the node has available in MB. In this case 773352 MB.

With this you should have all the necessary information for planning your job.

Creating a Slurm job​

To create a job in slurm, we use something called a slurm file. In this section we will run you through creating a basic slurm file and running a job on the HPC cluster. Save the following as job.slurm:

#!/bin/bash
#SBATCH --job-name=example_job
#SBATCH --output=stdout-%x-%j.out
#SBATCH --error=stderr-%x-%j.err
#SBATCH --time=00:10:00
#SBATCH --nodes=1
#SBATCH --ntasks=1
#SBATCH --ntasks-per-node=1
#SBATCH --cpus-per-task=1
#SBATCH --mem=200M
#SBATCH --gpus=1
#SBATCH --partition=research
#SBATCH --account=research

# set up EESSI
source /cvmfs/software.eessi.io/versions/2023.06/init/bash

# Load a module using EESSI
module load Python/3.11.5-GCCcore-13.2.0

srun python testcode.py

testcode.py​

import time

start = time.monotonic()
duration = 10 # seconds

while time.monotonic() - start < duration:
print("Running...", flush=True)
time.sleep(1)

print("Stopped.", flush=True)

This slurm script may seem overwhelming, but it is actually quite simple. For a slurm file, the very first line must be something we call a shebang, it indicates what shell interpreter slurm should use. #!/bin/bash is always correct in this case.

After the shebang, slurm files have the parameters that indicate the resources that you want to request from the scheduler. These resources are indicated with #SBATCH followed by the resources you want to request. These should always be at the start of the file. Make sure you don't request more than you actually need.

Our script then continues by loading in the modules. This document will not go in depth on how this works. A explanation of how it works can be found in the documentation of EESSI, that you have been provided with.

Finally, the srun command tells the slurm scheduler what command it should run based upon the requested resources. In the example case it will run python mycode.py.

This table contains an overview of the #SBATCH parameters you can pass to slurm. it is not an exhaustive list but it contains the most important ones.

ParameterDefinition
--job-nameGives the job a readable name. This name appears in commands such as squeue.
--outputDefines the file in which the standard output goes. Some usefull tokens are %x (job name) and %j (job id)
--errorDefines the file in which the standard error goes.
--timeSets the wall-clock time limit. When the limit is reached, Slurm will stop the job. You should request a realistic time, not an unnecessarily large one.
--nodesIndicates the amount of nodes that you want to use. For what you will be doing, 1 node should be enough.
--ntasksIndicates how many processes/tasks Slurm should allocate for your job. If you are running programs that use multiple processes (such as MPI) you should set a number larger than 1, while you would keep it to 1 for programs that run one process with multiple threads (such as pthreads and OpenMP).
--ntasks-per-nodeIndicates how many tasks you want to run on each node
--cpus-per-taskrepresent the amount of CPU cores you request per process. (so if you set --ntasks=2 and --cpus-per-task=4 you will request 8 cpu cores in total, or 4 per process)
--memIndicates how much memory your job should use per node
--gpusIndicates how many GPUs you want to use for the entire job
--partitionRequest a specific partition for the resource allocation. Different partitions can have different resource allocations / maximum runtime for jobs. You will be informed which partition you should use.
--accountThis is the group that you have been assigned to, it will allow you to make use of certain partitions of the cluster.

Running the slurm job​

Now that the slurm job has been created, we can move on the next step: sending the job to scheduler so that it can run the job with the requested resources. This is done with this command:

sbatch job.slurm

sbatch sends a script to Slurm. Slurm queues the job and runs it when resources become available. You can see what jobs are currently in the schedule using squeue. This command tells you what jobs are scheduled, how long they have been running, who scheduled them, their name and what it's current status is. If you only want to see jobs submitted by yourself you can add the -u flag as follows:

squeue -u <USER>

This will filter specificaly on the jobs submitted by the user specified. (you can also use $USER this will parse your name). Additionally, you can filter on job id using -j <JOBID>

Cancelling a job​

If you realise that you made a mistake in the setup of your job / the code you wrote you can always canceld the job. It can be done using the following command:

scancel <JOBID>

Monitoring a job's output​

To save time, you can ask slurm for the job id in a parsable format, that you can subsequently use in your bash scripts. An example using the OpenMP scripts:

JOB_ID=$(sbatch --parsable run_openmp3.slurm); sleep 1; tail -f stdout-openmp_test-$JOB_ID.out