Skip to content
Open
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
Original file line number Diff line number Diff line change
Expand Up @@ -156,10 +156,10 @@ def _load_lib(desc: LibDescriptor, filename: str) -> ctypes.CDLL:


def load_with_system_search(desc: LibDescriptor) -> LoadedDL | None:
"""Try to load a library using system search paths.
"""Try to load a library using the native Linux dynamic-loader search path.
Args:
libname: The name of the library to load
desc: Descriptor for the library to load
Returns:
A LoadedDL object if successful, None if the library cannot be loaded
Expand Down
10 changes: 8 additions & 2 deletions cuda_pathfinder/cuda/pathfinder/_dynamic_libs/load_dl_windows.py
Original file line number Diff line number Diff line change
Expand Up @@ -116,10 +116,16 @@ def check_if_already_loaded_from_elsewhere(desc: LibDescriptor, have_abs_path: b


def load_with_system_search(desc: LibDescriptor) -> LoadedDL | None:
"""Try to load a DLL using system search paths.
"""Try to load a DLL using the native Windows process DLL search path.

This calls ``LoadLibraryExW(dll_name, NULL, 0)`` directly. Under Python
3.8+, CPython configures the process with
``SetDefaultDllDirectories(LOAD_LIBRARY_SEARCH_DEFAULT_DIRS)``, so this
search does **not** include the system ``PATH``. Directories added via
``AddDllDirectory()`` still participate.

Args:
libname: The name of the library to load
desc: Descriptor for the library to load

Returns:
A LoadedDL object if successful, None if the library cannot be loaded
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,9 @@ def _load_driver_lib_no_cache(desc: LibDescriptor) -> LoadedDL:
"""Load an NVIDIA driver library (system-search only).

Driver libs (libcuda, libnvidia-ml) are part of the display driver, not
the CUDA Toolkit. They are always on the system linker path, so the
full CTK search cascade (site-packages, conda, CUDA_HOME, canary) is
unnecessary.
the CUDA Toolkit. They are expected to be discoverable via the platform's
native loader mechanisms, so the full CTK search cascade (site-packages,
conda, CUDA_HOME, canary) is unnecessary.
"""
loaded = LOADER.check_if_already_loaded_from_elsewhere(desc, False)
if loaded is not None:
Expand Down Expand Up @@ -234,35 +234,40 @@ def load_nvidia_dynamic_lib(libname: str) -> LoadedDL:

- Linux: ``dlopen()``

- Windows: ``LoadLibraryW()``
- Windows: ``LoadLibraryExW()``

- CUDA Toolkit (CTK) system installs with system config updates are often
discovered via:
On Linux, CUDA Toolkit (CTK) system installs with system config updates are
usually discovered via ``/etc/ld.so.conf.d/*cuda*.conf``.

- Linux: ``/etc/ld.so.conf.d/*cuda*.conf``

- Windows: ``C:\\Program Files\\NVIDIA GPU Computing Toolkit\\CUDA\\vX.Y\\bin``
on the system ``PATH``.
On Windows, under Python 3.8+, CPython configures the process with
``SetDefaultDllDirectories(LOAD_LIBRARY_SEARCH_DEFAULT_DIRS)``.
As a result, the native DLL search used here does **not** include
the system ``PATH``.

4. **Environment variables**

- If set, use ``CUDA_HOME`` or ``CUDA_PATH`` (in that order).
On Windows, this is the typical way system-installed CTK DLLs are
located. Note that the NVIDIA CTK installer automatically
adds ``CUDA_PATH`` to the system-wide environment.

5. **CTK root canary probe (discoverable libs only)**

- For selected libraries whose shared object doesn't reside on the
standard linker path (currently ``nvvm``), attempt to derive CTK
root by system-loading a well-known CTK canary library in a
subprocess and then searching relative to that root.
subprocess and then searching relative to that root. On Windows,
the canary uses the same native ``LoadLibraryExW`` semantics as
step 3, so there is also no ``PATH``-based discovery.

**Driver libraries** (``"cuda"``, ``"nvml"``):

These are part of the NVIDIA display driver (not the CUDA Toolkit) and
are always on the system linker path. For these libraries the search
is simplified to:
are expected to be reachable via the native OS loader path. For these
libraries the search is simplified to:

0. Already loaded in the current process
1. OS default mechanisms (``dlopen`` / ``LoadLibraryW``)
1. OS default mechanisms (``dlopen`` / ``LoadLibraryExW``)

The CTK-specific steps (site-packages, conda, ``CUDA_HOME``, canary
probe) are skipped entirely.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,13 @@ def find_in_conda(ctx: SearchContext) -> FindResult | None:


def find_in_cuda_home(ctx: SearchContext) -> FindResult | None:
"""Search ``$CUDA_HOME`` / ``$CUDA_PATH``."""
"""Search ``$CUDA_HOME`` / ``$CUDA_PATH``.

On Windows, this is the normal fallback for system-installed CTK DLLs when
they are not already discoverable via the native ``LoadLibraryExW(..., 0)``
path used by :func:`cuda.pathfinder._dynamic_libs.load_dl_windows.load_with_system_search`.
Python 3.8+ does not include ``PATH`` in that native DLL search.
"""
cuda_home = get_cuda_home_or_path()
if cuda_home is None:
return None
Expand Down
Loading