Skip to content

How Slurm states become observations

Find, FindMany and Inspect turn each Slurm job into a dispatch.ObjectObs: an object state, a cause with a kind, a provenance and a detail, and the facts around them. This page is the table the adapter applies. The state and cause names are go/dispatch's text forms, such as gated and node-lost.

A job is read from squeue or scontrol show job JSON while Slurm still holds it. Inspect reads it from sacct instead once it has left squeue, when AccountingHistory is yes; see From sacct.

Pending jobs

A job whose base state is PENDING is classified by its reason, state_reason, and its restart count, restart_cnt. The first row that matches applies.

Reason Restart count State Cause Provenance Detail
JobHeldAdmin any gated, with AdminHeld set none none
JobHeldUser 0 gated none none
JobHeldUser above 0 pending requeued scheduler JobHeldUser
BeginTime or None, with a start time that decodes as a hold 0 held none none
BeginTime or None, with a start time that decodes as a hold above 0 held requeued scheduler
BeginTime or None, with a start time at or past the hold base that does not decode 0 pending none none start time <epoch seconds> is past the hold base but no dispatch hold
BeginTime or None, as the row above above 0 pending requeued scheduler the same
anything else 0 pending none none
anything else above 0 pending requeued scheduler

JobHeldUser with no restart is the gate that sbatch --hold closes. After a requeue Slurm holds the job with the same reason, which is why the restart count tells the two apart.

A start time decodes as a hold when start − submit − 315,576,000 seconds is between 1 and 4,294,967,295; Holds as a far-future start time explains the encoding. The reason None counts with BeginTime because Slurm reports None for about two seconds after the gate is opened, until its next scheduling pass.

HoldInstance is filled from the start time for every pending job, whatever its reason, so a gated job that carries a hold shows both.

Running jobs

Base state State Cause
RUNNING running none
SUSPENDED running none

Ended jobs

These rows apply to squeue and to sacct alike.

Base state Condition State Cause Provenance Detail
COMPLETED ended none none
FAILED the flag LAUNCH_FAILED, or the reason JobLaunchFailure ended launch-failed scheduler
FAILED otherwise ended non-zero-exit application signal <number> <name> when a signal is set, such as signal 15 TERM; from sacct, signal <number>
TIMEOUT ended time-limit scheduler
OUT_OF_MEMORY ended out-of-memory application
CANCELLED ended cancelled scheduler from squeue, the reason, such as None; from sacct, what follows the state, such as by 1000
PREEMPTED preempt_time is set and not 0 ended preempted scheduler
PREEMPTED preempt_time is unset or 0 ended unknown none PREEMPTED without preempt_time
NODE_FAIL failed_node is set ended node-lost scheduler failed_node <node>
NODE_FAIL failed_node is empty ended unknown none NODE_FAIL without failed_node
BOOT_FAIL ended launch-failed scheduler
DEADLINE ended unknown none DEADLINE: dispatch never sets --deadline

A non-zero-exit cause carries the job's return code as ExitCode when Slurm set one. No other cause carries an exit code.

The adapter never reports the causes no-capacity, held, released or duplicate.

Unknown states and flags

Slurm prints job_state as a list: one base state and any flags. The adapter knows the twelve base states above and the flags of Slurm's data_parser/v0.0.44.

What the list holds State Cause Detail
no known base state, such as a new state FROZEN ended if the job's end time is set and not after now, otherwise running unknown the whole list, comma separated
the flag REVOKED, with or without a base state ended with no base state; otherwise as the base state says unknown the whole list, such as CANCELLED,REVOKED or PENDING,REVOKED
a flag other than COMPLETING, CONFIGURING, LAUNCH_FAILED and REVOKED as the rows above say as the rows above say flags <list> appended, after ; if there is already a detail

COMPLETING and CONFIGURING change nothing: a CANCELLED,COMPLETING job is ended with cause cancelled. LAUNCH_FAILED matters only under FAILED.

An end time still ahead says nothing, because for a live job it is only Slurm's expected end.

A node list in a form the adapter does not recognise makes the call fail with an error that has no sentinel. It is never classified without its nodes.

From sacct

Inspect reads a job from sacct only when the job id is no longer in squeue and AccountingHistory is yes. It uses the ended rows, with these differences:

  • sacct has no preempt_time, so a PREEMPTED row is always preempted.
  • The launch-failure test reads only the reason JobLaunchFailure; sacct prints no flags.
  • A non-zero-exit cause always carries ExitCode, from the return code in sacct's ExitCode field, 0 included.
  • A state with no row in the table is ended, cause unknown, with the state and what follows it as the detail. The row is gone from slurmctld, so the job has ended; what it ended as is not known.
  • A row that is still PENDING, RUNNING, SUSPENDED, REQUEUED or RESIZING is refused with an error that has no sentinel. sacct cannot tell gated, held and pending apart, so the adapter does not guess.

A sacct observation carries no restart count, no execution token, no hold instance and no requeue bit.

Foreign objects, submission and attempt

The adapter reads dispatch:s=<N>;a=<attempt> from the job's comment, with canonical decimals.

Comment From squeue From sacct
parses Submission and Attempt set the same
does not parse Foreign Foreign
empty Foreign neither: submission and attempt unknown, because accounting keeps the comment only with AccountingStoreFlags=job_comment

A foreign object is still reported, with its state and cause. Only objects named dj-<ULID> are found at all; see How identity works.

The other facts

Field From squeue
Execution.Restart restart_cnt
Execution.Nodes nodes, expanded
Execution.Token <N>.<Slurm job id>.<restart count>, the job's DISPATCH_ATTEMPT, when the comment parses
Execution.Started start_time, only when the state is running or ended
Execution.Ended end_time, only when the state is ended
RequeueBit requeue
HoldInstance decoded from the start time of a pending job; otherwise 0
AdminHeld set only for the reason JobHeldAdmin