Skip to content

First version of cuda.bindings.path_finder #578

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 36 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
147b242
First version of `cuda.bindings.path_finder` (#447)
rwgk Apr 9, 2025
7a0c068
Make `path_finder` work for `"nvrtc"` (#553)
rwgk Apr 10, 2025
32f6c76
Merge branch 'main' into path_finder_dev
rwgk Apr 25, 2025
74c9750
Add `path_finder.SUPPORTED_LIBNAMES` (#558)
rwgk Apr 25, 2025
00f8e4d
Fix tiny accident: a line in pyproject.toml got lost somehow.
rwgk Apr 25, 2025
17478da
Undo changes to the nvJitLink, nvrtc, nvvm bindings
rwgk Apr 25, 2025
7da74bd
Undo changes under .github, specific to nvvm, manipulating LD_LIBRARY…
rwgk Apr 25, 2025
211164d
PARTIALLY_SUPPORTED_LIBNAMES_LINUX, PARTIALLY_SUPPORTED_LIBNAMES_WINDOWS
rwgk Apr 25, 2025
a649e7d
Update EXPECTED_LIB_SYMBOLS for nvJitLink to cleanly support CTK vers…
rwgk Apr 25, 2025
b5cef1b
Save result of factoring out load_dl_common.py, load_dl_linux.py, loa…
rwgk Apr 25, 2025
bc0137a
Fix an auto-generated docstring
rwgk Apr 25, 2025
001a6a2
first round of Cursor refactoring (about 4 iterations until all tests…
rwgk Apr 26, 2025
9721079
Revert "first round of Cursor refactoring (about 4 iterations until a…
rwgk Apr 26, 2025
c409346
A couple trivial tweaks
rwgk Apr 26, 2025
ceff853
Merge branch 'main' into path_finder_dev
rwgk Apr 26, 2025
0cd20d8
Merge branch 'path_finder_dev' into path_finder_review1
rwgk Apr 26, 2025
b3a3b16
Prefix the public API (just two items) with underscores for now.
rwgk Apr 28, 2025
42cb9b6
Merge branch 'main' into path_finder_review1
rwgk Apr 29, 2025
180eefd
Add SPDX-License-Identifier to all files under toolshed/ that don't h…
rwgk Apr 29, 2025
bfc4b69
Add SPDX-License-Identifier under cuda_bindings/tests/
rwgk Apr 29, 2025
a7001e1
Respond to "Do these need to be run as subprocesses?" review question…
rwgk Apr 29, 2025
4d95eb4
Respond to "dead code?" review questions (e.g. https://github.com/NVI…
rwgk Apr 29, 2025
72c339a
Respond to "Do we need to implement a cache separately ..." review qu…
rwgk Apr 29, 2025
4ce94be
Remove cuDriverGetVersion() function for now.
rwgk Apr 29, 2025
26eb4b5
Move add_dll_directory() from load_dl_common.py to load_dl_windows.py…
rwgk Apr 29, 2025
72d2567
Add SPDX-License-Identifier and # Forked from: URL in cuda_paths.py
rwgk Apr 29, 2025
e14391d
Add Add SPDX-License-Identifier and Original LICENSE in findlib.py
rwgk Apr 29, 2025
9154995
Very first draft of README.md
rwgk Apr 29, 2025
bdfc6a7
Update README.md, mostly as revised by perplexity, with various manua…
rwgk Apr 29, 2025
2279bda
Merge branch 'main' into path_finder_review1
rwgk Apr 30, 2025
2ad4b79
Refork cuda_paths.py AS-IS: https://github.com/NVIDIA/numba-cuda/blob…
rwgk Apr 30, 2025
7dcaa50
ruff format cuda_paths.py (NO manual changes)
rwgk Apr 30, 2025
714b88c
Add back _get_numba_CUDA_INCLUDE_PATH from 2279bda65640b73a9a5632df87…
rwgk Apr 30, 2025
166837d
Remove cuda_paths.py dependency on numba.cuda.cudadrv.runtime
rwgk Apr 30, 2025
ad1e85e
Add Forked from URLs, two SPDX-License-Identifier, Original Numba LIC…
rwgk Apr 30, 2025
47ad79f
Temporarily restore debug changes under .github/workflows, for expand…
rwgk Apr 30, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 0 additions & 10 deletions .github/workflows/build-and-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,9 @@ jobs:
matrix:
host-platform:
- linux-64
- linux-aarch64
- win-64
python-version:
- "3.13"
- "3.12"
- "3.11"
- "3.10"
- "3.9"
cuda-version:
# Note: this is for build-time only.
- "12.8.0"
Expand Down Expand Up @@ -215,13 +210,8 @@ jobs:
matrix:
host-platform:
- linux-64
- linux-aarch64
python-version:
- "3.13"
- "3.12"
- "3.11"
- "3.10"
- "3.9"
cuda-version:
# Note: this is for test-time only.
- "12.8.0"
Expand Down
12 changes: 8 additions & 4 deletions .github/workflows/test-wheel-linux.yml
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,10 @@ jobs:
fi
fi

if [[ "${{ inputs.local-ctk }}" != 1 ]]; then
echo "CUDA_BINDINGS_PATH_FINDER_TEST_ALL_LIBNAMES=1" >> $GITHUB_ENV
fi

# make outputs from the previous job as env vars
CUDA_CORE_ARTIFACT_BASENAME="cuda-core-python${PYTHON_VERSION_FORMATTED}-${{ inputs.host-platform }}"
echo "PYTHON_VERSION_FORMATTED=${PYTHON_VERSION_FORMATTED}" >> $GITHUB_ENV
Expand Down Expand Up @@ -216,7 +220,7 @@ jobs:

pushd ./cuda_bindings
pip install -r requirements.txt
${SANITIZER_CMD} pytest -rxXs -v tests/
${SANITIZER_CMD} pytest -ra -s -v tests/

# It is a bit convoluted to run the Cython tests against CTK wheels,
# so let's just skip them.
Expand All @@ -227,7 +231,7 @@ jobs:
# TODO: enable this once win-64 runners are up
exit 1
fi
${SANITIZER_CMD} pytest -rxXs -v tests/cython
${SANITIZER_CMD} pytest -ra -s -v tests/cython
fi
popd

Expand All @@ -251,7 +255,7 @@ jobs:

pushd ./cuda_core
pip install -r "tests/requirements-cu${TEST_CUDA_MAJOR}.txt"
${SANITIZER_CMD} pytest -rxXs -v tests/
${SANITIZER_CMD} pytest -ra -s -v tests/

# It is a bit convoluted to run the Cython tests against CTK wheels,
# so let's just skip them. Also, currently our CI always installs the
Expand All @@ -265,7 +269,7 @@ jobs:
# TODO: enable this once win-64 runners are up
exit 1
fi
${SANITIZER_CMD} pytest -rxXs -v tests/cython
${SANITIZER_CMD} pytest -ra -s -v tests/cython
fi
popd

Expand Down
9 changes: 5 additions & 4 deletions .github/workflows/test-wheel-windows.yml
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@ jobs:
}
}

"CUDA_BINDINGS_PATH_FINDER_TEST_ALL_LIBNAMES=1" >> $env:GITHUB_ENV

# Make outputs from the previous job as env vars
$CUDA_CORE_ARTIFACT_BASENAME = "cuda-core-python${PYTHON_VERSION_FORMATTED}-${{ inputs.host-platform }}"
"PYTHON_VERSION_FORMATTED=${PYTHON_VERSION_FORMATTED}" >> $env:GITHUB_ENV
Expand Down Expand Up @@ -165,8 +167,7 @@ jobs:
uses: Jimver/[email protected]
with:
cuda: ${{ inputs.cuda-version }}
method: 'network'
sub-packages: ${{ env.MINI_CTK_DEPS }}
method: 'local'

- name: Update PATH
if: ${{ inputs.local-ctk == '1' }}
Expand All @@ -190,7 +191,7 @@ jobs:

Push-Location ./cuda_bindings
pip install -r requirements.txt
pytest -rxXs -v tests/
pytest -ra -s -v tests/
# skip Cython tests for now (NVIDIA/cuda-python#466)
Pop-Location

Expand All @@ -214,7 +215,7 @@ jobs:

Push-Location ./cuda_core
pip install -r "tests/requirements-cu${TEST_CUDA_MAJOR}.txt"
pytest -rxXs -v tests/
pytest -ra -s -v tests/
Pop-Location

- name: Ensure cuda-python installable
Expand Down
61 changes: 61 additions & 0 deletions cuda_bindings/cuda/bindings/_path_finder/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
# `cuda.bindings.path_finder` Module

## Public API (Work in Progress)

Currently exposes two primary interfaces:

```
cuda.bindings.path_finder._SUPPORTED_LIBNAMES # ('nvJitLink', 'nvrtc', 'nvvm')
cuda.bindings.path_finder._load_nvidia_dynamic_library(libname: str) -> LoadedDL
Comment on lines +8 to +9
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
cuda.bindings.path_finder._SUPPORTED_LIBNAMES # ('nvJitLink', 'nvrtc', 'nvvm')
cuda.bindings.path_finder._load_nvidia_dynamic_library(libname: str) -> LoadedDL
cuda.bindings._path_finder._SUPPORTED_LIBNAMES # ('nvJitLink', 'nvrtc', 'nvvm')
cuda.bindings._path_finder._load_nvidia_dynamic_library(libname: str) -> LoadedDL

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the path is correct

```

**Note:**
These APIs are prefixed with an underscore because they are considered
experimental while undergoing active development, although already
reasonably well-tested through CI pipelines.

## Library Loading Search Priority

The `load_nvidia_dynamic_library()` function implements a hierarchical search
strategy for locating NVIDIA shared libraries:
Comment on lines +19 to +20
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should clarify that the current behavior is that the search is done on a per library basis and that there is no centralized mechanism that ensures all libraries are found from the same location / installation method. I.E. if someone has a libcufft wheel installed in a conda environment with libcublas installed with a system installation of the toolkit, we'll currently find libcufft from the wheel, libcublas from the conda environment, and the rest of our needed libraries from the system toolkit.

In the future we should probably not allow this behavior to occur, but for now we should probably clearly document that this is not behavior we intend to support in the future and is essentially undefined behavior as of now.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FWIW in nvmath-python docs we simplified what Keith said into: "Don't mix-n-match pip, conda, and system (installations of CUDA)" 😄 https://docs.nvidia.com/cuda/nvmath-python/latest/installation.html#troubleshooting


Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we're missing using the CUDA_HOME / CUDA_PATH environment variables?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, if someone has already loaded libraries via some other mechanism I think we end up finding those before going down any of these other search paths?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes this should be documented

1. **Python Package Ecosystem**
- Scans `sys.path` to find libraries installed via NVIDIA Python wheels

2. **Conda Environments**
- Leverages Conda-specific paths through our fork of `get_cuda_paths()` from Numba

3. **System Installations**
- Checks traditional system locations via the same `get_cuda_paths()` implementation
Comment on lines +28 to +29
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you make this more explicit? Does this check /usr/local/cuda or other places?


4. **OS Default Mechanisms**
- Falls back to native loader:
- `dlopen()` on Linux
- `LoadLibraryW()` on Windows

## Implementation Philosophy

The current implementation balances stability and evolution:

- **Baseline Foundation:** Uses a fork of Numba's `cuda_paths.py` that has been
battle-tested in production environments

- **Validation Infrastructure:** Comprehensive CI testing matrix being developed to cover:
- Various Linux/Windows environments
- Python packaging formats (wheels, conda)
- CUDA Toolkit versions

- **Roadmap:** Planned refactoring to:
- Unify library discovery logic
- Improve maintainability
- Better enforce search priority
- Expand platform support

## Maintenance Requirements

These key components must be updated for new CUDA Toolkit releases:

- `supported_libs.SUPPORTED_LIBNAMES`
- `supported_libs.SUPPORTED_WINDOWS_DLLS`
- `supported_libs.SUPPORTED_LINUX_SONAMES`
- `supported_libs.EXPECTED_LIB_SYMBOLS`
Loading
Loading