Configuration reference - KasperSkytte/slurmjobpacker GitHub Wiki

Configuration reference

/etc/sjp/sjp.toml (or -c FILE, $SJP_CONFIG). Unset keys take the defaults below; python3 -m sjp.daemon --print-config prints them all. Restart sjpd after changes. Partitions, nodes, PriorityTier and QOS caps come from Slurm.

[general]

setting default
mode "observe" How far sjp may go. observe: log what it would do, change nothing. advise: also write the placement table, so sjp.place() sets partitions (no node pins). enforce: also pin nodes, release unstarted pins, recheck and widen pending jobs, and act on QOS limits
state_dir "/run/sjp" Where sjpd writes policy.lua (read by the plugin) and status.json
log_file "/var/log/sjp/decisions.jsonl" Every decision and action, one JSON object per line; read with python3 -m sjp.report
text_log "/var/log/sjp/sjp.log" The same, one readable line each; "" = off
disable_file "/etc/sjp/disable" While this file exists, sjp.place() returns false for every job and sjpd changes nothing (except releasing its pins)

[cadence]

setting default
score_interval 1.0 Seconds between placement table updates
node_poll_interval 1.0 Seconds between scontrol show nodes reads
queue_poll_interval 8.0 Seconds between squeue reads; it takes a job table lock, so keep it slow. Pin releases, rechecks and widening run after each read
act_interval 15.0 Seconds between QOS limit checks ([limits]) and status.json updates
policy_max_age 300.0 Seconds; the plugin ignores an older table ("stale"), so if sjpd stops, your own rules take over

[topology]

setting default
batch_partitions [] Partitions sjp may assign; empty = all from scontrol show partitions
exclude_partitions [] Partitions never assigned, by name
exclude_interactive true Never assign a partition named interactive
exclude_gpu_nodes true Ignore nodes with a GPU; partitions left without nodes are dropped

[policy]

setting default
demand six [MB per CPU, weight] pairs The memory per CPU jobs typically ask for, with weights. Free space counts as far as these jobs could use it (phi). Fit yours with python3 -m sjp.fit --since <date>
demand_median 4267 MB/CPU; only for the stranded-CPU figure in the log
tolerance 0.25 Besides the best partition, also allow those within this many CPUs of phi per job CPU
user_nodes "follow" A job's own --nodelist/--exclude: follow places it among those nodes, in partitions holding them; ignore drops them and places the job like any other (for sites where users ask for hardware by features only)
always_place false Place jobs even when no node has room now, in the partitions their shape fits best on an empty cluster; otherwise sjp.place() returns "no room" and your rules apply. The recheck moves them once room opens
buckets.mem_per_cpu [1024, 2048, 4096, 6144, 8192, 12288, 24576] MB/CPU bucket edges of the table
buckets.cpus [1, 4, 8, 16, 32, 64, 128] CPU bucket edges
buckets.walltime_h [1, 6, 24, 72] Time limit bucket edges, hours

See Decision making.

[pin]

setting default
enabled true Choose the node too (--nodelist) when a job can start at once; enforce only
min_gain 1.0 Nodes within this many CPUs of phi of the best count as equally good; among them, the closest memory per CPU wins
min_ratio_gain 0.1 Pin only if the chosen node beats the worst candidate by min_gain or by this much in |log ratio| (0.1 ≈ 10%); otherwise Slurm picks the node
release_after 60.0 Seconds a pinned job may stay pending before sjpd removes the pin and restores its partitions
max_age 10.0 Seconds; the plugin places and pins only from free-space data this fresh
wait_for_room false With always_place and [recheck]: also pin those jobs to the node expected to have room first (from the time limits of the jobs running and waiting there). The recheck moves the pin; it is released only past the job's [starvation] budget. enforce only
time_aware false Also weigh time limits: prefer nodes whose running jobs end around when the job would, so long jobs gather and nodes running short jobs empty together. Uses time limits, not real run times

[starvation]

setting default
enabled true Widen jobs sjp placed that pend too long to every partition that can hold them; once per job, enforce only
budget_hours {fat = 1.0, slim = 4.0} Hours pending for Resources/Priority (since eligible) before widening
fat_ratio_threshold 6000 MB/CPU at which a job counts as fat

[recheck]

setting default
interval 60 Seconds between rechecks of sjp's pending jobs (and those it skipped for want of room): each is placed again against the cluster as it is now, and moved if the choice changed and a node there has room; with wait_for_room, re-pinned to the node now expected to have room first. enforce only; 0 = off

[limits]

See QOS limits and flex.

setting default
mode "off" Jobs held only by a QOS CPU cap that would fit on idle nodes. off: nothing. global: raise the QOS's caps for everyone, briefly. flex: move those jobs to flex_qos_name
state_file "/var/lib/sjp/limits.json" global: the base caps during a pulse, restored if sjpd stops mid-pulse
ceiling 2.0 global: raised caps as a multiple of base
min_idle_share 0.25 Act only while at least this share of the cluster's phi is idle (was raise_above, still accepted)
count_pending false Count the CPUs of jobs waiting for room (Resources, Priority) as taken when working out the idle share: they get the idle capacity first. Not jobs the caps hold, or that cannot start yet
lower_below 0.10 global: end a pulse early when the idle share falls below this
hysteresis 5 global: consecutive checks that must meet the conditions before a pulse
pulse_seconds 60.0 global: how long the caps stay raised
cooldown_seconds 300.0 global: minimum time at base between pulses. flex: minimum time between moves of one job
flex_qos_name "flex" flex: the QOS held jobs move to; create it and allow it for users first
flex_revert_after 60.0 flex: seconds a moved job may stay pending before it moves back

Command line

python3 -m sjp.daemon [-c FILE] [--mode MODE] [--dry-run] [--state-dir DIR]
                      [--log-file FILE] [--text-log FILE] [--once] [--print-config]

--dry-run forces observe. --state-dir also moves the logs unless --log-file/ --text-log are given. --once: one pass to stdout.

⚠️ **GitHub.com Fallback** ⚠️