Workflows/Serial

From HPCwiki
Jump to navigation Jump to search

Every other page in this section describes a way of splitting work across many cores. This one describes not doing that — one program, running on a single core, from start to finish. It is the baseline, and, to be honest up front, it is not a parallel workflow at all.

It earns a page anyway, for two reasons. Most software you did not specifically choose for its parallelism runs this way, so this is where many jobs on Anunna may actually belong. And every other workflow in this section is best understood as a small change to the serial job script — so it is worth seeing the starting point clearly before you start changing lines in it.

When this is you

You are almost certainly looking at a serial workflow if any of these are true:

  • The program's manual never mentions threads, cores, ranks, MPI, or a GPU.
  • It has no flag like --threads, -p, or -n for handing it more cores.
  • You run it on your laptop today, and it uses one core there too.

That covers a lot of ground: most command-line bioinformatics tools, most R and Python scripts you did not deliberately parallelise, most one-off analyses. If you are not sure, assume serial — it is the safe default, and climbing the ladder later is easy once the baseline works.

What it looks like on Anunna

You never run the analysis directly on the login node — that machine is shared by everyone and is meant for editing, submitting, and light housekeeping only. Instead you describe the job in a short script and hand it to Slurm with sbatch; Slurm finds a compute node and runs it there.

A minimal serial job script looks like this:

#!/bin/bash
#SBATCH --job-name=my_analysis
#SBATCH --ntasks=1            # one process
#SBATCH --cpus-per-task=1     # one core for that process
#SBATCH --mem=4G              # memory, sized to your data
#SBATCH --time=01:00:00       # wall-clock limit; the job is killed past this
#SBATCH --output=%x-%j.out    # stdout + stderr, named by job name and id

cd "$myScratch/my_analysis"

module load 2024 Python/3.12.3     # replace with your actual module
python myScript.py --input data.csv --output results.csv

Save it as run.slurm and submit:

sbatch run.slurm

Two things to notice, because the other pages in this section keep coming back to them:

  • Work lives under your lustre directories, e.g. $myScratch, not in your home directory. Lustre is the fast, roomy filesystem built for job data; home is small and is not meant to handle computations.
  • The two lines that decide how much compute the job gets are --ntasks and --cpus-per-task, and here they are both 1. Every other workflow in this section is essentially this same script with one of those two numbers raised — plus a matching change telling the program to actually use what it was given.

Why asking for more cores does nothing

It is tempting to bump --cpus-per-task to 8 and hope for an eightfold speedup. For a serial program it buys you nothing.

A serial program is a single stream of instructions with nowhere to put a second core. Slurm will dutifully reserve all eight if you ask, but seven of them sit idle with your name on them for the entire run. You also wait longer in the queue for eight free cores than for one, and if the cluster does fairshare accounting you may be charged for the idle seven regardless. The job does not finish a moment sooner. The only thing that makes a serial program use more than one core is rewriting it to be parallel — which is what the rest of this section is about.

The one resource worth sizing on a serial job is --mem: give it enough memory for your data, and no more.

The honest limitation

Serial is not a parallel workflow, and no Slurm flag changes that. Its ceiling is one core's worth of speed, full stop.

That is not a problem until it is — until the run takes four days, or the dataset no longer fits in memory. When you hit that wall, the script above is your launch pad, and the only question is which line to change:

  • Same program, many independent inputs — a parameter sweep, two hundred samples? You want Embarrassingly Parallel: the job array, and often no change to the program at all.
  • The program itself offers a --threads option? That is Multi-Threaded — raise --cpus-per-task and point the tool at it.
  • The program is built on MPI? That is Multi-Process — raise --ntasks and launch with mpirun.

If you would rather see all of these run side by side on one small problem — with this serial job as the reference everything else is measured against — work through Parallelism: Estimating π. Its serial rung plays exactly this role, and the discussion shows what climbing the ladder does and does not buy you.

See also