From 9ff02da4d4977edd29cdeb81cd55732ffcaeb516 Mon Sep 17 00:00:00 2001 From: Phillip Cloud <417981+cpcloud@users.noreply.github.com> Date: Fri, 6 Mar 2026 21:04:50 -0500 Subject: [PATCH] refactor(pathfinder): introduce header descriptor catalog Mirror the dynamic-library descriptor-catalog pattern for headers. All per-header metadata (basename, site-packages dirs, anchor layout, platform availability, system install dirs) is now authored once in HeaderDescriptorSpec entries in header_descriptor_catalog.py. - header_descriptor_catalog.py: authored catalog with HeaderDescriptorSpec; each entry declares its own search capabilities via fields like use_ctk_root_canary, conda_targets_layout, and system_install_dirs - header_descriptor.py: name-keyed HEADER_DESCRIPTORS registry and platform-dispatch helpers (platform_include_subdirs, resolve_conda_anchor) - supported_nvidia_headers.py: derives legacy tables from the catalog - find_nvidia_headers.py: composable HeaderFindStep functions with a single unified FIND_STEPS sequence and run_find_steps cascade runner; each step self-gates based on descriptor fields; search code is platform-agnostic Public API (LocatedHeaderDir, find_nvidia_header_directory, locate_nvidia_header_directory, SUPPORTED_HEADERS_CTK) is unchanged. Made-with: Cursor --- .../_headers/find_nvidia_headers.py | 246 +++++++++--------- .../pathfinder/_headers/header_descriptor.py | 54 ++++ .../_headers/header_descriptor_catalog.py | 166 ++++++++++++ .../_headers/supported_nvidia_headers.py | 101 ++++--- 4 files changed, 386 insertions(+), 181 deletions(-) create mode 100644 cuda_pathfinder/cuda/pathfinder/_headers/header_descriptor.py create mode 100644 cuda_pathfinder/cuda/pathfinder/_headers/header_descriptor_catalog.py diff --git a/cuda_pathfinder/cuda/pathfinder/_headers/find_nvidia_headers.py b/cuda_pathfinder/cuda/pathfinder/_headers/find_nvidia_headers.py index 13f47fc2b5..b6118db64d 100644 --- a/cuda_pathfinder/cuda/pathfinder/_headers/find_nvidia_headers.py +++ b/cuda_pathfinder/cuda/pathfinder/_headers/find_nvidia_headers.py @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. # SPDX-License-Identifier: Apache-2.0 from __future__ import annotations @@ -6,16 +6,28 @@ import functools import glob import os +from collections.abc import Callable from dataclasses import dataclass +from typing import TYPE_CHECKING from cuda.pathfinder._dynamic_libs.load_nvidia_dynamic_lib import ( _resolve_system_loaded_abs_path_in_subprocess, ) from cuda.pathfinder._dynamic_libs.search_steps import derive_ctk_root -from cuda.pathfinder._headers import supported_nvidia_headers +from cuda.pathfinder._headers.header_descriptor import ( + HEADER_DESCRIPTORS, + platform_include_subdirs, + resolve_conda_anchor, +) 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 + +if TYPE_CHECKING: + from cuda.pathfinder._headers.header_descriptor import HeaderDescriptor + +# --------------------------------------------------------------------------- +# Data types +# --------------------------------------------------------------------------- @dataclass @@ -27,6 +39,14 @@ def __post_init__(self) -> None: self.abs_path = _abs_norm(self.abs_path) +#: Type alias for a header find step callable. +HeaderFindStep = Callable[["HeaderDescriptor"], LocatedHeaderDir | None] + +# --------------------------------------------------------------------------- +# Helpers +# --------------------------------------------------------------------------- + + def _abs_norm(path: str | None) -> str | None: if path: return os.path.normpath(os.path.abspath(path)) @@ -37,102 +57,119 @@ def _joined_isfile(dirpath: str, basename: str) -> bool: return os.path.isfile(os.path.join(dirpath, basename)) -def _locate_under_site_packages(sub_dir: str, h_basename: str) -> LocatedHeaderDir | None: - # Installed from a wheel - hdr_dir: str # help mypy - for hdr_dir in find_sub_dirs_all_sitepackages(tuple(sub_dir.split("/"))): - if _joined_isfile(hdr_dir, h_basename): - return LocatedHeaderDir(abs_path=hdr_dir, found_via="site-packages") +def _locate_in_anchor_layout(desc: HeaderDescriptor, anchor_point: str) -> str | None: + """Search for a header under *anchor_point* using the descriptor's layout fields.""" + h_basename = desc.header_basename + for rel_dir in desc.anchor_include_rel_dirs: + idir = os.path.join(anchor_point, rel_dir) + for subdir in platform_include_subdirs(desc): + cdir = os.path.join(idir, subdir) + if _joined_isfile(cdir, h_basename): + return cdir + if _joined_isfile(idir, h_basename): + return idir return None -def _locate_based_on_ctk_layout(libname: str, h_basename: str, anchor_point: str) -> str | None: - parts = [anchor_point] - if libname == "nvvm": - parts.append(libname) - parts.append("include") - idir = os.path.join(*parts) - if libname == "cccl": - if IS_WINDOWS: - cdir_ctk12 = os.path.join(idir, "targets", "x64") # conda has this anomaly - cdir_ctk13 = os.path.join(cdir_ctk12, "cccl") - if _joined_isfile(cdir_ctk13, h_basename): - return cdir_ctk13 - if _joined_isfile(cdir_ctk12, h_basename): - return cdir_ctk12 - cdir = os.path.join(idir, "cccl") # CTK 13 - if _joined_isfile(cdir, h_basename): - return cdir - if _joined_isfile(idir, h_basename): - return idir +# --------------------------------------------------------------------------- +# Find steps +# --------------------------------------------------------------------------- + + +def find_in_site_packages(desc: HeaderDescriptor) -> LocatedHeaderDir | None: + """Search pip wheel install locations.""" + for sub_dir in desc.site_packages_dirs: + hdr_dir: str # help mypy + for hdr_dir in find_sub_dirs_all_sitepackages(tuple(sub_dir.split("/"))): + if _joined_isfile(hdr_dir, desc.header_basename): + return LocatedHeaderDir(abs_path=hdr_dir, found_via="site-packages") return None -def _find_based_on_conda_layout(libname: str, h_basename: str, ctk_layout: bool) -> LocatedHeaderDir | None: +def find_in_conda(desc: HeaderDescriptor) -> LocatedHeaderDir | None: + """Search ``$CONDA_PREFIX``.""" conda_prefix = os.environ.get("CONDA_PREFIX") if not conda_prefix: return None - if IS_WINDOWS: - anchor_point = os.path.join(conda_prefix, "Library") - if not os.path.isdir(anchor_point): - return None - else: - if ctk_layout: - targets_include_path = glob.glob(os.path.join(conda_prefix, "targets", "*", "include")) - if not targets_include_path: - return None - if len(targets_include_path) != 1: - # Conda does not support multiple architectures. - # QUESTION(PR#956): Do we want to issue a warning? - return None - include_path = targets_include_path[0] - else: - include_path = os.path.join(conda_prefix, "include") - anchor_point = os.path.dirname(include_path) - found_header_path = _locate_based_on_ctk_layout(libname, h_basename, anchor_point) + anchor_point = resolve_conda_anchor(desc, conda_prefix) + if anchor_point is None: + return None + found_header_path = _locate_in_anchor_layout(desc, anchor_point) if found_header_path: return LocatedHeaderDir(abs_path=found_header_path, found_via="conda") return None -def _find_ctk_header_directory_via_canary(libname: str, h_basename: str) -> str | None: +def find_in_cuda_home(desc: HeaderDescriptor) -> LocatedHeaderDir | None: + """Search ``$CUDA_HOME`` / ``$CUDA_PATH``.""" + cuda_home = get_cuda_home_or_path() + if cuda_home is None: + return None + result = _locate_in_anchor_layout(desc, cuda_home) + if result is not None: + return LocatedHeaderDir(abs_path=result, found_via="CUDA_HOME") + return None + + +def find_via_ctk_root_canary(desc: HeaderDescriptor) -> LocatedHeaderDir | None: """Try CTK header lookup via CTK-root canary probing. - Uses the same canary as dynamic-library CTK-root discovery: system-load - ``cudart`` in a spawned child process, derive CTK root from the resolved - absolute library path, then search the expected CTK include layout under - that root. + Skips immediately if the descriptor does not opt in (``use_ctk_root_canary``). + Otherwise, system-loads ``cudart`` in a spawned child process, derives + CTK root from the resolved library path, and searches the expected include + layout under that root. """ + if not desc.use_ctk_root_canary: + return None canary_abs_path = _resolve_system_loaded_abs_path_in_subprocess("cudart") if canary_abs_path is None: return None ctk_root = derive_ctk_root(canary_abs_path) if ctk_root is None: return None - return _locate_based_on_ctk_layout(libname, h_basename, ctk_root) + result = _locate_in_anchor_layout(desc, ctk_root) + if result is not None: + return LocatedHeaderDir(abs_path=result, found_via="system-ctk-root") + return None -def _find_ctk_header_directory(libname: str) -> LocatedHeaderDir | None: - h_basename = supported_nvidia_headers.SUPPORTED_HEADERS_CTK[libname] - candidate_dirs = supported_nvidia_headers.SUPPORTED_SITE_PACKAGE_HEADER_DIRS_CTK[libname] +def find_in_system_install_dirs(desc: HeaderDescriptor) -> LocatedHeaderDir | None: + """Search system install directories (glob patterns).""" + for pattern in desc.system_install_dirs: + for hdr_dir in sorted(glob.glob(pattern), reverse=True): + if _joined_isfile(hdr_dir, desc.header_basename): + return LocatedHeaderDir(abs_path=hdr_dir, found_via="supported_install_dir") + return None - for cdir in candidate_dirs: - if hdr_dir := _locate_under_site_packages(cdir, h_basename): - return hdr_dir - if hdr_dir := _find_based_on_conda_layout(libname, h_basename, True): - return hdr_dir +# --------------------------------------------------------------------------- +# Step sequence and cascade runner +# --------------------------------------------------------------------------- - cuda_home = get_cuda_home_or_path() - if cuda_home and (result := _locate_based_on_ctk_layout(libname, h_basename, cuda_home)): - return LocatedHeaderDir(abs_path=result, found_via="CUDA_HOME") +#: Unified find steps — each step self-gates based on descriptor fields. +FIND_STEPS: tuple[HeaderFindStep, ...] = ( + find_in_site_packages, + find_in_conda, + find_in_cuda_home, + find_via_ctk_root_canary, + find_in_system_install_dirs, +) - if result := _find_ctk_header_directory_via_canary(libname, h_basename): - return LocatedHeaderDir(abs_path=result, found_via="system-ctk-root") +def run_find_steps(desc: HeaderDescriptor, steps: tuple[HeaderFindStep, ...]) -> LocatedHeaderDir | None: + """Run find steps in order, returning the first hit.""" + for step in steps: + result = step(desc) + if result is not None: + return result return None +# --------------------------------------------------------------------------- +# Public API +# --------------------------------------------------------------------------- + + @functools.cache def locate_nvidia_header_directory(libname: str) -> LocatedHeaderDir | None: """Locate the header directory for a supported NVIDIA library. @@ -150,51 +187,17 @@ def locate_nvidia_header_directory(libname: str) -> LocatedHeaderDir | None: RuntimeError: If ``libname`` is not in the supported set. Search order: - 1. **NVIDIA Python wheels** - - - Scan installed distributions (``site-packages``) for header layouts - shipped in NVIDIA wheels (e.g., ``cuda-toolkit[nvrtc]``). - - 2. **Conda environments** - - - Check Conda-style installation prefixes, which use platform-specific - include directory layouts. - - 3. **CUDA Toolkit environment variables** - - - Use ``CUDA_HOME`` or ``CUDA_PATH`` (in that order). - - 4. **CTK root canary probe** - - - Probe a system-loaded ``cudart`` in a spawned child process, - derive the CTK root from the resolved library path, then search - CTK include layout under that root. + 1. **NVIDIA Python wheels** — site-packages directories from the descriptor. + 2. **Conda environments** — platform-specific conda include layouts. + 3. **CUDA Toolkit environment variables** — ``CUDA_HOME`` / ``CUDA_PATH``. + 4. **CTK root canary probe** — subprocess canary (descriptors with + ``use_ctk_root_canary=True`` only). + 5. **System install directories** — glob patterns from the descriptor. """ - - if libname in supported_nvidia_headers.SUPPORTED_HEADERS_CTK: - return _find_ctk_header_directory(libname) - - h_basename = supported_nvidia_headers.SUPPORTED_HEADERS_NON_CTK.get(libname) - if h_basename is None: + desc = HEADER_DESCRIPTORS.get(libname) + if desc is None: raise RuntimeError(f"UNKNOWN {libname=}") - - candidate_dirs = supported_nvidia_headers.SUPPORTED_SITE_PACKAGE_HEADER_DIRS_NON_CTK.get(libname, []) - - for cdir in candidate_dirs: - if found_hdr := _locate_under_site_packages(cdir, h_basename): - return found_hdr - - if found_hdr := _find_based_on_conda_layout(libname, h_basename, False): - return found_hdr - - # Fall back to system install directories - candidate_dirs = supported_nvidia_headers.SUPPORTED_INSTALL_DIRS_NON_CTK.get(libname, []) - for cdir in candidate_dirs: - for hdr_dir in sorted(glob.glob(cdir), reverse=True): - if _joined_isfile(hdr_dir, h_basename): - # For system installs, we don't have a clear found_via, so use "system" - return LocatedHeaderDir(abs_path=hdr_dir, found_via="supported_install_dir") - return None + return run_find_steps(desc, FIND_STEPS) def find_nvidia_header_directory(libname: str) -> str | None: @@ -212,25 +215,12 @@ def find_nvidia_header_directory(libname: str) -> str | None: RuntimeError: If ``libname`` is not in the supported set. Search order: - 1. **NVIDIA Python wheels** - - - Scan installed distributions (``site-packages``) for header layouts - shipped in NVIDIA wheels (e.g., ``cuda-toolkit[nvrtc]``). - - 2. **Conda environments** - - - Check Conda-style installation prefixes, which use platform-specific - include directory layouts. - - 3. **CUDA Toolkit environment variables** - - - Use ``CUDA_HOME`` or ``CUDA_PATH`` (in that order). - - 4. **CTK root canary probe** - - - Probe a system-loaded ``cudart`` in a spawned child process, - derive the CTK root from the resolved library path, then search - CTK include layout under that root. + 1. **NVIDIA Python wheels** — site-packages directories from the descriptor. + 2. **Conda environments** — platform-specific conda include layouts. + 3. **CUDA Toolkit environment variables** — ``CUDA_HOME`` / ``CUDA_PATH``. + 4. **CTK root canary probe** — subprocess canary (descriptors with + ``use_ctk_root_canary=True`` only). + 5. **System install directories** — glob patterns from the descriptor. """ found = locate_nvidia_header_directory(libname) return found.abs_path if found else None diff --git a/cuda_pathfinder/cuda/pathfinder/_headers/header_descriptor.py b/cuda_pathfinder/cuda/pathfinder/_headers/header_descriptor.py new file mode 100644 index 0000000000..609dcab718 --- /dev/null +++ b/cuda_pathfinder/cuda/pathfinder/_headers/header_descriptor.py @@ -0,0 +1,54 @@ +# SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 + +"""Per-header descriptor, registry, and platform-aware accessors. + +The canonical authored data lives in :mod:`header_descriptor_catalog`. This +module provides a name-keyed registry and platform-dispatch helpers consumed +by the runtime search path — keeping the search code itself platform-agnostic. +""" + +from __future__ import annotations + +import glob +import os +from typing import TypeAlias, cast + +from cuda.pathfinder._headers.header_descriptor_catalog import ( + HEADER_DESCRIPTOR_CATALOG, + HeaderDescriptorSpec, +) +from cuda.pathfinder._utils.platform_aware import IS_WINDOWS + +HeaderDescriptor: TypeAlias = HeaderDescriptorSpec + +#: Canonical registry of all known header libraries. +HEADER_DESCRIPTORS: dict[str, HeaderDescriptor] = {desc.name: desc for desc in HEADER_DESCRIPTOR_CATALOG} + + +def platform_include_subdirs(desc: HeaderDescriptor) -> tuple[str, ...]: + """Return the effective include subdirectory search list for the current platform. + + On Windows, Windows-specific subdirs are checked first, followed by the + common subdirs. On Linux, only the common subdirs are returned. + """ + if IS_WINDOWS: + return cast(tuple[str, ...], desc.include_subdirs_windows + desc.include_subdirs) + return cast(tuple[str, ...], desc.include_subdirs) + + +def resolve_conda_anchor(desc: HeaderDescriptor, conda_prefix: str) -> str | None: + """Resolve the conda anchor point for header search on the current platform. + + Returns the directory that ``_locate_in_anchor_layout`` should use as + *anchor_point*, or ``None`` if the conda layout is not usable. + """ + if IS_WINDOWS: + anchor = os.path.join(conda_prefix, "Library") + return anchor if os.path.isdir(anchor) else None + if desc.conda_targets_layout: + targets_include_path = glob.glob(os.path.join(conda_prefix, "targets", "*", "include")) + if not targets_include_path or len(targets_include_path) != 1: + return None + return os.path.dirname(targets_include_path[0]) + return conda_prefix diff --git a/cuda_pathfinder/cuda/pathfinder/_headers/header_descriptor_catalog.py b/cuda_pathfinder/cuda/pathfinder/_headers/header_descriptor_catalog.py new file mode 100644 index 0000000000..32b222b8fd --- /dev/null +++ b/cuda_pathfinder/cuda/pathfinder/_headers/header_descriptor_catalog.py @@ -0,0 +1,166 @@ +# SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 + +"""Canonical authored descriptor catalog for header directories.""" + +from __future__ import annotations + +from dataclasses import dataclass +from typing import Literal + +HeaderPackagedWith = Literal["ctk", "other"] + + +@dataclass(frozen=True, slots=True) +class HeaderDescriptorSpec: + name: str + packaged_with: HeaderPackagedWith + header_basename: str + site_packages_dirs: tuple[str, ...] = () + available_on_linux: bool = True + available_on_windows: bool = True + # Relative path(s) from anchor point to the include directory. + anchor_include_rel_dirs: tuple[str, ...] = ("include",) + # Subdirectories within the include dir to check before the include dir itself. + include_subdirs: tuple[str, ...] = () + # Windows-only additional subdirectories within the include dir. + include_subdirs_windows: tuple[str, ...] = () + # System install directories (glob patterns). + system_install_dirs: tuple[str, ...] = () + # Whether to use targets//include layout for conda on Linux. + conda_targets_layout: bool = True + # Whether to attempt CTK-root canary probing (spawns a subprocess). + use_ctk_root_canary: bool = True + + +HEADER_DESCRIPTOR_CATALOG: tuple[HeaderDescriptorSpec, ...] = ( + # ----------------------------------------------------------------------- + # CTK (CUDA Toolkit) headers + # ----------------------------------------------------------------------- + HeaderDescriptorSpec( + name="cccl", + packaged_with="ctk", + header_basename="cuda/std/version", + site_packages_dirs=( + "nvidia/cu13/include/cccl", # cuda-toolkit[cccl]==13.* + "nvidia/cuda_cccl/include", # cuda-toolkit[cccl]==12.* + ), + include_subdirs=("cccl",), + include_subdirs_windows=("targets/x64/cccl", "targets/x64"), + ), + HeaderDescriptorSpec( + name="cublas", + packaged_with="ctk", + header_basename="cublas.h", + site_packages_dirs=("nvidia/cu13/include", "nvidia/cublas/include"), + ), + HeaderDescriptorSpec( + name="cudart", + packaged_with="ctk", + header_basename="cuda_runtime.h", + site_packages_dirs=("nvidia/cu13/include", "nvidia/cuda_runtime/include"), + ), + HeaderDescriptorSpec( + name="cufft", + packaged_with="ctk", + header_basename="cufft.h", + site_packages_dirs=("nvidia/cu13/include", "nvidia/cufft/include"), + ), + HeaderDescriptorSpec( + name="cufile", + packaged_with="ctk", + header_basename="cufile.h", + site_packages_dirs=("nvidia/cu13/include", "nvidia/cufile/include"), + available_on_windows=False, + ), + HeaderDescriptorSpec( + name="curand", + packaged_with="ctk", + header_basename="curand.h", + site_packages_dirs=("nvidia/cu13/include", "nvidia/curand/include"), + ), + HeaderDescriptorSpec( + name="cusolver", + packaged_with="ctk", + header_basename="cusolverDn.h", + site_packages_dirs=("nvidia/cu13/include", "nvidia/cusolver/include"), + ), + HeaderDescriptorSpec( + name="cusparse", + packaged_with="ctk", + header_basename="cusparse.h", + site_packages_dirs=("nvidia/cu13/include", "nvidia/cusparse/include"), + ), + HeaderDescriptorSpec( + name="npp", + packaged_with="ctk", + header_basename="npp.h", + site_packages_dirs=("nvidia/cu13/include", "nvidia/npp/include"), + ), + HeaderDescriptorSpec( + name="nvcc", + packaged_with="ctk", + header_basename="fatbinary_section.h", + site_packages_dirs=("nvidia/cu13/include", "nvidia/cuda_nvcc/include"), + ), + HeaderDescriptorSpec( + name="nvfatbin", + packaged_with="ctk", + header_basename="nvFatbin.h", + site_packages_dirs=("nvidia/cu13/include", "nvidia/nvfatbin/include"), + ), + HeaderDescriptorSpec( + name="nvjitlink", + packaged_with="ctk", + header_basename="nvJitLink.h", + site_packages_dirs=("nvidia/cu13/include", "nvidia/nvjitlink/include"), + ), + HeaderDescriptorSpec( + name="nvjpeg", + packaged_with="ctk", + header_basename="nvjpeg.h", + site_packages_dirs=("nvidia/cu13/include", "nvidia/nvjpeg/include"), + ), + HeaderDescriptorSpec( + name="nvrtc", + packaged_with="ctk", + header_basename="nvrtc.h", + site_packages_dirs=("nvidia/cu13/include", "nvidia/cuda_nvrtc/include"), + ), + HeaderDescriptorSpec( + name="nvvm", + packaged_with="ctk", + header_basename="nvvm.h", + site_packages_dirs=("nvidia/cu13/include", "nvidia/cuda_nvcc/nvvm/include"), + anchor_include_rel_dirs=("nvvm/include",), + ), + # ----------------------------------------------------------------------- + # Third-party / separately packaged headers + # ----------------------------------------------------------------------- + HeaderDescriptorSpec( + name="cusparseLt", + packaged_with="other", + header_basename="cusparseLt.h", + site_packages_dirs=("nvidia/cusparselt/include",), + conda_targets_layout=False, + use_ctk_root_canary=False, + ), + HeaderDescriptorSpec( + name="cutensor", + packaged_with="other", + header_basename="cutensor.h", + site_packages_dirs=("cutensor/include",), + conda_targets_layout=False, + use_ctk_root_canary=False, + ), + HeaderDescriptorSpec( + name="nvshmem", + packaged_with="other", + header_basename="nvshmem.h", + site_packages_dirs=("nvidia/nvshmem/include",), + available_on_windows=False, + system_install_dirs=("/usr/include/nvshmem_*",), + conda_targets_layout=False, + use_ctk_root_canary=False, + ), +) diff --git a/cuda_pathfinder/cuda/pathfinder/_headers/supported_nvidia_headers.py b/cuda_pathfinder/cuda/pathfinder/_headers/supported_nvidia_headers.py index af29551dd8..c7b40834e6 100644 --- a/cuda_pathfinder/cuda/pathfinder/_headers/supported_nvidia_headers.py +++ b/cuda_pathfinder/cuda/pathfinder/_headers/supported_nvidia_headers.py @@ -1,35 +1,41 @@ -# SPDX-FileCopyrightText: Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. # SPDX-License-Identifier: Apache-2.0 +"""Legacy table exports derived from the authored header descriptor catalog. + +The canonical data entry point is :mod:`header_descriptor_catalog`. This module +keeps historical constant names for backward compatibility by deriving them +from the catalog. +""" + +from __future__ import annotations + from typing import Final +from cuda.pathfinder._headers.header_descriptor_catalog import HEADER_DESCRIPTOR_CATALOG from cuda.pathfinder._utils.platform_aware import IS_WINDOWS -SUPPORTED_HEADERS_CTK_COMMON = { - "cccl": "cuda/std/version", - "cublas": "cublas.h", - "cudart": "cuda_runtime.h", - "cufft": "cufft.h", - "curand": "curand.h", - "cusolver": "cusolverDn.h", - "cusparse": "cusparse.h", - "npp": "npp.h", - "nvcc": "fatbinary_section.h", - "nvfatbin": "nvFatbin.h", - "nvjitlink": "nvJitLink.h", - "nvjpeg": "nvjpeg.h", - "nvrtc": "nvrtc.h", - "nvvm": "nvvm.h", -} +_CTK_DESCRIPTORS = tuple(desc for desc in HEADER_DESCRIPTOR_CATALOG if desc.packaged_with == "ctk") +_NON_CTK_DESCRIPTORS = tuple(desc for desc in HEADER_DESCRIPTOR_CATALOG if desc.packaged_with == "other") -SUPPORTED_HEADERS_CTK_LINUX_ONLY = { - "cufile": "cufile.h", +SUPPORTED_HEADERS_CTK_COMMON: Final[dict[str, str]] = { + desc.name: desc.header_basename + for desc in _CTK_DESCRIPTORS + if desc.available_on_linux and desc.available_on_windows +} +SUPPORTED_HEADERS_CTK_LINUX_ONLY: Final[dict[str, str]] = { + desc.name: desc.header_basename + for desc in _CTK_DESCRIPTORS + if desc.available_on_linux and not desc.available_on_windows +} +SUPPORTED_HEADERS_CTK_WINDOWS_ONLY: Final[dict[str, str]] = { + desc.name: desc.header_basename + for desc in _CTK_DESCRIPTORS + if desc.available_on_windows and not desc.available_on_linux } -SUPPORTED_HEADERS_CTK_LINUX = SUPPORTED_HEADERS_CTK_COMMON | SUPPORTED_HEADERS_CTK_LINUX_ONLY -SUPPORTED_HEADERS_CTK_WINDOWS_ONLY: dict[str, str] = {} +SUPPORTED_HEADERS_CTK_LINUX = SUPPORTED_HEADERS_CTK_COMMON | SUPPORTED_HEADERS_CTK_LINUX_ONLY SUPPORTED_HEADERS_CTK_WINDOWS = SUPPORTED_HEADERS_CTK_COMMON | SUPPORTED_HEADERS_CTK_WINDOWS_ONLY - SUPPORTED_HEADERS_CTK_ALL = ( SUPPORTED_HEADERS_CTK_COMMON | SUPPORTED_HEADERS_CTK_LINUX_ONLY | SUPPORTED_HEADERS_CTK_WINDOWS_ONLY ) @@ -37,35 +43,26 @@ SUPPORTED_HEADERS_CTK_WINDOWS if IS_WINDOWS else SUPPORTED_HEADERS_CTK_LINUX ) -SUPPORTED_SITE_PACKAGE_HEADER_DIRS_CTK = { - "cccl": ( - "nvidia/cu13/include/cccl", # cuda-toolkit[cccl]==13.* - "nvidia/cuda_cccl/include", # cuda-toolkit[cccl]==12.* - ), - "cublas": ("nvidia/cu13/include", "nvidia/cublas/include"), - "cudart": ("nvidia/cu13/include", "nvidia/cuda_runtime/include"), - "cufft": ("nvidia/cu13/include", "nvidia/cufft/include"), - "cufile": ("nvidia/cu13/include", "nvidia/cufile/include"), - "curand": ("nvidia/cu13/include", "nvidia/curand/include"), - "cusolver": ("nvidia/cu13/include", "nvidia/cusolver/include"), - "cusparse": ("nvidia/cu13/include", "nvidia/cusparse/include"), - "npp": ("nvidia/cu13/include", "nvidia/npp/include"), - "nvcc": ("nvidia/cu13/include", "nvidia/cuda_nvcc/include"), - "nvfatbin": ("nvidia/cu13/include", "nvidia/nvfatbin/include"), - "nvjitlink": ("nvidia/cu13/include", "nvidia/nvjitlink/include"), - "nvjpeg": ("nvidia/cu13/include", "nvidia/nvjpeg/include"), - "nvrtc": ("nvidia/cu13/include", "nvidia/cuda_nvrtc/include"), - "nvvm": ("nvidia/cu13/include", "nvidia/cuda_nvcc/nvvm/include"), +SUPPORTED_SITE_PACKAGE_HEADER_DIRS_CTK: Final[dict[str, tuple[str, ...]]] = { + desc.name: desc.site_packages_dirs for desc in _CTK_DESCRIPTORS if desc.site_packages_dirs } -SUPPORTED_HEADERS_NON_CTK_COMMON = { - "cusparseLt": "cusparseLt.h", - "cutensor": "cutensor.h", +SUPPORTED_HEADERS_NON_CTK_COMMON: Final[dict[str, str]] = { + desc.name: desc.header_basename + for desc in _NON_CTK_DESCRIPTORS + if desc.available_on_linux and desc.available_on_windows } -SUPPORTED_HEADERS_NON_CTK_LINUX_ONLY = { - "nvshmem": "nvshmem.h", +SUPPORTED_HEADERS_NON_CTK_LINUX_ONLY: Final[dict[str, str]] = { + desc.name: desc.header_basename + for desc in _NON_CTK_DESCRIPTORS + if desc.available_on_linux and not desc.available_on_windows } -SUPPORTED_HEADERS_NON_CTK_WINDOWS_ONLY: Final[dict[str, str]] = {} +SUPPORTED_HEADERS_NON_CTK_WINDOWS_ONLY: Final[dict[str, str]] = { + desc.name: desc.header_basename + for desc in _NON_CTK_DESCRIPTORS + if desc.available_on_windows and not desc.available_on_linux +} + SUPPORTED_HEADERS_NON_CTK_LINUX = SUPPORTED_HEADERS_NON_CTK_COMMON | SUPPORTED_HEADERS_NON_CTK_LINUX_ONLY SUPPORTED_HEADERS_NON_CTK_WINDOWS = SUPPORTED_HEADERS_NON_CTK_COMMON | SUPPORTED_HEADERS_NON_CTK_WINDOWS_ONLY SUPPORTED_HEADERS_NON_CTK_ALL = ( @@ -75,12 +72,10 @@ SUPPORTED_HEADERS_NON_CTK_WINDOWS if IS_WINDOWS else SUPPORTED_HEADERS_NON_CTK_LINUX ) -SUPPORTED_SITE_PACKAGE_HEADER_DIRS_NON_CTK = { - "cusparseLt": ("nvidia/cusparselt/include",), - "cutensor": ("cutensor/include",), - "nvshmem": ("nvidia/nvshmem/include",), +SUPPORTED_SITE_PACKAGE_HEADER_DIRS_NON_CTK: Final[dict[str, tuple[str, ...]]] = { + desc.name: desc.site_packages_dirs for desc in _NON_CTK_DESCRIPTORS if desc.site_packages_dirs } -SUPPORTED_INSTALL_DIRS_NON_CTK = { - "nvshmem": ("/usr/include/nvshmem_*",), +SUPPORTED_INSTALL_DIRS_NON_CTK: Final[dict[str, tuple[str, ...]]] = { + desc.name: desc.system_install_dirs for desc in _NON_CTK_DESCRIPTORS if desc.system_install_dirs }