Skip to content
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
b8238f9
initial
brandon-b-miller Mar 10, 2025
9c56e55
slightly refactor cuda_paths
brandon-b-miller Mar 11, 2025
886b9b0
refactor libdevice search mechanism
brandon-b-miller Mar 11, 2025
7ffef77
debug get_cuda_paths
brandon-b-miller Mar 11, 2025
fcedb13
can launch kernel
brandon-b-miller Mar 11, 2025
151e565
cleanup
brandon-b-miller Mar 11, 2025
b4ededf
style
brandon-b-miller Mar 11, 2025
4f2bc2b
reset files
brandon-b-miller Mar 11, 2025
5f4ed8f
initial ci scripts
brandon-b-miller Mar 18, 2025
d4bf113
add pynvjitlink to tests and enable
brandon-b-miller Mar 18, 2025
443e998
locate nvrtc
brandon-b-miller Mar 22, 2025
1b436c6
working inside container
brandon-b-miller Mar 22, 2025
532d864
somewhat roundabout logic works for system/wheel
brandon-b-miller Mar 23, 2025
59bb493
skip tests with no set bin dir
brandon-b-miller Mar 24, 2025
f5dbee6
ensure builtins on windows
brandon-b-miller Mar 24, 2025
43c3ec2
merge/resolve
brandon-b-miller Mar 31, 2025
6a68eb8
remove system nvrtc from wheel test job
brandon-b-miller Mar 31, 2025
3dbd42d
refactor _get_nvvm_wheel
brandon-b-miller Mar 31, 2025
3f4ca51
actually install nvrtc from wheel
brandon-b-miller Apr 1, 2025
3e8651c
merge/resolve
brandon-b-miller Apr 2, 2025
2364278
merge/resolve
brandon-b-miller Apr 8, 2025
42af9ad
ruff
brandon-b-miller Apr 8, 2025
8cf66d0
prioritize wheels over system installs
brandon-b-miller Apr 10, 2025
4f686e9
global search priority
brandon-b-miller Apr 11, 2025
1e3f9a6
Merge branch 'main' into locate-nvvm-nvrtc-wheels
brandon-b-miller Apr 14, 2025
3d65c3d
local import of driver to determine cuda version
brandon-b-miller Apr 14, 2025
78cebea
short circuit
brandon-b-miller Apr 14, 2025
4e8f73f
bugfix
brandon-b-miller Apr 14, 2025
00bb4da
address reviews
brandon-b-miller Apr 15, 2025
5cebb44
Update numba_cuda/numba/cuda/cuda_paths.py
brandon-b-miller Apr 17, 2025
c14644a
get runtime lib from wheel as well
brandon-b-miller Apr 17, 2025
9b3bad9
remove system packages from conda test jobs
brandon-b-miller Apr 17, 2025
51f7694
only remove system packages in cuda 12 ci test jobs
brandon-b-miller Apr 17, 2025
8cc37d7
address reviews in cuda_paths.py
brandon-b-miller Apr 17, 2025
d5b68a9
add Graham's patch
brandon-b-miller Apr 17, 2025
dfe25c8
source cudart from wheel
brandon-b-miller Apr 17, 2025
9fc2531
simplify logic
brandon-b-miller Apr 18, 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
9 changes: 9 additions & 0 deletions .github/workflows/pr.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ jobs:
- build-wheels
- test-wheels
- test-wheels-pynvjitlink
- test-wheels-deps-wheels
- build-docs
secrets: inherit
uses: rapidsai/shared-workflows/.github/workflows/pr-builder.yaml@branch-25.04
Expand Down Expand Up @@ -92,6 +93,14 @@ jobs:
build_type: pull-request
script: "ci/test_wheel_pynvjitlink.sh"
matrix_filter: map(select(.ARCH == "amd64" and .CUDA_VER == "12.5.1" and .PY_VER == "3.12"))
test-wheels-deps-wheels:
needs:
- build-wheels
uses: ./.github/workflows/wheels-test.yaml
with:
build_type: pull-request
script: "ci/test_wheel_deps_wheels.sh"
matrix_filter: map(select(.ARCH == "amd64" and .CUDA_VER == "12.5.1" and .PY_VER == "3.12"))
build-docs:
needs:
- build-conda
Expand Down
52 changes: 52 additions & 0 deletions ci/test_wheel_deps_wheels.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
#!/bin/bash
# Copyright (c) 2023-2024, NVIDIA CORPORATION

set -euo pipefail

rapids-logger "Install testing dependencies"
# TODO: Replace with rapids-dependency-file-generator
python -m pip install \
psutil \
cffi \
cuda-python \
nvidia-curand-cu12 \
nvidia-cuda-nvcc-cu12 \
pytest


rapids-logger "Build tests"
PY_SCRIPT="
import numba_cuda
root = numba_cuda.__file__.rstrip('__init__.py')
test_dir = root + \"numba/cuda/tests/test_binary_generation/\"
print(test_dir)
"

NUMBA_CUDA_TEST_BIN_DIR=$(python -c "$PY_SCRIPT")
pushd $NUMBA_CUDA_TEST_BIN_DIR
make
popd

rapids-logger "Install wheel"
package=$(realpath wheel/numba_cuda*.whl)
echo "Package path: $package"
python -m pip install $package

rapids-logger "Check GPU usage"
nvidia-smi

RAPIDS_TESTS_DIR=${RAPIDS_TESTS_DIR:-"${PWD}/test-results"}/
mkdir -p "${RAPIDS_TESTS_DIR}"
pushd "${RAPIDS_TESTS_DIR}"

rapids-logger "Show Numba system info"
python -m numba --sysinfo

# remove cuda-nvvm-12-5 leaving libnvvm.so from nvidia-cuda-nvcc-cu12 only
apt-get update
apt remove --purge cuda-nvvm-12-5 -y
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

This combined with the addition of nvidia-cuda-nvcc-cu12 was the easiest way I could think of to get to the relevant test environment, but I'm by no means married to it, this would have to be dynamic wrt the minor version as well.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

You can get the installed package name with something like

CUDA_NVVM_PACKAGE=`dpkg --get-selections | grep cuda-nvvm | awk '{print $1}'`


rapids-logger "Run Tests"
NUMBA_CUDA_TEST_BIN_DIR=$NUMBA_CUDA_TEST_BIN_DIR python -m numba.runtests numba.cuda.tests -v

popd
78 changes: 68 additions & 10 deletions numba_cuda/numba/cuda/cuda_paths.py
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The following changes lead to success on Windows:

diff --git a/numba_cuda/numba/cuda/cuda_paths.py b/numba_cuda/numba/cuda/cuda_paths.py
index 9b38a86..bc3822a 100644
--- a/numba_cuda/numba/cuda/cuda_paths.py
+++ b/numba_cuda/numba/cuda/cuda_paths.py
@@ -224,8 +224,9 @@ def _cuda_home_static_cudalib_path():
 def _get_cudalib_wheel():
     """Get the cudalib path from the NVCC wheel."""
     site_paths = [site.getusersitepackages()] + site.getsitepackages()
+    libdir = IS_LINUX and "lib" or "bin"
     for sp in filter(None, site_paths):
-        cudalib_path = Path(sp, "nvidia", "cuda_runtime", "lib")
+        cudalib_path = Path(sp, "nvidia", "cuda_runtime", libdir)
         if cudalib_path.exists():
             return str(cudalib_path)
     return None
@@ -373,8 +374,20 @@ def get_cuda_home(*subdirs):

 def _get_nvvm_path():
     by, path = _get_nvvm_path_decision()
+
     if by == "NVIDIA NVCC Wheel":
-        path = os.path.join(path, "libnvvm.so")
+        platform_map = {
+            "linux": "libnvvm.so",
+            "win32": "nvvm64_40_0.dll",
+        }
+
+        for plat, dso_name in platform_map.items():
+            if sys.platform.startswith(plat):
+                break
+        else:
+            raise NotImplementedError("Unsupported platform")
+
+        path = os.path.join(path, dso_name)
     else:
         candidates = find_lib("nvvm", path)
         path = max(candidates) if candidates else None

Library test output:

(test-cuda-wheels) PS C:\Users\gmarkall\numbadev\numba-cuda> python -c "from numba import cuda; cuda.cudadrv.libs.test()"
Finding driver from candidates:
        nvcuda.dll
        \windows\system32\nvcuda.dll
Using loader <class 'ctypes.WinDLL'>
        Trying to load driver...        ok
                Loaded from nvcuda.dll
Finding nvvm from NVIDIA NVCC Wheel
        Located at D:\miniforge\envs\test-cuda-wheels\Lib\site-packages\nvidia\cuda_nvcc\nvvm\bin\nvvm64_40_0.dll
        Trying to open library...       ok
Finding nvrtc from NVIDIA NVCC Wheel
        Located at D:\miniforge\envs\test-cuda-wheels\Lib\site-packages\nvidia\cuda_nvrtc\bin\nvrtc64_120_0.dll
        Trying to open library...       ok
Finding cudart from NVIDIA NVCC Wheel
        Located at D:\miniforge\envs\test-cuda-wheels\Lib\site-packages\nvidia\cuda_runtime\bin\cudart64_12.dll
        Trying to open library...       ok
Finding cudadevrt from <unknown>
        Located at cudadevrt.lib
        Checking library...     ERROR: failed to find cudadevrt:
cudadevrt.lib not found
Finding libdevice from NVIDIA NVCC Wheel
        Located at D:\miniforge\envs\test-cuda-wheels\Lib\site-packages\nvidia\cuda_nvcc\nvvm\libdevice\libdevice.10.bc
        Checking library...     ok
Include directory configuration variable:
        CUDA_INCLUDE_PATH=cuda_include_not_found
Finding include directory from CUDA_INCLUDE_PATH Config Entry
        Located at cuda_include_not_found
        Checking include directory...   ERROR: failed to find cuda include directory:

We will just have to ignore that the includes and cudadevrt don't seem to be available in wheels, though.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

patch added in d5b68a9

Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
import os
from collections import namedtuple
import platform

import site
from pathlib import Path
from numba.core.config import IS_WIN32
from numba.misc.findlib import find_lib, find_file
from numba import config
Expand All @@ -29,9 +30,13 @@ def _get_libdevice_path_decision():
('Conda environment', get_conda_ctk()),
('Conda environment (NVIDIA package)', get_nvidia_libdevice_ctk()),
('CUDA_HOME', get_cuda_home('nvvm', 'libdevice')),
('System', get_system_ctk('nvvm', 'libdevice')),
('Debian package', get_debian_pkg_libdevice()),
('NVIDIA NVCC Wheel', get_libdevice_wheel()),
]
libdevice_ctk_dir = get_system_ctk('nvvm', 'libdevice')
if os.path.exists(libdevice_ctk_dir):
options.append(('System', libdevice_ctk_dir))

by, libdir = _find_valid_path(options)
return by, libdir

Expand All @@ -48,19 +53,58 @@ def _get_nvvm_path_decision():
('Conda environment', get_conda_ctk()),
('Conda environment (NVIDIA package)', get_nvidia_nvvm_ctk()),
('CUDA_HOME', get_cuda_home(*_nvvm_lib_dir())),
('System', get_system_ctk(*_nvvm_lib_dir())),
('NVIDIA NVCC Wheel', _get_nvvm_wheel()),
]
# need to ensure nvvm dir actually exists
nvvm_ctk_dir = get_system_ctk(*_nvvm_lib_dir())
if os.path.exists(nvvm_ctk_dir):
options.append(('System', nvvm_ctk_dir))

by, path = _find_valid_path(options)
return by, path


def _get_nvvm_wheel():
site_paths = [
site.getusersitepackages()
] + site.getsitepackages() + ["conda", None]
for sp in site_paths:
# The SONAME is taken based on public CTK 12.x releases
if sys.platform.startswith("linux"):
dso_dir = "lib64"
# Hack: libnvvm from Linux wheel
# does not have any soname (CUDAINST-3183)
dso_path = "libnvvm.so"
elif sys.platform.startswith("win32"):
dso_dir = "bin"
dso_path = "nvvm64_40_0.dll"
else:
raise AssertionError()

if sp is not None:
dso_dir = os.path.join(
sp,
"nvidia",
"cuda_nvcc",
"nvvm",
dso_dir
)
dso_path = os.path.join(dso_dir, dso_path)
if os.path.exists(dso_path):
return str(Path(dso_path).parent)


def _get_libdevice_paths():
by, libdir = _get_libdevice_path_decision()
# Search for pattern
pat = r'libdevice(\.\d+)*\.bc$'
candidates = find_file(re.compile(pat), libdir)
# Keep only the max (most recent version) of the bitcode files.
out = max(candidates, default=None)
if by == "NVIDIA NVCC Wheel":
# The NVVM path is a directory, not a file
out = os.path.join(libdir, "libdevice.10.bc")
else:
# Search for pattern
pat = r'libdevice(\.\d+)*\.bc$'
candidates = find_file(re.compile(pat), libdir)
# Keep only the max (most recent version) of the bitcode files.
out = max(candidates, default=None)
return _env_path_tuple(by, out)


Expand Down Expand Up @@ -217,8 +261,12 @@ def get_cuda_home(*subdirs):

def _get_nvvm_path():
by, path = _get_nvvm_path_decision()
candidates = find_lib('nvvm', path)
path = max(candidates) if candidates else None
if by == "NVIDIA NVCC Wheel":
# The NVVM path is a directory, not a file
path = os.path.join(path, "libnvvm.so")
else:
candidates = find_lib('nvvm', path)
path = max(candidates) if candidates else None
return _env_path_tuple(by, path)


Expand Down Expand Up @@ -261,6 +309,16 @@ def get_debian_pkg_libdevice():
return pkg_libdevice_location


def get_libdevice_wheel():
nvvm_path = _get_nvvm_wheel()
if nvvm_path is None:
return None
nvvm_path = Path(nvvm_path)
libdevice_path = nvvm_path.parent / "libdevice"

return str(libdevice_path)


def get_current_cuda_target_name():
"""Determine conda's CTK target folder based on system and machine arch.

Expand Down
Loading