Skip to content

First version of cuda.bindings.path_finder #447

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

Merged
merged 79 commits into from
Apr 9, 2025

Conversation

rwgk
Copy link
Collaborator

@rwgk rwgk commented Feb 12, 2025

The third iteration of this PR description is:

Closes #453 (expected, but currently not tested)

This PR has these main aspects:

  • All dynamic library loading (except libcuda) is moved from these cython files
cuda/bindings/_internal/nvjitlink_linux.pyx
cuda/bindings/_internal/nvjitlink_windows.pyx
cuda/bindings/_internal/nvvm_linux.pyx
cuda/bindings/_internal/nvvm_windows.pyx

to pure Python code under the new cuda/bindings/_path_finder directory.

The API for calling from cython is simply:

path_finder.load_nvidia_dynamic_library("nvJitLink")  # or "nvvm"
  • load_nvidia_dynamic_library() first attempts to load the dynamic library using the system search features (rpath | LD_LIBRARY_PATH | PATH). If that succeeds, the handle to the library (a Python int on all platforms) is returned.

  • Otherwise, load_nvidia_dynamic_library() calls find_nvidia_dynamic_library() to determine an absolute pathname for the dynamic library. Then it loads the library given that pathname.

  • find_nvidia_dynamic_library() first searches for the library under site-packages/nvidia, using sys.path to search for site-packages, in order. If that fails, it uses a clone of numba/cuda/cuda_paths.py to search for the library.

    To pass all tests in the cuda-python CI, this trick is needed under Linux:

    Here the last /lib/ is replaced with /lib64/ or vice versa in get_cuda_paths()[name].info and both are searched.

    • The search for a library stops as soon as there is a match.
  • @functools.cache is used for load_nvidia_dynamic_library(name), therefore the involved search & load code is certain to be invoked only once per process, per library.

  • numba/cuda/cuda_paths.py was changed as little as possible, so that it is feasible to keep our copy in sync with the original while they both exist. The idea is to work towards using cuda.bindings.path_finder from numba-cuda. (After that is achieved, the code under cuda/bindings/_path_finder can probably be refactored significantly.)

TODO

  • The changes to the .pyx files need to be backported to the upstream code generator.

Deferred (follow-on PRs)


The second iteration of this PR description was:

These commits expand the experiment to adopt the entire numba/cuda/cuda_paths.py

  • commit d31920c — Copy from NVIDIA/numba-cuda#155 as-is (as of Tue Mar 18 09:29:19 2025 -0700)
  • commit ed0ebb3 — ruff format, no manual changes
  • commit 0c5aca5 — Minimal changes to replace external dependencies.

Example:

$ python tests/show_ecosystem_cuda_paths.py
nvvm: _env_path_tuple(by='CUDA_HOME', info='/usr/local/cuda/nvvm/lib64/libnvvm.so.4.0.0')
libdevice: _env_path_tuple(by='CUDA_HOME', info='/usr/local/cuda/nvvm/libdevice/libdevice.10.bc')
cudalib_dir: _env_path_tuple(by='CUDA_HOME', info='/usr/local/cuda/lib64')
static_cudalib_dir: _env_path_tuple(by='CUDA_HOME', info='/usr/local/cuda/lib64')
include_dir: _env_path_tuple(by='CUDA_INCLUDE_PATH Config Entry', info='/usr/local/cuda/include')

The first iteration of this PR description was:

Experiment related to #441, triggered by this comment (by @kkraus14).

Context: Potentially use this code from cuda_bindings/cuda/bindings/_internal/nvvm_linux.pyx

This PR: Stripped-down (and ruff'ed) copies of:

Tested interactively with:

import cuda_paths
nvvm_path = cuda_paths.get_nvvm_path()
print(f"{nvvm_path=}")

Output:

nvvm_path=_env_path_tuple(by='System', info='/usr/local/cuda/nvvm/lib64/libnvvm.so.4.0.0')

Advantage of this approach: Battle-tested and time-tested.

Disadvantages: TBD

Copy link
Contributor

copy-pr-bot bot commented Feb 12, 2025

Auto-sync is disabled for draft pull requests in this repository. Workflows must be run manually.

Contributors can view more details about this message here.

@rwgk rwgk changed the title [Experimental] Clone numba get_nvvm_path() [Experimental] Adopt numba/cuda/cuda_paths.py Mar 19, 2025
@rwgk
Copy link
Collaborator Author

rwgk commented Mar 22, 2025

/ok to test

Copy link

```
______________________ ERROR collecting test_nvjitlink.py ______________________
tests/test_nvjitlink.py:62: in <module>
    not check_nvjitlink_usable(), reason="nvJitLink not usable, maybe not installed or too old (<12.3)"
tests/test_nvjitlink.py:58: in check_nvjitlink_usable
    return inner_nvjitlink._inspect_function_pointer("__nvJitLinkVersion") != 0
cuda/bindings/_internal/nvjitlink.pyx:257: in cuda.bindings._internal.nvjitlink._inspect_function_pointer
    ???
cuda/bindings/_internal/nvjitlink.pyx:260: in cuda.bindings._internal.nvjitlink._inspect_function_pointer
    ???
cuda/bindings/_internal/nvjitlink.pyx:208: in cuda.bindings._internal.nvjitlink._inspect_function_pointers
    ???
cuda/bindings/_internal/nvjitlink.pyx:102: in cuda.bindings._internal.nvjitlink._check_or_init_nvjitlink
    ???
cuda/bindings/_internal/nvjitlink.pyx:59: in cuda.bindings._internal.nvjitlink.load_library
    ???
/opt/hostedtoolcache/Python/3.13.2/x64/lib/python3.13/site-packages/cuda/bindings/path_finder.py:312: in get_cuda_paths
    "nvvm": _get_nvvm_path(),
/opt/hostedtoolcache/Python/3.13.2/x64/lib/python3.13/site-packages/cuda/bindings/path_finder.py:285: in _get_nvvm_path
    by, path = _get_nvvm_path_decision()
/opt/hostedtoolcache/Python/3.13.2/x64/lib/python3.13/site-packages/cuda/bindings/path_finder.py:96: in _get_nvvm_path_decision
    if os.path.exists(nvvm_ctk_dir):
<frozen genericpath>:19: in exists
    ???
E   TypeError: stat: path should be string, bytes, os.PathLike or integer, not NoneType
```
@rwgk
Copy link
Collaborator Author

rwgk commented Mar 22, 2025

/ok to test

```
______________________ ERROR collecting test_nvjitlink.py ______________________
tests/test_nvjitlink.py:62: in <module>
    not check_nvjitlink_usable(), reason="nvJitLink not usable, maybe not installed or too old (<12.3)"
tests/test_nvjitlink.py:58: in check_nvjitlink_usable
    return inner_nvjitlink._inspect_function_pointer("__nvJitLinkVersion") != 0
cuda/bindings/_internal/nvjitlink.pyx:257: in cuda.bindings._internal.nvjitlink._inspect_function_pointer
    ???
cuda/bindings/_internal/nvjitlink.pyx:260: in cuda.bindings._internal.nvjitlink._inspect_function_pointer
    ???
cuda/bindings/_internal/nvjitlink.pyx:208: in cuda.bindings._internal.nvjitlink._inspect_function_pointers
    ???
cuda/bindings/_internal/nvjitlink.pyx:102: in cuda.bindings._internal.nvjitlink._check_or_init_nvjitlink
    ???
cuda/bindings/_internal/nvjitlink.pyx:59: in cuda.bindings._internal.nvjitlink.load_library
    ???
/opt/hostedtoolcache/Python/3.13.2/x64/lib/python3.13/site-packages/cuda/bindings/path_finder.py:313: in get_cuda_paths
    "libdevice": _get_libdevice_paths(),
/opt/hostedtoolcache/Python/3.13.2/x64/lib/python3.13/site-packages/cuda/bindings/path_finder.py:126: in _get_libdevice_paths
    by, libdir = _get_libdevice_path_decision()
/opt/hostedtoolcache/Python/3.13.2/x64/lib/python3.13/site-packages/cuda/bindings/path_finder.py:73: in _get_libdevice_path_decision
    if os.path.exists(libdevice_ctk_dir):
<frozen genericpath>:19: in exists
    ???
E   TypeError: stat: path should be string, bytes, os.PathLike or integer, not NoneType
```
@rwgk
Copy link
Collaborator Author

rwgk commented Mar 22, 2025

/ok to test

@rwgk
Copy link
Collaborator Author

rwgk commented Mar 25, 2025

/ok to test

@rwgk
Copy link
Collaborator Author

rwgk commented Mar 25, 2025

/ok to test

@rwgk
Copy link
Collaborator Author

rwgk commented Apr 6, 2025

/ok to test

@rwgk
Copy link
Collaborator Author

rwgk commented Apr 6, 2025

/ok to test

@rwgk
Copy link
Collaborator Author

rwgk commented Apr 7, 2025

/ok to test

@rwgk
Copy link
Collaborator Author

rwgk commented Apr 7, 2025

/ok to test

@rwgk
Copy link
Collaborator Author

rwgk commented Apr 7, 2025

Tracking link provided by @leofang on chat:

There, when the cusparse dll is loaded, the dll search path is expanded to so that nvjitlink can be found.

@rwgk
Copy link
Collaborator Author

rwgk commented Apr 8, 2025

/ok to test

@rwgk rwgk changed the title [WIP] First version of cuda.bindings.path_finder First version of cuda.bindings.path_finder Apr 8, 2025
@rwgk rwgk marked this pull request as ready for review April 8, 2025 15:00
Copy link
Contributor

copy-pr-bot bot commented Apr 8, 2025

Auto-sync is disabled for ready for review pull requests in this repository. Workflows must be run manually.

Contributors can view more details about this message here.

@rwgk rwgk requested a review from kkraus14 April 8, 2025 15:00
@rwgk
Copy link
Collaborator Author

rwgk commented Apr 8, 2025

@leofang @kkraus14 This PR is ready for review. It's certain that more work is needed, but I believe what I have now is a meaningful milestone.

I backed out my experiments with NVRTC for now (see PR description). After this PR is merged, I want to pick up that work, and then work towards replacing more/all dynamic library loading code with calls to cuda.bindings.path_finder.

@rwgk rwgk changed the base branch from main to path_finder_dev April 9, 2025 18:30
@rwgk
Copy link
Collaborator Author

rwgk commented Apr 9, 2025

To stay organized while we're in a code freeze, I created the "temporary integration branch" with name path_finder_dev. I'll squash-merge this PR into that branch.

@rwgk rwgk merged commit 147b242 into NVIDIA:path_finder_dev Apr 9, 2025
1 check passed
@rwgk rwgk deleted the find_libnvvm branch April 9, 2025 18:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
cuda.bindings Everything related to the cuda.bindings module feature New feature or request P1 Medium priority - Should do triage Needs the team's attention
Projects
None yet
Development

Successfully merging this pull request may close these issues.

NVVM bindings not working on Windows + CUDA conda packages
2 participants