Python and OpenMP on a node
Last updated on 2026-10-27 | Edit this page
Overview
Questions
- What sum does
python.shprint, and which modules does the script load? - Why does every line of
pi.shreport the samepi, with a different thread count? - What do you pass to
sbatchon a two-core node, without editing the script?
Objectives
- Submit the published Python script and check the sum
499999500000. - Build the OpenMP pi program and read
pi = 3.141592654for each thread count the allocation allows. - Leave
#SBATCH --partition=romein the published scripts, and override the core count on thesbatchcommand when the node is small.
Two published scripts
The files are in episodes/files/hands-on/. They are the
batch examples from the fundamentals deck. Run them from that directory.
Both scripts set #SBATCH --partition=rome. Leave that line.
The site tab says what to do on the machine in your welcome note.
A Python sum
python.sh asks for one node, one task, and two minutes.
It loads the 2025 stack and Python/3.13.1-GCCcore-14.2.0,
then runs:
BASH
srun python3 -c 'import platform; print("Python on", platform.node()); print("sum:", sum(range(1000000)))'
sum(range(1000000)) is the sum of 0 through 999999. That
sum is 499999500000. The node name on the first line is
whatever node Slurm gave the job.
The version string in this script is
Python/3.13.1-GCCcore-14.2.0. The modules episode loads
Python/3.13.5-GCCcore-14.3.0 from the current stack. They
are different lines. Use the line that is in the file you submit.
What is the sum?
Without running the job, what does sum(range(1000000))
print? After the job finishes, where do you read that number?
499999500000.
The formula for the sum of 0 .. n-1 is
n*(n-1)/2. With n = 1000000 that is
1000000*999999/2 = 499999500000.
Slurm writes the script’s stdout to
slurm-<jobid>.out in the directory where you ran
sbatch. The line starts with sum:.
OpenMP pi
pi.c integrates 4/(1+x^2) from 0 to 1 with
the midpoint rule, 100000000 steps. The loop is
#pragma omp parallel for reduction(+:sum). Each rank of the
loop adds into a private sum, and OpenMP adds those into one
sum at the end. The print is:
pi = 3.141592654; threads = N; elapsed = ... s
%.9f is why you see nine digits. Every thread count
should print pi = 3.141592654. The elapsed time is the
thing that changes, and a short loop can spend a visible fraction of
that time just starting the threads.
compilepi loads module load 2025 and
module load GCC/14.2.0, then:
pi is that binary. It is not a module.
pi.sh asks for one node, one task, 32 CPUs, and ten
minutes, on rome. It loads the same GCC module and
loops:
BASH
for ncores in 1 2 4 8 16 32; do
if (( ncores <= SLURM_CPUS_PER_TASK ))
then
export OMP_NUM_THREADS=$ncores
srun --cpu-bind=cores ./pi
fi
done
A thread count above SLURM_CPUS_PER_TASK is skipped. On
the published 32-CPU request you get six lines. Compare each elapsed
time with the one-thread line. Speedup for this short integral is often
poor: the loop is not long enough to hide the cost of starting more
threads.
A two-core node
The published scripts stay as they are, including
--cpus-per-task=32 and --partition=rome. On a
small node you pass the smaller request on the sbatch
command. That overrides the line in the file.
On the course cluster the pi override is:
Check sinfo before you quote a core count in the
room.
How many lines?
pi.sh loops over 1, 2, 4, 8, 16, and 32 threads, and
skips a count that is larger than SLURM_CPUS_PER_TASK.
- How many
pi =lines do you get fromsbatch pi.shon a node that honours--cpus-per-task=32? - How many do you get from
sbatch --cpus-per-task=2 pi.sh? - Which digits of pi should differ between those lines?
- Six lines: 1, 2, 4, 8, 16, and 32.
- Two lines: 1 and 2. The test
ncores <= SLURM_CPUS_PER_TASKdrops 4, 8, 16, and 32. - None. Each line should report
pi = 3.141592654. Threads and elapsed time change. The integral does not.