Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
#!/usr/bin/env python
# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0

from __future__ import annotations

import os
import sys
from collections.abc import Sequence

from cuda.pathfinder._dynamic_libs.lib_descriptor import LIB_DESCRIPTORS
from cuda.pathfinder._dynamic_libs.load_dl_common import DynamicLibNotFoundError, LoadedDL
from cuda.pathfinder._dynamic_libs.platform_loader import LOADER
from cuda.pathfinder._dynamic_libs.subprocess_protocol import (
MODE_CANARY,
MODE_LOAD,
STATUS_NOT_FOUND,
STATUS_OK,
VALID_MODES,
format_dynamic_lib_subprocess_payload,
)


def _probe_canary_abs_path(libname: str) -> str | None:
desc = LIB_DESCRIPTORS.get(libname)
if desc is None:
raise ValueError(f"Unsupported canary library name: {libname!r}")
try:
loaded: LoadedDL | None = LOADER.load_with_system_search(desc)
except DynamicLibNotFoundError:
return None
if loaded is None:
return None
abs_path = loaded.abs_path
if not isinstance(abs_path, str):
return None
return abs_path


def _validate_abs_path(abs_path: str) -> None:
assert abs_path, f"empty path: {abs_path=!r}"
assert os.path.isabs(abs_path), f"not absolute: {abs_path=!r}"
assert os.path.isfile(abs_path), f"not a file: {abs_path=!r}"


def _load_nvidia_dynamic_lib_for_test(libname: str) -> str:
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This feels super weird to me to have in the actual library code.

# Keep imports inside the subprocess body so startup stays focused on the
# code under test rather than the parent test module.
from cuda.pathfinder import load_nvidia_dynamic_lib
from cuda.pathfinder._dynamic_libs.load_nvidia_dynamic_lib import _load_lib_no_cache
from cuda.pathfinder._dynamic_libs.supported_nvidia_libs import (
SUPPORTED_LINUX_SONAMES,
SUPPORTED_WINDOWS_DLLS,
)
from cuda.pathfinder._utils.platform_aware import IS_WINDOWS

loaded_dl_fresh = load_nvidia_dynamic_lib(libname)
if loaded_dl_fresh.was_already_loaded_from_elsewhere:
raise RuntimeError("loaded_dl_fresh.was_already_loaded_from_elsewhere")

abs_path = loaded_dl_fresh.abs_path
if not isinstance(abs_path, str):
raise RuntimeError(f"loaded_dl_fresh.abs_path is not a string: {abs_path!r}")
_validate_abs_path(abs_path)
assert loaded_dl_fresh.found_via is not None

loaded_dl_from_cache = load_nvidia_dynamic_lib(libname)
if loaded_dl_from_cache is not loaded_dl_fresh:
raise RuntimeError("loaded_dl_from_cache is not loaded_dl_fresh")

loaded_dl_no_cache = _load_lib_no_cache(libname)
supported_libs = SUPPORTED_WINDOWS_DLLS if IS_WINDOWS else SUPPORTED_LINUX_SONAMES
if not loaded_dl_no_cache.was_already_loaded_from_elsewhere and libname in supported_libs:
raise RuntimeError("not loaded_dl_no_cache.was_already_loaded_from_elsewhere")
abs_path_no_cache = loaded_dl_no_cache.abs_path
if not isinstance(abs_path_no_cache, str):
raise RuntimeError(f"loaded_dl_no_cache.abs_path is not a string: {abs_path_no_cache!r}")
if not os.path.samefile(abs_path_no_cache, abs_path):
raise RuntimeError(f"not os.path.samefile({abs_path_no_cache=!r}, {abs_path=!r})")
_validate_abs_path(abs_path_no_cache)
return abs_path


def probe_dynamic_lib_and_print_json(libname: str, mode: str) -> None:
if mode == MODE_CANARY:
abs_path = _probe_canary_abs_path(libname)
status = STATUS_OK if abs_path is not None else STATUS_NOT_FOUND
print(format_dynamic_lib_subprocess_payload(status, abs_path))
return

if mode == MODE_LOAD:
try:
abs_path = _load_nvidia_dynamic_lib_for_test(libname)
except DynamicLibNotFoundError:
print(format_dynamic_lib_subprocess_payload(STATUS_NOT_FOUND, None))
return
print(format_dynamic_lib_subprocess_payload(STATUS_OK, abs_path))
return

raise ValueError(f"Unsupported subprocess probe mode: {mode!r}")


def main(argv: Sequence[str] | None = None) -> int:
args = list(sys.argv[1:] if argv is None else argv)
if len(args) != 2 or args[0] not in VALID_MODES:
modes = ", ".join(VALID_MODES)
raise SystemExit(
f"Usage: python -m cuda.pathfinder._dynamic_libs.dynamic_lib_subprocess <mode> <libname>\nModes: {modes}"
)
mode, libname = args
probe_dynamic_lib_and_print_json(libname, mode)
return 0


if __name__ == "__main__":
raise SystemExit(main())
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,9 @@
from __future__ import annotations

import functools
import json
import struct
import subprocess
import sys
from pathlib import Path
from typing import TYPE_CHECKING

from cuda.pathfinder._dynamic_libs.lib_descriptor import LIB_DESCRIPTORS
Expand All @@ -28,6 +26,15 @@
find_via_ctk_root,
run_find_steps,
)
from cuda.pathfinder._dynamic_libs.subprocess_protocol import (
DYNAMIC_LIB_SUBPROCESS_CWD,
MODE_CANARY,
STATUS_NOT_FOUND,
STATUS_OK,
DynamicLibSubprocessPayload,
build_dynamic_lib_subprocess_command,
parse_dynamic_lib_subprocess_payload,
)
from cuda.pathfinder._utils.platform_aware import IS_WINDOWS

if TYPE_CHECKING:
Expand All @@ -40,9 +47,7 @@
name for name, desc in LIB_DESCRIPTORS.items() if (desc.windows_dlls if IS_WINDOWS else desc.linux_sonames)
)
_PLATFORM_NAME = "Windows" if IS_WINDOWS else "Linux"
_CANARY_PROBE_MODULE = "cuda.pathfinder._dynamic_libs.canary_probe_subprocess"
_CANARY_PROBE_TIMEOUT_SECONDS = 10.0
_CANARY_PROBE_IMPORT_ROOT = Path(__file__).resolve().parents[3]

# Driver libraries: shipped with the NVIDIA display driver, always on the
# system linker path. These skip all CTK search steps (site-packages,
Expand Down Expand Up @@ -99,32 +104,30 @@ def _resolve_system_loaded_abs_path_in_subprocess(libname: str) -> str | None:
"""Resolve a canary library's absolute path in a fresh Python subprocess."""
try:
result = subprocess.run( # noqa: S603 - trusted argv: current interpreter + internal probe module
[sys.executable, "-m", _CANARY_PROBE_MODULE, libname],
build_dynamic_lib_subprocess_command(MODE_CANARY, libname),
capture_output=True,
text=True,
timeout=_CANARY_PROBE_TIMEOUT_SECONDS,
check=False,
cwd=_CANARY_PROBE_IMPORT_ROOT,
cwd=DYNAMIC_LIB_SUBPROCESS_CWD,
)
except subprocess.TimeoutExpired as exc:
_raise_canary_probe_child_process_error(timeout=exc.timeout, stderr=exc.stderr)

if result.returncode != 0:
_raise_canary_probe_child_process_error(returncode=result.returncode, stderr=result.stderr)

# Use the final non-empty line in case earlier output lines are emitted.
lines = [line for line in result.stdout.splitlines() if line.strip()]
if not lines:
raise RuntimeError(f"Canary probe child process produced no stdout payload for {libname!r}")
try:
payload = json.loads(lines[-1])
except json.JSONDecodeError:
raise RuntimeError(
f"Canary probe child process emitted invalid JSON payload for {libname!r}: {lines[-1]!r}"
) from None
if isinstance(payload, str):
return payload
if payload is None:
payload: DynamicLibSubprocessPayload = parse_dynamic_lib_subprocess_payload(
result.stdout,
libname=libname,
error_label="Canary probe child process",
)
abs_path: str | None = payload.abs_path
if payload.status == STATUS_OK:
if abs_path is None:
raise RuntimeError(f"Canary probe child process emitted unexpected payload for {libname!r}: {payload!r}")
return abs_path
if payload.status == STATUS_NOT_FOUND:
return None
raise RuntimeError(f"Canary probe child process emitted unexpected payload for {libname!r}: {payload!r}")

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

from __future__ import annotations

import json
import sys
from dataclasses import dataclass
from pathlib import Path
from typing import Literal

MODE_CANARY: Literal["canary"] = "canary"
MODE_LOAD: Literal["load"] = "load"
VALID_MODES: tuple[Literal["canary"], Literal["load"]] = (MODE_CANARY, MODE_LOAD)

STATUS_OK: Literal["ok"] = "ok"
STATUS_NOT_FOUND: Literal["not-found"] = "not-found"
VALID_STATUSES: tuple[Literal["ok"], Literal["not-found"]] = (STATUS_OK, STATUS_NOT_FOUND)

DYNAMIC_LIB_SUBPROCESS_MODULE = "cuda.pathfinder._dynamic_libs.dynamic_lib_subprocess"
DYNAMIC_LIB_SUBPROCESS_CWD = Path(__file__).resolve().parents[3]


@dataclass(frozen=True)
class DynamicLibSubprocessPayload:
status: Literal["ok", "not-found"]
abs_path: str | None


def format_dynamic_lib_subprocess_payload(status: Literal["ok", "not-found"], abs_path: str | None) -> str:
if status not in VALID_STATUSES:
raise ValueError(f"Unsupported subprocess payload status: {status!r}")
return json.dumps({"status": status, "abs_path": abs_path})


def build_dynamic_lib_subprocess_command(mode: str, libname: str) -> list[str]:
if mode not in VALID_MODES:
raise ValueError(f"Unsupported subprocess probe mode: {mode!r}")
return [sys.executable, "-m", DYNAMIC_LIB_SUBPROCESS_MODULE, mode, libname]


def parse_dynamic_lib_subprocess_payload(
stdout: str,
*,
libname: str,
error_label: str,
) -> DynamicLibSubprocessPayload:
# Use the final non-empty line in case earlier output lines are emitted.
lines = [line for line in stdout.splitlines() if line.strip()]
if not lines:
raise RuntimeError(f"{error_label} produced no stdout payload for {libname!r}")
try:
payload = json.loads(lines[-1])
except json.JSONDecodeError:
raise RuntimeError(f"{error_label} emitted invalid JSON payload for {libname!r}: {lines[-1]!r}") from None
if not isinstance(payload, dict):
raise RuntimeError(f"{error_label} emitted unexpected payload for {libname!r}: {payload!r}")
status = payload.get("status")
abs_path = payload.get("abs_path")
if status == STATUS_OK:
if not isinstance(abs_path, str):
raise RuntimeError(f"{error_label} emitted unexpected payload for {libname!r}: {payload!r}")
return DynamicLibSubprocessPayload(status=STATUS_OK, abs_path=abs_path)
if status == STATUS_NOT_FOUND:
if abs_path is not None:
raise RuntimeError(f"{error_label} emitted unexpected payload for {libname!r}: {payload!r}")
return DynamicLibSubprocessPayload(status=STATUS_NOT_FOUND, abs_path=None)
raise RuntimeError(f"{error_label} emitted unexpected payload for {libname!r}: {payload!r}")
2 changes: 0 additions & 2 deletions cuda_pathfinder/cuda/pathfinder/_testing/__init__.py

This file was deleted.

Loading