Skip to content

Commit 7845e3f

Browse files
allenwang28facebook-github-bot
authored andcommitted
Migrate static metadata to pyproject.toml (meta-pytorch#2136)
Summary: Migrates Monarch to more modern Python packaging standards by moving static metadata to pyproject.toml, adopting a declarative config approach. Ideally, everything is kept within pyproject.toml and is easily installed with `pip install .` Concretely this means, getting rid of setup.py altogether and all `*-requirements.txt`. But there are a few challenges that I want to cover: Why we need setup.py still: `setup.py` cannot be fully eliminated because Monarch has dynamic build requirements: 1. C++ extensions that link against PyTorch (requires torch library paths and headers) 2. Rust extensions via setuptools-rust (requires LIBTORCH_LIB environment variables) 3. Dynamic CUDA detection and CXX11 ABI detection at build time 4. Platform-specific rpath configuration for linking 5. Environment variable overrides (MONARCH_PACKAGE_NAME, MONARCH_VERSION, USE_TENSOR_ENGINE) 6. Custom build commands (Clean command) Why we still need build-requirements.txt in this change: build-requirements.txt (mirroring [build-system.requires]) is required because: 1. setup.py detects torch paths at module import time (lines 99-103) BEFORE the build 2. This requires torch to be pre-installed in the build environment 3. torch cannot be declared in [build-system.requires] because it needs custom index URLs (e.g., --index-url https://download.pytorch.org/whl/nightly/cu126) 4. Therefore we use `--no-build-isolation` which then disables automatic installation of `[build-system.requires]`, requiring manual installation via build-requirements.txt To eliminate build-requirement.txt, this would require us to enable standard isolated builds. Concretely: 1. Refactor setup.py to move torch detection from module-level into build command methods (e.g., inside CustomBuildExt.run()) 2. Delay all torch path detection until the build_ext command actually executes 3. This would allow build isolation to work because torch would be installed by the user before running `pip install .`, but build deps would be auto-installed Changes: - Add [build-system] configuration per PEP 517/518 - Move all static metadata to [project] section per PEP 621 (dependencies, authors, license, entry points, etc.) - Migrate runtime dependencies from requirements.txt to pyproject.toml - Migrate test dependencies to [project.optional-dependencies.test] - Simplify setup.py to only contain dynamic configuration (torch detection, C++/Rust extensions, environment variables) - Updates in CI and READMEs - Migrates from `python setup.py bdist_wheel` to `python -m build`. Setup.py is being deprecated: https://packaging.python.org/en/latest/discussions/setup-py-deprecated/ Differential Revision: D89066231
1 parent f849daa commit 7845e3f

File tree

10 files changed

+131
-87
lines changed

10 files changed

+131
-87
lines changed

.github/workflows/build-cpu.yml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,4 +34,7 @@ jobs:
3434
pip install -r build-requirements.txt
3535
3636
# Build monarch (No tensor engine, CPU version)
37-
USE_TENSOR_ENGINE=0 python setup.py bdist_wheel
37+
USE_TENSOR_ENGINE=0 python -m build --no-isolation --wheel
38+
39+
# Fix permissions for artifact upload
40+
chmod -R 755 dist/

.github/workflows/build-cuda.yml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,4 +42,7 @@ jobs:
4242
setup_tensor_engine
4343
4444
# Build monarch (CUDA version)
45-
python setup.py bdist_wheel
45+
python -m build --no-isolation --wheel
46+
47+
# Fix permissions for artifact upload
48+
chmod -R 755 dist/

.github/workflows/wheels.yml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,10 @@ jobs:
5050
export MONARCH_PACKAGE_NAME="torchmonarch-nightly"
5151
export MONARCH_VERSION=$(date +'%Y.%m.%d')
5252
53-
python setup.py bdist_wheel
53+
python -m build --no-isolation --wheel
54+
55+
# Fix permissions for artifact upload
56+
chmod -R 755 dist/
5457
5558
# hacky until the right distribution wheel can be made...
5659
find dist -name "*linux_x86_64.whl" -type f -exec bash -c 'mv "$1" "${1/linux_x86_64.whl/manylinux2014_x86_64.whl}"' _ {} \;

README.md

Lines changed: 53 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,18 @@
33
**Monarch** is a distributed programming framework for PyTorch based on scalable
44
actor messaging. It provides:
55

6-
1. Remote actors with scalable messaging: Actors are grouped into collections called meshes and messages can be broadcast to all members.
7-
2. Fault tolerance through supervision trees: Actors and processes form a tree and failures propagate up the tree, providing good default error behavior and enabling fine-grained fault recovery.
8-
3. Point-to-point RDMA transfers: cheap registration of any GPU or CPU memory in a process, with the one-sided transfers based on libibverbs
9-
4. Distributed tensors: actors can work with tensor objects sharded across processes
10-
11-
Monarch code imperatively describes how to create processes and actors using a simple python API:
6+
1. Remote actors with scalable messaging: Actors are grouped into collections
7+
called meshes and messages can be broadcast to all members.
8+
2. Fault tolerance through supervision trees: Actors and processes form a tree
9+
and failures propagate up the tree, providing good default error behavior and
10+
enabling fine-grained fault recovery.
11+
3. Point-to-point RDMA transfers: cheap registration of any GPU or CPU memory in
12+
a process, with the one-sided transfers based on libibverbs
13+
4. Distributed tensors: actors can work with tensor objects sharded across
14+
processes
15+
16+
Monarch code imperatively describes how to create processes and actors using a
17+
simple python API:
1218

1319
```python
1420
from monarch.actor import Actor, endpoint, this_host
@@ -33,8 +39,9 @@ fut = trainers.train.call(step=0)
3339
fut.get()
3440
```
3541

36-
37-
The [introduction to monarch concepts](https://meta-pytorch.org/monarch/generated/examples/getting_started.html) provides an introduction to using these features.
42+
The
43+
[introduction to monarch concepts](https://meta-pytorch.org/monarch/generated/examples/getting_started.html)
44+
provides an introduction to using these features.
3845

3946
> ⚠️ **Early Development Warning** Monarch is currently in an experimental
4047
> stage. You should expect bugs, incomplete features, and APIs that may change
@@ -45,16 +52,21 @@ The [introduction to monarch concepts](https://meta-pytorch.org/monarch/generate
4552
4653
## 📖 Documentation
4754

48-
View Monarch's hosted documentation [at this link](https://meta-pytorch.org/monarch/).
55+
View Monarch's hosted documentation
56+
[at this link](https://meta-pytorch.org/monarch/).
4957

5058
## Installation
51-
Note for running distributed tensors and RDMA, the local torch version must match the version that monarch was built with.
52-
Stable and nightly distributions require libmxl and libibverbs (runtime).
59+
60+
Note for running distributed tensors and RDMA, the local torch version must
61+
match the version that monarch was built with. Stable and nightly distributions
62+
require libmxl and libibverbs (runtime).
5363

5464
## Fedora
65+
5566
`sudo dnf install -y libibverbs rdma-core libmlx5 libibverbs-devel rdma-core-devel`
5667

5768
## Ubuntu
69+
5870
`sudo apt install -y rdma-core libibverbs1 libmlx5-1 libibverbs-dev`
5971

6072
### Stable
@@ -64,21 +76,22 @@ Stable and nightly distributions require libmxl and libibverbs (runtime).
6476
torchmonarch stable is built with the latest stable torch.
6577

6678
### Nightly
79+
6780
`pip install torchmonarch-nightly`
6881

6982
torchmonarch-nightly is built with torch nightly.
7083

7184
### Build and Install from Source
7285

73-
If you're building Monarch from source, you should be building it with the nightly PyTorch as well for ABI compatibility.
74-
86+
If you're building Monarch from source, you should be building it with the
87+
nightly PyTorch as well for ABI compatibility.
7588

7689
#### On Fedora distributions
7790

7891
```sh
7992

8093
# Create and activate the conda environment
81-
conda create -n monarchenv python=3.10 -y
94+
conda create -n monarchenv python=3.12 -y
8295
conda activate monarchenv
8396

8497
# Install nightly rust toolchain
@@ -101,10 +114,11 @@ conda update -n monarchenv --all -c conda-forge -y
101114
# If you are building with RDMA support, build monarch with `USE_TENSOR_ENGINE=1 pip install --no-build-isolation .` and dnf install the following packages
102115
sudo dnf install -y libibverbs rdma-core libmlx5 libibverbs-devel rdma-core-devel
103116

104-
# Install build dependencies
105-
pip install -r torch-requirements.txt -r build-requirements.txt
106-
# Install test dependencies
107-
pip install -r python/tests/requirements.txt
117+
# Install PyTorch nightly (required for building)
118+
pip install -r torch-requirements.txt
119+
120+
# Install build dependencies (required when using --no-build-isolation)
121+
pip install -r build-requirements.txt
108122

109123
# Build and install Monarch
110124
pip install --no-build-isolation .
@@ -140,10 +154,11 @@ export CXX=clang++
140154
# Install the correct cuda and cuda-toolkit versions for your machine
141155
sudo apt install -y cuda-toolkit-12-8 cuda-12-8
142156

143-
# Install build dependencies
144-
pip install -r torch-requirements.txt -r build-requirements.txt
145-
# Install test dependencies
146-
pip install -r python/tests/requirements.txt
157+
# Install PyTorch nightly (required for building)
158+
pip install -r torch-requirements.txt
159+
160+
# Install build dependencies (required when using --no-build-isolation)
161+
pip install -r build-requirements.txt
147162

148163
# Build and install Monarch (with tensor engine support)
149164
pip install --no-build-isolation .
@@ -161,27 +176,28 @@ pip list | grep monarch
161176

162177
#### On non-CUDA machines
163178

164-
You can also build Monarch to run on non-CUDA machines, e.g. locally on a MacOS system.
165-
166-
Note that this does not support tensor engine, which is tied to CUDA and RDMA (via ibverbs).
179+
You can also build Monarch to run on non-CUDA machines, e.g. locally on a MacOS
180+
system.
167181

182+
Note that this does not support tensor engine, which is tied to CUDA and RDMA
183+
(via ibverbs).
168184

169185
```sh
170186

171187
# Create and activate the conda environment
172-
conda create -n monarchenv python=3.10 -y
188+
conda create -n monarchenv python=3.12 -y
173189
conda activate monarchenv
174190

175191
# Install nightly rust toolchain
176192
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
177193
rustup toolchain install nightly
178194
rustup default nightly
179195

180-
# Install build dependencies
196+
# Install PyTorch nightly (CPU version)
181197
pip install --pre torch --index-url https://download.pytorch.org/whl/nightly/cpu
198+
199+
# Install build dependencies (required when using --no-build-isolation)
182200
pip install -r build-requirements.txt
183-
# Install test dependencies
184-
pip install -r python/tests/requirements.txt
185201

186202
# Build and install Monarch
187203
USE_TENSOR_ENGINE=0 pip install --no-build-isolation .
@@ -192,10 +208,10 @@ USE_TENSOR_ENGINE=0 pip install --no-build-isolation -e .
192208
pip list | grep monarch
193209
```
194210

195-
196211
## Running examples
197212

198-
Check out the `examples/` directory for demonstrations of how to use Monarch's APIs.
213+
Check out the `examples/` directory for demonstrations of how to use Monarch's
214+
APIs.
199215

200216
We'll be adding more examples as we stabilize and polish functionality!
201217

@@ -205,6 +221,7 @@ We have both Rust and Python unit tests. Rust tests are run with `cargo-nextest`
205221
and Python tests are run with `pytest`.
206222

207223
Rust tests:
224+
208225
```sh
209226
# We use cargo-nextest to run our tests, as they can provide strong process isolation
210227
# between every test.
@@ -213,12 +230,15 @@ Rust tests:
213230
cargo install cargo-nextest --locked
214231
cargo nextest run
215232
```
233+
216234
cargo-nextest supports all of the filtering flags of "cargo test".
217235

218236
Python tests:
237+
219238
```sh
220-
# Make sure to install test dependencies first
221-
pip install -r python/tests/requirements.txt
239+
# Install test dependencies if not already installed
240+
pip install -e '.[test]'
241+
222242
# Run unit tests. consider -s for more verbose output
223243
pytest python/tests/ -v -m "not oss_skip"
224244
```

build-requirements.txt

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,15 @@
1-
setuptools
1+
# Build dependencies for Monarch
2+
#
3+
# This file mirrors [build-system.requires] in pyproject.toml for convenience.
4+
# It's needed when using --no-build-isolation (required because setup.py needs
5+
# torch installed before it runs, and torch can't be declared in pyproject.toml
6+
# due to needing custom index URLs like nightly/cu126).
7+
#
8+
# Modern build tools (pip, python -m build) will automatically install these
9+
# dependencies when using isolated builds, but Monarch requires --no-build-isolation.
10+
11+
setuptools>=64
212
setuptools-rust
313
wheel
414
numpy
15+
build

pyproject.toml

Lines changed: 52 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,56 @@
1-
[tool.pytest.ini_options]
1+
[build-system]
2+
requires = ["setuptools>=64", "setuptools-rust", "wheel", "numpy"]
3+
build-backend = "setuptools.build_meta"
4+
5+
[project]
6+
name = "monarch"
7+
version = "0.0.1"
8+
description = "Monarch: Single controller library"
9+
readme = "README.md"
10+
requires-python = ">=3.10"
11+
license = {text = "BSD-3-Clause"}
12+
authors = [
13+
{name = "Meta", email = "[email protected]"}
14+
]
15+
16+
dependencies = [
17+
"pyzmq",
18+
"requests",
19+
"numpy",
20+
"pyre-extensions",
21+
"typing-extensions>=4.12",
22+
"cloudpickle",
23+
"torchx-nightly",
24+
"lark",
25+
"tabulate",
26+
"opentelemetry-api",
27+
"clusterscope",
28+
]
29+
30+
[project.optional-dependencies]
31+
examples = [
32+
"bs4",
33+
"ipython",
34+
]
35+
test = [
36+
"pytest",
37+
"pytest-timeout",
38+
"pytest-asyncio",
39+
"pytest-xdist",
40+
"pyright",
41+
]
42+
43+
[project.scripts]
44+
monarch = "monarch.tools.cli:main"
45+
monarch_bootstrap = "monarch._src.actor.bootstrap_main:invoke_main"
246

47+
[tool.setuptools]
48+
packages = {find = {where = ["python"], exclude = ["tests*", "tests.*"]}}
49+
50+
[tool.setuptools.package-dir]
51+
"" = "python"
52+
53+
[tool.pytest.ini_options]
354
markers = [
455
"oss_skip: marks tests to skip in OSS CI",
556
]

python/tests/requirements.txt

Lines changed: 0 additions & 5 deletions
This file was deleted.

requirements.txt

Lines changed: 0 additions & 11 deletions
This file was deleted.

scripts/common-setup.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ setup_rust_toolchain() {
4949
# Install Python test dependencies
5050
install_python_test_dependencies() {
5151
echo "Installing test dependencies..."
52-
pip install -r python/tests/requirements.txt
52+
pip install -e '.[test]'
5353
dnf install -y rsync # required for code sync tests
5454
}
5555

setup.py

Lines changed: 1 addition & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
import sys
1212
import sysconfig
1313

14-
from setuptools import Command, find_packages, setup
14+
from setuptools import Command, setup
1515
from setuptools.command.build_ext import build_ext
1616
from setuptools.extension import Extension
1717

@@ -198,12 +198,6 @@ def run(self):
198198
subprocess.run(["cargo", "clean"])
199199

200200

201-
with open("requirements.txt") as f:
202-
reqs = f.read()
203-
204-
with open("README.md", encoding="utf8") as f:
205-
readme = f.read()
206-
207201
if sys.platform.startswith("linux"):
208202
# Always include the active env's lib (Conda-safe)
209203
conda_lib = os.path.join(sys.prefix, "lib")
@@ -278,35 +272,10 @@ def run(self):
278272
setup(
279273
name=package_name,
280274
version=package_version,
281-
packages=find_packages(
282-
where="python",
283-
exclude=["python/tests.*", "python/tests"],
284-
),
285-
package_dir={"": "python"},
286-
python_requires=">= 3.10",
287-
install_requires=reqs.strip().split("\n"),
288-
extras_require={
289-
"examples": [
290-
"bs4",
291-
"ipython",
292-
],
293-
},
294-
license="BSD-3-Clause",
295-
author="Meta",
296-
author_email="[email protected]",
297-
description="Monarch: Single controller library",
298-
long_description=readme,
299-
long_description_content_type="text/markdown",
300275
ext_modules=[
301276
controller_C,
302277
common_C,
303278
],
304-
entry_points={
305-
"console_scripts": [
306-
"monarch=monarch.tools.cli:main",
307-
"monarch_bootstrap=monarch._src.actor.bootstrap_main:invoke_main",
308-
],
309-
},
310279
rust_extensions=rust_extensions,
311280
cmdclass={
312281
"build_ext": build_ext,

0 commit comments

Comments
 (0)