fix: per-CPU memory accounting and --ntasks in SLURM executor (#352) - #353
Merged
mpvanderschelling merged 1 commit intoJul 31, 2026
Merged
Conversation
The SLURM executor hard-coded per-node --mem + --nodes and never emitted --ntasks, so every job it submitted (the orchestrator and every step) was rejected at submission time on sites whose job_submit filter mandates per-CPU accounting — notably TU Delft's DelftBlue. There was no config-only workaround: --mem and --mem-per-cpu are mutually exclusive (fatal) at every SLURM site, so extra_sbatch could not rescue it. - SlurmResources gains `ntasks` (default 1) and `mem_per_cpu` (default None); `mem` is ignored when `mem_per_cpu` is set. - Both header renderers now share `_render_resource_directives`: `--ntasks` is always emitted; `--mem-per-cpu` replaces `--mem` when set; `--nodes` is omitted only when `mem_per_cpu` is set and `nodes == 1` (an explicit `nodes > 1` is always emitted). - Precedence is documented, not validated (a dataclass cannot tell an explicitly-set `mem` from its default). - Add ADR 0003; regenerate the 6 golden fixtures (one --ntasks=1 line each); extend test_resources/test_slurm; bump to 2.4.0. Backward compatible: mem_per_cpu defaults to None, so per-node --mem output is unchanged where not opted into; the only change for existing configs is the added --ntasks=1 line (confirmed harmless on both DelftBlue and Oscar). Validated on the real DelftBlue scheduler via `sbatch --test-only`: the new step and orchestrator scripts are accepted on the `compute` partition; the old-style header reproduces the exact rejection. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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.
Summary
Fixes #352. The SLURM executor hard-coded per-node
--mem+--nodesand never emitted--ntasks, so every job (orchestrator and every step) was rejected at submission time on sites whosejob_submitfilter mandates per-CPU memory accounting — notably TU Delft's DelftBlue. Because--memand--mem-per-cpuare mutually exclusive (fatal) at every SLURM site,extra_sbatchcould not work around it — the fix has to omit--mem, which only the renderer can do.Changes
SlurmResourcesgains two fields:ntasks: int = 1andmem_per_cpu: str | None = None. Whenmem_per_cpuis set,memis ignored (documented, not validated).render_sbatch_script,render_orchestrator_script) now share one_render_resource_directives(res)helper so they cannot drift:--ntasks={res.ntasks}is emitted unconditionally on every cluster (confirmed harmless on plain-SLURM sites like Oscar).--mem-per-cpureplaces--memwhenmem_per_cpuis set.--nodesis omitted only whenmem_per_cpuis set andnodes == 1; an explicitnodes > 1is always emitted.Pipeline.orchestrator_resourceswith amem_per_cpu(the built-in orchestrator default stays per-node by design).tests/pipeline/golden/*.sh(one--ntasks=1line each); extendedtest_resources.pyandtest_slurm.py(newTestPerCpuMemory); bumped version to 2.4.0.Backward compatibility
mem_per_cpudefaults toNone, so per-node--memoutput is unchanged wherever it is not opted into. The only behavior change for existing configs is the added--ntasks=1line.Verification
uv run pytest(full suite,[tests,all]extras + coverage gate): 1133 passed, coverage 91.84% (gate 85%).pre-commit run --all-files: passing (ruff format/check, toml-sort).sbatch --test-only: new step + orchestrator scripts accepted oncompute; the old-style header rejected with the exact error from the issue.🤖 Generated with Claude Code