-
Notifications
You must be signed in to change notification settings - Fork 0
/
setup.py
100 lines (78 loc) · 3.88 KB
/
setup.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
import subprocess
from pathlib import Path
import torch
from setuptools import Extension, setup
from setuptools.command.build_ext import build_ext
"""
Build / install instructions:
- use a virtual env (conda or whatever you want)
- install pytorch nightly (https://pytorch.org/get-started/locally/)
- pip install -e . --no-build-isolation
Note:
The "torch" package is not just a runtime dependency but also a *build time*
dependency, since we are including pytorch's headers. We are however not
specifying either of these dependencies in our pyproject.toml file.
Why we don't specify torch as a runtime dep: I'm not 100% sure, all I know is
that no project does it and those who tried had tons of problems. I think it has
to do with the fact that there are different flavours of torch (cpu, cuda, etc.)
and the pyproject.toml system does not allow a fine-grained enough control over
that.
Why we don't specify torch as a build time dep: because really developers need
to rely on torch-nightly, not on the stable version of torch. And the only way
to install torch nightly is to specify a custom `--index-url` and sadly
pyproject.toml does not allow that.
To be perfeclty honest I'm not 110% sure about the above, but this is definitely
fine for now. Basically what that means is that we expect developers and users
to install the correct version of torch before they install / build torchcodec.
This is what all other libraries expect as well.
Oh, and by default, doing `pip install -e .` would try to build the package in
an isolated virtual environment, not in the current one. But because we're not
specifying torch as a build-time dependency, this fails loudly as torch can't be
found. That's why we're passing `--no-build-isolation`: this tells pip to build
the package within the current virtual env, where torch would have already been
installed.
Does packaging suck? Yes.
"""
_ROOT_DIR = Path(__file__).parent.resolve()
class CMakeBuild(build_ext):
def run(self):
try:
subprocess.check_output(["cmake", "--version"])
except OSError:
raise RuntimeError("CMake is not available.") from None
super().run()
def build_extension(self, ext):
ext_dir = Path(self.get_ext_fullpath(ext.name)).parent.absolute()
torch_dir = Path(torch.utils.cmake_prefix_path) / "Torch"
cmake_args = [
f"-DCMAKE_INSTALL_PREFIX={ext_dir}",
f"-DTorch_DIR={torch_dir}",
"-DCMAKE_VERBOSE_MAKEFILE=ON",
]
Path(self.build_temp).mkdir(parents=True, exist_ok=True)
subprocess.check_call(
["cmake", str(_ROOT_DIR)] + cmake_args, cwd=self.build_temp
)
subprocess.check_call(["cmake", "--build", "."], cwd=self.build_temp)
subprocess.check_call(["cmake", "--install", "."], cwd=self.build_temp)
def get_ext_filename(self, fullname):
# When copying the .so files from the build tmp dir to the actual
# package dir, this tells setuptools to look for a .so file without the
# Python ABI suffix, i.e. "module.so" instead of e.g.
# "module.cpython-38-x86_64-linux-gnu.so", which is what setuptools
# looks for by default.
ext_filename = super().get_ext_filename(fullname)
ext_filename_parts = ext_filename.split(".")
without_abi = ext_filename_parts[:-2] + ext_filename_parts[-1:]
ext_filename = ".".join(without_abi)
return ext_filename
video_library = Extension(
# The name parameter specifies not just the name but mainly *where* the .so
# file should be copied to.
name="torchcodec.libtorchcodec",
# sources is a mandatory parameter so we have to pass it, but we leave it
# empty because we'll be building the extension with our custom CMakeBuild
# class, and the sources are specified within CMakeFiles.txt.
sources=[],
)
setup(ext_modules=[video_library], cmdclass={"build_ext": CMakeBuild})