@@ -14,14 +14,103 @@ permissions:
1414 contents : read
1515
1616jobs :
17- build_wheels :
18- name : Build wheel for ${{ matrix.os }}
19- runs-on : ${{ matrix.os }}
20- strategy :
21- fail-fast : false
22- matrix :
23- os : [ubuntu-22.04, windows-2022]
24- python-version : ["3.12"]
17+ build_wheels_linux :
18+ name : Build Linux wheels
19+ runs-on : ubuntu-22.04
20+
21+ steps :
22+ - name : Checkout code
23+ uses : actions/checkout@v4
24+
25+ - name : Set up Python 3.12
26+ uses : actions/setup-python@v5
27+ with :
28+ python-version : " 3.12"
29+
30+ # Build CUDA wheel using cibuildwheel with manylinux container
31+ - name : Build CUDA wheel (manylinux)
32+ 33+ env :
34+ # Use NVIDIA's CUDA devel image based on UBI8 (manylinux_2_28 compatible)
35+ # CUDA 13.0 will be installed inside the container
36+ CIBW_MANYLINUX_X86_64_IMAGE : quay.io/pypa/manylinux_2_28_x86_64
37+
38+ # Build only for Python 3.12 with stable ABI
39+ CIBW_BUILD : " cp312-manylinux_x86_64"
40+ CIBW_SKIP : " *-musllinux_*"
41+
42+ # Install CUDA 13.0 toolkit inside the container
43+ CIBW_BEFORE_ALL_LINUX : |
44+ # Install dnf plugins for config-manager command
45+ dnf install -y dnf-plugins-core
46+ # Add NVIDIA CUDA repository for RHEL 8
47+ dnf config-manager --add-repo https://developer.download.nvidia.com/compute/cuda/repos/rhel8/x86_64/cuda-rhel8.repo
48+ dnf clean all
49+ # Install ONLY the minimal CUDA packages needed for compilation (not the full toolkit)
50+ dnf install -y cuda-nvcc-13-0 cuda-cudart-devel-13-0 libcublas-devel-13-0 libnvjitlink-devel-13-0
51+ # Install Python development headers (fallback for CMake FindPython)
52+ dnf install -y python3-devel
53+ # Verify CUDA installation
54+ /usr/local/cuda-13.0/bin/nvcc --version
55+
56+ # Set CUDA environment and install build dependencies
57+ CIBW_ENVIRONMENT_LINUX : >
58+ CUDA_HOME=/usr/local/cuda-13.0
59+ PATH=/usr/local/cuda-13.0/bin:$PATH
60+ LD_LIBRARY_PATH=/usr/local/cuda-13.0/lib64:$LD_LIBRARY_PATH
61+ LIBRARY_PATH=/usr/local/cuda-13.0/lib64/stubs:$LIBRARY_PATH
62+
63+ # Install Python build dependencies
64+ CIBW_BEFORE_BUILD : " pip install nanobind cmake setuptools wheel"
65+
66+ # Repair wheel for manylinux compliance, excluding CUDA runtime libs
67+ # Users must have CUDA installed on their system
68+ CIBW_REPAIR_WHEEL_COMMAND_LINUX : >
69+ auditwheel repair -w {dest_dir} {wheel}
70+ --exclude libcuda.so.1
71+ --exclude libcudart.so.13
72+ --exclude libnvrtc.so.13
73+ --exclude libcublas.so.13
74+ --exclude libcublasLt.so.13
75+ --exclude libnvJitLink.so.13
76+
77+ with :
78+ output-dir : wheelhouse
79+
80+ - name : Build CPU-only wheel (py3-none-any)
81+ shell : bash
82+ run : |
83+ python -m pip install --upgrade pip
84+ pip install build setuptools wheel
85+ # Build CPU-only variant (pure Python, no CUDA)
86+ python setup.py bdist_wheel --no-cuda
87+ # Move to wheelhouse directory
88+ mv dist/*py3-none-any.whl wheelhouse/
89+
90+ - name : List built wheels
91+ shell : bash
92+ run : |
93+ ls -lh wheelhouse/
94+ echo "Built wheels:"
95+ ls -1 wheelhouse/*.whl
96+
97+ - name : Upload Linux CUDA wheel
98+ uses : actions/upload-artifact@v4
99+ with :
100+ name : wheels-linux-cuda
101+ path : wheelhouse/*manylinux*.whl
102+ if-no-files-found : error
103+
104+ - name : Upload CPU-only wheel
105+ uses : actions/upload-artifact@v4
106+ with :
107+ name : wheels-cpu-only
108+ path : wheelhouse/*py3-none-any.whl
109+ if-no-files-found : error
110+
111+ build_wheels_windows :
112+ name : Build Windows wheel
113+ runs-on : windows-2022
25114
26115 steps :
27116 - name : Checkout code
@@ -34,17 +123,9 @@ jobs:
34123 cuda : ' 13.0.2'
35124 method : ' network'
36125 use-github-cache : ' true'
37- log-file-suffix : ' ${{ matrix.os }}.txt'
38-
39- - name : Set additional CUDA environment variables (Linux)
40- if : runner.os == 'Linux'
41- shell : bash
42- run : |
43- echo "LD_LIBRARY_PATH=$CUDA_PATH/lib64:$CUDA_PATH/lib64/stubs:$LD_LIBRARY_PATH" >> $GITHUB_ENV
44- echo "LIBRARY_PATH=$CUDA_PATH/lib64:$CUDA_PATH/lib64/stubs:$LIBRARY_PATH" >> $GITHUB_ENV
126+ log-file-suffix : ' windows-2022.txt'
45127
46- - name : Set additional CUDA environment variables (Windows)
47- if : runner.os == 'Windows'
128+ - name : Set additional CUDA environment variables
48129 shell : pwsh
49130 run : |
50131 echo "CUDA_PATH_V13_0=$env:CUDA_PATH" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
@@ -56,12 +137,10 @@ jobs:
56137 echo "CUDA_PATH: $CUDA_PATH"
57138 nvcc --version
58139
59- - name : Setup MSVC (Windows)
60- if : runner.os == 'Windows'
140+ - name : Setup MSVC
61141 uses : ilammy/msvc-dev-cmd@v1
62142
63- - name : Setup CUDA MSBuild integration (Windows)
64- if : runner.os == 'Windows'
143+ - name : Setup CUDA MSBuild integration
65144 shell : pwsh
66145 run : |
67146 # Copy CUDA MSBuild integration files to Visual Studio directory
@@ -140,13 +219,12 @@ jobs:
140219
141220 Write-Host "CUDA MSBuild integration configured successfully"
142221
143- - name : Set up Python ${{ matrix.python-version }}
222+ - name : Set up Python 3.12
144223 uses : actions/setup-python@v5
145224 with :
146- python-version : ${{ matrix.python-version }}
225+ python-version : " 3.12 "
147226
148- - name : Create python3.lib for stable ABI (Windows)
149- if : runner.os == 'Windows'
227+ - name : Create python3.lib for stable ABI
150228 shell : pwsh
151229 run : |
152230 # Create python3.lib for stable ABI support
@@ -182,53 +260,80 @@ jobs:
182260 # Build with default platform-specific CUDA architectures from setup.py
183261 python setup.py bdist_wheel
184262
185- - name : Build CPU-only wheel (Linux only - py3-none-any)
186- if : runner.os == 'Linux'
187- shell : bash
188- run : |
189- # Clean build artifacts to avoid conflicts
190- rm -rf build *.egg-info
191- # Build CPU-only variant (pure Python, no CUDA)
192- # This produces a universal wheel that works on any platform
193- python setup.py bdist_wheel --no-cuda
194-
195263 - name : List built wheels
196264 shell : bash
197265 run : |
198266 ls -lh dist/
199267 echo "Built wheels:"
200268 ls -1 dist/*.whl
201269
202- - name : Upload wheels
270+ - name : Upload Windows wheel
203271 uses : actions/upload-artifact@v4
204272 with :
205- name : wheels-${{ matrix.os }}-py${{ matrix.python-version }}
273+ name : wheels-windows-cuda
206274 path : dist/*.whl
207275 if-no-files-found : error
208276
209- test :
210- name : Test on ${{ matrix.os }}
211- needs : build_wheels
212- runs-on : ${{ matrix.os }}
213- strategy :
214- fail-fast : false
215- matrix :
216- os : [ubuntu-22.04, windows-2022]
217- python-version : ["3.12"]
277+ test_linux :
278+ name : Test on Linux
279+ needs : build_wheels_linux
280+ runs-on : ubuntu-22.04
281+
282+ steps :
283+ - name : Checkout code
284+ uses : actions/checkout@v4
285+
286+ - name : Set up Python 3.12
287+ uses : actions/setup-python@v5
288+ with :
289+ python-version : " 3.12"
290+
291+ - name : Download CPU-only wheel
292+ uses : actions/download-artifact@v4
293+ with :
294+ name : wheels-cpu-only
295+ path : dist/
296+
297+ - name : Install wheel and test dependencies
298+ shell : bash
299+ run : |
300+ python -m pip install --upgrade pip
301+ # Install CPU-only PyTorch first (smaller download, no CUDA needed for CI)
302+ pip install torch --index-url https://download.pytorch.org/whl/cpu
303+ # Install the CPU-only wheel (py3-none-any works everywhere)
304+ pip install dist/*py3-none-any.whl
305+ pip install pytest ruff
306+
307+ - name : Ruff check
308+ shell : bash
309+ run : |
310+ ruff check .
311+
312+ - name : Run tests
313+ shell : bash
314+ run : |
315+ # Run all tests - conftest handles backend availability
316+ # Tests requiring CUDA will be skipped on CPU-only runners
317+ python -m pytest tests/ -v --tb=short
318+
319+ test_windows :
320+ name : Test on Windows
321+ needs : build_wheels_windows
322+ runs-on : windows-2022
218323
219324 steps :
220325 - name : Checkout code
221326 uses : actions/checkout@v4
222327
223- - name : Set up Python ${{ matrix.python-version }}
328+ - name : Set up Python 3.12
224329 uses : actions/setup-python@v5
225330 with :
226- python-version : ${{ matrix.python-version }}
331+ python-version : " 3.12 "
227332
228- - name : Download wheels
333+ - name : Download Windows wheel
229334 uses : actions/download-artifact@v4
230335 with :
231- name : wheels-${{ matrix.os }}-py${{ matrix.python-version }}
336+ name : wheels-windows-cuda
232337 path : dist/
233338
234339 - name : Install wheel and test dependencies
@@ -237,14 +342,8 @@ jobs:
237342 python -m pip install --upgrade pip
238343 # Install CPU-only PyTorch first (smaller download, no CUDA needed for CI)
239344 pip install torch --index-url https://download.pytorch.org/whl/cpu
240- # Install the CPU-only wheel on Linux, CUDA wheel on Windows
241- # (CPU wheel is py3-none-any, works everywhere without CUDA runtime)
242- if [ "$RUNNER_OS" == "Linux" ]; then
243- pip install dist/*py3-none-any.whl
244- else
245- # Windows: install the CUDA wheel (will work in CPU-only mode)
246- pip install dist/*.whl
247- fi
345+ # Windows: install the CUDA wheel (will work in CPU-only mode)
346+ pip install dist/*.whl
248347 pip install pytest ruff
249348
250349 - name : Ruff check
@@ -261,21 +360,34 @@ jobs:
261360
262361 publish :
263362 name : Publish to PyPI
264- needs : [build_wheels, test ]
363+ needs : [build_wheels_linux, build_wheels_windows, test_linux, test_windows ]
265364 runs-on : ubuntu-latest
266365 if : github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v')
267366 environment : pypi
268367
269368 steps :
270- - name : Download all wheel artifacts
369+ - name : Download Linux CUDA wheel
370+ uses : actions/download-artifact@v4
371+ with :
372+ name : wheels-linux-cuda
373+ path : dist/
374+
375+ - name : Download Windows CUDA wheel
271376 uses : actions/download-artifact@v4
272377 with :
273- pattern : wheels-*
378+ name : wheels-windows-cuda
379+ path : dist/
380+
381+ - name : Download CPU-only wheel
382+ uses : actions/download-artifact@v4
383+ with :
384+ name : wheels-cpu-only
274385 path : dist/
275- merge-multiple : true
276386
277387 - name : List wheels to publish
278- run : ls -la dist/
388+ run : |
389+ echo "Wheels to publish:"
390+ ls -la dist/
279391
280392 - name : Publish to PyPI
281393 uses : pypa/gh-action-pypi-publish@release/v1
0 commit comments