Skip to content

Commit 6f635da

Browse files
committed
[dist] Build module with CUDA enabled
1 parent ba84fb8 commit 6f635da

File tree

2 files changed

+89
-37
lines changed

2 files changed

+89
-37
lines changed

.github/workflows/build_wheels_windows.yml

Lines changed: 67 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,13 @@
1-
name: Windows x86_64
1+
# GitHub Actions Workflow: Build opencv-python with CUDA support on Windows
2+
#
3+
# This workflow compiles opencv-python from source with CUDA enabled on a
4+
# GitHub-hosted Windows runner. The resulting Python wheel is then uploaded
5+
# as a build artifact.
6+
#
7+
# This is a complex and long-running process. It is configured to run only
8+
# on manual trigger (workflow_dispatch).
9+
10+
name: Windows CUDA x64
211

312
on:
413
workflow_dispatch:
@@ -12,14 +21,11 @@ jobs:
1221
matrix:
1322
python-version: ['3.9']
1423
platform: [x64]
15-
with_contrib: [1]
16-
headless: [0]
17-
build_sdist: [0]
1824
env:
1925
ACTIONS_ALLOW_UNSECURE_COMMANDS: true
20-
SDIST: ${{ matrix.build_sdist || 0 }}
21-
ENABLE_HEADLESS: ${{ matrix.headless }}
22-
ENABLE_CONTRIB: ${{ matrix.with_contrib }}
26+
SDIST: 0
27+
ENABLE_HEADLESS: 0
28+
ENABLE_CONTRIB: 1
2329
OPENCV_TEST_DATA_PATH: ${{ github.workspace }}\opencv_extra\testdata
2430
steps:
2531
- name: Cleanup
@@ -48,6 +54,58 @@ jobs:
4854
uses: microsoft/setup-msbuild@v1.1
4955
- name: Setup NASM
5056
uses: ilammy/setup-nasm@v1
57+
- name: Cache CUDA Toolkit Installer
58+
id: cache-cuda-installer
59+
uses: actions/cache@v3
60+
with:
61+
path: ./.cache/cuda_installer.exe
62+
key: cuda-installer-12.0.0
63+
- name: 🔧 Install NVIDIA CUDA Toolkit
64+
run: |
65+
$installer_path = "./.cache/cuda_installer.exe"
66+
if (-not (Test-Path $installer_path)) {
67+
echo "Downloading CUDA Toolkit..."
68+
$cuda_installer_url = "https://developer.download.nvidia.com/compute/cuda/12.0.0/network_installers/cuda_12.0.0_windows_network.exe"
69+
New-Item -Path (Split-Path $installer_path) -ItemType Directory -Force
70+
curl -L -o $installer_path $cuda_installer_url
71+
} else {
72+
echo "CUDA Toolkit installer found in cache."
73+
}
74+
echo "Installing CUDA Toolkit silently..."
75+
$arguments = "-s nvcc_12.0 cudart_12.0 cublas_12.0 cublas_dev_12.0 cufft_12.0 cufft_dev_12.0 npp_12.0 npp_dev_12.0"
76+
Start-Process -FilePath $installer_path -ArgumentList $arguments -Wait -NoNewWindow
77+
echo "Adding CUDA to PATH..."
78+
$CUDA_PATH = "C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v12.0"
79+
echo "CUDA_PATH=$CUDA_PATH" | Out-File -FilePath $env:GITHUB_ENV -Append
80+
shell: pwsh
81+
#$arguments = "-s cublas_12.0 cublas_dev_12.0 cudart_12.0 cufft_12.0 cufft_dev_12.0 npp_12.0 npp_dev_12.0 nvcc_12.0"
82+
#echo "$CUDA_PATH\bin" | Out-File -FilePath $env:GITHUB_PATH -Append
83+
#echo "$CUDA_PATH\lib\x64" | Out-File -FilePath $env:GITHUB_PATH -Append
84+
#echo "$CUDA_PATH"
85+
- name: Cache CuDNN Installer
86+
id: cache-cudnn-installer
87+
uses: actions/cache@v3
88+
with:
89+
path: ./.cache/cudnn.zip
90+
key: cudnn-8.9.7.29-cuda-12-windows
91+
- name: 🔧 Install NVIDIA CuDNN
92+
run: |
93+
$cudnn_path = "./.cache/cudnn.zip"
94+
if (-not (Test-Path $cudnn_path)) {
95+
echo "Downloading CuDNN..."
96+
$cudnn_installer_url = "https://developer.download.nvidia.com/compute/cudnn/redist/cudnn/windows-x86_64/cudnn-windows-x86_64-8.9.7.29_cuda12-archive.zip"
97+
New-Item -Path (Split-Path $cudnn_path) -ItemType Directory -Force
98+
curl -L -o $cudnn_path $cudnn_installer_url
99+
} else {
100+
echo "CuDNN installer found in cache."
101+
}
102+
echo "Installing CuDNN..."
103+
7z x $cudnn_path
104+
$CUDNN_PATH = "/a/opencv-python-cuda/opencv-python-cuda/cudnn-windows-x86_64-8.9.7.29_cuda12-archive"
105+
echo "CUDNN_LIBRARY=$CUDNN_PATH/lib/x64" | Out-File -FilePath $env:GITHUB_ENV -Append
106+
echo "CUDNN_INCLUDE_DIR=$CUDNN_PATH/include" | Out-File -FilePath $env:GITHUB_ENV -Append
107+
shell: pwsh
108+
51109
- name: Build a package
52110
# CMake 3.25 regression fix. See https://stackoverflow.com/questions/74162633/problem-compiling-from-source-opencv-with-mvsc2019-in-64-bit-version
53111
run: |
@@ -61,7 +119,7 @@ jobs:
61119
- name: Saving all wheels
62120
uses: actions/upload-artifact@v4
63121
with:
64-
name: wheel-${{ matrix.with_contrib }}-${{ matrix.headless }}-${{ matrix.build_sdist }}-${{ matrix.platform }}
122+
name: wheel-cuda-${{ matrix.platform }}
65123
path: wheelhouse/opencv*
66124

67125
Test:
@@ -75,9 +133,6 @@ jobs:
75133
matrix:
76134
python-version: ['3.12']
77135
platform: [x64]
78-
with_contrib: [1]
79-
headless: [0]
80-
build_sdist: [0]
81136
env:
82137
ACTIONS_ALLOW_UNSECURE_COMMANDS: true
83138
OPENCV_TEST_DATA_PATH: ${{ github.workspace }}\opencv_extra\testdata
@@ -103,7 +158,7 @@ jobs:
103158
- name: Download a wheel accordingly to matrix
104159
uses: actions/download-artifact@v4
105160
with:
106-
name: wheel-${{ matrix.with_contrib }}-${{ matrix.headless }}-${{ matrix.build_sdist }}-${{ matrix.platform }}
161+
name: wheel-cuda-${{ matrix.platform }}
107162
path: wheelhouse/
108163
- name: Package installation
109164
run: |

setup.py

Lines changed: 22 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -75,21 +75,7 @@ def main():
7575
# https://stackoverflow.com/questions/1405913/python-32bit-or-64bit-mode
7676
is64 = sys.maxsize > 2 ** 32
7777

78-
package_name = "opencv-python"
79-
80-
if build_contrib and not build_headless:
81-
package_name = "opencv-contrib-python"
82-
83-
if build_contrib and build_headless:
84-
package_name = "opencv-contrib-python-headless"
85-
86-
if build_headless and not build_contrib:
87-
package_name = "opencv-python-headless"
88-
89-
if build_rolling:
90-
package_name += "-rolling"
91-
92-
package_name = os.environ.get('OPENCV_PYTHON_PACKAGE_NAME', package_name)
78+
package_name = "opencv-python-cuda"
9379

9480
long_description = io.open("README.md", encoding="utf-8").read()
9581

@@ -162,18 +148,23 @@ def main():
162148
else ["-G", "Unix Makefiles"]
163149
)
164150

151+
cudnn_library = os.environ["CUDNN_LIBRARY"]
152+
cudnn_include_dir = os.environ["CUDNN_INCLUDE_DIR"]
153+
cuda_arch_bin = "6.0;6.1;7.0;7.5"
154+
cuda_arch_ptx = "7.5"
155+
165156
cmake_args = (
166157
(ci_cmake_generator if is_CI_build else [])
167158
+ [
168159
# skbuild inserts PYTHON_* vars. That doesn't satisfy opencv build scripts in case of Py3
169-
"-DPYTHON3_EXECUTABLE=%s" % sys.executable,
170-
"-DPYTHON_DEFAULT_EXECUTABLE=%s" % sys.executable,
171-
"-DPYTHON3_INCLUDE_DIR=%s" % python_include_dir,
172-
"-DPYTHON3_LIBRARY=%s" % python_lib_path,
160+
f"-DPYTHON3_EXECUTABLE={sys.executable}",
161+
f"-DPYTHON_DEFAULT_EXECUTABLE={sys.executable}",
162+
f"-DPYTHON3_INCLUDE_DIR=\"{python_include_dir}\"",
163+
f"-DPYTHON3_LIBRARY=\"{python_lib_path}\"",
173164
"-DBUILD_opencv_python3=ON",
174165
"-DBUILD_opencv_python2=OFF",
175166
# Disable the Java build by default as it is not needed
176-
"-DBUILD_opencv_java=%s" % build_java,
167+
f"-DBUILD_opencv_java={build_java}",
177168
# Relative dir to install the built module to in the build tree.
178169
# The default is generated from sysconfig, we'd rather have a constant for simplicity
179170
"-DOPENCV_PYTHON3_INSTALL_PATH=python",
@@ -189,6 +180,13 @@ def main():
189180
"-DBUILD_DOCS=OFF",
190181
"-DPYTHON3_LIMITED_API=ON",
191182
"-DBUILD_OPENEXR=ON",
183+
"-DWITH_CUDA=ON",
184+
"-DWITH_NVCUVID=OFF",
185+
f"-DCUDA_ARCH_BIN=\"{cuda_arch_bin}\"",
186+
f"-DCUDA_ARCH_PTX=\"{cuda_arch_ptx}\"",
187+
"-DOPENCV_ENABLE_NONFREE=ON",
188+
f"-DCUDNN_LIBRARY=\"{cudnn_library}\"",
189+
f"-DCUDNN_INCLUDE_DIR=\"{cudnn_include_dir}\"",
192190
]
193191
+ (
194192
# CMake flags for windows/arm64 build
@@ -266,17 +264,17 @@ def main():
266264
setup(
267265
name=package_name,
268266
version=package_version,
269-
url="https://github.com/opencv/opencv-python",
267+
url="https://github.com/Breakthrough/opencv-python-cuda",
270268
license="Apache 2.0",
271-
description="Wrapper package for OpenCV python bindings.",
269+
description="[Unofficial] OpenCV Python bindings with CUDA support.",
272270
long_description=long_description,
273271
long_description_content_type="text/markdown",
274272
packages=packages,
275273
package_data=package_data,
276-
maintainer="OpenCV Team",
274+
maintainer="Breakthrough",
277275
ext_modules=EmptyListWithLength(),
278276
install_requires=install_requires,
279-
python_requires=">=3.6",
277+
python_requires=">=3.7",
280278
classifiers=[
281279
"Development Status :: 5 - Production/Stable",
282280
"Environment :: Console",
@@ -292,7 +290,6 @@ def main():
292290
"Programming Language :: Python",
293291
"Programming Language :: Python :: 3",
294292
"Programming Language :: Python :: 3 :: Only",
295-
"Programming Language :: Python :: 3.6",
296293
"Programming Language :: Python :: 3.7",
297294
"Programming Language :: Python :: 3.8",
298295
"Programming Language :: Python :: 3.9",

0 commit comments

Comments
 (0)