Skip to content

Commit 820ffba

Browse files
committed
Add exact-name bitcode locate API
1 parent 1a16604 commit 820ffba

4 files changed

Lines changed: 49 additions & 11 deletions

File tree

cuda_pathfinder/cuda/pathfinder/__init__.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,9 @@
4747
from cuda.pathfinder._static_libs.find_bitcode_lib import (
4848
locate_bitcode_lib as locate_bitcode_lib,
4949
)
50+
from cuda.pathfinder._static_libs.find_bitcode_lib import (
51+
locate_bitcode_lib_by_name as locate_bitcode_lib_by_name,
52+
)
5053
from cuda.pathfinder._static_libs.find_static_lib import (
5154
SUPPORTED_STATIC_LIBS as _SUPPORTED_STATIC_LIBS,
5255
)
@@ -80,8 +83,8 @@
8083
SUPPORTED_BINARY_UTILITIES = _SUPPORTED_BINARIES
8184

8285
#: Tuple of supported bitcode library names that can be resolved
83-
#: via ``locate_bitcode_lib()``, ``find_bitcode_lib()``, and
84-
#: ``find_bitcode_lib_by_name()``.
86+
#: via ``locate_bitcode_lib()``, ``locate_bitcode_lib_by_name()``,
87+
#: ``find_bitcode_lib()``, and ``find_bitcode_lib_by_name()``.
8588
#: Example value: ``"device"``.
8689
SUPPORTED_BITCODE_LIBS = _SUPPORTED_BITCODE_LIBS
8790

cuda_pathfinder/cuda/pathfinder/_static_libs/find_bitcode_lib.py

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,25 @@ def locate_bitcode_lib(name: str) -> LocatedBitcodeLib:
182182
return _locate_bitcode_lib(name)
183183

184184

185+
def locate_bitcode_lib_by_name(name: str, filename: str) -> LocatedBitcodeLib:
186+
"""Locate an exact bitcode filename using a supported library's search paths.
187+
188+
This lets a library define its own filename convention, including any
189+
architecture or other attributes encoded in the filename.
190+
191+
Args:
192+
name: Supported bitcode library whose configured directories to search.
193+
filename: Exact file name to locate. Directory components are not allowed.
194+
195+
Raises:
196+
TypeError: If ``filename`` is not a string.
197+
ValueError: If ``name`` is unsupported or ``filename`` is not a file name.
198+
BitcodeLibNotFoundError: If ``filename`` cannot be found.
199+
"""
200+
_validate_filename(filename)
201+
return _locate_bitcode_lib(name, filename=filename)
202+
203+
185204
@functools.cache
186205
def find_bitcode_lib(name: str) -> str:
187206
"""Find the absolute path to a bitcode library.
@@ -209,5 +228,4 @@ def find_bitcode_lib_by_name(name: str, filename: str) -> str:
209228
ValueError: If ``name`` is unsupported or ``filename`` is not a file name.
210229
BitcodeLibNotFoundError: If ``filename`` cannot be found.
211230
"""
212-
_validate_filename(filename)
213-
return _locate_bitcode_lib(name, filename=filename).abs_path
231+
return locate_bitcode_lib_by_name(name, filename).abs_path

cuda_pathfinder/docs/source/api.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ CUDA bitcode and static libraries.
3737
find_bitcode_lib
3838
find_bitcode_lib_by_name
3939
locate_bitcode_lib
40+
locate_bitcode_lib_by_name
4041
LocatedBitcodeLib
4142
BitcodeLibNotFoundError
4243

cuda_pathfinder/tests/test_find_bitcode_lib.py

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
find_bitcode_lib,
1414
find_bitcode_lib_by_name,
1515
locate_bitcode_lib,
16+
locate_bitcode_lib_by_name,
1617
)
1718
from cuda.pathfinder._utils.env_vars import get_cuda_path_or_home
1819

@@ -141,7 +142,7 @@ def find_expected_sub_dir(sub_dir):
141142

142143
@pytest.mark.usefixtures("clear_find_bitcode_lib_cache")
143144
@pytest.mark.agent_authored(model="gpt-5")
144-
def test_find_bitcode_lib_by_name_search_order(monkeypatch, tmp_path):
145+
def test_bitcode_lib_by_name_search_order(monkeypatch, tmp_path):
145146
libname = "device"
146147
filename = "libdevice_sm_90.bc"
147148
site_packages_lib_dir = _site_packages_bitcode_lib_dir_under(tmp_path / "site-packages", libname)
@@ -172,14 +173,26 @@ def find_expected_sub_dir(sub_dir):
172173
monkeypatch.setenv("CUDA_HOME", str(cuda_home))
173174
monkeypatch.delenv("CUDA_PATH", raising=False)
174175

176+
located_lib = locate_bitcode_lib_by_name(libname, filename)
177+
assert located_lib.abs_path == site_packages_path
178+
assert located_lib.filename == filename
179+
assert located_lib.found_via == "site-packages"
175180
assert find_bitcode_lib_by_name(libname, filename) == site_packages_path
176181
os.remove(site_packages_path)
177182
find_bitcode_lib_by_name.cache_clear()
178183

184+
located_lib = locate_bitcode_lib_by_name(libname, filename)
185+
assert located_lib.abs_path == conda_path
186+
assert located_lib.filename == filename
187+
assert located_lib.found_via == "conda"
179188
assert find_bitcode_lib_by_name(libname, filename) == conda_path
180189
os.remove(conda_path)
181190
find_bitcode_lib_by_name.cache_clear()
182191

192+
located_lib = locate_bitcode_lib_by_name(libname, filename)
193+
assert located_lib.abs_path == cuda_home_path
194+
assert located_lib.filename == filename
195+
assert located_lib.found_via == "CUDA_PATH"
183196
assert find_bitcode_lib_by_name(libname, filename) == cuda_home_path
184197

185198

@@ -283,20 +296,23 @@ def test_find_bitcode_lib_invalid_name():
283296
"filename",
284297
("", ".", "..", "../file.bc", "subdir/file.bc", r"subdir\file.bc", r"C:\lib\file.bc", "bad\0name.bc"),
285298
)
299+
@pytest.mark.parametrize("lookup", (find_bitcode_lib_by_name, locate_bitcode_lib_by_name))
286300
@pytest.mark.agent_authored(model="gpt-5")
287-
def test_find_bitcode_lib_by_name_rejects_paths(filename):
301+
def test_bitcode_lib_by_name_rejects_paths(lookup, filename):
288302
with pytest.raises(ValueError, match="without a directory"):
289-
find_bitcode_lib_by_name("device", filename)
303+
lookup("device", filename)
290304

291305

292306
@pytest.mark.parametrize("filename", (None, 90))
307+
@pytest.mark.parametrize("lookup", (find_bitcode_lib_by_name, locate_bitcode_lib_by_name))
293308
@pytest.mark.agent_authored(model="gpt-5")
294-
def test_find_bitcode_lib_by_name_requires_string(filename):
309+
def test_bitcode_lib_by_name_requires_string(lookup, filename):
295310
with pytest.raises(TypeError, match="filename must be a string"):
296-
find_bitcode_lib_by_name("device", filename)
311+
lookup("device", filename)
297312

298313

314+
@pytest.mark.parametrize("lookup", (find_bitcode_lib_by_name, locate_bitcode_lib_by_name))
299315
@pytest.mark.agent_authored(model="gpt-5")
300-
def test_find_bitcode_lib_by_name_invalid_project():
316+
def test_bitcode_lib_by_name_invalid_project(lookup):
301317
with pytest.raises(ValueError, match="Unknown bitcode library"):
302-
find_bitcode_lib_by_name("not_a_real_lib", "libdevice_sm_90.bc")
318+
lookup("not_a_real_lib", "libdevice_sm_90.bc")

0 commit comments

Comments
 (0)