fix(srun): honor step node selection - #599
Conversation
There was a problem hiding this comment.
Pull request overview
Fixes step-mode srun node selection so -N and -w are honored inside an existing allocation, with controller-side validation, step-scoped dispatch, and Slurm-style warnings surfaced back to the CLI. This fits into Spur’s Slurm-compatibility layer by aligning step creation/dispatch semantics across the CLI, controller, and agent environment.
Changes:
- Extend the step creation API to carry an explicit step node count (
-N) and return warnings tosrun. - Store a selected node subset on the step and dispatch tasks only to that subset (instead of fanning out across all allocated nodes).
- Pass allocation-vs-step nodelists to agents and set step-scoped env vars (
*_STEP_*,*_NNODES) appropriately; add coverage in unit + native-host e2e tests.
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/native_host/e2e/test_srun_multi_node.py | Adds native-host e2e coverage for step node count and -w targeting semantics. |
| proto/slurm.proto | Adds CreateJobStepRequest.num_nodes, CreateJobStepResponse.warnings, and RunCommandRequest.step_nodelist. |
| crates/spurd/src/agent_server.rs | Applies step-vs-job nodelist scoping when setting env vars; adds unit tests for env scoping behavior. |
| crates/spurctld/src/server.rs | Implements controller-side step node selection/validation, stores selected nodes on the step, dispatches only to step nodes, and forwards step nodelist to agents. |
| crates/spur-core/src/spur_env.rs | Adds step/job node-count separation in env (SPUR_STEP_NUM_NODES, SPUR_JOB_NUM_NODES). |
| crates/spur-cli/src/srun.rs | Tracks step layout (tasks/nodes/hostlist), forwards -w and optional -N into step creation, and prints controller warnings. |
| crates/spur-cli/src/mock_controller.rs | Extends the mock controller capture to assert forwarded step node count and hostlist in tests. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| let target_node = selection | ||
| .nodes | ||
| .first() | ||
| .ok_or_else(|| Status::internal("step node selection returned no nodes"))? | ||
| .clone(); |
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
|
Hi @sgopinath1 , this PR is trying to address the issue #597 which was self-assigned to you, can you check whether this is overlapping with what you are working on ? |
Alright. @joshkmartinez please close #597 once this PR is merged. |
Closes #597.
Inside an allocation,
srun -N 1still fanned out across every allocated node, and-wwas dropped before step creation.This keeps step node count separate from task count through the CLI and controller. The controller validates the requested count and hostlist against the parent allocation, stores the selected nodes on the step, and dispatches only to that subset. Slurm-style node-count warnings are returned to
sruninstead of silently clamping.Agents now receive both the allocation and step nodelists.
SLURM_JOB_*stays allocation-scoped, whileSLURM_STEP_*andSLURM_NNODESdescribe the step. empty step nodelist falls back to the allocation for compatibility with older controllers.Tested locally:
cargo test -p spur-cli --lockedcargo test -p spurctld --locked, including a live two-agent loopback dispatch testcargo test -p spur-core spur_env::tests --lockedcargo clippy -p spur-core -p spur-cli -p spurctld --all-targets --locked -- -D warningsI could not run two node native-host E2E coverage b/c i'm on macos