-
Notifications
You must be signed in to change notification settings - Fork 216
Add LoadedDL.found_via
#1049
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add LoadedDL.found_via
#1049
Changes from 4 commits
599ef39
b5d53c0
8746a22
bf44cdf
95d913c
9c5a059
7557d50
711179f
96574e5
936cd20
4f1abfd
a969731
8df1369
f7994fc
d0b9d65
e02bf25
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,7 +7,7 @@ | |
import os | ||
from typing import Optional, cast | ||
|
||
from cuda.pathfinder._dynamic_libs.load_dl_common import LoadedDL | ||
from cuda.pathfinder._dynamic_libs.load_dl_common import LoadedDL, Distribution | ||
from cuda.pathfinder._dynamic_libs.supported_nvidia_libs import ( | ||
LIBNAMES_REQUIRING_RTLD_DEEPBIND, | ||
SUPPORTED_LINUX_SONAMES, | ||
|
@@ -170,9 +170,21 @@ def load_with_system_search(libname: str) -> Optional[LoadedDL]: | |
abs_path = abs_path_for_dynamic_library(libname, handle) | ||
if abs_path is None: | ||
raise RuntimeError(f"No expected symbol for {libname=!r}") | ||
return LoadedDL(abs_path, False, handle._handle) | ||
return LoadedDL(abs_path, False, handle._handle, Distribution("system", None)) | ||
return None | ||
|
||
def find_with_system_search_linux(libname: str) -> Optional[str]: | ||
|
||
for soname in get_candidate_sonames(libname): | ||
try: | ||
handle = _load_lib(libname, soname) | ||
except OSError: | ||
pass | ||
else: | ||
abs_path = abs_path_for_dynamic_library(libname, handle) | ||
if abs_path is None: | ||
raise RuntimeError(f"No expected symbol for {libname=!r}") | ||
return abs_path | ||
return None | ||
|
||
def _work_around_known_bugs(libname: str, found_path: str) -> None: | ||
if libname == "nvrtc": | ||
|
@@ -194,21 +206,11 @@ def _work_around_known_bugs(libname: str, found_path: str) -> None: | |
|
||
|
||
def load_with_abs_path(libname: str, found_path: str) -> LoadedDL: | ||
"""Load a dynamic library from the given path. | ||
|
||
Args: | ||
libname: The name of the library to load | ||
found_path: The absolute path to the library file | ||
|
||
Returns: | ||
A LoadedDL object representing the loaded library | ||
|
||
Raises: | ||
RuntimeError: If the library cannot be loaded | ||
""" | ||
_work_around_known_bugs(libname, found_path) | ||
try: | ||
handle = _load_lib(libname, found_path) | ||
except OSError as e: | ||
raise RuntimeError(f"Failed to dlopen {found_path}: {e}") from e | ||
return LoadedDL(found_path, False, handle._handle) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,51 +6,27 @@ | |
import sys | ||
|
||
from cuda.pathfinder._dynamic_libs.find_nvidia_dynamic_lib import _FindNvidiaDynamicLib | ||
from cuda.pathfinder._dynamic_libs.load_dl_common import LoadedDL, load_dependencies | ||
from cuda.pathfinder._dynamic_libs.load_dl_common import Distribution, LoadedDL, load_dependencies | ||
from cuda.pathfinder._utils.platform_aware import IS_WINDOWS | ||
|
||
if IS_WINDOWS: | ||
from cuda.pathfinder._dynamic_libs.load_dl_windows import ( | ||
check_if_already_loaded_from_elsewhere, | ||
load_with_abs_path, | ||
load_with_system_search, | ||
) | ||
else: | ||
from cuda.pathfinder._dynamic_libs.load_dl_linux import ( | ||
check_if_already_loaded_from_elsewhere, | ||
load_with_abs_path, | ||
load_with_system_search, | ||
) | ||
|
||
from typing import Callable, Optional | ||
|
||
def _load_lib_no_cache(libname: str) -> LoadedDL: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I suspect it'll be simpler (less code) to wrap this function in a helper that adds
Alternatively, we could pass |
||
finder = _FindNvidiaDynamicLib(libname) | ||
abs_path = finder.try_site_packages() | ||
if abs_path is None: | ||
abs_path = finder.try_with_conda_prefix() | ||
|
||
# If the library was already loaded by someone else, reproduce any OS-specific | ||
# side-effects we would have applied on a direct absolute-path load (e.g., | ||
# AddDllDirectory on Windows for libs that require it). | ||
loaded = check_if_already_loaded_from_elsewhere(libname, abs_path is not None) | ||
|
||
# Load dependencies regardless of who loaded the primary lib first. | ||
# Doing this *after* the side-effect ensures dependencies resolve consistently | ||
# relative to the actually loaded location. | ||
load_dependencies(libname, load_nvidia_dynamic_lib) | ||
|
||
if loaded is not None: | ||
return loaded | ||
|
||
if abs_path is None: | ||
loaded = load_with_system_search(libname) | ||
if loaded is not None: | ||
return loaded | ||
abs_path = finder.try_with_cuda_home() | ||
if abs_path is None: | ||
finder.raise_not_found_error() | ||
|
||
return load_with_abs_path(libname, abs_path) | ||
def _load_lib_no_cache(libname: str) -> LoadedDL: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Would be nice to move this below the Also, this could be a one-liner:
|
||
loader = _LoadNvidiaDynamicLib(libname) | ||
dl = loader.load_lib() | ||
return dl | ||
|
||
|
||
@functools.cache | ||
|
@@ -130,3 +106,75 @@ def load_nvidia_dynamic_lib(libname: str) -> LoadedDL: | |
f" {sys.version_info.major}.{sys.version_info.minor}" | ||
) | ||
return _load_lib_no_cache(libname) | ||
|
||
|
||
class _LoadNvidiaDynamicLib: | ||
def __init__(self, libname: str): | ||
self.finder = _FindNvidiaDynamicLib(libname) | ||
self.libname = self.finder.libname | ||
|
||
def _load_with_dependencies( | ||
self, get_path_func: Callable[[], Optional[LoadedDL]], dist_name: str | ||
) -> Optional[LoadedDL]: | ||
# If the library was already loaded by someone else, reproduce any OS-specific | ||
# side-effects we would have applied on a direct absolute-path load (e.g., | ||
# AddDllDirectory on Windows for libs that require it). | ||
loaded = check_if_already_loaded_from_elsewhere(self.libname, True) | ||
|
||
# Load dependencies regardless of who loaded the primary lib first. | ||
# Doing this *after* the side-effect ensures dependencies resolve consistently | ||
# relative to the actually loaded location. | ||
load_dependencies(self.libname, load_nvidia_dynamic_lib) | ||
|
||
abs_path = get_path_func() | ||
if abs_path is None: | ||
return None | ||
|
||
dist = Distribution(name=dist_name, version="unknown") | ||
if loaded is not None: | ||
loaded.distribution = dist | ||
return loaded | ||
|
||
dl = load_with_abs_path(self.libname, abs_path) | ||
dl.distribution = dist | ||
return dl | ||
|
||
def _load_simple(self, get_path_func: Callable[[], Optional[LoadedDL]], dist_name: str) -> Optional[LoadedDL]: | ||
abs_path = get_path_func() | ||
if abs_path is None: | ||
return None | ||
|
||
dl = load_with_abs_path(self.libname, abs_path) | ||
dl.distribution = Distribution(name=dist_name, version="unknown") | ||
return dl | ||
|
||
def load_with_site_packages(self) -> Optional[LoadedDL]: | ||
return self._load_simple(self.finder.try_site_packages, "site-packages") | ||
|
||
|
||
def load_with_conda_prefix(self) -> Optional[LoadedDL]: | ||
return self._load_simple(self.finder.try_with_conda_prefix, "conda") | ||
|
||
def load_with_system_search(self) -> Optional[LoadedDL]: | ||
return self._load_with_dependencies(self.finder.try_with_system_search, "system") | ||
|
||
|
||
def load_with_cuda_home(self) -> Optional[LoadedDL]: | ||
return self._load_with_dependencies(self.finder.try_with_cuda_home, "CUDA_HOME") | ||
|
||
def load_lib(self) -> LoadedDL: | ||
dl = self.load_with_site_packages() | ||
if dl is not None: | ||
return dl | ||
|
||
dl = self.load_with_conda_prefix() | ||
if dl is not None: | ||
return dl | ||
|
||
dl = self.load_with_system_search() | ||
if dl is not None: | ||
return dl | ||
|
||
dl = self.load_with_cuda_home() | ||
if dl is not None: | ||
return dl | ||
|
||
|
||
self.finder.raise_not_found_error() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is not used anymore?