Repository: numba/numba

Issue:
Searching `%PREFIX%\Library` for new CTK Windows packages
In PR ( https://github.com/numba/numba/pull/7255 ) logic was added to Numba to handle the new-style CTK Conda packages on the `nvidia` channel (and now also on `conda-forge`)

In particular this added a series of `get_nvidia...` functions to search for libraries as part of `numba/cuda /cuda_paths.py`. For example

https://github.com/numba/numba/blob/a4664180ddc91e4c8a37dd06324f4e229a76df91/numba/cuda/cuda_paths.py#L82

<hr>

While it does look like these have some logic for searching for Windows libraries (like looking in `bin` instead of `lib`). It appears they start with `%PREFIX%` instead of `%PREFIX%\Library` (where Conda packages typically [put content on Windows]( https://docs.conda.io/projects/conda-build/en/latest/user-guide/environment-variables.html#environment-variables-set-during-the-build-process ))

Admittedly the `nvidia` package do use `%PREFIX%` to structure content. Though most Conda packages (include the CTK packages in `conda-forge`) do not do this using `%PREFIX%\Library` instead. In the future `nvidia` packages will match this behavior.

Given this wonder if we could search `%PREFIX%\Library` for the CTK first and then search `%PREFIX%` second. This would handle both structures seamlessly


Discussion:
For reference this came out of testing Numba with the new-style CTK packages on conda-forge

ref: https://github.com/conda-forge/numba-feedstock/issues/130
Also it looks like for static libraries, `%PREFIX%\lib\x64` is used as opposed to `%PREFIX%\Library\lib`

https://github.com/numba/numba/blob/a4664180ddc91e4c8a37dd06324f4e229a76df91/numba/cuda/cuda_paths.py#L74
Thanks for the report. CC @gmarkall is this something to fix for 0.59?

Resolving patch:
diff --git a/numba/cuda/cuda_paths.py b/numba/cuda/cuda_paths.py
--- a/numba/cuda/cuda_paths.py
+++ b/numba/cuda/cuda_paths.py
@@ -140,10 +140,20 @@ def get_nvidia_nvvm_ctk():
     is_conda_env = os.path.exists(os.path.join(sys.prefix, 'conda-meta'))
     if not is_conda_env:
         return
-    # Assume the existence of NVVM to imply cudatoolkit installed
+
+    # Assume the existence of NVVM in the conda env implies that a CUDA toolkit
+    # conda package is installed.
+
+    # First, try the location used on Linux and the Windows 11.x packages
     libdir = os.path.join(sys.prefix, 'nvvm', _cudalib_path())
     if not os.path.exists(libdir) or not os.path.isdir(libdir):
-        return
+        # If that fails, try the location used for Windows 12.x packages
+        libdir = os.path.join(sys.prefix, 'Library', 'nvvm', _cudalib_path())
+        if not os.path.exists(libdir) or not os.path.isdir(libdir):
+            # If that doesn't exist either, assume we don't have the NVIDIA
+            # conda package
+            return
+
     paths = find_lib('nvvm', libdir=libdir)
     if not paths:
         return
@@ -178,8 +188,15 @@ def get_nvidia_static_cudalib_ctk():
     nvvm_ctk = get_nvidia_nvvm_ctk()
     if not nvvm_ctk:
         return
+
+    if IS_WIN32 and ("Library" not in nvvm_ctk):
+        # Location specific to CUDA 11.x packages on Windows
+        dirs = ('Lib', 'x64')
+    else:
+        # Linux, or Windows with CUDA 12.x packages
+        dirs = ('lib',)
+
     env_dir = os.path.dirname(os.path.dirname(nvvm_ctk))
-    dirs = ('Lib', 'x64') if IS_WIN32 else ('lib',)
     return os.path.join(env_dir, *dirs)
 
 


Test patch: