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
Original file line number Diff line number Diff line change
Expand Up @@ -2,29 +2,14 @@
# SPDX-License-Identifier: Apache-2.0

import functools
import importlib
import os
from collections.abc import Iterable
from typing import Any

from cuda.pathfinder._binaries import supported_nvidia_binaries
from cuda.pathfinder._binaries import supported_nvidia_binaries, windows_nsight
from cuda.pathfinder._utils.ctk_root_canary import CTK_ROOT_CANARY_ANCHOR_LIBNAMES
from cuda.pathfinder._utils.env_vars import get_cuda_path_or_home
from cuda.pathfinder._utils.find_sub_dirs import find_sub_dirs_all_sitepackages
from cuda.pathfinder._utils.platform_aware import IS_WINDOWS
from cuda.pathfinder._utils.windows_arch import windows_machine_arch

_NSIGHT_REGISTRY_ROOT = r"SOFTWARE\NVIDIA Corporation\Installed Products\Nsight"

_NSYS_TARGET_DIR_BY_ARCH = {
"x64": "target-windows-x64",
"arm64": "target-windows-armv8",
}

_NCU_TARGET_DIR_BY_ARCH = {
"x64": os.path.join("target", "windows-desktop-win7-x64"),
"arm64": os.path.join("target", "windows-desktop-win10-t23x-a64"),
}


class UnsupportedBinaryError(Exception):
Expand Down Expand Up @@ -83,61 +68,6 @@ def _find_windows_compute_sanitizer(ctk_root: str) -> str | None:
)


def _windows_installed_nsight_root(product: str) -> str | None:
"""Return the active Nsight product installation recorded by its MSI."""
# ``winreg`` attributes are absent from the type stubs on non-Windows hosts.
winreg: Any = importlib.import_module("winreg")

access = winreg.KEY_READ | winreg.KEY_WOW64_64KEY
product_key_path = rf"{_NSIGHT_REGISTRY_ROOT}\{product}"
try:
product_context = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, product_key_path, 0, access)
except FileNotFoundError:
return None

try:
with product_context as product_key:
current_version, _ = winreg.QueryValueEx(product_key, "CurrentVersion")
if not isinstance(current_version, str) or not current_version.strip():
raise RuntimeError(
f"Invalid CurrentVersion value {current_version!r} in "
f"Nsight {product!r} registry registration at {product_key_path!r}"
)
with winreg.OpenKey(product_key, current_version, 0, access) as version_key:
install_root, _ = winreg.QueryValueEx(version_key, None)
except FileNotFoundError as exc:
raise RuntimeError(f"Incomplete Nsight {product!r} registry registration at {product_key_path!r}") from exc

if not isinstance(install_root, str) or not install_root.strip():
raise RuntimeError(
f"Invalid installation directory {install_root!r} in Nsight {product!r} "
f"registry registration at {product_key_path!r} version {current_version!r}"
)
return install_root


def _find_windows_nsys() -> str | None:
install_root = _windows_installed_nsight_root("Systems")
if install_root is None:
return None

target_dir = _NSYS_TARGET_DIR_BY_ARCH[windows_machine_arch()]
return _resolve_candidate_paths((os.path.join(install_root, target_dir, "nsys.exe"),))


def _find_windows_ncu() -> str | None:
install_root = _windows_installed_nsight_root("Compute")
if install_root is None:
return None

launcher = os.path.join(install_root, "ncu.bat")
if (found := _resolve_candidate_paths((launcher,))) is not None:
return found

target_dir = _NCU_TARGET_DIR_BY_ARCH[windows_machine_arch()]
return _resolve_candidate_paths((os.path.join(install_root, target_dir, "ncu.exe"),))


def _resolve_ctk_root_via_canary() -> str | None:
from cuda.pathfinder._dynamic_libs.load_nvidia_dynamic_lib import resolve_ctk_root_via_canary

Expand Down Expand Up @@ -287,9 +217,9 @@ def find_nvidia_binary_utility(utility_name: str) -> str | None:
# 3. Search library-specific standalone installations.
# 3.1. Standalone Nsight CLI lookup is terminal; CTK does not contain nsys/ncu.
if IS_WINDOWS and utility_name == "nsys":
return _find_windows_nsys()
return _resolve_candidate_paths(windows_nsight.nsys_candidate_paths())
if IS_WINDOWS and utility_name == "ncu":
return _find_windows_ncu()
return _resolve_candidate_paths(windows_nsight.ncu_candidate_paths())

# 3.2. Search in CUDA Toolkit (CUDA_PATH/CUDA_HOME).
if (cuda_path := get_cuda_path_or_home()) is not None:
Expand Down
74 changes: 74 additions & 0 deletions cuda_pathfinder/cuda/pathfinder/_binaries/windows_nsight.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0

import importlib
import os
from collections.abc import Iterator
from typing import Any

from cuda.pathfinder._utils.windows_arch import windows_machine_arch

_REGISTRY_ROOT = r"SOFTWARE\NVIDIA Corporation\Installed Products\Nsight"

_NSYS_TARGET_DIR_BY_ARCH = {
"x64": "target-windows-x64",
"arm64": "target-windows-armv8",
}

_NCU_TARGET_DIR_BY_ARCH = {
"x64": os.path.join("target", "windows-desktop-win7-x64"),
"arm64": os.path.join("target", "windows-desktop-win10-t23x-a64"),
}


def _installed_product_root(product: str) -> str | None:
"""Return the active Nsight product installation recorded by its MSI."""
# ``winreg`` attributes are absent from the type stubs on non-Windows hosts.
winreg: Any = importlib.import_module("winreg")

access = winreg.KEY_READ | winreg.KEY_WOW64_64KEY
product_key_path = rf"{_REGISTRY_ROOT}\{product}"
try:
product_context = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, product_key_path, 0, access)
except FileNotFoundError:
return None

try:
with product_context as product_key:
current_version, _ = winreg.QueryValueEx(product_key, "CurrentVersion")
if not isinstance(current_version, str) or not current_version.strip():
raise RuntimeError(
f"Invalid CurrentVersion value {current_version!r} in "
f"Nsight {product!r} registry registration at {product_key_path!r}"
)
with winreg.OpenKey(product_key, current_version, 0, access) as version_key:
install_root, _ = winreg.QueryValueEx(version_key, None)
except FileNotFoundError as exc:
raise RuntimeError(f"Incomplete Nsight {product!r} registry registration at {product_key_path!r}") from exc

if not isinstance(install_root, str) or not install_root.strip():
raise RuntimeError(
f"Invalid installation directory {install_root!r} in Nsight {product!r} "
f"registry registration at {product_key_path!r} version {current_version!r}"
)
return install_root


def nsys_candidate_paths() -> Iterator[str]:
install_root = _installed_product_root("Systems")
if install_root is None:
return

target_dir = _NSYS_TARGET_DIR_BY_ARCH[windows_machine_arch()]
yield os.path.join(install_root, target_dir, "nsys.exe")


def ncu_candidate_paths() -> Iterator[str]:
install_root = _installed_product_root("Compute")
if install_root is None:
return

yield os.path.join(install_root, "ncu.bat")

target_dir = _NCU_TARGET_DIR_BY_ARCH[windows_machine_arch()]
yield os.path.join(install_root, target_dir, "ncu.exe")
Loading
Loading