66import functools
77import os
88import sys
9+ from dataclasses import dataclass
910from typing import Optional , Tuple
1011
1112if sys .platform == "win32" :
@@ -114,19 +115,29 @@ def _load_and_report_path_linux(libname, soname: str) -> Tuple[int, str]:
114115 return handle , info .dli_fname .decode ()
115116
116117
118+ @dataclass
119+ class LoadedDL :
120+ # ATTENTION: To convert `handle` back to `void*` in cython:
121+ # Linux: `cdef void* ptr = <void*><uintptr_t>`
122+ # Windows: `cdef void* ptr = <void*><intptr_t>`
123+ handle : int
124+ abs_path : Optional [str ]
125+ was_already_loaded_from_elsewhere : bool
126+
127+
117128@functools .cache
118- def load_nvidia_dynamic_library (libname : str ) -> int :
129+ def load_nvidia_dynamic_library (libname : str ) -> LoadedDL :
119130 # Detect if the library was loaded already in some other way (i.e. not via this function).
120131 if sys .platform == "win32" :
121- for dll_name in SUPPORTED_WINDOWS_DLLS .get (libname ):
132+ for dll_name in SUPPORTED_WINDOWS_DLLS .get (libname , () ):
122133 try :
123- return win32api .GetModuleHandle (dll_name )
134+ return LoadedDL ( win32api .GetModuleHandle (dll_name ), None , True )
124135 except pywintypes .error :
125136 pass
126137 else :
127- for soname in SUPPORTED_LINUX_SONAMES .get (libname ):
138+ for soname in SUPPORTED_LINUX_SONAMES .get (libname , () ):
128139 try :
129- return ctypes .CDLL (soname , mode = os .RTLD_NOLOAD )
140+ return LoadedDL ( ctypes .CDLL (soname , mode = os .RTLD_NOLOAD ), None , True )
130141 except OSError :
131142 pass
132143
@@ -138,18 +149,14 @@ def load_nvidia_dynamic_library(libname: str) -> int:
138149 if sys .platform == "win32" :
139150 handle , abs_path = _windows_load_with_dll_basename (libname )
140151 if handle :
141- # Use `cdef void* ptr = <void*><intptr_t>` in cython to convert back to void*
142- print (f"SYSTEM ABS_PATH for { libname = !r} : { abs_path } " , flush = True )
143- return handle
152+ return LoadedDL (handle , abs_path , False )
144153 else :
145154 try :
146155 handle , abs_path = _load_and_report_path_linux (libname , found .lib_searched_for )
147- except OSError as e :
148- print ( f"SYSTEM OSError for { libname = !r } : { e !r } " , flush = True )
156+ except OSError :
157+ pass
149158 else :
150- # Use `cdef void* ptr = <void*><uintptr_t>` in cython to convert back to void*
151- print (f"SYSTEM ABS_PATH for { libname = !r} : { abs_path } " , flush = True )
152- return handle ._handle # C unsigned int
159+ return LoadedDL (handle ._handle , abs_path , False )
153160 found .raise_if_abs_path_is_None ()
154161
155162 if sys .platform == "win32" :
@@ -160,14 +167,10 @@ def load_nvidia_dynamic_library(libname: str) -> int:
160167 handle = win32api .LoadLibraryEx (found .abs_path , 0 , flags )
161168 except pywintypes .error as e :
162169 raise RuntimeError (f"Failed to load DLL at { found .abs_path } : { e } " ) from e
163- # Use `cdef void* ptr = <void*><intptr_t>` in cython to convert back to void*
164- print (f"FOUND ABS_PATH for { libname = !r} : { found .abs_path } " , flush = True )
165- return handle # C signed int, matches win32api.GetProcAddress
170+ return LoadedDL (handle , found .abs_path , False )
166171 else :
167172 try :
168173 handle = ctypes .CDLL (found .abs_path , _LINUX_CDLL_MODE )
169174 except OSError as e :
170175 raise RuntimeError (f"Failed to dlopen { found .abs_path } : { e } " ) from e
171- # Use `cdef void* ptr = <void*><uintptr_t>` in cython to convert back to void*
172- print (f"FOUND ABS_PATH for { libname = !r} : { found .abs_path } " , flush = True )
173- return handle ._handle # C unsigned int
176+ return LoadedDL (handle ._handle , found .abs_path , False )
0 commit comments