amd-agi/primus/spur-cluster-status
Claude Code and agent skill by amd-agi/primus
- community
Checking that the SKILL.md file is still in the repository.
Inspect the current Spur (AMD SLURM-compatible) cluster node-allocation state and produce a Markdown report (optionally rendered to a standalone HTML page) covering the caller's account/QoS permissions, partitions and per-state node counts, per-QoS node caps vs live usage, per-QoS and per-account node usage, reservations, queue pressure, GPU capacity, and the caller's own jobs. Use when the user asks about Spur/SLURM cluster status, node allocation, which QoS/account/partition holds how many nodes, what a QoS's node limit is or how close it is to that limit, why jobs are stuck pending, how many idle nodes are available, wants a cluster snapshot report, or wants an HTML/browser-viewable/shareable version of one.
Install
npx vskill@latest install amd-agi/primus/spur-cluster-statusSKILL.md
Spur Cluster Status Report
Generate a read-only snapshot of the Spur cluster's node-allocation state plus the caller's account/QoS permissions, and emit a single Markdown report (with an appendix of common commands), optionally rendered to a standalone HTML page. Spur is AMD's SLURM-compatible scheduler exposed via sinfo / squeue / scontrol / spur accounts.
Workflow
Step 1: Generate the report
Run the collector from the repo root (it is read-only and takes a few seconds):
- Reports on the current user by default. To target another user:
--user <name>. - The script prints a complete Markdown report to stdout and never mutates cluster state.
Step 2: Save and present
- Save the output under the repo root (create the dir if missing):
- Show the report to the user. Present the tables inline; the idle-node list can be
long, so summarize it (count + a short sample) unless the user wants the full list.
- Print the saved file path.
Step 3: Render an HTML version (optional)
Do this when the user asks for HTML, a browser-viewable page, something to share with people who will not open a .md, or a PDF (print the HTML from the browser).
- Writes the
.htmlnext to the.mdby default; override with-o <path>. - Output is a single self-contained file (CSS and JS inlined, no network
fetches), because the login nodes have neither markdown nor pandoc installed and the report is usually copied around as one file.
- The page reuses the palette of the dashboard in
tools/backend_gap_report, adds
a sticky table-of-contents that tracks the current section, right-aligns numeric columns, flags QoS at >=100% of their node cap in red and >=80% in amber, and carries a print stylesheet so browser "Save as PDF" drops the nav and avoids splitting sections across pages.
- Verify before presenting: section count, table count, and tag balance should
match the Markdown source (see Extending for the check).
Step 4: Add insights (optional)
After the tables, add a short analysis when relevant, e.g.:
- Whether enough idle nodes exist for the user's target job size.
- Whether the user's jobs are on shared (
mix) nodes (GPU-contention risk) vs--exclusive. - Whether a low-priority QoS (e.g.
amd-burst-qos, Prio=100, PreemptMode=cancel) is being
used for a job that should use the account's normal QoS — burst jobs can be cancelled to make room for higher-priority QoS.
- Why a job is stuck: separate pending jobs held by
QOSGrpNodeLimit(the QoS is at its
cap — more hardware will not help, the cap has to be raised) from Dependency (waiting on another job), Resources (genuinely waiting on free nodes), and JobHoldMaxRequeue (the job exhausted its requeue budget and is held until scontrol release <jobid>).
- Cap vs capacity: caps are heavily oversubscribed (currently ~2.2x usable nodes), and
amd-burst-qos is capped above the whole cluster, so it is effectively unconstrained while small-cap QoS starve. If a team keeps hitting QOSGrpNodeLimit on its own QoS but burst is well below its cap, that team is being pushed onto preemptible burst capacity — worth calling out.
Report contents
The collector emits these sections (see scripts/spur_status.py). The report is written in English:
- Account / QoS (you) — the caller's account(s), default account, default QoS, the
permission-model note, and the global QoS list with priority/preempt/node cap/per-user job caps.
- Partitions & Node States — per-partition total + per-state node counts, overall
state breakdown, utilization %, GPU capacity, idle nodelist, and drain/down nodes.
- QoS Node Limits vs Usage — sorted by QoS name: running jobs, distinct nodes in
use, the GrpTRES=node= cap, used %, pending jobs/nodes, how many pending jobs are held by QOSGrpNodeLimit, and MaxSubmitPU. Followed by the sum of all caps vs usable nodes (oversubscription factor), which QoS sit at their cap, which are capped at 0, and total demand held by the caps.
- Node Usage by QoS — for running jobs, per QoS: #jobs, distinct nodes, node-job
slots, GPUs, plus pending jobs and pending node demand.
- Node Usage by Account — same breakdown grouped by account.
- Reservations — name, node count, users, end time.
- Queue Pressure — running vs pending job counts and pending node demand.
- My Jobs — the caller's running/pending jobs.
- Jobs by User (all users) — one row per user: total jobs (running/pending),
distinct nodes held, number of accounts + which, which QoS, and which partitions.
- Appendix: Common Commands — the command reference used to build the report.
Spur quirks (important)
These are baked into the collector; keep them in mind if you extend it:
-oformat strings render space-separated regardless of literal delimiters — parse by whitespace column, not by a custom separator.squeuealso drops empty fields, which shifts later columns (seeparse_jobs).spur accounts show user|account <name>ignores the positional filter and lists everything — filter withgrep/awk.- The
sacctmgrbinary is not on PATH, butspur accountsis the same tool (its--helpeven printsUsage: sacctmgr), so policy queries do work through that entry point. - There is no
scontrol show hostnames; expand compressed nodelists locally (the script does this). - QoS membership is not enforced per account — only the account is enforced at submit time, so any QoS from the global list is accepted. But per-QoS capacity is enforced: each QoS has a
GrpTRES=node=cap, and jobs over it sit inPENDINGwith reasonQOSGrpNodeLimit. scontrol show assoc_mgroutput has two blocks:QOS RecordsthenAssociation Records. Both containGrpTRES=lines, so any parser must stop atAssociation Recordsor it will attribute per-account rows to the last QoS seen.- In a TRES string,
node=Nmeans unlimited whilenode=0is a real cap of zero — do not collapse them (amd-mlperf-training-qosis currently capped at 0). - The
(IN_USE)figure inassoc_mgris a distinct node count. Summing each job'sNumNodesgives a larger number when two jobs of the same QoS share a node.
Answering ad-hoc questions without the full report
For one-off questions, these are the underlying commands (all read-only):
Note that historical QoS data is not available: this cluster's sacct returns an empty QoS column, so anything beyond the currently-resident queue has to come from the cluster admins. Per-job GPU/CPU detail also needs scontrol show job <id> (ReqTRES, ReqGPUs, Exclusive) — scontrol here takes one job ID at a time, so loop with xargs -P for many jobs. When totalling resources, an Exclusive=1 job holds the whole node (236 CPUs / 8 GPUs) regardless of what it requested, while Exclusive=0 jobs only hold their requested share.
Extending
To add a metric, add a parser + a section in build_report() in scripts/spur_status.py, and add the underlying command to COMMANDS_APPENDIX so the report's command list stays in sync. Candidate additions: top users by node count, largest contiguous idle block for N-node jobs, spur report cluster historical utilization, and per-node CPUAlloc from scontrol show node.
scripts/md_to_html.py is a deliberately small line-based renderer covering only the Markdown this report emits: #/##/### headings, GFM pipe tables, bullet lists, blockquotes, fenced code blocks, and inline bold/italic/code/links. Each ## becomes a <section> plus a TOC entry, and the bullet list directly under the # title is lifted into the page header as metadata chips — so keep that structure if you restyle the report. Code spans are extracted before the emphasis pass, so ** inside backticks stays literal. If a new section needs different treatment, extend convert() (block dispatch) or cell_classes() (per-cell numeric and saturation styling).
After changing either script, re-render and sanity-check that nothing was dropped:
The body is emitted as one long line, so count with grep -o | wc -l, not grep -c:
Security
- Security scanPassed, 100 of 100Pattern checks on the skill's files.
- Model reviewNot runA model review is scheduled for the next rescan.
Quality evaluation
- Task evaluationNot runNo evaluation yet. Run one in Skill Studio.
Source
- SKILL.md in the repositoryCheckingskills/spur-cluster-status/SKILL.md
Popularity
- Repository stars
- 120
- Repository forks
- 46
- 7-day trend score
- 24
Stars and forks are for the whole GitHub repository, not this skill alone. Not refreshed yet.
Works with
Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.
- Claude Code
- Cursor
- GitHub Copilot
- Windsurf
- Codex
- Gemini CLI
- Cline
- Amp
- Roo Code
- Goose
- Continue
- Kilo Code
- Junie
- Trae
- OpenHands
- Qwen Code
- AI Agent
- Tabnine Chat
- Sourcegraph Cody
- Amazon Q
- Firebase Genkit
- Sweep
- Devin
- Phind
- Mentat
- Claude Desktop
- Aider
- GPT Pilot
- Plandex
- bolt.new
- v0
- Replit Agent
- Anse
- TypingMind
- BetterChatGPT
- LibreChat
- Warp AI
- Pieces
- Fig AI
Embed badge
[](https://verified-skill.com/skills/amd-agi/primus/spur-cluster-status)