diff --git a/cuda_bindings/tests/test_cufile.py b/cuda_bindings/tests/test_cufile.py index 7de4ceb2e20..055f9018175 100644 --- a/cuda_bindings/tests/test_cufile.py +++ b/cuda_bindings/tests/test_cufile.py @@ -1520,6 +1520,7 @@ def stats(driver): cufileVersionLessThan(1150), reason="cuFile parameter APIs require cuFile library version 13.0 or later" ) @pytest.mark.usefixtures("stats") +@pytest.mark.thread_unsafe(reason="cuFile stats level is process-global") def test_set_stats_level(): """Test cuFile statistics level configuration.""" # Test setting different statistics levels diff --git a/cuda_pathfinder/tests/local_helpers.py b/cuda_pathfinder/tests/local_helpers.py index 7893ba8229f..540a0692752 100644 --- a/cuda_pathfinder/tests/local_helpers.py +++ b/cuda_pathfinder/tests/local_helpers.py @@ -1,16 +1,20 @@ -# 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 import functools import importlib.metadata import re +from packaging.version import Version + @functools.cache -def have_distribution(name_pattern: str) -> bool: +def have_distribution(name_pattern: str, *, minimum_version: str | None = None) -> bool: re_name_pattern = re.compile(name_pattern) + parsed_minimum_version = Version(minimum_version) if minimum_version is not None else None return any( re_name_pattern.match(dist.metadata["Name"]) + and (parsed_minimum_version is None or Version(dist.version) >= parsed_minimum_version) for dist in importlib.metadata.distributions() if "Name" in dist.metadata ) diff --git a/cuda_pathfinder/tests/test_load_nvidia_dynamic_lib.py b/cuda_pathfinder/tests/test_load_nvidia_dynamic_lib.py index f08d100a1ae..a6a69e5c6ac 100644 --- a/cuda_pathfinder/tests/test_load_nvidia_dynamic_lib.py +++ b/cuda_pathfinder/tests/test_load_nvidia_dynamic_lib.py @@ -4,6 +4,7 @@ import os import platform from pathlib import Path +from types import SimpleNamespace import pytest from child_load_nvidia_dynamic_lib_helper import ( @@ -123,12 +124,39 @@ def test_known_but_platform_unavailable_libname_raises_dynamic_lib_not_available def _is_expected_load_nvidia_dynamic_lib_failure(libname): if libname == "nvpl_fftw" and platform.machine().lower() != "aarch64": return True + if libname == "cutensorMg": + # cuTENSOR 2.8 removed cuTENSORMg in favor of cuTENSORMp. + return have_distribution(r"^cutensor-cu(?:12|13)$", minimum_version="2.8") dist_name_pattern = IMPORTLIB_METADATA_DISTRIBUTIONS_NAMES.get(libname) if dist_name_pattern is not None: return not have_distribution(dist_name_pattern) return False +@pytest.mark.parametrize( + ("installed_distributions", "expected"), + [ + ([], False), + ([SimpleNamespace(metadata={"Name": "cutensor-cu13"}, version="2.7.0")], False), + ([SimpleNamespace(metadata={"Name": "cutensor-cu12"}, version="2.8.0")], True), + ([SimpleNamespace(metadata={"Name": "cutensor-cu13"}, version="2.9.0")], True), + ([SimpleNamespace(metadata={"Name": "unrelated-package"}, version="2.8.0")], False), + ], +) +@pytest.mark.agent_authored(model="gpt-5.6-sol") +def test_cutensor_mg_expected_failure_follows_installed_cutensor_version( + mocker, + installed_distributions, + expected, +): + mocker.patch("local_helpers.importlib.metadata.distributions", return_value=installed_distributions) + have_distribution.cache_clear() + try: + assert _is_expected_load_nvidia_dynamic_lib_failure("cutensorMg") is expected + finally: + have_distribution.cache_clear() + + @pytest.mark.parametrize( "libname", supported_nvidia_libs.SUPPORTED_WINDOWS_DLLS if IS_WINDOWS else supported_nvidia_libs.SUPPORTED_LINUX_SONAMES,