Skip to content

Commit 346afc8

Browse files
authored
docs(pathfinder): clarify Windows DLL search semantics (#1795)
Document that Python 3.8+ excludes PATH from the native Windows DLL search used by cuda.pathfinder, so CTK installs are typically found via CUDA_HOME/CUDA_PATH or other explicit locations instead. Made-with: Cursor
1 parent a7670b6 commit 346afc8

File tree

4 files changed

+36
-19
lines changed

4 files changed

+36
-19
lines changed

cuda_pathfinder/cuda/pathfinder/_dynamic_libs/load_dl_linux.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -156,10 +156,10 @@ def _load_lib(desc: LibDescriptor, filename: str) -> ctypes.CDLL:
156156

157157

158158
def load_with_system_search(desc: LibDescriptor) -> LoadedDL | None:
159-
"""Try to load a library using system search paths.
159+
"""Try to load a library using the native Linux dynamic-loader search path.
160160
161161
Args:
162-
libname: The name of the library to load
162+
desc: Descriptor for the library to load
163163
164164
Returns:
165165
A LoadedDL object if successful, None if the library cannot be loaded

cuda_pathfinder/cuda/pathfinder/_dynamic_libs/load_dl_windows.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -116,10 +116,16 @@ def check_if_already_loaded_from_elsewhere(desc: LibDescriptor, have_abs_path: b
116116

117117

118118
def load_with_system_search(desc: LibDescriptor) -> LoadedDL | None:
119-
"""Try to load a DLL using system search paths.
119+
"""Try to load a DLL using the native Windows process DLL search path.
120+
121+
This calls ``LoadLibraryExW(dll_name, NULL, 0)`` directly. Under Python
122+
3.8+, CPython configures the process with
123+
``SetDefaultDllDirectories(LOAD_LIBRARY_SEARCH_DEFAULT_DIRS)``, so this
124+
search does **not** include the system ``PATH``. Directories added via
125+
``AddDllDirectory()`` still participate.
120126
121127
Args:
122-
libname: The name of the library to load
128+
desc: Descriptor for the library to load
123129
124130
Returns:
125131
A LoadedDL object if successful, None if the library cannot be loaded

cuda_pathfinder/cuda/pathfinder/_dynamic_libs/load_nvidia_dynamic_lib.py

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -58,9 +58,9 @@ def _load_driver_lib_no_cache(desc: LibDescriptor) -> LoadedDL:
5858
"""Load an NVIDIA driver library (system-search only).
5959
6060
Driver libs (libcuda, libnvidia-ml) are part of the display driver, not
61-
the CUDA Toolkit. They are always on the system linker path, so the
62-
full CTK search cascade (site-packages, conda, CUDA_HOME, canary) is
63-
unnecessary.
61+
the CUDA Toolkit. They are expected to be discoverable via the platform's
62+
native loader mechanisms, so the full CTK search cascade (site-packages,
63+
conda, CUDA_HOME, canary) is unnecessary.
6464
"""
6565
loaded = LOADER.check_if_already_loaded_from_elsewhere(desc, False)
6666
if loaded is not None:
@@ -234,35 +234,40 @@ def load_nvidia_dynamic_lib(libname: str) -> LoadedDL:
234234
235235
- Linux: ``dlopen()``
236236
237-
- Windows: ``LoadLibraryW()``
237+
- Windows: ``LoadLibraryExW()``
238238
239-
- CUDA Toolkit (CTK) system installs with system config updates are often
240-
discovered via:
239+
On Linux, CUDA Toolkit (CTK) system installs with system config updates are
240+
usually discovered via ``/etc/ld.so.conf.d/*cuda*.conf``.
241241
242-
- Linux: ``/etc/ld.so.conf.d/*cuda*.conf``
243-
244-
- Windows: ``C:\\Program Files\\NVIDIA GPU Computing Toolkit\\CUDA\\vX.Y\\bin``
245-
on the system ``PATH``.
242+
On Windows, under Python 3.8+, CPython configures the process with
243+
``SetDefaultDllDirectories(LOAD_LIBRARY_SEARCH_DEFAULT_DIRS)``.
244+
As a result, the native DLL search used here does **not** include
245+
the system ``PATH``.
246246
247247
4. **Environment variables**
248248
249249
- If set, use ``CUDA_HOME`` or ``CUDA_PATH`` (in that order).
250+
On Windows, this is the typical way system-installed CTK DLLs are
251+
located. Note that the NVIDIA CTK installer automatically
252+
adds ``CUDA_PATH`` to the system-wide environment.
250253
251254
5. **CTK root canary probe (discoverable libs only)**
252255
253256
- For selected libraries whose shared object doesn't reside on the
254257
standard linker path (currently ``nvvm``), attempt to derive CTK
255258
root by system-loading a well-known CTK canary library in a
256-
subprocess and then searching relative to that root.
259+
subprocess and then searching relative to that root. On Windows,
260+
the canary uses the same native ``LoadLibraryExW`` semantics as
261+
step 3, so there is also no ``PATH``-based discovery.
257262
258263
**Driver libraries** (``"cuda"``, ``"nvml"``):
259264
260265
These are part of the NVIDIA display driver (not the CUDA Toolkit) and
261-
are always on the system linker path. For these libraries the search
262-
is simplified to:
266+
are expected to be reachable via the native OS loader path. For these
267+
libraries the search is simplified to:
263268
264269
0. Already loaded in the current process
265-
1. OS default mechanisms (``dlopen`` / ``LoadLibraryW``)
270+
1. OS default mechanisms (``dlopen`` / ``LoadLibraryExW``)
266271
267272
The CTK-specific steps (site-packages, conda, ``CUDA_HOME``, canary
268273
probe) are skipped entirely.

cuda_pathfinder/cuda/pathfinder/_dynamic_libs/search_steps.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,13 @@ def find_in_conda(ctx: SearchContext) -> FindResult | None:
183183

184184

185185
def find_in_cuda_home(ctx: SearchContext) -> FindResult | None:
186-
"""Search ``$CUDA_HOME`` / ``$CUDA_PATH``."""
186+
"""Search ``$CUDA_HOME`` / ``$CUDA_PATH``.
187+
188+
On Windows, this is the normal fallback for system-installed CTK DLLs when
189+
they are not already discoverable via the native ``LoadLibraryExW(..., 0)``
190+
path used by :func:`cuda.pathfinder._dynamic_libs.load_dl_windows.load_with_system_search`.
191+
Python 3.8+ does not include ``PATH`` in that native DLL search.
192+
"""
187193
cuda_home = get_cuda_home_or_path()
188194
if cuda_home is None:
189195
return None

0 commit comments

Comments
 (0)