opencv-python-cuda

Workflow Guide

Repository Setup

Cloning the Repository

git clone https://github.com/Breakthrough/opencv-python-cuda.git
cd opencv-python-cuda

Adding Upstream Remote

To sync with the main opencv/opencv-python repository, add it as a remote:

git remote add upstream https://github.com/opencv/opencv-python.git

Preventing Tag Pollution

The upstream opencv/opencv-python repo has numeric tags (0, 1, 2, ... 90) that will pollute your local repo during fetches. To prevent this, configure the remote to exclude tags:

git config remote.upstream.tagOpt --no-tags
git config --add remote.upstream.fetch '^refs/tags/*'

The tagOpt setting alone is sometimes not respected, so the negative refspec (^refs/tags/*) explicitly excludes all tags.

Syncing with Upstream

After configuring the remote, you can sync without getting unwanted tags:

git fetch upstream
git pull --rebase upstream 4.x

Removing Accidentally Fetched Tags

If you already fetched the numeric tags, remove them with:

git tag -d 0 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 68 70 72 74 76 78 80 82 84 86 88 90

Triggering Builds

To trigger the Windows CUDA build workflow:

gh workflow run build_wheels_windows.yml --ref 4.x-cuda -R Breakthrough/opencv-python-cuda

Important: Always specify -R Breakthrough/opencv-python-cuda when using gh commands. This repo is a fork of opencv/opencv-python, and gh will default to the parent repository without the explicit -R flag.

Build Options

Option Description Default
restore_build_cache Restore build cache from previous runs true
save_build_cache Save build cache after completion false
rolling_build Use latest commit from upstream OpenCV false

Example with options:

gh workflow run build_wheels_windows.yml --ref 4.x-cuda -R Breakthrough/opencv-python-cuda \
  -f restore_build_cache=false \
  -f save_build_cache=true

Force Rebuild (No Cache)

To force a complete rebuild without using cached artifacts:

gh workflow run build_wheels_windows.yml --ref 4.x-cuda -R Breakthrough/opencv-python-cuda \
  -f restore_build_cache=false

Monitoring Builds

List recent runs:

gh run list -R Breakthrough/opencv-python-cuda --limit 5

Watch a running build:

gh run watch <run-id> -R Breakthrough/opencv-python-cuda

View build details:

gh run view <run-id> -R Breakthrough/opencv-python-cuda

Package Index

Wheels are too large for PyPI, so a PEP 503 "simple" index is published on this site at packages/. It is a static HTML listing of every .whl asset on GitHub Releases, each link carrying a #sha256= fragment so pip verifies the download. The wheels themselves stay on GitHub Releases; the index is only a few kilobytes.

pip install opencv-python-cuda --extra-index-url https://breakthrough.github.io/opencv-python-cuda/packages/

The index is generated by tools/gen_simple_index.py, which reads the GitHub Releases API (including the per-asset SHA-256 digest, so nothing is downloaded) and writes packages/index.html plus packages/opencv-python-cuda/index.html. Draft releases are skipped; pre-releases are included. The publish-docs.yml workflow runs the generator and deploys the result to the gh-pages branch together with docs/. It is triggered automatically by release events (publish, edit, delete) and by pushes to docs/; to regenerate it by hand:

gh workflow run publish-docs.yml --ref 4.x-cuda -R Breakthrough/opencv-python-cuda

To check what the index resolves to without downloading anything:

pip index versions opencv-python-cuda --index-url https://breakthrough.github.io/opencv-python-cuda/packages/

The generated packages/ directory only exists on gh-pages; it is never committed to 4.x-cuda. Run the generator locally with python tools/gen_simple_index.py --out <dir> to preview it.

Wheel Size & Format

The wheel ships as a standard ZIP using the default DEFLATE compression - no special repacking. GitHub limits each release asset to 2 GiB, and the wheel must fit under that limit.

The size strategy is DLL trimming, not compression. The "Remove unused CUDA DLLs" build step keeps only the CUDA libraries that cv2.pyd actually links against (determined via PE import analysis) and discards the rest - roughly 1.3 GB of unused libraries such as cuSPARSE, cuSOLVER, cuRAND, and nvRTC. This is what keeps the DEFLATE wheel under 2 GiB.

An earlier revision repacked the wheel with LZMA (ZIP_LZMA) to shrink it further, but this was abandoned: uv cannot install LZMA-compressed wheels (it errors with compression not supported: 14, see astral-sh/uv#13192). Plain DEFLATE installs correctly under both pip and uv.

Reference: Git Config for Remotes

After setup, your .git/config remote sections should look like:

[remote "origin"]
    url = https://github.com/Breakthrough/opencv-python-cuda.git
    fetch = +refs/heads/*:refs/remotes/origin/*

[remote "upstream"]
    url = https://github.com/opencv/opencv-python.git
    fetch = +refs/heads/*:refs/remotes/upstream/*
    fetch = ^refs/tags/*
    tagOpt = --no-tags