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
9 changes: 8 additions & 1 deletion cuda_pathfinder/cuda/pathfinder/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,15 @@
from cuda.pathfinder._static_libs.find_bitcode_lib import (
find_bitcode_lib as find_bitcode_lib,
)
from cuda.pathfinder._static_libs.find_bitcode_lib import (
find_bitcode_lib_by_name as find_bitcode_lib_by_name,
)
from cuda.pathfinder._static_libs.find_bitcode_lib import (
locate_bitcode_lib as locate_bitcode_lib,
)
from cuda.pathfinder._static_libs.find_bitcode_lib import (
locate_bitcode_lib_by_name as locate_bitcode_lib_by_name,
)
from cuda.pathfinder._static_libs.find_static_lib import (
SUPPORTED_STATIC_LIBS as _SUPPORTED_STATIC_LIBS,
)
Expand Down Expand Up @@ -77,7 +83,8 @@
SUPPORTED_BINARY_UTILITIES = _SUPPORTED_BINARIES

#: Tuple of supported bitcode library names that can be resolved
#: via ``locate_bitcode_lib()`` and ``find_bitcode_lib()``.
#: via ``locate_bitcode_lib()``, ``locate_bitcode_lib_by_name()``,
#: ``find_bitcode_lib()``, and ``find_bitcode_lib_by_name()``.
#: Example value: ``"device"``.
SUPPORTED_BITCODE_LIBS = _SUPPORTED_BITCODE_LIBS

Expand Down
71 changes: 61 additions & 10 deletions cuda_pathfinder/cuda/pathfinder/_static_libs/find_bitcode_lib.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
# SPDX-License-Identifier: Apache-2.0

import functools
import ntpath
import os
from dataclasses import dataclass
from typing import NoReturn, TypedDict
Expand Down Expand Up @@ -74,13 +75,21 @@ def _no_such_file_in_dir(dir_path: str, filename: str, error_messages: list[str]
attachments.append(f' Directory does not exist: "{dir_path}"')


def _validate_filename(filename: str) -> str:
if not isinstance(filename, str):
raise TypeError(f"filename must be a string, got {type(filename).__name__}")
if filename in ("", ".", "..") or "\0" in filename or ntpath.basename(filename) != filename:
raise ValueError(f"filename must be a file name without a directory: {filename!r}")
return filename


class _FindBitcodeLib:
def __init__(self, name: str) -> None:
def __init__(self, name: str, *, filename: str | None = None) -> None:
if name not in _SUPPORTED_BITCODE_LIBS_INFO: # Updated reference
raise ValueError(f"Unknown bitcode library: '{name}'. Supported: {', '.join(SUPPORTED_BITCODE_LIBS)}")
self.name: str = name
self.config: _BitcodeLibInfo = _SUPPORTED_BITCODE_LIBS_INFO[name] # Updated reference
self.filename: str = self.config["filename"]
self.filename: str = self.config["filename"] if filename is None else _validate_filename(filename)
self.rel_path: str = self.config["rel_path"]
self.site_packages_dirs: tuple[str, ...] = self.config["site_packages_dirs"]
self.error_messages: list[str] = []
Expand Down Expand Up @@ -130,14 +139,8 @@ def raise_not_found_error(self) -> NoReturn:
raise BitcodeLibNotFoundError(f'Failure finding "{self.filename}": {err}\n{att}')


def locate_bitcode_lib(name: str) -> LocatedBitcodeLib:
"""Locate a bitcode library by name.

Raises:
ValueError: If ``name`` is not a supported bitcode library.
BitcodeLibNotFoundError: If the bitcode library cannot be found.
"""
finder = _FindBitcodeLib(name)
def _locate_bitcode_lib(name: str, *, filename: str | None = None) -> LocatedBitcodeLib:
finder = _FindBitcodeLib(name, filename=filename)

abs_path = finder.try_site_packages()
if abs_path is not None:
Expand Down Expand Up @@ -169,6 +172,35 @@ def locate_bitcode_lib(name: str) -> LocatedBitcodeLib:
finder.raise_not_found_error()


def locate_bitcode_lib(name: str) -> LocatedBitcodeLib:
"""Locate a bitcode library by name.

Raises:
ValueError: If ``name`` is not a supported bitcode library.
BitcodeLibNotFoundError: If the bitcode library cannot be found.
"""
return _locate_bitcode_lib(name)


def locate_bitcode_lib_by_name(name: str, filename: str) -> LocatedBitcodeLib:

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

name and filename are quite confusing IMHO. Is name the directory name that contains the bitcode library?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Name is the library name (e.g. "nvshmem"). Filename is the bitcode filename (e.g. "libnvshmem_device.bc")

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

agree it's confusing

"""Locate an exact bitcode filename using a supported library's search paths.

This lets a library define its own filename convention, including any
architecture or other attributes encoded in the filename.

Args:
name: Supported bitcode library whose configured directories to search.
filename: Exact file name to locate. Directory components are not allowed.

Raises:
TypeError: If ``filename`` is not a string.
ValueError: If ``name`` is unsupported or ``filename`` is not a file name.
BitcodeLibNotFoundError: If ``filename`` cannot be found.
"""
_validate_filename(filename)
return _locate_bitcode_lib(name, filename=filename)


@functools.cache
def find_bitcode_lib(name: str) -> str:
"""Find the absolute path to a bitcode library.
Expand All @@ -178,3 +210,22 @@ def find_bitcode_lib(name: str) -> str:
BitcodeLibNotFoundError: If the bitcode library cannot be found.
"""
return locate_bitcode_lib(name).abs_path


@functools.cache
def find_bitcode_lib_by_name(name: str, filename: str) -> str:
"""Find an exact bitcode filename using a supported library's search paths.

This lets a library define its own filename convention, including any
architecture or other attributes encoded in the filename.

Args:
name: Supported bitcode library whose configured directories to search.
filename: Exact file name to find. Directory components are not allowed.

Raises:
TypeError: If ``filename`` is not a string.
ValueError: If ``name`` is unsupported or ``filename`` is not a file name.
BitcodeLibNotFoundError: If ``filename`` cannot be found.
"""
return locate_bitcode_lib_by_name(name, filename).abs_path
2 changes: 2 additions & 0 deletions cuda_pathfinder/docs/source/api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,9 @@ CUDA bitcode and static libraries.

SUPPORTED_BITCODE_LIBS
find_bitcode_lib
find_bitcode_lib_by_name
locate_bitcode_lib
locate_bitcode_lib_by_name
LocatedBitcodeLib
BitcodeLibNotFoundError

Expand Down
4 changes: 2 additions & 2 deletions cuda_pathfinder/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ cu12 = [
"nvidia-cusparselt-cu12",
"nvidia-libmathdx-cu12",
"nvidia-nccl-cu12; sys_platform != 'win32'",
"nvidia-nvshmem-cu12<3.7; sys_platform != 'win32'",
"nvidia-nvshmem-cu12; sys_platform != 'win32'",
]
cu13 = [
"cuda-toolkit[nvcc,cublas,nvrtc,cudart,cufft,curand,cusolver,cusparse,npp,nvfatbin,nvjitlink,nvjpeg,cccl,cupti,profiler,nvvm]==13.*",
Expand All @@ -43,7 +43,7 @@ cu13 = [
"nvidia-cusparselt-cu13",
"nvidia-libmathdx-cu13",
"nvidia-nccl-cu13; sys_platform != 'win32'",
"nvidia-nvshmem-cu13<3.7; sys_platform != 'win32'",
"nvidia-nvshmem-cu13; sys_platform != 'win32'",
]
host = [
# TODO: remove the Python 3.15 guard once 3.15 is officially supported
Expand Down
Loading
Loading