Repository navigation
Conversation
…-node allocation Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
It was derived from PROFILE with str.replace on "[scheduler]\n", which silently no-ops if that fixture changes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Slurm does not reject --mem above cpus x MaxMemPerCPU: it raises the cpu count to fit and bills every core. On a 2764M/cpu partition a single-threaded job asking --mem=3G ran on one core and paid for two. - cluster_probe: record DefMemPerCPU/MaxMemPerCPU per partition (scontrol show partition, falling back to scontrol show config, which on such sites is empty); emit them in [[partitions]] and the card. - cluster_guardrail: grade a --mem/--mem-per-cpu request at the cpu count Slurm will allocate, with a soft 'memory' verdict; warn when the cap is unknown. - using-slurm: size memory from the partition's per-cpu memory and a measured peak before writing the job; check 'using N processors' in --test-only. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
What sacct reports for a job (partition, cpus, nodes, memory, time limit, billing) follows from the request and the partition policy in the profile, so it can be written down before sbatch and compared once tasks run. - cluster_guardrail expect: predicted allocation per task, including cpus raised by memory above MaxMemPerCPU or by whole-node partitions, and DefMemPerCPU x cpus when no memory is requested. - harness_slurm submit prints the prediction and saves it to results/.slurm/<jobid>.expect.json; alloc-check <jobid> compares sacct with it (exit 1 on a mismatch) and reports peak RSS against the request. - using-slurm: a mismatch is explained (scontrol show job/partition) and its source fixed before anything else is submitted. Checked on a live job: the prediction for a 1-cpu --mem=3G array on a 2764M/cpu partition (2 cpus, 2 billing units, 3072M, 1 day) matched all six tasks. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
Setting up a profile on a large shared Slurm cluster exposed six gaps in
/setup-cluster//using-slurm:.gitignorenamed one site's profile explicitly, so any newly created<name>.toml(username, host, key path) showed up as an untracked file ready to commit. The skill only "reminded" the student.harness_slurm.sh probe-partitionsprinted partition/state/node-count rows only — no cores, memory or GPUs — one row per node state, for every partition on the cluster, including ones the user's account cannot submit to. The richerscripts/cluster_probe.pyexisted but no skill called it.[limits]were seeded from the wrong source. The skill derived hard caps from partitionMaxTimeand node totals, but the limits a user actually hits are the per-user QOS caps (MaxTRESPU,MaxJobsPU,MaxWall). QOS was never read.coresvalue, so on whole-node partitions the guardrail cannot know what a job will occupy (it counted a 1-task job as 1 cpu while it takes a full node), and there was no record of the node features needed to pin a node type with--constraintfor fit or reproducible timing.--memabovecpus × MaxMemPerCPU; it raises the cpu count to fit and bills every core. Many sites setMaxMemPerCPUonly per partition, soscontrol show config(the only place the probe looked) reports nothing. A single-threaded job asking--mem=3Gon a 2764 MB/cpu partition ran on one core and was billed for two.sacctwith the request, although that allocation is fully predictable from the request and the partition policy.What
.gitignore: ignore every*.toml/*.mdinskills/using-slurm/profiles/and allow-list the public examples (localhost,qdeshell,scnet,*-setup.md)./setup-cluster§4 now verifies withgit check-ignoreinstead of reminding.cluster_probe.pysinfo %f) and groups each partition intonode_types;cores/memorybecome the largest node typescontrol show partition -oand the user's associations; drops partitions the user cannot submit to (account/QOS rules, or a QOS granting 0 cpus)sacctmgr show qos) →user_caps, partition QOS overriding the default QOSOverSubscribe=EXCLUSIVEor asbatch --test-onlydry run of a 1-task job (nothing is submitted)preemptibleclass[limits]block (--limits-for <partition>to change the source partition)sinfotimes out (the ssh timeout text was previously parsed as partition rows)harness_slurm.sh probe-partitionsdelegates tocluster_probe.py --emit card, so/using-slurmand/cluster-jobsget the same per-user table.cluster_guardrail.py: on awhole_nodepartition or with--exclusive, gradenodes × cores-per-node;--constraint/-Cselects the matching node type.cluster_probe.pyrecordsDefMemPerCPU/MaxMemPerCPUper partition (scontrol show partition, falling back toscontrol show config) asdef_mem_per_cpu_mb/max_mem_per_cpu_mbin[[partitions]]and the card;cluster_guardrail.pygrades a--mem/--mem-per-cpurequest at the cpu count Slurm will allocate (softmemoryverdict) and warns when the cap is unknown;/using-slurmgains a Sizing memory step (read the cap, size from a measuredMaxRSS, checkusing N processorsin--test-only) before the job is written.cluster_guardrail.py expectpredicts whatsacctwill report per task (partition, task count, cpus incl. memory- or whole-node-raised ones, nodes, memory incl.DefMemPerCPU × cpus, time limit, billing).harness_slurm.sh submitprints it and savesresults/.slurm/<jobid>.expect.json;harness_slurm.sh alloc-check <jobid>comparessacctwith it (exit 1 on any difference) and reports peak RSS against the request./using-slurmrequires a mismatch to be explained (scontrol show job/partition) and its source fixed before anything else is submitted.whole_node,qos,user_caps,[[partitions.node_types]],preemptible) incluster-profiles.md;/setup-cluster§2–§4 rewritten around the new probe and QOS-seeded limits.Testing
make test— 283 passed, 9 skipped. Cluster suites: 21 new tests in the first commits, plus memory-per-cpu tests (partition vs cluster-wide cap,--mem/--mem-per-cpu/--mem=0/ unparseable), on a synthetic cluster fixture: shared / own-group / other-group / preemptible / GPU / request-only partitions).MaxMemPerCPU=2764: the probe records it, and the guardrail flags a 1-cpu--mem=3Gscript as allocating 2 cpus (matchingsacctAllocCPUS=2for jobs that ran with it) while the--mem=2Gversion is clean. Theexpectprediction for that job (2 cpus, 2 billing units, 3072M, 1 day) matchedsaccton all six array tasks viaalloc-check; the 2G prediction against the same job reports the cpu, billing and memory differences.🤖 Generated with Claude Code