Skip to content

Commit a92772c

Browse files
authored
Bindings: Add Python wrapper in meta-package (#954)
* Add Python wrapper in meta-package Signed-off-by: Ovidiu Mara <[email protected]> * Clarify installation procedure Signed-off-by: Ovidiu Mara <[email protected]> * Remove shebang Signed-off-by: Ovidiu Mara <[email protected]> * Revert quote change Signed-off-by: Ovidiu Mara <[email protected]> * Silence mypy warning in precommit Signed-off-by: Ovidiu Mara <[email protected]> * Fix `pip install .` it should build nixl-cu12 by default Signed-off-by: Ovidiu Mara <[email protected]> * Make nixl-cu12 a required dependency of nixl Signed-off-by: Ovidiu Mara <[email protected]> * Install uv build dependency in CI Signed-off-by: Ovidiu Mara <[email protected]> * Fix wheel build issues in CI environment Signed-off-by: Ovidiu Mara <[email protected]> * Fix gitlab CI pipeline Signed-off-by: Ovidiu Mara <[email protected]> --------- Signed-off-by: Ovidiu Mara <[email protected]>
1 parent 3e79948 commit a92772c

File tree

17 files changed

+136
-25
lines changed

17 files changed

+136
-25
lines changed

.gitlab/build.sh

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,11 @@ chmod +x rustup-init
122122
./rustup-init -y --default-toolchain 1.86.0
123123
export PATH="$HOME/.cargo/bin:$PATH"
124124

125+
wget --tries=3 --waitretry=5 "https://astral.sh/uv/install.sh" -O install_uv.sh
126+
chmod +x install_uv.sh
127+
./install_uv.sh
128+
export PATH="$HOME/.local/bin:$PATH"
129+
125130
curl -fSsL "https://github.com/openucx/ucx/tarball/${UCX_VERSION}" | tar xz
126131
( \
127132
cd openucx-ucx* && \
@@ -211,6 +216,7 @@ export UCX_TLS=^cuda_ipc
211216
# shellcheck disable=SC2086
212217
meson setup nixl_build --prefix=${INSTALL_DIR} -Ducx_path=${UCX_INSTALL_DIR} -Dbuild_docs=true -Drust=false ${EXTRA_BUILD_ARGS} -Dlibfabric_path="${LIBFABRIC_INSTALL_DIR}"
213218
ninja -C nixl_build && ninja -C nixl_build install
219+
mkdir -p dist && cp nixl_build/src/bindings/python/nixl-meta/nixl-*.whl dist/
214220

215221
# TODO(kapila): Copy the nixl.pc file to the install directory if needed.
216222
# cp ${BUILD_DIR}/nixl.pc ${INSTALL_DIR}/lib/pkgconfig/nixl.pc

.gitlab/test_python.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ export NIXL_PREFIX=${INSTALL_DIR}
4141
export NIXL_DEBUG_LOGGING=yes
4242

4343
pip3 install --break-system-packages .
44+
pip3 install --break-system-packages dist/nixl-*none-any.whl
4445
pip3 install --break-system-packages pytest
4546
pip3 install --break-system-packages pytest-timeout
4647
pip3 install --break-system-packages zmq

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,7 @@ Or build from source:
162162
```bash
163163
# From the root nixl directory
164164
pip install .
165+
pip install <name_of_build_dir>/src/bindings/python/nixl-meta/nixl-*.whl
165166
```
166167

167168
For Python examples, see [examples/python/](examples/python/).

contrib/Dockerfile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -222,4 +222,5 @@ RUN export PATH=$VIRTUAL_ENV/bin:$PATH && \
222222
--nixl-plugins-dir $NIXL_PLUGIN_DIR \
223223
--output-dir /workspace/nixl/dist
224224

225-
RUN uv pip install dist/nixl*cp${DEFAULT_PYTHON_VERSION//./}*.whl
225+
RUN cp build/src/bindings/python/nixl-meta/nixl-*.whl dist/
226+
RUN uv pip install dist/nixl*cp${DEFAULT_PYTHON_VERSION//./}*.whl dist/nixl-*-none-any.whl

contrib/build-wheel.sh

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,8 @@ if [ "$CUDA_MAJOR" -ne 12 ] && [ "$CUDA_MAJOR" -ne 13 ]; then
8383
exit 1
8484
fi
8585
PKG_NAME="nixl-cu${CUDA_MAJOR}"
86-
./contrib/tomlutil.py --set-name $PKG_NAME pyproject.toml
86+
PKG_DIR="nixl_cu${CUDA_MAJOR}"
87+
./contrib/tomlutil.py --wheel-name $PKG_NAME --wheel-dir $PKG_DIR pyproject.toml
8788
uv build --wheel --out-dir $TMP_DIR --python $PYTHON_VERSION
8889

8990
# Bundle libraries

contrib/tomlutil.py

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,15 +20,38 @@
2020
import tomlkit
2121

2222
parser = argparse.ArgumentParser()
23-
parser.add_argument("--set-name", type=str, help="Set the project name")
23+
parser.add_argument("--wheel-name", type=str, help="Set the project name")
24+
parser.add_argument("--wheel-dir", type=str, help="Set the wheel dir")
2425
parser.add_argument("file", type=str, help="The toml file to modify")
2526
args = parser.parse_args()
2627

2728
with open(args.file) as f:
2829
doc = tomlkit.parse(f.read())
2930

30-
if args.set_name:
31-
doc["project"]["name"] = args.set_name
31+
if args.wheel_name:
32+
# Set the wheel name
33+
# Example:
34+
# ```toml
35+
# [project]
36+
# name = "<wheel_name>"
37+
# ```
38+
doc["project"]["name"] = args.wheel_name
39+
40+
if args.wheel_dir:
41+
# Set the wheel dir
42+
# Example:
43+
# ```toml
44+
# [tool.meson-python.args]
45+
# setup = ["-Dinstall_headers=false", "-Dwheel_dir=<wheel_dir>"]
46+
# ```
47+
if "meson-python" not in doc["tool"]:
48+
doc["tool"]["meson-python"] = tomlkit.table()
49+
if "args" not in doc["tool"]["meson-python"]:
50+
doc["tool"]["meson-python"]["args"] = tomlkit.table()
51+
setup = doc["tool"]["meson-python"]["args"].get("setup", [])
52+
setup = [s for s in setup if not s.startswith("-Dwheel_dir=")]
53+
setup.append(f"-Dwheel_dir={args.wheel_dir}")
54+
doc["tool"]["meson-python"]["args"]["setup"] = setup
3255

3356
with open(args.file, "w") as f:
3457
f.write(tomlkit.dumps(doc))

meson_options.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ option('static_plugins', type: 'string', value: '', description: 'Plugins to be
2828
option('build_docs', type: 'boolean', value: false, description: 'Build Doxygen documentation')
2929
option('log_level', type: 'combo', choices: ['trace', 'debug', 'info', 'warning', 'error', 'fatal', 'auto'], value: 'auto', description: 'Log Level (auto: auto-detect based on build type: trace for debug builds, info for release builds)')
3030
option('rust', type: 'boolean', value: false, description: 'Build Rust bindings')
31+
option('wheel_dir', type : 'string', value : 'nixl', description : 'Set a custom Python wheel dir (e.g. nixl_cu12)')
3132

3233
# Tests
3334
option('build_tests', type: 'boolean', value: true, description: 'Build all tests')

pyproject.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ requires = ["meson-python", "pybind11", "patchelf", "pyyaml", "types-PyYAML", "p
1818
build-backend = "mesonpy"
1919

2020
[project]
21-
name = 'nixl'
21+
name = 'nixl-cu12'
2222
version = '0.6.1'
2323
description = 'NIXL Python API'
2424
readme = 'README.md'
@@ -34,4 +34,4 @@ dependencies = ["torch", "numpy"]
3434
profile = "black"
3535

3636
[tool.meson-python.args]
37-
setup = ['-Dinstall_headers=false']
37+
setup = ['-Dinstall_headers=false', '-Dwheel_dir=nixl_cu12']

src/api/python/__init__.py

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,17 +15,14 @@
1515

1616
import os
1717

18-
import nixl
19-
20-
__all__ = ["nixl"]
21-
2218
if "NIXL_PLUGIN_DIR" not in os.environ:
2319
# name for local installation
24-
plugin_dir = nixl.__file__[:-16] + ".nixl.mesonpy.libs/plugins/"
20+
package_root = os.path.dirname(__file__)
21+
plugin_dir = os.path.join(package_root, ".nixl.mesonpy.libs/plugins/")
2522

26-
# name for pypi installation
23+
# fallback for PyPI installation
2724
if not os.path.isdir(plugin_dir):
28-
plugin_dir = nixl.__file__[:-16] + ".nixl_pybind.mesonpy.libs/plugins/"
25+
plugin_dir = os.path.join(package_root, ".nixl_pybind.mesonpy.libs/plugins/")
2926

3027
if os.path.isdir(plugin_dir):
3128
os.environ["NIXL_PLUGIN_DIR"] = plugin_dir

src/api/python/_api.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@
1919
import numpy as np
2020
import torch
2121

22-
import nixl._bindings as nixlBind
23-
from nixl.logging import get_logger
22+
from . import _bindings as nixlBind # type: ignore
23+
from .logging import get_logger
2424

2525
# Get logger using centralized configuration
2626
logger = get_logger(__name__)

0 commit comments

Comments
 (0)