Skip to content

[Slurm] Multi-node clusters#8219

Merged
kevinmingtarja merged 27 commits into
masterfrom
slurm-multi-node
Dec 9, 2025
Merged

[Slurm] Multi-node clusters#8219
kevinmingtarja merged 27 commits into
masterfrom
slurm-multi-node

Conversation

@kevinmingtarja

@kevinmingtarja kevinmingtarja commented Dec 6, 2025

Copy link
Copy Markdown
Collaborator

This PR implements multi-node clusters support for Slurm.

Tested (run the relevant ones):

@gemini-code-assist

Copy link
Copy Markdown
Contributor

Summary of Changes

Hello @kevinmingtarja, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly enhances SkyPilot's integration with Slurm by introducing full support for multi-node clusters. It achieves this through a dedicated Slurm executor script that manages per-node task execution, environment variable propagation, and synchronized setup/run phases. The changes also involve refactoring the core task code generation to accommodate distributed logging and robust command execution, alongside updates to the Slurm cloud backend and test suite to validate the new capabilities.

Highlights

  • Slurm Multi-Node Support: Fully enabled multi-node cluster capabilities for Slurm, removing previous limitations and allowing distributed workloads.
  • Dedicated Slurm Executor: Introduced sky/skylet/executor/slurm.py, a new Python script to manage distributed task execution, environment variables, and logging on individual Slurm compute nodes.
  • Refactored Task Code Generation: Centralized log path handling and introduced a new build_task_runner_cmd function for robust srun command construction and script execution, including synchronization mechanisms via signal files.
  • Enhanced Setup and Logging: Improved the setup process for multi-node Slurm jobs, ensuring directory creation only on the head node and providing distinct per-node logging for setup and run tasks.
  • Updated Test Suite: Modified smoke and unit tests to reflect and validate the new multi-node Slurm functionality, removing previous Slurm-specific single-node restrictions.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@kevinmingtarja

Copy link
Copy Markdown
Collaborator Author

/smoke-test --slurm -k test_cli_logs
/smoke-test --slurm -k test_launch_with_failing_setup
/smoke-test --slurm -k test_multi_echo
/smoke-test --slurm -k test_worker_provision_logs_streaming
/smoke-test --slurm -k minimal

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces multi-node cluster support for Slurm, which is a significant enhancement. The changes involve a major refactoring of the Slurm code generation logic, moving it to a dedicated remote executor module (sky.skylet.executor.slurm). This is a good architectural decision that improves modularity and maintainability. The implementation details for multi-node support, such as node IP discovery, per-node logging, and synchronization, appear to be well-thought-out. However, I've identified a critical issue in the provisioning script that could prevent clusters from being set up correctly. Overall, this is a great step forward, and with the identified issue fixed, it will be a solid contribution.

Comment thread sky/provision/slurm/instance.py Outdated
@kevinmingtarja

Copy link
Copy Markdown
Collaborator Author

/smoke-test --slurm -k test_multi_echo

1 similar comment
@kevinmingtarja

Copy link
Copy Markdown
Collaborator Author

/smoke-test --slurm -k test_multi_echo

@kevinmingtarja

Copy link
Copy Markdown
Collaborator Author

/smoke-test --slurm -k ray_basic
/smoke-test --slurm -k env_check
/smoke-test --slurm -k test_multi_hostname
/smoke-test --slurm -k test_multi_node_failure
/smoke-test --slurm -k test_cancel_pytorch

@kevinmingtarja

Copy link
Copy Markdown
Collaborator Author

/smoke-test --slurm -k test_cancel_pytorch

@kevinmingtarja

Copy link
Copy Markdown
Collaborator Author

/smoke-test --slurm -k test_cancel_pytorch
/smoke-test --slurm -k env_check

@kevinmingtarja

Copy link
Copy Markdown
Collaborator Author

/smoke-test --slurm -k ray_train

@kevinmingtarja

Copy link
Copy Markdown
Collaborator Author

/smoke-test --slurm -k test_multi_node_failure

@Michaelvll

Copy link
Copy Markdown
Collaborator

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread sky/provision/slurm/instance.py Outdated
@kevinmingtarja

Copy link
Copy Markdown
Collaborator Author

/smoke-test --slurm -k test_cancel_pytorch

Comment thread sky/provision/slurm/instance.py Outdated
Comment thread sky/backends/task_codegen.py
Comment thread sky/backends/task_codegen.py Outdated
Comment thread sky/backends/task_codegen.py Outdated
Comment thread sky/backends/task_codegen.py
Comment thread sky/backends/task_codegen.py Outdated
Comment on lines 713 to 718
'has_setup_cmd = False',
'setup_cmd = None',
'setup_envs = None',
'setup_log_path = None',
'setup_log_dir = None',
'setup_num_nodes = None',
]

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm generally a fan of moving things out of the string scripts for maintainability, since any scripts in string doesn't benefit from automated tools, etc. What do you think about doing something here like:

        self._code += [
            'autostop_lib.set_last_active_time_to_now()',
            f'job_lib.set_status({job_id!r}, job_lib.JobStatus.PENDING)',
        ]
        self._has_setup_cmd = False
        self._setup_cmd = None,
        self._setup_envs = None,
        self._setup_log_dir = None,
        self._setup_num_nodes = None,

and build the command dynamically on add_task?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds good, that would indeed be cleaner.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice! I have more ideas on how to clean up this part more, but let's merge this PR in and I can make a separate PR incorporating those cleanups. The code is functional, and that's what matters for now.

Comment on lines +187 to +196
# Clean up sky runtime directory on each node.
srun --nodes={num_nodes} rm -rf {skypilot_runtime_dir}
rm -rf {sky_home_dir}
}}
trap cleanup TERM

# Create sky directory for the cluster.
mkdir -p {sky_home_dir} {skypilot_runtime_dir}
# Create sky home directory for the cluster.
mkdir -p {sky_home_dir}
# Create sky runtime directory on each node.
srun --nodes={num_nodes} mkdir -p {skypilot_runtime_dir}

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When you do multiple sruns of multiple nodes, are these sruns guarenteed to run on the same set of nodes?

@kevinmingtarja kevinmingtarja Dec 9, 2025

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In this case yes, because it is being run from inside an sbatch script.

@kevinmingtarja kevinmingtarja Dec 9, 2025

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But actually in this case, it's just because we do srun --nodes N (N number of nodes requested by sbatch).

If we did srun --nodes M, M < N, I think there are no guarantees that multiple sruns would run on the same subset of M nodes.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That makes sense, it is a quirk so I'd ideally like it jotted down in a comment somewhere

Comment on lines -298 to +304
'failed': status_lib.ClusterStatus.INIT,
'failed': None,

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm curious what this change was motivated by

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah yes so apparently when we sky down a cluster in Slurm, under the hood we will call scancel, and the job will go into failed state and will remain in squeue for a few minutes:

$ squeue --states failed
             JOBID PARTITION     NAME     USER ST       TIME  NODES NODELIST(REASON)
              3111      CPUs sky-93c7   ubuntu  F      40:50      2 (NonZeroExitCode)

And so then if we relaunch a new cluster with the same name, our status refresh / query_instances would include the status of this previously downed cluster in the statuses map it returns, which would be confusing.

So by making it None, it is omitted when non_terminated_only is True.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah ok, interesting. Could we jot this done in a comment somewhere as well

@kevinmingtarja kevinmingtarja marked this pull request as ready for review December 9, 2025 00:59

@SeungjinYang SeungjinYang left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @kevinmingtarja, awesome work! This PR is ready to be merged in my opinion, once all the tests listed in the PR description is run successfully.

@kevinmingtarja

Copy link
Copy Markdown
Collaborator Author

/smoke-test --slurm -k ray_train
/smoke-test --slurm -k env_check
/smoke-test --slurm -k test_multi_hostname
/smoke-test --slurm -k test_multi_node_failure
/smoke-test --slurm -k test_cancel_pytorch

@kevinmingtarja

Copy link
Copy Markdown
Collaborator Author

/smoke-test --slurm -k test_cli_logs
/smoke-test --slurm -k test_launch_with_failing_setup
/smoke-test --slurm -k test_worker_provision_logs_streaming
/smoke-test --slurm -k minimal

@kevinmingtarja

Copy link
Copy Markdown
Collaborator Author

/smoke-test -k test_job_pipeline --slurm --jobs-consolidation

@kevinmingtarja

Copy link
Copy Markdown
Collaborator Author

/quicktest-core

@kevinmingtarja

Copy link
Copy Markdown
Collaborator Author

/smoke-test --slurm -k ray_basic

@kevinmingtarja kevinmingtarja merged commit fced388 into master Dec 9, 2025
30 of 32 checks passed
@kevinmingtarja kevinmingtarja deleted the slurm-multi-node branch December 9, 2025 04:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants