Skip to content

Monitoring & Accounting

Exercises

  1. Generate a cluster utilization report

Use sreport to produce an overall cluster utilization report for the current month. Identify the percentage of CPU time that was allocated vs. idle.

Hint / Solution
# Overall cluster utilization
sreport cluster utilization start=2026-04-01

# Output shows columns: Allocated, Down, PLND Down (planned), Idle, Reserved, Reported
# Allocated / Reported = utilization percentage

# Break down by partition
sreport cluster utilization start=2026-04-01 -t percent
Expected output: Validated 2026-10-19 on slurm-training-val (Slurm 25.11.8, ParallelCluster 3.16.1).
$ sreport cluster utilization start=now-7days
--------------------------------------------------------------------------------
Cluster Utilization 2026-10-12T01:00:00 - 2026-10-19T00:59:59
Usage reported in CPU Minutes
--------------------------------------------------------------------------------
  Cluster Allocate     Down PLND Dow     Idle  Planned Reported 
--------- -------- -------- -------- -------- -------- -------- 
slurm-tr+       14        0   282356   201437       34   483840 
  1. Find the top 5 users by CPU hours

Generate a report showing the five heaviest CPU consumers this month. Include both their CPU hours and the account they charged to.

Hint / Solution
sreport user TopUsage start=2026-04-01 --tres=cpu TopCount=5

# For GPU hours instead:
sreport user TopUsage start=2026-04-01 --tres=gres/gpu TopCount=5

# For a specific account's users only:
sreport user TopUsage start=2026-04-01 --tres=cpu TopCount=5 Accounts=smith_lab
Expected output: Validated 2026-10-19 on slurm-training-val (Slurm 25.11.8, ParallelCluster 3.16.1).
$ sreport user TopUsage start=now-7days --tres=cpu TopCount=5
--------------------------------------------------------------------------------
Top 5 Users 2026-10-12T01:00:00 - 2026-10-19T00:59:59 (604800 secs)
Usage reported in TRES Minutes
--------------------------------------------------------------------------------
  Cluster     Login     Proper Name         Account      TRES Name     Used 
--------- --------- --------------- --------------- -------------- -------- 
slurm-tr+  ec2-user AWS ParallelCl+       pcdefault            cpu       13 
slurm-tr+ testuser1                        research            cpu        0 
  1. Check scheduler health with sdiag

Run sdiag and assess the scheduler's performance. Determine the mean scheduling cycle time, how many jobs have been backfilled, and whether the agent queue is healthy.

Hint / Solution
sdiag

# Key things to check:
# 1. "Mean cycle" under "Main schedule statistics" -- should be well under 1,000,000 us (1 second)
# 2. "Total backfilled jobs" -- a healthy number indicates backfill is working
# 3. "Agent queue size" -- should be 0 or near 0; high values mean communication delays
# 4. "Last cycle" timestamp -- should be very recent

# Reset stats to track from a known point:
sdiag --reset
Expected output: Validated 2026-10-19 on slurm-training-val (Slurm 25.11.8, ParallelCluster 3.16.1).
$ sdiag
*******************************************************
sdiag output at Mon Oct 19 01:05:33 2026 (1792371933)
Data since      Mon Oct 19 01:05:29 2026 (1792371929)
*******************************************************
Server thread count:  1
RPC queue enabled:    0
Agent queue size:     0
Agent count:          0
Agent thread count:   0
DBD Agent queue size: 0

Jobs submitted: 0
Jobs started:   0
Jobs completed: 0
Jobs canceled:  0
Jobs failed:    0

Job states ts:  Mon Oct 19 01:05:29 2026 (1792371929)
Jobs pending:   0
Jobs running:   0

Main schedule statistics (microseconds):
 Last cycle:   17
 Max cycle:    17
 Total cycles: 1
 Mean cycle:   17
 Mean depth cycle:  0
 Last queue length: 0

Main scheduler exit:
 End of job queue: 1
 Hit default_queue_depth: 0
 Hit sched_max_job_start: 0
 Blocked on licenses: 0
 Hit max_rpc_cnt: 0
 Timeout (max_sched_time): 0

Backfilling stats
 Total backfilled jobs (since last slurm start): 0
 Total backfilled jobs (since last stats cycle start): 0
 Total backfilled heterogeneous job components: 0
 Total cycles: 0
 Last cycle when: Mon Oct 19 00:51:48 2026 (1792371108)
 Last cycle: 0
 Max cycle:  0
 Last depth cycle: 0
 Last depth cycle (try sched): 0
 Last queue length: 0
 Last table size: 0

Backfill exit
 End of job queue: 0
 Hit bf_max_job_start: 0
 Hit bf_max_job_test: 0
 System state changed: 0
 Hit table size limit (bf_node_space_size): 0
 Timeout (bf_max_time): 0

Latency for 1000 calls to gettimeofday(): 27 microseconds

Remote Procedure Call statistics by message type
 REQUEST_PARTITION_INFO                  ( 2009) count:6      ave_time:58     total_time:352
 REQUEST_NODE_INFO                       ( 2007) count:6      ave_time:158    total_time:949
 REQUEST_UPDATE_NODE                     ( 3002) count:5      ave_time:147    total_time:738
 REQUEST_PING                            ( 1008) count:3      ave_time:60     total_time:182
 REQUEST_BUILD_INFO                      ( 2001) count:2      ave_time:151    total_time:303

Remote Procedure Call statistics by user
 ec2-user        (    1000) count:17     ave_time:105    total_time:1786
 root            (       0) count:5      ave_time:147    total_time:738

Pending RPC statistics
 No pending RPCs
  1. Find jobs that exceeded their memory request

Use sacct to find completed jobs from the past 7 days where the actual peak memory usage (MaxRSS) was close to or exceeded the requested memory. Identify jobs that were killed by OOM.

Hint / Solution
# Find jobs killed by OOM directly
sacct --starttime=now-7days --state=OUT_OF_MEMORY \
    --format=JobID,User,JobName,ReqMem,MaxRSS,Elapsed,State,ExitCode

# Find completed jobs where MaxRSS was high relative to request
# (look for jobs where MaxRSS approaches ReqMem)
sacct --starttime=now-7days --state=COMPLETED \
    --format=JobID%-12,User%-10,JobName%-20,ReqMem,MaxRSS,Elapsed \
    | sort -k5 -h | tail -20

# Find jobs killed by signal 9 (SIGKILL -- often OOM even if not tagged)
sacct --starttime=now-7days \
    --format=JobID,User,JobName,State,ExitCode | grep "0:9"
Expected output: Validated 2026-10-19 on slurm-training-val (Slurm 25.11.8, ParallelCluster 3.16.1).
$ sacct --starttime=now-7days --state=OUT_OF_MEMORY --format=JobID,User,JobName,ReqMem,MaxRSS,Elapsed,State,ExitCode
JobID             User    JobName     ReqMem     MaxRSS    Elapsed      State ExitCode 
------------ --------- ---------- ---------- ---------- ---------- ---------- -------- 

$ sacct --starttime=now-7days --state=COMPLETED --format=JobID%-12,User%-10,JobName%-20,ReqMem,MaxRSS,Elapsed | head -10
JobID        User       JobName                  ReqMem     MaxRSS    Elapsed 
------------ ---------- -------------------- ---------- ---------- ---------- 
  1. Force a log rotation and prove the new file grows

Use the SIGUSR2 postrotate from the Log Rotation section. Force one rotation, then show that the daemon writes to the new slurmctld.log and that no deleted log is still held open. Needs root on the controller (a harness runs this only when root: skip_unless_root).

Hint / Solution
sudo ls -la /var/log/slurm/slurmctld.log*          # note size/inode of the live file
sudo logrotate -f /etc/logrotate.d/slurm           # force one rotation
scontrol ping >/dev/null; sbatch --wrap="true"     # generate log traffic
sudo ls -li /var/log/slurm/slurmctld.log*          # new log: new inode, size growing; .1 is not
sleep 5; sudo ls -la /var/log/slurm/slurmctld.log* # run twice: only the new file should grow
sudo lsof +L1 | grep slurm                         # expect no output (no deleted-but-open logs)
If `slurmctld.log.1` keeps growing or `lsof +L1` lists a slurm log, the `postrotate` is not sending `SIGUSR2` to that daemon.
  1. Compare accounting's running jobs with the controller's

Count the jobs slurmdbd believes are running and the jobs slurmctld has running. Decide whether the difference is a runaway-job problem.

Hint / Solution
sacct -a -X -n -P -s RUNNING -S 2000-01-01 -o JobIDRaw,Start,State | wc -l   # database view
squeue -h -t R | wc -l                                                      # controller view

# Which IDs does the database hold that the controller does not?
comm -23 <(sacct -a -X -n -P -s RUNNING -S 2000-01-01 -o JobIDRaw | sort) \
         <(squeue -h -t R -o %i | sort)
Equal counts (allow a one-second race) mean no runaways. Any ID listed by `comm` is a runaway candidate; the fix (`sacctmgr show runawayjobs`, after a database snapshot) is an admin action -- do not run it in this exercise. Expected output: Validated 2026-10-19 on slurm-training-val (Slurm 25.11.8, ParallelCluster 3.16.1).
$ sacct -a -X -n -P -s RUNNING -S 2000-01-01 -o JobIDRaw,Start,State | wc -l
0

$ squeue -h -t R | wc -l
0

$ comm -23 <(sacct -a -X -n -P -s RUNNING -S 2000-01-01 -o JobIDRaw | sort) <(squeue -h -t R -o %i | sort)
  1. Trace one job's lifecycle in slurmctld.log

Submit a short job and follow its JobId through slurmctld.log from submission to completion. Name the start-line shape you find (main scheduler or backfill) and whether it carries a CPU count.

Hint / Solution
LOG=$(scontrol show config | awk '/SlurmctldLogFile/ {print $3}')
JOB=$(sbatch --parsable --wrap="sleep 5")
sleep 15
grep -E "JobId=${JOB}( |\$)|JobId=${JOB}_" "$LOG"

# Shapes to look for (sample real lines first; they vary by version):
#   sched: Allocate JobId=<id> NodeList=... #CPUs=N       <- main scheduler, has CPU count
#   sched/backfill: _start_job: Started JobId=<id> in ... <- backfill, NO CPU count
#   _job_complete: JobId=<id> WEXITSTATUS 0
#   _job_complete: JobId=<id> done
The log must be readable by your user and `SlurmctldDebug` at `info` or higher; otherwise run as root. Expected output: Validated 2026-10-19 on slurm-training-val (Slurm 25.11.8, ParallelCluster 3.16.1).
$ sudo grep -E 'JobId=42( |$)|JobId=42_' /var/log/slurmctld.log
[2026-10-19T01:05:34.308] _slurm_rpc_submit_batch_job: JobId=42 SLUID=sBHSM58V2H3400 InitPrio=3500 usec=490
[2026-10-19T01:05:35.007] sched: Allocate JobId=42 NodeList=batch-dy-compute-1 #CPUs=1 Partition=batch
[2026-10-19T01:06:01.027] POWER: no more nodes to resume for job JobId=42
[2026-10-19T01:08:29.007] job_time_limit: Configuration for JobId=42 complete
[2026-10-19T01:08:29.007] Resetting JobId=42 start time for node power up
[2026-10-19T01:08:34.358] _job_complete: JobId=42 WEXITSTATUS 0
[2026-10-19T01:08:34.358] _job_complete: JobId=42 done

References