Windows CUDA x64 #79
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # GitHub Actions Workflow: Build opencv-python with CUDA support on Windows | |
| # | |
| # This workflow compiles opencv-python from source with CUDA enabled on a | |
| # GitHub-hosted Windows runner. The resulting Python wheel is then uploaded | |
| # as a build artifact. | |
| # | |
| # This is a complex and long-running process. It is configured to run only | |
| # on manual trigger (workflow_dispatch). | |
| name: Windows CUDA x64 | |
| on: | |
| workflow_dispatch: | |
| inputs: | |
| # TODO: Add cuda_version input to allow running only CUDA 12 or 13 builds for debugging | |
| # TODO: Right now we don't correctly determine when things have changed and we require a | |
| # rebuild, so for now we just manually trigger rebuilds between runs. | |
| restore_build_cache: | |
| description: "Restore build cache. Uncheck to force re-build." | |
| required: false | |
| type: boolean | |
| default: true | |
| save_build_cache: | |
| description: "Save build cache." | |
| required: false | |
| type: boolean | |
| default: true | |
| rolling_build: | |
| description: "Use latest commit from upstream OpenCV repo. Cache settings will be ignored." | |
| required: false | |
| type: boolean | |
| default: false | |
| jobs: | |
| Build: | |
| runs-on: ${{ matrix.runs-on }} | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| # Build variants control binary size vs JIT compilation tradeoff: | |
| # - full: CUDA 12, native SASS for all GPUs (5.0-10.0), largest binary, no JIT needed | |
| # - legacy: CUDA 11, PTX/SASS 3.5, for older GPUs (Kepler+) and systems with older drivers | |
| build-variant: ['full', 'legacy'] | |
| python-version: ['3.13'] | |
| platform: [x64] | |
| include: | |
| # CUDA 12 - Full variant: All SASS targets for maximum performance | |
| - build-variant: 'full' | |
| runs-on: 'windows-2025' | |
| cuda-version: '12' | |
| cmake-toolset: 'v143' | |
| cuda-installer: 'cuda_12.9.1_windows_network.exe' | |
| cuda-path-version: 'v12.9' | |
| cudnn-archive: 'cudnn-windows-x86_64-9.18.1.3_cuda12-archive.zip' | |
| cudnn-folder: 'cudnn-windows-x86_64-9.18.1.3_cuda12-archive' | |
| cudnn-dll-path: 'bin/x64' | |
| video-codec-sdk-archive: 'Video_Codec_SDK_13.0.37.zip' | |
| video-codec-sdk-folder: 'Video_Codec_SDK_13.0.37' | |
| cuda-arch-bin: '5.0;5.2;6.0;6.1;7.0;7.5;8.0;8.6;8.9;9.0;10.0' | |
| cuda-arch-ptx: '10.0' | |
| cache-key: 'nvidia-deps-cuda-12.9.1-cudnn-9.18.1.3' | |
| # CUDA 11 - Legacy variant: For older GPUs (Kepler+) and systems with older drivers | |
| # NOTE: CUDA 11.8 requires VS2017-VS2022, so we use windows-2022 with v142 toolset | |
| - build-variant: 'legacy' | |
| runs-on: 'windows-2022' | |
| cuda-version: '11' | |
| cmake-toolset: 'v142' | |
| cuda-installer: 'cuda_11.8.0_windows_network.exe' | |
| cuda-path-version: 'v11.8' | |
| cudnn-archive: 'cudnn-windows-x86_64-8.9.7.29_cuda11-archive.zip' | |
| cudnn-folder: 'cudnn-windows-x86_64-8.9.7.29_cuda11-archive' | |
| cudnn-dll-path: 'bin' | |
| video-codec-sdk-archive: 'Video_Codec_SDK_13.0.37.zip' | |
| video-codec-sdk-folder: 'Video_Codec_SDK_13.0.37' | |
| cuda-arch-bin: '3.5' | |
| cuda-arch-ptx: '3.5' | |
| cache-key: 'nvidia-deps-cuda-11.8.0-cudnn-8.9.7.29' | |
| env: | |
| ACTIONS_ALLOW_UNSECURE_COMMANDS: true | |
| SDIST: 0 | |
| ENABLE_HEADLESS: 0 | |
| ENABLE_CONTRIB: 1 | |
| ENABLE_ROLLING: ${{ inputs.rolling_build && 1 || 0 }} | |
| OPENCV_TEST_DATA_PATH: ${{ github.workspace }}\opencv_extra\testdata | |
| CUDA_ARCH_BIN: ${{ matrix.cuda-arch-bin }} | |
| CUDA_ARCH_PTX: ${{ matrix.cuda-arch-ptx }} | |
| steps: | |
| - name: Cleanup | |
| shell: bash | |
| run: | | |
| rm -rf ./* || true | |
| rm -rf ./.??* || true | |
| working-directory: ${{ github.workspace }} | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| with: | |
| submodules: false | |
| fetch-depth: 0 | |
| - name: Set up Python ${{ matrix.python-version }} | |
| uses: actions/setup-python@v4 | |
| with: | |
| python-version: ${{ matrix.python-version }} | |
| architecture: ${{ matrix.platform }} | |
| - name: Setup MSBuild.exe | |
| uses: microsoft/setup-msbuild@v1.1 | |
| - name: Setup NASM | |
| uses: ilammy/setup-nasm@v1 | |
| - name: Cache NVIDIA dependencies | |
| id: cache-nvidia-deps | |
| uses: actions/cache@v3 | |
| with: | |
| path: .deps/Nvidia | |
| key: ${{ matrix.cache-key }} | |
| - name: Clone NVIDIA dependencies | |
| if: steps.cache-nvidia-deps.outputs.cache-hit != 'true' | |
| env: | |
| SSH_PRIVATE_KEY: ${{ secrets.DEPS_REPO_SSH_KEY }} | |
| run: | | |
| eval "$(ssh-agent -s)" | |
| ssh-add - <<< "${SSH_PRIVATE_KEY}" | |
| ssh-keyscan github.com >> ~/.ssh/known_hosts 2>/dev/null | |
| git clone git@github.com:Breakthrough/opencv-python-cuda-deps.git .deps | |
| shell: bash | |
| - name: 🔧 Install NVIDIA CUDA Toolkit | |
| run: | | |
| $installer_path = ".deps/Nvidia/${{ matrix.cuda-installer }}" | |
| if (-not (Test-Path $installer_path)) { | |
| throw "CUDA Toolkit installer not found at $installer_path" | |
| } | |
| echo "Installing CUDA ${{ matrix.cuda-version }} Toolkit silently..." | |
| Start-Process -FilePath $installer_path -ArgumentList "-s" -Wait -NoNewWindow | |
| echo "Adding CUDA to PATH..." | |
| $CUDA_PATH = "C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\${{ matrix.cuda-path-version }}" | |
| echo "CUDA_PATH=$CUDA_PATH" | Out-File -FilePath $env:GITHUB_ENV -Append | |
| Copy-Item -Path "$CUDA_PATH/bin/*" -Destination . -Include "*.dll" | |
| shell: pwsh | |
| - name: 🔧 Install NVIDIA CuDNN | |
| run: | | |
| $cudnn_path = ".deps/Nvidia/${{ matrix.cudnn-archive }}" | |
| if (-not (Test-Path $cudnn_path)) { | |
| throw "CuDNN archive not found at $cudnn_path" | |
| } | |
| echo "Installing CuDNN for CUDA ${{ matrix.cuda-version }}..." | |
| 7z x $cudnn_path | |
| $CUDNN_PATH = "D:/a/opencv-python-cuda/opencv-python-cuda/${{ matrix.cudnn-folder }}" | |
| echo "CUDNN_LIBRARY=$CUDNN_PATH/lib/x64/cudnn.lib" | Out-File -FilePath $env:GITHUB_ENV -Append | |
| echo "CUDNN_INCLUDE_DIR=$CUDNN_PATH/include" | Out-File -FilePath $env:GITHUB_ENV -Append | |
| Copy-Item -Path "$CUDNN_PATH/${{ matrix.cudnn-dll-path }}/*" -Destination . -Include "*.dll" | |
| shell: pwsh | |
| - name: 🔧 Install NVIDIA Video Codec SDK | |
| run: | | |
| $sdk_path = ".deps/Nvidia/${{ matrix.video-codec-sdk-archive }}" | |
| if (-not (Test-Path $sdk_path)) { | |
| throw "Video Codec SDK archive not found at $sdk_path" | |
| } | |
| echo "Installing Video Codec SDK..." | |
| 7z x $sdk_path | |
| $SDK_PATH = "D:/a/opencv-python-cuda/opencv-python-cuda/${{ matrix.video-codec-sdk-folder }}" | |
| echo "CUDA_nvcuvid_LIBRARY=$SDK_PATH/Lib/win/x64/nvcuvid.lib" | Out-File -FilePath $env:GITHUB_ENV -Append | |
| echo "CUDA_nvencodeapi_LIBRARY=$SDK_PATH/Lib/win/x64/nvencodeapi.lib" | Out-File -FilePath $env:GITHUB_ENV -Append | |
| echo "NVCUVID_INCLUDE_DIR=$SDK_PATH/Interface" | Out-File -FilePath $env:GITHUB_ENV -Append | |
| shell: pwsh | |
| - name: Restore build artifacts | |
| uses: actions/cache/restore@v3 | |
| if: ${{ inputs.restore_build_cache && !inputs.rolling_build }} | |
| with: | |
| path: _skbuild | |
| key: ${{ runner.os }}-${{ matrix.python-version }}-cuda${{ matrix.cuda-version }}-${{ matrix.build-variant }}-${{ hashFiles('**/CMakeLists.txt') }} | |
| restore-keys: | | |
| ${{ runner.os }}-${{ matrix.python-version }}-cuda${{ matrix.cuda-version }}-${{ matrix.build-variant }}- | |
| - name: Build a package | |
| # CMake 3.25 regression fix. See https://stackoverflow.com/questions/74162633/problem-compiling-from-source-opencv-with-mvsc2019-in-64-bit-version | |
| run: | | |
| python --version | |
| python -m pip install --upgrade pip | |
| python -m pip install --upgrade setuptools | |
| python -m pip install cmake==3.24.2 | |
| python -m pip install toml | |
| python -c "import toml; c = toml.load('pyproject.toml'); print('\n'.join(c['build-system']['requires']))" > requirements.txt | |
| python -m pip install -r requirements.txt | |
| $CI_BUILD = 1 | |
| if (Test-Path _skbuild) { | |
| $SKIP_CMAKE = "--skip-cmake" | |
| } | |
| # Set CMake generator and toolset (e.g., v142 for CUDA 11, v143 for CUDA 12) | |
| # Note: Toolset (-T) requires Visual Studio generator, not Ninja | |
| # Using environment variables avoids quoting issues with CMAKE_ARGS | |
| $env:CMAKE_GENERATOR = "Visual Studio 17 2022" | |
| $env:CMAKE_GENERATOR_PLATFORM = "x64" | |
| $env:CMAKE_GENERATOR_TOOLSET = "${{ matrix.cmake-toolset }}" | |
| echo "Using CMake generator: Visual Studio 17 2022, platform: x64, toolset: ${{ matrix.cmake-toolset }}" | |
| python setup.py $SKIP_CMAKE bdist_wheel --py-limited-api=cp37 --dist-dir="$PWD\wheelhouse" -v | |
| shell: pwsh | |
| - name: Save build artifacts to cache | |
| uses: actions/cache/save@v3 | |
| if: ${{ inputs.save_build_cache && !inputs.rolling_build }} | |
| with: | |
| path: _skbuild | |
| key: ${{ runner.os }}-${{ matrix.python-version }}-cuda${{ matrix.cuda-version }}-${{ matrix.build-variant }}-${{ hashFiles('**/CMakeLists.txt') }} | |
| - name: Saving all wheels | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: opencv-python-cuda-${{ matrix.build-variant }}-${{ matrix.platform }} | |
| path: wheelhouse/opencv* | |
| Test: | |
| needs: [Build] | |
| runs-on: windows-2025 | |
| defaults: | |
| run: | |
| shell: cmd | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| python-version: ['3.12'] | |
| platform: [x64] | |
| build-variant: ['full', 'legacy'] | |
| env: | |
| ACTIONS_ALLOW_UNSECURE_COMMANDS: true | |
| OPENCV_TEST_DATA_PATH: ${{ github.workspace }}\opencv_extra\testdata | |
| steps: | |
| - name: Cleanup | |
| shell: bash | |
| run: | | |
| rm -rf ./* || true | |
| rm -rf ./.??* || true | |
| working-directory: ${{ github.workspace }} | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| with: | |
| submodules: true | |
| fetch-depth: 0 | |
| - name: Set up Python ${{ matrix.python-version }} | |
| uses: actions/setup-python@v4 | |
| with: | |
| python-version: ${{ matrix.python-version }} | |
| architecture: ${{ matrix.platform }} | |
| - name: Download a wheel accordingly to matrix | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: opencv-python-cuda-${{ matrix.build-variant }}-${{ matrix.platform }} | |
| path: wheelhouse/ | |
| - name: Package installation | |
| run: | | |
| cd ${{ github.workspace }}/tests | |
| &python -m pip install --user --no-warn-script-location (ls "../wheelhouse/opencv*.whl") | |
| if ($LastExitCode -ne 0) {throw $LastExitCode} | |
| python get_build_info.py | |
| shell: powershell | |
| - name: Run tests | |
| run: | | |
| cd ${{ github.workspace }}/tests | |
| python test.py |