Skip to content

Commit 526ce53

Browse files
committed
Test unpinned NVSHMEM bitcode layouts
1 parent 820ffba commit 526ce53

2 files changed

Lines changed: 99 additions & 3 deletions

File tree

cuda_pathfinder/pyproject.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ cu12 = [
2929
"nvidia-cusparselt-cu12",
3030
"nvidia-libmathdx-cu12",
3131
"nvidia-nccl-cu12; sys_platform != 'win32'",
32-
"nvidia-nvshmem-cu12<3.7; sys_platform != 'win32'",
32+
"nvidia-nvshmem-cu12; sys_platform != 'win32'",
3333
]
3434
cu13 = [
3535
"cuda-toolkit[nvcc,cublas,nvrtc,cudart,cufft,curand,cusolver,cusparse,npp,nvfatbin,nvjitlink,nvjpeg,cccl,cupti,profiler,nvvm]==13.*",
@@ -43,7 +43,7 @@ cu13 = [
4343
"nvidia-cusparselt-cu13",
4444
"nvidia-libmathdx-cu13",
4545
"nvidia-nccl-cu13; sys_platform != 'win32'",
46-
"nvidia-nvshmem-cu13<3.7; sys_platform != 'win32'",
46+
"nvidia-nvshmem-cu13; sys_platform != 'win32'",
4747
]
4848
host = [
4949
# TODO: remove the Python 3.15 guard once 3.15 is officially supported

cuda_pathfinder/tests/test_find_bitcode_lib.py

Lines changed: 97 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
22
# SPDX-License-Identifier: Apache-2.0
33

4+
import importlib.metadata
45
import os
6+
import re
57
from pathlib import Path
68

79
import pytest
@@ -20,6 +22,10 @@
2022
STRICTNESS = os.environ.get("CUDA_PATHFINDER_TEST_FIND_NVIDIA_BITCODE_LIB_STRICTNESS", "see_what_works")
2123
assert STRICTNESS in ("see_what_works", "all_must_work")
2224

25+
_NVSHMEM_DISTRIBUTION_PATTERN = re.compile(r"^nvidia-nvshmem-cu(?:12|13)$", re.IGNORECASE)
26+
_NVSHMEM_LIB_DIR_PARTS = ("nvidia", "nvshmem", "lib")
27+
_NVSHMEM_LEGACY_FILENAME = "libnvshmem_device.bc"
28+
2329

2430
def _bitcode_lib_info(libname: str):
2531
return find_bitcode_lib_module._SUPPORTED_BITCODE_LIBS_INFO[libname]
@@ -62,6 +68,26 @@ def _conda_anchor(conda_prefix: Path) -> Path:
6268
return conda_prefix
6369

6470

71+
def _installed_nvshmem_distributions():
72+
return tuple(
73+
dist
74+
for dist in importlib.metadata.distributions()
75+
if "Name" in dist.metadata and _NVSHMEM_DISTRIBUTION_PATTERN.fullmatch(dist.metadata["Name"])
76+
)
77+
78+
79+
def _installed_nvshmem_bitcode_paths(distributions):
80+
paths = {
81+
Path(dist.locate_file(file))
82+
for dist in distributions
83+
for file in (dist.files or ())
84+
if file.parts[-4:-1] == _NVSHMEM_LIB_DIR_PARTS
85+
and file.name.startswith("libnvshmem_device")
86+
and file.suffix == ".bc"
87+
}
88+
return tuple(sorted(paths))
89+
90+
6591
def _located_bitcode_lib_asserts(located_bitcode_lib):
6692
"""Common assertions for a located bitcode library."""
6793
assert located_bitcode_lib is not None
@@ -74,7 +100,7 @@ def _located_bitcode_lib_asserts(located_bitcode_lib):
74100

75101

76102
@pytest.mark.usefixtures("clear_find_bitcode_lib_cache")
77-
@pytest.mark.parametrize("libname", SUPPORTED_BITCODE_LIBS)
103+
@pytest.mark.parametrize("libname", tuple(name for name in SUPPORTED_BITCODE_LIBS if name != "nvshmem_device"))
78104
def test_locate_bitcode_lib(info_summary_append, libname):
79105
try:
80106
located_lib = locate_bitcode_lib(libname)
@@ -93,6 +119,40 @@ def test_locate_bitcode_lib(info_summary_append, libname):
93119
assert os.path.basename(lib_path) == expected_filename
94120

95121

122+
@pytest.mark.skipif(
123+
find_bitcode_lib_module.IS_WINDOWS,
124+
reason="NVSHMEM wheel test dependencies are not installed on Windows",
125+
)
126+
@pytest.mark.usefixtures("clear_find_bitcode_lib_cache")
127+
@pytest.mark.agent_authored(model="gpt-5")
128+
def test_locate_installed_nvshmem_bitcode(info_summary_append):
129+
distributions = _installed_nvshmem_distributions()
130+
if not distributions:
131+
if STRICTNESS == "all_must_work":
132+
pytest.fail("No nvidia-nvshmem-cu12/13 distribution is installed")
133+
info_summary_append("NVSHMEM distribution not installed")
134+
return
135+
136+
bitcode_paths = _installed_nvshmem_bitcode_paths(distributions)
137+
versions = ", ".join(f"{dist.metadata['Name']}=={dist.version}" for dist in distributions)
138+
info_summary_append(f"{versions}: {[path.name for path in bitcode_paths]}")
139+
assert bitcode_paths, f"No NVSHMEM device bitcode files found in {versions}"
140+
141+
for expected_path in bitcode_paths:
142+
located_lib = locate_bitcode_lib_by_name("nvshmem_device", expected_path.name)
143+
assert Path(located_lib.abs_path).samefile(expected_path)
144+
assert located_lib.filename == expected_path.name
145+
assert located_lib.found_via == "site-packages"
146+
assert Path(find_bitcode_lib_by_name("nvshmem_device", expected_path.name)).samefile(expected_path)
147+
148+
legacy_paths = [path for path in bitcode_paths if path.name == _NVSHMEM_LEGACY_FILENAME]
149+
if legacy_paths:
150+
assert len(legacy_paths) == 1
151+
located_lib = locate_bitcode_lib("nvshmem_device")
152+
assert Path(located_lib.abs_path).samefile(legacy_paths[0])
153+
assert Path(find_bitcode_lib("nvshmem_device")).samefile(legacy_paths[0])
154+
155+
96156
@pytest.mark.usefixtures("clear_find_bitcode_lib_cache")
97157
@pytest.mark.parametrize("libname", SUPPORTED_BITCODE_LIBS)
98158
def test_locate_bitcode_lib_search_order(monkeypatch, tmp_path, libname):
@@ -140,6 +200,42 @@ def find_expected_sub_dir(sub_dir):
140200
assert located_lib.found_via == "CUDA_PATH"
141201

142202

203+
@pytest.mark.skipif(
204+
find_bitcode_lib_module.IS_WINDOWS,
205+
reason="NVSHMEM wheel test dependencies are not installed on Windows",
206+
)
207+
@pytest.mark.usefixtures("clear_find_bitcode_lib_cache")
208+
@pytest.mark.agent_authored(model="gpt-5")
209+
def test_nvshmem_legacy_unversioned_bitcode_filename(monkeypatch, tmp_path):
210+
libname = "nvshmem_device"
211+
assert _bitcode_lib_filename(libname) == _NVSHMEM_LEGACY_FILENAME
212+
213+
lib_dir = _site_packages_bitcode_lib_dir_under(tmp_path / "site-packages", libname)
214+
expected_path = _make_bitcode_lib_file(lib_dir, _NVSHMEM_LEGACY_FILENAME)
215+
expected_sub_dir = tuple(_bitcode_lib_info(libname)["site_packages_dirs"][0].split("/"))
216+
217+
def find_expected_sub_dir(sub_dir):
218+
assert sub_dir == expected_sub_dir
219+
return [str(lib_dir)]
220+
221+
monkeypatch.setattr(find_bitcode_lib_module, "find_sub_dirs_all_sitepackages", find_expected_sub_dir)
222+
monkeypatch.delenv("CONDA_PREFIX", raising=False)
223+
monkeypatch.delenv("CUDA_HOME", raising=False)
224+
monkeypatch.delenv("CUDA_PATH", raising=False)
225+
226+
located_lib = locate_bitcode_lib(libname)
227+
assert located_lib.abs_path == expected_path
228+
assert located_lib.filename == _NVSHMEM_LEGACY_FILENAME
229+
assert located_lib.found_via == "site-packages"
230+
assert find_bitcode_lib(libname) == expected_path
231+
232+
located_by_name = locate_bitcode_lib_by_name(libname, _NVSHMEM_LEGACY_FILENAME)
233+
assert located_by_name.abs_path == expected_path
234+
assert located_by_name.filename == _NVSHMEM_LEGACY_FILENAME
235+
assert located_by_name.found_via == "site-packages"
236+
assert find_bitcode_lib_by_name(libname, _NVSHMEM_LEGACY_FILENAME) == expected_path
237+
238+
143239
@pytest.mark.usefixtures("clear_find_bitcode_lib_cache")
144240
@pytest.mark.agent_authored(model="gpt-5")
145241
def test_bitcode_lib_by_name_search_order(monkeypatch, tmp_path):

0 commit comments

Comments
 (0)