Skip to content
80 changes: 40 additions & 40 deletions cuda_bindings/pixi.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions cuda_pathfinder/cuda/pathfinder/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@

"""cuda.pathfinder public APIs"""

from cuda.pathfinder._version import __version__ # noqa: F401

from cuda.pathfinder._binaries.find_nvidia_binaries import find_nvidia_binary as find_nvidia_binary
from cuda.pathfinder._binaries.supported_nvidia_binaries import SUPPORTED_BINARIES as SUPPORTED_NVIDIA_BINARIES
from cuda.pathfinder._dynamic_libs.load_dl_common import DynamicLibNotFoundError as DynamicLibNotFoundError
from cuda.pathfinder._dynamic_libs.load_dl_common import LoadedDL as LoadedDL
from cuda.pathfinder._dynamic_libs.load_nvidia_dynamic_lib import load_nvidia_dynamic_lib as load_nvidia_dynamic_lib
Expand All @@ -11,6 +15,10 @@
)
from cuda.pathfinder._headers.find_nvidia_headers import find_nvidia_header_directory as find_nvidia_header_directory
from cuda.pathfinder._headers.supported_nvidia_headers import SUPPORTED_HEADERS_CTK as _SUPPORTED_HEADERS_CTK
from cuda.pathfinder._static_libs.find_nvidia_static_libs import find_nvidia_static_lib as find_nvidia_static_lib
from cuda.pathfinder._static_libs.supported_nvidia_static_libs import (
SUPPORTED_STATIC_LIBS as SUPPORTED_NVIDIA_STATIC_LIBS,
)

from cuda.pathfinder._version import __version__ # isort: skip # noqa: F401

Expand Down
92 changes: 92 additions & 0 deletions cuda_pathfinder/cuda/pathfinder/_binaries/find_nvidia_binaries.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
# SPDX-FileCopyrightText: Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0

"""Find CUDA binary executables across different installation sources."""

import functools
import os
from typing import Optional

from cuda.pathfinder._binaries.supported_nvidia_binaries import SITE_PACKAGES_BINDIRS, SUPPORTED_BINARIES
from cuda.pathfinder._utils.env_vars import get_cuda_home_or_path
from cuda.pathfinder._utils.find_sub_dirs import find_sub_dirs_all_sitepackages
from cuda.pathfinder._utils.platform_aware import IS_WINDOWS


@functools.cache
def find_nvidia_binary(binary_name: str) -> Optional[str]:
"""Locate a CUDA binary executable.

This function searches for CUDA binaries across multiple installation
sources in priority order.

Args:
binary_name: The name of the binary to find (e.g., ``"nvdisasm"``,
``"cuobjdump"``).

Returns:
Absolute path to the discovered binary, or ``None`` if the
binary cannot be found.

Raises:
ValueError: If ``binary_name`` is not in the supported set.

Search order:
1. **NVIDIA Python wheels (site-packages)**

- Scan installed distributions for binaries
shipped in NVIDIA wheels (e.g., ``cuda-nvcc``).

2. **Conda environments**

- Check ``$CONDA_PREFIX/bin`` (Linux/Mac) or
``$CONDA_PREFIX/Library/bin`` (Windows).

3. **CUDA Toolkit environment variables**

- Use ``CUDA_HOME`` or ``CUDA_PATH`` (in that order),
look in the ``bin`` subdirectory.

Examples:
Basic usage:

>>> from cuda.pathfinder import find_nvidia_binary
>>> path = find_nvidia_binary("nvcc")
>>> if path:
... print(f"Found nvcc at {path}")

Note:
Results are cached via ``functools.cache`` for performance.
"""
if binary_name not in SUPPORTED_BINARIES:
raise ValueError(f"Unknown binary: {binary_name!r}")

# Filename variants (try both with and without .exe for cross-platform support)
variants = (binary_name, f"{binary_name}.exe")

# 1. Search site-packages (NVIDIA Python wheels)
if site_dirs := SITE_PACKAGES_BINDIRS.get(binary_name):
for rel_path in site_dirs:
for abs_dir in find_sub_dirs_all_sitepackages(tuple(rel_path.split("/"))):
for variant in variants:
path = os.path.join(abs_dir, variant)
if os.path.isfile(path):
return os.path.abspath(path)

# 2. Search Conda environment
if conda_prefix := os.environ.get("CONDA_PREFIX"):
subdirs = ("Library/bin", "bin") if IS_WINDOWS else ("bin",)
for subdir in subdirs:
for variant in variants:
path = os.path.join(conda_prefix, subdir, variant)
if os.path.isfile(path):
return os.path.abspath(path)

# 3. Search CUDA_HOME/CUDA_PATH
if cuda_home := get_cuda_home_or_path():
for variant in variants:
path = os.path.join(cuda_home, "bin", variant)
if os.path.isfile(path):
return os.path.abspath(path)

return None
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# SPDX-FileCopyrightText: Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0

# THIS FILE NEEDS TO BE REVIEWED/UPDATED FOR EACH CTK RELEASE
# Likely candidates for updates are:
# SUPPORTED_BINARIES
# SITE_PACKAGES_BINDIRS

from cuda.pathfinder._utils.platform_aware import IS_WINDOWS

# Supported CUDA binaries that can be found
SUPPORTED_BINARIES_COMMON = (
"nvdisasm",
"cuobjdump",
)

SUPPORTED_BINARIES = SUPPORTED_BINARIES_COMMON

# Map from binary name to relative paths under site-packages
# These are typically from cuda-toolkit[nvcc] wheels
SITE_PACKAGES_BINDIRS = {
"nvdisasm": ["nvidia/cuda_nvcc/bin"],
"cuobjdump": ["nvidia/cuda_nvcc/bin"],
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@


def _abs_norm(path: str | None) -> str | None:
"""Normalize and return absolute path, or None if path is None."""
if path:
return os.path.normpath(os.path.abspath(path))
return None
Expand Down Expand Up @@ -111,14 +112,14 @@ def find_nvidia_header_directory(libname: str) -> str | None:
RuntimeError: If ``libname`` is not in the supported set.

Search order:
1. **NVIDIA Python wheels**
1. **NVIDIA Python wheels (site-packages)**

- Scan installed distributions (``site-packages``) for header layouts
- Scan installed distributions for header layouts
shipped in NVIDIA wheels (e.g., ``cuda-toolkit[nvrtc]``).

2. **Conda environments**

- Check Conda-style installation prefixes, which use platform-specific
- Check ``$CONDA_PREFIX`` with platform-specific
include directory layouts.

3. **CUDA Toolkit environment variables**
Expand Down
Loading