Skip to content

Move pathfinder to cuda-python top level #723

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 72 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
72 commits
Select commit Hold shift + click to select a range
fbdebfa
Move files WITHOUT trying to make anything work.
rwgk Jun 22, 2025
731256d
First pass changing imports from cuda.bindings → cuda.path_finder WIT…
rwgk Jun 22, 2025
6e0ec6c
Move README.md one level up.
rwgk Jun 22, 2025
07e1385
Move find_sub_dirs.py → ../_utils/find_sub_dirs.py
rwgk Jun 22, 2025
68aa8d5
Move files from cuda_bindings/tests to cuda_path_finder/tests WITHOUT…
rwgk Jun 22, 2025
fafa998
First VERY ROUGH version of pyproject.toml
rwgk Jun 22, 2025
4eff7d2
Change imports in tests/ WITHOUT trying to make anything work.
rwgk Jun 22, 2025
db0f540
Clean up pyproject.toml (with the help of ChatGPT) WITHOUT trying to …
rwgk Jun 22, 2025
9fea2e7
ruff automatic fix: Replace deprecated typing.Sequence with collectio…
rwgk Jun 22, 2025
c494ef2
Add `dynamic = ["version"]` in pyproject.toml and cuda/path_finder/__…
rwgk Jun 23, 2025
78b8c6d
Modernize `[project] license` line.
rwgk Jun 23, 2025
5690d96
Change dir/file names: path_finder → pathfinder
rwgk Jun 23, 2025
81b9bd9
Change imports: path_finder → pathfinder
rwgk Jun 23, 2025
b9be5cb
Fix up broken imports.
rwgk Jun 23, 2025
79a8019
add [project.optional-dependencies] test
rwgk Jun 23, 2025
975ba0b
Adopt cuda_core license.
rwgk Jun 25, 2025
3678fb4
cuda.pathfinder.nvidia_dynamic_libs.load_lib → cuda.pathfinder.load_n…
rwgk Jun 25, 2025
c25184e
Merge branch 'main' into move_path_finder_to_top
rwgk Jul 1, 2025
58b2513
Revert "cuda.pathfinder.nvidia_dynamic_libs.load_lib → cuda.pathfinde…
rwgk Jul 1, 2025
050f857
Simple name changes for consistency: library -> lib
rwgk Jul 1, 2025
1933869
Implement consensus API
rwgk Jul 1, 2025
50f4f8e
Use suggested version number 0.1.0
rwgk Jul 1, 2025
787236c
Fix oversight: `license =` line in pyproject.toml
rwgk Jul 1, 2025
5b5078b
Simplify `description =` line in pyproject.toml
rwgk Jul 1, 2025
13e08ae
Remove Maintenance Requirements from main README. Add the list of "Li…
rwgk Jul 1, 2025
97f9dc8
Adjust cuda_bindings/cuda/bindings/path_finder.py to changes in cuda_…
rwgk Jul 1, 2025
e18cf05
First guess at what changes are needed to include cuda_pathfinder in …
rwgk Jul 1, 2025
b015bbe
Merge branch 'main' into move_path_finder_to_top
rwgk Jul 2, 2025
36491c8
git mv nvidia_dynamic_libs.py __init__.py
rwgk Jul 2, 2025
c6187db
Do not use `cibuildwheel` for a `noarch` package (`cuda-pathfinder`).…
rwgk Jul 2, 2025
346e8b9
twine cleanup
rwgk Jul 2, 2025
9207966
Hard-wire cuda-pathfinder artifact name and path for simplicity, simi…
rwgk Jul 2, 2025
3682f7d
Change to __version__ = "1.0.0"
rwgk Jul 2, 2025
7742c5c
Import __version__ in cuda/pathfinder/__init__.py
rwgk Jul 2, 2025
92c8441
Add missing line in step `name: List the cuda.pathfinder artifacts di…
rwgk Jul 2, 2025
a5b7190
`Install cuda.pathfinder` before ` Build cuda.bindings Cython tests`
rwgk Jul 2, 2025
db0ea56
Add missing line in step `name: Check cuda.pathfinder wheel`
rwgk Jul 3, 2025
9a9f1d7
fix build workflow
leofang Jul 3, 2025
aac1cf7
Merge branch 'main' into move_path_finder_to_top
rwgk Jul 3, 2025
989db08
Remove `__all__` in cuda/pathfinder/__init__.py
rwgk Jul 3, 2025
222df6c
Fix `Check if the script was called with exactly 1 argument` implemen…
rwgk Jul 3, 2025
0b8af00
Add pathfinder install & test into ci/tools/run-tests
rwgk Jul 3, 2025
f902dc9
Add Download cuda-pathfinder, Run cuda.pathfinder tests in test-whee…
rwgk Jul 3, 2025
481f8de
Download cuda-pathfinder-wheel into `./cuda_pathfinder` (not `.`)
rwgk Jul 3, 2025
fd18e1e
Run cuda.pathfinder tests only after cuda.bindings tests, so that all…
rwgk Jul 3, 2025
796bd46
Drive-by fix: test_find_or_load → test_load
rwgk Jul 3, 2025
06763af
Introduce CUDA_PATHFINDER_TEST_LOAD_NVIDIA_DYNAMIC_LIB_STRICTNESS env…
rwgk Jul 3, 2025
b2135cf
CUDA_PATHFINDER_TEST_LOAD_NVIDIA_DYNAMIC_LIB_STRICTNESS=supported_mus…
rwgk Jul 3, 2025
bf48142
Add cuda-pathfinder in .github/workflows/build-docs.yml
rwgk Jul 3, 2025
135a37d
Remove 32-bit DLLs from SUPPORTED_WINDOWS_DLLS
rwgk Jul 5, 2025
48c6d63
Add guard: RuntimeError: cuda.pathfinder.load_nvidia_dynamic_lib() r…
rwgk Jul 5, 2025
7ab201a
is_suppressed_dll_file(): return path_basename.startswith(("cudart32_…
rwgk Jul 5, 2025
9f3e9a4
Add nvidia_wheels_cu12 to [project.optional-dependencies] in cuda_pat…
rwgk Jul 5, 2025
00c8b6a
Install cuda.pathfinder nvidia_wheels_cu12 and run-tests pathfinder a…
rwgk Jul 5, 2025
034286a
ci/tools/run-tests: use bash `-v` instead of `-z` to test if CUDA_PAT…
rwgk Jul 6, 2025
aaed5f2
Add missing `shell: bash` line in test-wheel-windows.yml
rwgk Jul 6, 2025
9d8c70c
test_load_nvidia_dynamic_lib: increase timeout to 120 seconds for Win…
rwgk Jul 6, 2025
8440f90
Add test_load_nvidia_dynamic_lib::test_runtime_error_on_non_64bit_python
rwgk Jul 6, 2025
98ae874
Add DynamicLibNotFound exception type in load_dl_common.py and simpli…
rwgk Jul 6, 2025
9686c2f
Run cuda.pathfinder tests with see_what_works before running any othe…
rwgk Jul 6, 2025
f3c0006
Use `if: startsWith(matrix.CUDA_VER, 12.)` to guard pathfinder tests …
rwgk Jul 6, 2025
8f015d2
Get rid of "partially supported" concept.
rwgk Jul 6, 2025
9f17cd1
Consistently use `IS_WINDOWS` (instead of `sys.platform == "win32"`).
rwgk Jul 6, 2025
db7933a
Rename toolshed/build_pathfinder*.py scripts (no functional changes).
rwgk Jul 6, 2025
1b9a929
Rename toolshed/run_cuda_pathfinder.py
rwgk Jul 6, 2025
b69bf23
Make output of toolshed/build_pathfinder_dlls.py usable as-is.
rwgk Jul 6, 2025
80ebbda
Add DynamicLibNotFound to cuda/pathfinder/__init__.py
rwgk Jul 7, 2025
1c8d315
Merge branch 'move_path_finder_to_top' of https://github.com/rwgk/cud…
rwgk Jul 7, 2025
52e1369
Fix accident in previous commit (DynamicLibNotFound)
rwgk Jul 7, 2025
70d1c14
Update README.md
rwgk Jul 7, 2025
342ca49
mypy cleanup
rwgk Jul 7, 2025
4e0033c
Run mypy from pre-commit
rwgk Jul 7, 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
15 changes: 15 additions & 0 deletions .github/workflows/build-docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,17 @@ jobs:
pwd
ls -lahR .
- name: Download cuda-pathfinder build artifacts
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
with:
name: cuda-pathfinder-wheel
path: ./cuda_pathfinder

- name: Display structure of downloaded cuda-pathfinder artifacts
run: |
pwd
ls -lahR cuda_pathfinder
- name: Download cuda.bindings build artifacts
if: ${{ !inputs.is-release }}
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
Expand Down Expand Up @@ -161,6 +172,10 @@ jobs:
- name: Install all packages
run: |
pushd cuda_pathfinder
pip install *.whl
popd
pushd "${CUDA_BINDINGS_ARTIFACTS_DIR}"
pip install *.whl
popd
Expand Down
45 changes: 42 additions & 3 deletions .github/workflows/build-wheel.yml
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ jobs:
- name: Set up MSVC
if: ${{ startsWith(inputs.host-platform, 'win') }}
uses: ilammy/msvc-dev-cmd@v1 # TODO: ask admin to allow pinning commits

- name: Set environment variables
env:
CUDA_VER: ${{ inputs.cuda-version }}
Expand All @@ -69,7 +69,43 @@ jobs:
- name: Dump environment
run: |
env
- name: Install twine
run: |
pip install twine
# To keep the build workflow simple, all matrix jobs will build a wheel for later use within this workflow.
- name: Build and check cuda.pathfinder wheel
run: |
pushd cuda_pathfinder
pip wheel -v --no-deps .
popd
- name: List the cuda.pathfinder artifacts directory
run: |
if [[ "${{ inputs.host-platform }}" == win* ]]; then
export CHOWN=chown
else
export CHOWN="sudo chown"
fi
$CHOWN -R $(whoami) cuda_pathfinder/*.whl
ls -lahR cuda_pathfinder
# We only need/want a single pure python wheel, pick linux-64 index 0.
# This is what we will use for testing & releasing.
- name: Check cuda.pathfinder wheel
if: ${{ strategy.job-index == 0 && inputs.host-platform == 'linux-64' }}
run: |
twine check cuda_pathfinder/*.whl
- name: Upload cuda.pathfinder build artifacts
if: ${{ strategy.job-index == 0 && inputs.host-platform == 'linux-64' }}
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: cuda-pathfinder-wheel
path: cuda_pathfinder/*.whl
if-no-files-found: error

- name: Build cuda.core wheel
uses: pypa/cibuildwheel@5f22145df44122af0f5a201f93cf0207171beca7 # v3.0.0
env:
Expand All @@ -96,7 +132,6 @@ jobs:
- name: Check cuda.core wheel
run: |
pip install twine
twine check ${{ env.CUDA_CORE_ARTIFACTS_DIR }}/*.whl
- name: Upload cuda.core build artifacts
Expand Down Expand Up @@ -200,6 +235,10 @@ jobs:
# For caching
echo "PY_EXT_SUFFIX=$(python -c "import sysconfig; print(sysconfig.get_config_var('EXT_SUFFIX'))")" >> $GITHUB_ENV
- name: Install cuda.pathfinder (required for next step)
run: |
pip install cuda_pathfinder/*.whl
- name: Build cuda.bindings Cython tests
run: |
pip install $(ls ${{ env.CUDA_BINDINGS_ARTIFACTS_DIR }}/*.whl)[test]
Expand Down
25 changes: 25 additions & 0 deletions .github/workflows/test-wheel-linux.yml
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,12 @@ jobs:
SHA: ${{ github.sha }}
run: ./ci/tools/env-vars test

- name: Download cuda-pathfinder build artifacts
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
with:
name: cuda-pathfinder-wheel
path: ./cuda_pathfinder

- name: Download cuda-python build artifacts
if: ${{ env.SKIP_CUDA_BINDINGS_TEST == '0'}}
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
Expand Down Expand Up @@ -286,6 +292,11 @@ jobs:
- name: Set up compute-sanitizer
run: setup-sanitizer

- name: Run cuda.pathfinder tests with see_what_works
env:
CUDA_PATHFINDER_TEST_LOAD_NVIDIA_DYNAMIC_LIB_STRICTNESS: see_what_works
run: run-tests pathfinder

- name: Run cuda.bindings tests
if: ${{ env.SKIP_CUDA_BINDINGS_TEST == '0' }}
env:
Expand All @@ -306,3 +317,17 @@ jobs:
else
pip install $(ls cuda_python*.whl)[all]
fi
- name: Install cuda.pathfinder nvidia_wheels_cu12
if: startsWith(matrix.CUDA_VER, '12.')
run: |
pushd cuda_pathfinder
pip install -v .[nvidia_wheels_cu12]
pip freeze
popd
- name: Run cuda.pathfinder tests with all_must_work
if: startsWith(matrix.CUDA_VER, '12.')
env:
CUDA_PATHFINDER_TEST_LOAD_NVIDIA_DYNAMIC_LIB_STRICTNESS: all_must_work
run: run-tests pathfinder
30 changes: 29 additions & 1 deletion .github/workflows/test-wheel-windows.yml
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,12 @@ jobs:
shell: bash --noprofile --norc -xeuo pipefail {0}
run: ./ci/tools/env-vars test

- name: Download cuda-pathfinder build artifacts
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
with:
name: cuda-pathfinder-wheel
path: ./cuda_pathfinder

- name: Download cuda-python build artifacts
if: ${{ env.SKIP_CUDA_BINDINGS_TEST == '0'}}
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
Expand Down Expand Up @@ -184,7 +190,7 @@ jobs:
New-Item -Path "${{ env.CUDA_BINDINGS_ARTIFACTS_DIR }}" -ItemType Directory -Force
Move-Item -Path "$OLD_BASENAME/*.whl" -Destination "${{ env.CUDA_BINDINGS_ARTIFACTS_DIR }}"
Remove-Item -Path $OLD_BASENAME -Force

gh run download $LATEST_PRIOR_RUN_ID -p cuda-python-wheel -R NVIDIA/cuda-python
Get-ChildItem -Path cuda-python-wheel
Move-Item -Path "cuda-python-wheel/*.whl" -Destination .
Expand Down Expand Up @@ -250,6 +256,12 @@ jobs:
host-platform: ${{ inputs.host-platform }}
cuda-version: ${{ matrix.CUDA_VER }}

- name: Run cuda.pathfinder tests with see_what_works
env:
CUDA_PATHFINDER_TEST_LOAD_NVIDIA_DYNAMIC_LIB_STRICTNESS: see_what_works
shell: bash --noprofile --norc -xeuo pipefail {0}
run: run-tests pathfinder

- name: Run cuda.bindings tests
if: ${{ env.SKIP_CUDA_BINDINGS_TEST == '0' }}
env:
Expand All @@ -272,3 +284,19 @@ jobs:
} else {
pip install "$((Get-ChildItem -Filter cuda_python*.whl).FullName)[all]"
}

- name: Install cuda.pathfinder nvidia_wheels_cu12
if: startsWith(matrix.CUDA_VER, '12.')
shell: bash --noprofile --norc -xeuo pipefail {0}
run: |
pushd cuda_pathfinder
pip install -v .[nvidia_wheels_cu12]
pip freeze
popd

- name: Run cuda.pathfinder tests with all_must_work
if: startsWith(matrix.CUDA_VER, '12.')
env:
CUDA_PATHFINDER_TEST_LOAD_NVIDIA_DYNAMIC_LIB_STRICTNESS: all_must_work
shell: bash --noprofile --norc -xeuo pipefail {0}
run: run-tests pathfinder
8 changes: 8 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -37,5 +37,13 @@ repos:
- --ini
- .bandit

- repo: https://github.com/pre-commit/mirrors-mypy
rev: v1.8.0
hooks:
- id: mypy
name: mypy-pathfinder
files: ^cuda_pathfinder/cuda/.*\.py$ # Exclude tests directory
args: [--config-file=cuda_pathfinder/mypy.ini]

default_language_version:
python: python3
26 changes: 22 additions & 4 deletions ci/tools/run-tests
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,33 @@
set -euo pipefail

# Check if the script was called with exactly 1 argument
if [[ ${#} -ne 1 && ( "${1}" == "bindings" || "${1}" == "core" ) ]]; then
echo "Error: This script requires exactly 1 argument (what is tested). You provided ${#}"
echo "Usage: ${0} test_module[bindings or core]"
if [[ ${#} -ne 1 ]]; then
echo "Error: This script requires exactly 1 argument. You provided ${#}"
exit 1
fi
if [[ "${1}" != "bindings" && "${1}" != "core" && "${1}" != "pathfinder" ]]; then
echo "Error: Invalid test module '${1}'. Must be 'bindings', 'core', or 'pathfinder'"
exit 1
fi

test_module=${1}

if [[ "${test_module}" == "bindings" ]]; then
# Unconditionally install pathfinder wheel
# (it is a direct dependency of bindings, and a transitive dependency of core)
pushd ./cuda_pathfinder
echo "Installing pathfinder wheel"
pwd
ls
pip install $(ls *.whl)[test]
popd

if [[ "${test_module}" == "pathfinder" ]]; then
pushd ./cuda_pathfinder
echo "Running pathfinder tests with ${CUDA_PATHFINDER_TEST_LOAD_NVIDIA_DYNAMIC_LIB_STRICTNESS}"
pwd
pytest -ra -s -v tests/
popd
elif [[ "${test_module}" == "bindings" ]]; then
pushd "${CUDA_BINDINGS_ARTIFACTS_DIR}"
echo "Installing bindings wheel"
pwd
Expand Down
57 changes: 1 addition & 56 deletions cuda_bindings/cuda/bindings/_path_finder/README.md
Original file line number Diff line number Diff line change
@@ -1,56 +1 @@
# `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
```

**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:

0. **Check if a library was loaded into the process already by some other means.**
- If yes, there is no alternative to skipping the rest of the search logic.
The absolute path of the already loaded library will be returned, along
with the handle to the library.

1. **NVIDIA Python wheels**
- Scans all site-packages to find libraries installed via NVIDIA Python wheels.

2. **OS default mechanisms / Conda environments**
- Falls back to native loader:
- `dlopen()` on Linux
- `LoadLibraryW()` on Windows
- Conda installations are expected to be discovered:
- Linux: Via `$ORIGIN/../lib` on `RPATH` (of the `python` binary;
note that this preempts `LD_LIBRARY_PATH` and `/etc/ld.so.conf.d/`)
- Windows: Via `%CONDA_PREFIX%\Library\bin` on system `PATH`
- CTK installations with system config updates are expected to be discovered:
- Linux: Via `/etc/ld.so.conf.d/*cuda*.conf`
- Windows: Via `C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\vX.Y\bin` on system `PATH`

3. **Environment variables**
- Relies on `CUDA_HOME` or `CUDA_PATH` environment variables if set
(in that order).

Note that the search is done on a per-library basis. There is no centralized
mechanism that ensures all libraries are found in the same way.

## 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`
# The `cuda.bindings.path_finder` module was moved → `cuda.pathfinder`
36 changes: 0 additions & 36 deletions cuda_bindings/cuda/bindings/_path_finder/load_dl_common.py

This file was deleted.

7 changes: 2 additions & 5 deletions cuda_bindings/cuda/bindings/path_finder.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
# Copyright 2024-2025 NVIDIA Corporation. All rights reserved.
#
# SPDX-License-Identifier: LicenseRef-NVIDIA-SOFTWARE-LICENSE

from cuda.bindings._path_finder.load_nvidia_dynamic_library import (
load_nvidia_dynamic_library as _load_nvidia_dynamic_library,
)
from cuda.bindings._path_finder.supported_libs import SUPPORTED_LIBNAMES as _SUPPORTED_LIBNAMES
from cuda.pathfinder import SUPPORTED_NVIDIA_LIBNAMES as _SUPPORTED_LIBNAMES
from cuda.pathfinder import load_nvidia_dynamic_lib as _load_nvidia_dynamic_library

__all__ = [
"_load_nvidia_dynamic_library",
Expand Down
1 change: 1 addition & 0 deletions cuda_bindings/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ dynamic = [
"readme",
]
dependencies = [
"cuda-pathfinder",
Copy link
Member

Choose a reason for hiding this comment

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

as discussed in the meeting we probably need a lower bound here

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I was thinking it's best to add the lower bound as needed? It'll only become a consideration after we have a second cuda-pathfinder release.

"pywin32; sys_platform == 'win32'",
]

Expand Down
Loading
Loading