Scheduling jobs
Instructor note
Total: 75min (Teaching:45Min | Discussion:0min | Breaks:0min | Exercises:30Min)
Objectives
Objectives
Run a simple Hello World style program on the cluster.
Submit a simple Hello World style script to the cluster.
Use the batch system command line tools to monitor the execution of your job.
Inspect the output and error files of your jobs.
Job scheduler
An HPC system might have thousands of nodes and thousands of users. How do we decide who gets what and when? How do we ensure that a task is run with the resources it needs? This job is handled by a special piece of software called the scheduler. On an HPC system, the scheduler manages which jobs run where and when.
The following illustration compares these tasks of a job scheduler to a waiter in a restaurant. If you can relate to an instance where you had to wait for a while in a queue to get in to a popular restaurant, then you may now understand why sometimes your job do not start instantly as in your laptop.
The scheduler used in this lesson is SLURM
. Although SLURM
is not
used everywhere, running jobs is quite similar regardless of what software is being used.
The exact syntax might change, but the concepts remain the same.
Discussion
Have you experienced having to wait to get into a popular restaurant
Creating our test job
The most basic use of the scheduler is to run a command non-interactively. Any command (or series of commands) that you want to run on the cluster is called a job, and the process of using a scheduler to run the job is called batch job submission.
In this case, the job we want to run is just a shell script. Let’s create a demo shell script to
run as a test. The landing pad will have a number of terminal-based text editors installed. Use
whichever you prefer. Unsure? nano
is a pretty good, basic choice.
Instructor note
What is a terminal text editor ?
## Create a file named example-job.sh your favourite editor
## The content should match what the ´cat´ command
## displays below
[MY_USER_NAME@CLUSTER_NAME ~]$ nano example-job.sh
[MY_USER_NAME@CLUSTER_NAME ~]$ cat example-job.sh
#!/bin/bash
echo -n "This script is running on "
hostname
## Make the file executable
[MY_USER_NAME@CLUSTER_NAME ~]$ chmod +x example-job.sh
Run the script in the login node.
Instructor note
Remind what are login nodes and compute nodes
Try to use the same project as the one students have access to
If the cluster is too busy, even for a test job use
–reservation=
e.g. sbatch –account=nn9987k –reservation=nn9987k_gpu –mem=1G –partition=accel –time=01:00 example-job.sh
For tests jobs on Betzy use
–qos=preproc
[MY_USER_NAME@CLUSTER_NAME ~ ]$ ./example-job.sh
This script is running on <HOSTNAME_OF_CLUSTER_LOGIN_NODE>
This job runs on the login node.
There is a distinction between running the job through the scheduler and just
“running it”. To submit this job to the scheduler, we use the sbatch
command.
Note
Find your project account(s)
All users on HPC clusters in Norway are part of at leaset one project. Each project is allocated an amount of credit. The currency used is “CPU-hours”. When you communicating with the scheduler, we should indicate which account should be charged.
#Most Likely your output would be different
#must you should see at least one project
[MY_USER_NAME@CLUSTER_NAME ~]$ projects
nn9736k
nn9997k
nn9999k
nn9999o
#Most Likely your output would be different
#must you should see at least one project
[MY_USER_NAME@login-4 ~]$ projects
ec01
ec11
ec12
ec34
Warning
You need a replace the <PROJECT_NAME>
in the following command
with one of the outputs you get from the projects
command above
Discussion
Do you have any examples of automation that you can relate to the scheduler ?
[MY_USER_NAME@CLUSTER_NAME ~]$ sbatch --account=<PROJECT_NAME> --qos=preproc --mem=1G --time=01:00 example-job.sh
Submitted batch job 137860
And that’s all we need to do to submit a job. Our work is done – now the scheduler takes over and
tries to run the job for us. While the job is waiting to run, it goes into a list of jobs called
the queue. To check on our job’s status, we check the queue using the command
squeue -u $USER
.
[MY_USER_NAME@CLUSTER_NAME ~]$ squeue -u $USER
JOBID PARTITION NAME USER ST TIME NODES NODELIST(REASON)
137860 normal example- usernm R 0:02 1 c5-59
The best way to check our job’s status is with squeue
. Of course, running
squeue
repeatedly to check on things can be a little tiresome. To see a real-time
view of our jobs, we can use the --iterate argument
command with how frequent
should the output be refreshed.
Warning
Press
Ctrl-C
when you want to stop the command.This test job may end before first iteration starts, if that happens we will see the output in a later job that takes more time
[MY_USER_NAME@CLUSTER_NAME ~]$ sbatch --account=<PROJECT_NAME> --mem=1G --time=01:00 example-job.sh
[MY_USER_NAME@CLUSTER_NAME ~]$ squeue -u $USER --iterate 5
Where’s the output?
On the login node, this script printed output to the terminal – but when we exit watch
,
there’s nothing. Where did it go?
Cluster job output is typically redirected to a file in the directory you launched it from.
Use ls
to find and read the file.
Move arguments to the job script
[MY_USER_NAME@CLUSTER_NAME ~]$ cat example-job.sh
#!/bin/bash
#SBATCH --nodes=1
#SBATCH --time=00:01:00
#SBATCH --account=<PROJECT_NAME>
#SBATCH --qos=preproc
#SBATCH --mem=1G
echo -n "This script is running on "
hostname
Using software modules in scripts
Here we create a job script that loads a particular version of Python, and prints the version number to the Slurm output file.
[MY_USER_NAME@CLUSTER_NAME ~ ]$ nano python-module.sh
[MY_USER_NAME@CLUSTER_NAME ~ ]$ cat python-module.sh
#!/bin/bash
#SBATCH --nodes=1
#SBATCH --time=00:01:00
#SBATCH --account=<PROJECT_NAME>
#SBATCH --mem=1G
#SBATCH --job-name=Python_module_test
module purge
module load Python/3.9.6-GCCcore-11.2.0
python --version
[MY_USER_NAME@CLUSTER_NAME ~ ]$ sbatch python-module.sh
For full reproducibility it is always good practice to start your job script by purging any existing modules which you might have loaded when you submit the job script. You can then explicitly load all the dependencies for the current job, which makes it much more robust for future execution.