How a job becomes an sbatch submission¶
Start turns a model.StartRequest into one script, runs it on the Slurm host, and checks the job
it created by reading it back. This page lists what goes into the script. The golden scripts in
testdata/golden in the repository are the exact text, and the adapter's tests compare against
them.
The script¶
Start sends one script of three steps, in this order. Each step stops the script if it fails.
mkdir -pthe job's output directories.- Write the output manifest, a file naming where this submission's output goes.
- Run
sbatch, with the batch script in a quoted here-document.
The whole script may be at most 90 KiB.
The sbatch options¶
| Option | When | From |
|---|---|---|
--parsable |
always | |
--hold |
always | the gate: the job cannot run until Open |
--no-requeue |
always | Slurm never restarts the job by itself |
--job-name=dj-<ULID> |
always | the job's identity |
--comment=dispatch:s=<N>;a=<attempt> |
always | the submission and attempt numbers |
--export=NIL |
always | the job inherits nothing from the submitting environment |
--chdir=<dir> |
always | JobSpec.WorkDir, which must be absolute; otherwise the cluster home |
--nodes=<n> |
always | JobSpec.Nodes |
--gpus-per-node=[<type>:]<n> |
GPUsPerNode above 0 |
JobSpec.GPUsPerNode, with Resources.GPUType |
--ntasks-per-node=<n> |
ProcsPerNode above 0 |
JobSpec.ProcsPerNode |
--time=<minutes> |
TimeLimit above 0 |
JobSpec.TimeLimit, rounded up to whole minutes |
--partition, --account, --qos, --reservation, --constraint |
when set | Placement over defaults |
--cpus-per-task=<n> |
CPUsPerTask above 0 |
Resources |
--mem=<n> |
MemPerNodeMiB above 0 |
Resources |
--exclusive |
Exclusive is true |
Resources |
--dependency=singleton |
singleton is true |
configuration |
--output=<dir>/<ULID>/s<N>-%j.slurm |
always | Slurm's own messages about the job. <dir> is output.dir resolved |
--open-mode=append |
always | a requeued execution appends |
JobSpec.Name and JobSpec.Checkpoint do not reach sbatch.
All values are shell-quoted. Placement and defaults merge field by field: each field Placement
sets replaces the same field of defaults.
The batch script¶
sbatch stores a script and runs it on the first allocated node. It is a POSIX sh script that:
- sets
DISPATCH_JOB_IDandDISPATCH_SUBMISSION; - reads
SLURM_RESTART_COUNTasR(0 if unset) and exits with an error ifRis 1,000,000 or more; - sets
DISPATCH_ATTEMPTandDISPATCH_EPOCH, and exports all four, with the values below; - redirects the shell's stdout and stderr, by
exec, to this execution's files (below); - exports each
environment.passvariable, with the value it had on the host atStart; - exports
SLURM_EXPORT_ENV=ALL, so steps launched bysruninherit the environment; - exports each variable of
JobSpec.Env, sorted by name; execs the command, each argument quoted.
The variables the job sees, for job <ULID>, generation G, submission N and restart count R:
| Variable | Value |
|---|---|
DISPATCH_JOB_ID |
the ULID, without the dj- |
DISPATCH_SUBMISSION |
N |
DISPATCH_ATTEMPT |
<N>.<Slurm job id>.<R> |
DISPATCH_EPOCH |
G × 10^12 + N × 10^6 + R, written out as decimal text |
What they mean to a job is in the execution environment.
The command runs once, on the batch host, as sbatch runs it. It is never wrapped in srun;
launching ranks (srun, torchrun) is the command's job.
Under --export=NIL the batch environment has no PATH and no HOME. The script exports the
environment.pass variables first (PATH by default), so a job that needs HOME must list it
there.
Every value is a literal in the script, and slurmctld stores the script. An administrator can
read it, and accounting keeps it where the cluster records job scripts. Keep secrets out of
JobSpec.Env and environment.pass.
JobSpec.Env names and environment.pass names must be shell identifiers, and neither may start
DISPATCH_. JobSpec.Validate refuses such an Env key, so Start returns ErrInvalid; the
adapter refuses such a pass name when it decodes the configuration.
Output files¶
For job <ULID> and submission <N>, with output.dir resolved:
| File | Holds |
|---|---|
<dir>/<ULID>/s<N>.manifest |
two lines, one per stream: the file name prefix and suffix, separated by a tab |
<dir>/<ULID>/s<N>-<job id>-r<R>.out |
the command's stdout for the execution with that Slurm job id and restart count |
<dir>/<ULID>/s<N>-<job id>-r<R>.err |
its stderr |
<dir>/<ULID>/s<N>-<job id>.slurm |
Slurm's own --output for the job |
Output reads a stream by listing the files under its manifest prefix and suffix, in restart
order, numerically, so r10 follows r9. With follow it polls every two seconds for new bytes
and for a new execution's file.
A job that carries model.Output writes elsewhere. Its stdout path P becomes
P.s<N>-<job id>-r<R>, with no suffix, and the same for stderr. Both must be absolute and free of
newlines and tabs, and the directories are created.
Extensions¶
A JobSpec carries extensions by namespace and name. The adapter registers two in the slurm
namespace:
slurm.Placement chooses where the job runs. Each non-empty field overrides the same
defaults key for this job.
| Field | JSON |
|---|---|
Partition |
partition |
Account |
account |
QOS |
qos |
Reservation |
reservation |
Constraint |
constraint |
slurm.Resources asks for what JobSpec has no field for.
| Field | JSON | Type | Becomes |
|---|---|---|---|
GPUType |
gpuType |
string | the type in --gpus-per-node. May not contain : or , |
CPUsPerTask |
cpusPerTask |
int | --cpus-per-task. Not negative |
MemPerNodeMiB |
memPerNodeMiB |
int | --mem. Not negative |
Exclusive |
exclusive |
bool | --exclusive |
Of go/dispatch's own extensions, model.Output is mapped as above and model.SharedCheckpoint is
accepted and needs nothing from Slurm. model.Image is refused with ErrUnsupported, as is any
extension from another namespace.
What is refused before anything runs¶
An invalid job id, a spec that fails JobSpec.Validate, a negative attempt, a submission outside
1 to 999,999, a relative WorkDir, an output.dir containing %, \, a newline or a tab, an
unusable extension, or a script over 90 KiB is refused with ErrInvalid or ErrUnsupported, and
no command runs. See Errors and error mapping.