Skip to content

Commit 1bfda53

Browse files
authored
Reworked setup system using both pyproject.toml and setup.py. Reworked CI (#46)
* reworked the setup system to use pyproject.toml * changed the way custom CUDA extension build flag is passed * reworked the CI * changed to source distribution only in the CI
1 parent ef5bf03 commit 1bfda53

File tree

5 files changed

+121
-102
lines changed

5 files changed

+121
-102
lines changed

.github/workflows/deploy_pypi.yml

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,27 +7,31 @@ on:
77
workflow_dispatch:
88

99
jobs:
10-
build:
11-
10+
pypi-publish:
11+
name: Publish release to PyPI
1212
runs-on: ubuntu-latest
13+
environment:
14+
name: pypi
15+
url: https://pypi.org/p/torch-harmonics
1316

1417
steps:
1518
- uses: actions/checkout@v4
19+
1620
- name: Set up Python 3.9
1721
uses: actions/setup-python@v5
1822
with:
19-
python-version: 3.9
20-
- name: Install dependencies
21-
run: |
22-
python -m pip install --upgrade pip
23-
python -m pip install torch --index-url https://download.pytorch.org/whl/cpu
24-
python -m pip install setuptools wheel
25-
- name: Install package
23+
python-version: "3.9"
24+
25+
- name: Install build dependencies
2626
run: |
27-
python -m pip install -e .
28-
- name: Build a binary wheel and a source tarball
27+
python3 -m pip install --upgrade pip setuptools build wheel
28+
python3 -m pip install numpy
29+
python3 -m pip install torch --extra-index-url https://download.pytorch.org/whl/cpu
30+
31+
- name: Build distribution
2932
run: |
30-
python setup.py sdist bdist_wheel
33+
python3 -m build --sdist
34+
3135
- name: Publish package to PyPI
3236
uses: pypa/gh-action-pypi-publish@release/v1
3337
with:

.github/workflows/tests.yml

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,31 @@
1-
name: tests
1+
name: Run local tests
22

3-
on: [push]
3+
on:
4+
push:
5+
workflow_dispatch:
46

57
jobs:
68
build:
7-
9+
name: Run local tests
810
runs-on: ubuntu-latest
911

1012
steps:
1113
- uses: actions/checkout@v4
14+
1215
- name: Set up Python 3.9
1316
uses: actions/setup-python@v5
1417
with:
15-
python-version: '3.10'
18+
python-version: "3.9"
19+
1620
- name: Install dependencies
1721
run: |
1822
python3 -m pip install --upgrade pip setuptools wheel
19-
python3 -m pip install torch torchvision torchaudio --extra-index-url https://download.pytorch.org/whl/cpu
23+
python3 -m pip install torch --extra-index-url https://download.pytorch.org/whl/cpu
24+
2025
- name: Install package
2126
run: |
2227
python3 -m pip install -e .
28+
2329
- name: Test with pytest
2430
run: |
2531
python3 -m pip install pytest pytest-cov parameterized

README.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,9 +80,11 @@ Download directly from PyPI:
8080
```bash
8181
pip install torch-harmonics
8282
```
83-
If you would like to have accelerated CUDA extensions for the discrete-continuous convolutions, please use the '--cuda_ext' flag:
83+
If you would like to enforce the compilation of CUDA extensions for the discrete-continuous convolutions, you can do so by setting the `FORCE_CUDA_EXTENSION` flag. You may also want to set appropriate architectures with the `TORCH_CUDA_ARCH_LIST` flag.
8484
```bash
85-
pip install --global-option --cuda_ext torch-harmonics
85+
export FORCE_CUDA_EXTENSION=1
86+
export TORCH_CUDA_ARCH_LIST="7.0 7.2 7.5 8.0 8.6 8.7 9.0+PTX"
87+
pip install torch-harmonics
8688
```
8789
:warning: Please note that the custom CUDA extensions currently only support CUDA architectures >= 7.0.
8890

pyproject.toml

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
[build-system]
2+
requires = [ "setuptools", "setuptools-scm", "torch>=2.4.0"]
3+
build-backend = "setuptools.build_meta"
4+
5+
[project]
6+
name = "torch_harmonics"
7+
authors = [
8+
{ name="Boris Bonev", email = "[email protected]" },
9+
{ name="Thorsten Kurth", email = "[email protected]" },
10+
{ name="Mauro Bisson" },
11+
{ name="Massimiliano Fatica" },
12+
{ name="Jean Kossaifi" },
13+
{ name="Nikola Kovachki" },
14+
{ name="Christian Hundt" },
15+
]
16+
17+
maintainers = [
18+
{ name="Thorsten Kurth", email = "[email protected]" },
19+
{ name="Boris Bonev", email = "[email protected]" },
20+
]
21+
22+
readme = "README.md"
23+
24+
dynamic = ["version"]
25+
26+
description = "Differentiable signal processing on the sphere for PyTorch."
27+
requires-python = ">=3.9"
28+
29+
classifiers = [
30+
"Development Status :: 3 - Alpha",
31+
"Programming Language :: Python :: 3.9",
32+
"License :: OSI Approved :: BSD License",
33+
"Operating System :: OS Independent",
34+
]
35+
36+
dependencies = [
37+
"torch>=2.4.0",
38+
"numpy>=1.22.4,<1.25",
39+
]
40+
41+
[tool.setuptools.dynamic]
42+
version = {attr = "torch_harmonics.__version__"}
43+
44+
[tool.setuptools.packages.find]
45+
include = ["torch_harmonics*"]
46+
47+
[project.optional-dependencies]
48+
dev = [
49+
"pytest>=6.0.0",
50+
"coverage>=6.5.0",
51+
]

setup.py

Lines changed: 39 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -29,67 +29,44 @@
2929
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3030
#
3131

32-
import sys
32+
import os, sys
33+
import warnings
3334

34-
try:
35-
from setuptools import setup, find_packages
36-
except ImportError:
37-
from distutils.core import setup, find_packages
38-
39-
import re
40-
from pathlib import Path
41-
42-
import torch
43-
from torch.utils import cpp_extension
44-
45-
def version(root_path):
46-
"""Returns the version taken from __init__.py
47-
48-
Parameters
49-
----------
50-
root_path : pathlib.Path
51-
path to the root of the package
35+
from setuptools import setup, find_packages
36+
from setuptools.command.install import install
5237

53-
Reference
54-
---------
55-
https://packaging.python.org/guides/single-sourcing-package-version/
56-
"""
57-
version_path = root_path.joinpath("torch_harmonics", "__init__.py")
58-
with version_path.open() as f:
59-
version_file = f.read()
60-
version_match = re.search(r"^__version__ = ['\"]([^'\"]*)['\"]", version_file, re.M)
61-
if version_match:
62-
return version_match.group(1)
63-
raise RuntimeError("Unable to find version string.")
38+
# some code to handle the building of custom modules
39+
FORCE_CUDA_EXTENSION = os.getenv("FORCE_CUDA_EXTENSION", "0") == "1"
40+
BUILD_CPP = BUILD_CUDA = False
6441

42+
# try to import torch
43+
try:
44+
import torch
6545

66-
def readme(root_path):
67-
"""Returns the text content of the README.md of the package
68-
69-
Parameters
70-
----------
71-
root_path : pathlib.Path
72-
path to the root of the package
73-
"""
74-
with root_path.joinpath("README.md").open(encoding="UTF-8") as f:
75-
return f.read()
46+
print(f"setup.py with torch {torch.__version__}")
47+
from torch.utils.cpp_extension import BuildExtension, CppExtension
7648

49+
BUILD_CPP = True
50+
from torch.utils.cpp_extension import CUDA_HOME, CUDAExtension
7751

78-
def get_ext_modules(argv):
52+
BUILD_CUDA = FORCE_CUDA_EXTENSION or (torch.cuda.is_available() and (CUDA_HOME is not None))
53+
except (ImportError, TypeError, AssertionError, AttributeError) as e:
54+
warnings.warn(f"building custom extensions skipped: {e}")
7955

80-
compile_cuda_extension = False
56+
def get_ext_modules():
8157

82-
if "--cuda_ext" in sys.argv:
83-
sys.argv.remove("--cuda_ext")
84-
compile_cuda_extension = True
58+
ext_modules = []
59+
cmdclass = {}
8560

86-
ext_modules = [
87-
cpp_extension.CppExtension("disco_helpers", ["torch_harmonics/csrc/disco/disco_helpers.cpp"]),
88-
]
61+
if BUILD_CPP:
62+
print(f"Compiling helper routines for torch-harmonics.")
63+
ext_modules.append(CppExtension("disco_helpers", ["torch_harmonics/csrc/disco/disco_helpers.cpp"]))
64+
cmdclass["build_ext"] = BuildExtension
8965

90-
if torch.cuda.is_available() or compile_cuda_extension:
66+
if BUILD_CUDA:
67+
print(f"Compiling custom CUDA kernels for torch-harmonics.")
9168
ext_modules.append(
92-
cpp_extension.CUDAExtension(
69+
CUDAExtension(
9370
"disco_cuda_extension",
9471
[
9572
"torch_harmonics/csrc/disco/disco_interface.cu",
@@ -98,37 +75,16 @@ def get_ext_modules(argv):
9875
],
9976
)
10077
)
78+
cmdclass["build_ext"] = BuildExtension
79+
80+
return ext_modules, cmdclass
81+
82+
if __name__ == "__main__":
83+
84+
ext_modules, cmdclass = get_ext_modules()
10185

102-
return ext_modules
103-
104-
105-
root_path = Path(__file__).parent
106-
README = readme(root_path)
107-
VERSION = version(root_path)
108-
109-
# external modules
110-
ext_modules = get_ext_modules(sys.argv)
111-
112-
config = {
113-
"name": "torch_harmonics",
114-
"packages": find_packages(),
115-
"description": "A differentiable spherical harmonic transform for PyTorch.",
116-
"long_description": README,
117-
"long_description_content_type": "text/markdown",
118-
"url": "https://github.com/NVIDIA/torch-harmonics",
119-
"author": "Boris Bonev",
120-
"author_email": "[email protected]",
121-
"version": VERSION,
122-
"install_requires": ["torch", "numpy"],
123-
"extras_require": {
124-
"sfno": ["tensorly", "tensorly-torch"],
125-
},
126-
"license": "Modified BSD",
127-
"scripts": [],
128-
"include_package_data": True,
129-
"classifiers": ["Topic :: Scientific/Engineering", "License :: OSI Approved :: BSD License", "Programming Language :: Python :: 3"],
130-
"ext_modules": ext_modules,
131-
"cmdclass": {"build_ext": cpp_extension.BuildExtension} if ext_modules else {},
132-
}
133-
134-
setup(**config)
86+
setup(
87+
packages=find_packages(),
88+
ext_modules=ext_modules,
89+
cmdclass=cmdclass,
90+
)

0 commit comments

Comments
 (0)