Skip to content

[cuda_pathfinder] Remove win32api dependency (use ctypes instead). #751

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

Closed
wants to merge 7 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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@95d2f3a92fbf80abe066b09418bbf128a8923df2 # v3.0.1
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 @@ -39,5 +39,13 @@ repos:
- --ini
- .bandit

- repo: https://github.com/pre-commit/mirrors-mypy
rev: 0f86793af5ef5f6dc63c8d04a3cabfa3ea8f9c6a # frozen: v1.16.1
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.

Loading
Loading