Skip to content

Commit 6da23cf

Browse files
rwgkcursoragent
andcommitted
pathfinder: cache static and bitcode locate results
Move static and bitcode caching to the shared locate layer so strict-mode public APIs reuse the same discovery boundary after process-wide guard-rails indirection. Add symmetric wrapper cache clears and a regression test that exercises the strict-mode path. Co-authored-by: Cursor <cursoragent@cursor.com>
1 parent ad4a531 commit 6da23cf

6 files changed

Lines changed: 99 additions & 6 deletions

File tree

cuda_pathfinder/cuda/pathfinder/_process_wide_compatibility_guard_rails.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,12 @@ def find_nvidia_binary_utility(utility_name: str) -> str | None:
261261
locate_nvidia_header_directory.cache_clear = _cache_clear_with_process_state_reset( # type: ignore[attr-defined]
262262
_locate_nvidia_header_directory.cache_clear
263263
)
264+
_locate_static_lib_cache_clear = _cache_clear_with_process_state_reset(_locate_static_lib.cache_clear)
265+
locate_static_lib.cache_clear = _locate_static_lib_cache_clear # type: ignore[attr-defined]
266+
find_static_lib.cache_clear = _locate_static_lib_cache_clear # type: ignore[attr-defined]
267+
_locate_bitcode_lib_cache_clear = _cache_clear_with_process_state_reset(_locate_bitcode_lib.cache_clear)
268+
locate_bitcode_lib.cache_clear = _locate_bitcode_lib_cache_clear # type: ignore[attr-defined]
269+
find_bitcode_lib.cache_clear = _locate_bitcode_lib_cache_clear # type: ignore[attr-defined]
264270
find_nvidia_binary_utility.cache_clear = _cache_clear_with_process_state_reset( # type: ignore[attr-defined]
265271
_find_nvidia_binary_utility.cache_clear
266272
)

cuda_pathfinder/cuda/pathfinder/_static_libs/find_bitcode_lib.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,7 @@ def raise_not_found_error(self) -> NoReturn:
137137
raise BitcodeLibNotFoundError(f'Failure finding "{self.filename}": {err}\n{att}')
138138

139139

140+
@functools.cache
140141
def locate_bitcode_lib(name: str) -> LocatedBitcodeLib:
141142
"""Locate a bitcode library by name.
142143
@@ -176,7 +177,6 @@ def locate_bitcode_lib(name: str) -> LocatedBitcodeLib:
176177
finder.raise_not_found_error()
177178

178179

179-
@functools.cache
180180
def find_bitcode_lib(name: str) -> str:
181181
"""Find the absolute path to a bitcode library.
182182
@@ -185,3 +185,6 @@ def find_bitcode_lib(name: str) -> str:
185185
BitcodeLibNotFoundError: If the bitcode library cannot be found.
186186
"""
187187
return locate_bitcode_lib(name).abs_path
188+
189+
190+
find_bitcode_lib.cache_clear = locate_bitcode_lib.cache_clear # type: ignore[attr-defined]

cuda_pathfinder/cuda/pathfinder/_static_libs/find_static_lib.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@ def raise_not_found_error(self) -> NoReturn:
122122
raise StaticLibNotFoundError(f'Failure finding "{self.filename}": {err}\n{att}')
123123

124124

125+
@functools.cache
125126
def locate_static_lib(name: str) -> LocatedStaticLib:
126127
"""Locate a static library by name.
127128
@@ -161,7 +162,6 @@ def locate_static_lib(name: str) -> LocatedStaticLib:
161162
finder.raise_not_found_error()
162163

163164

164-
@functools.cache
165165
def find_static_lib(name: str) -> str:
166166
"""Find the absolute path to a static library.
167167
@@ -170,3 +170,6 @@ def find_static_lib(name: str) -> str:
170170
StaticLibNotFoundError: If the static library cannot be found.
171171
"""
172172
return locate_static_lib(name).abs_path
173+
174+
175+
find_static_lib.cache_clear = locate_static_lib.cache_clear # type: ignore[attr-defined]

cuda_pathfinder/tests/test_compatibility_guard_rails_public.py

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
from __future__ import annotations
55

66
import sys
7+
from pathlib import Path
78

89
import pytest
910
from compatibility_guard_rails_test_utils import (
@@ -21,6 +22,8 @@
2122
process_wide_module,
2223
)
2324

25+
import cuda.pathfinder._static_libs.find_bitcode_lib as find_bitcode_lib_module
26+
import cuda.pathfinder._static_libs.find_static_lib as find_static_lib_module
2427
from cuda import pathfinder
2528
from cuda.pathfinder import (
2629
CompatibilityCheckError,
@@ -30,6 +33,7 @@
3033
LocatedHeaderDir,
3134
process_wide_compatibility_guard_rails,
3235
)
36+
from cuda.pathfinder._utils.env_vars import get_cuda_path_or_home
3337

3438

3539
def test_process_wide_compatibility_guard_rails_is_public_singleton():
@@ -313,3 +317,76 @@ def test_public_apis_share_process_wide_guard_rails_state(monkeypatch, tmp_path)
313317
assert loaded.abs_path == lib_path
314318
with pytest.raises(CompatibilityCheckError, match=r"companion tag 'api_nvrtc'"):
315319
pathfinder.find_nvidia_header_directory("nvrtc")
320+
321+
322+
@pytest.mark.parametrize(
323+
("public_find_name", "public_locate_name", "raw_module", "finder_class_name", "name", "relative_path"),
324+
[
325+
(
326+
"find_static_lib",
327+
"locate_static_lib",
328+
find_static_lib_module,
329+
"_FindStaticLib",
330+
"cudadevrt",
331+
Path(find_static_lib_module._SUPPORTED_STATIC_LIBS_INFO["cudadevrt"]["ctk_rel_paths"][0])
332+
/ find_static_lib_module._SUPPORTED_STATIC_LIBS_INFO["cudadevrt"]["filename"],
333+
),
334+
(
335+
"find_bitcode_lib",
336+
"locate_bitcode_lib",
337+
find_bitcode_lib_module,
338+
"_FindBitcodeLib",
339+
"device",
340+
Path(find_bitcode_lib_module._SUPPORTED_BITCODE_LIBS_INFO["device"]["rel_path"])
341+
/ find_bitcode_lib_module._SUPPORTED_BITCODE_LIBS_INFO["device"]["filename"],
342+
),
343+
],
344+
)
345+
def test_public_strict_mode_static_and_bitcode_reuse_cached_locate_path(
346+
monkeypatch,
347+
tmp_path,
348+
public_find_name,
349+
public_locate_name,
350+
raw_module,
351+
finder_class_name,
352+
name,
353+
relative_path,
354+
):
355+
ctk_root = tmp_path / "cuda-12.9"
356+
abs_path = _touch_ctk_file(ctk_root, "12.9.20250531", relative_path)
357+
finder_class = getattr(raw_module, finder_class_name)
358+
original_try_with_cuda_home = finder_class.try_with_cuda_home
359+
try_with_cuda_home_calls: list[str] = []
360+
361+
def counting_try_with_cuda_home(self):
362+
try_with_cuda_home_calls.append(self.name)
363+
return original_try_with_cuda_home(self)
364+
365+
monkeypatch.setattr(raw_module, "find_sub_dirs_all_sitepackages", lambda _sub_dir: [])
366+
monkeypatch.setattr(finder_class, "try_with_cuda_home", counting_try_with_cuda_home)
367+
monkeypatch.delenv("CONDA_PREFIX", raising=False)
368+
monkeypatch.delenv("CUDA_PATH", raising=False)
369+
monkeypatch.setenv("CUDA_HOME", str(ctk_root))
370+
monkeypatch.setattr(
371+
pathfinder,
372+
"process_wide_compatibility_guard_rails",
373+
CompatibilityGuardRails(driver_cuda_version=_driver_cuda_version(13000)),
374+
)
375+
376+
public_find = getattr(pathfinder, public_find_name)
377+
public_locate = getattr(pathfinder, public_locate_name)
378+
379+
public_locate.cache_clear()
380+
get_cuda_path_or_home.cache_clear()
381+
try:
382+
assert public_find(name) == abs_path
383+
assert public_find(name) == abs_path
384+
assert try_with_cuda_home_calls == [name]
385+
386+
public_find.cache_clear()
387+
assert public_locate(name).abs_path == abs_path
388+
assert try_with_cuda_home_calls == [name, name]
389+
finally:
390+
public_find.cache_clear()
391+
public_locate.cache_clear()
392+
get_cuda_path_or_home.cache_clear()

cuda_pathfinder/tests/test_find_bitcode_lib.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,10 @@ def _bitcode_lib_filename(libname: str) -> str:
2929

3030
@pytest.fixture
3131
def clear_find_bitcode_lib_cache():
32-
find_bitcode_lib_module.find_bitcode_lib.cache_clear()
32+
find_bitcode_lib_module.locate_bitcode_lib.cache_clear()
3333
get_cuda_path_or_home.cache_clear()
3434
yield
35-
find_bitcode_lib_module.find_bitcode_lib.cache_clear()
35+
find_bitcode_lib_module.locate_bitcode_lib.cache_clear()
3636
get_cuda_path_or_home.cache_clear()
3737

3838

@@ -124,11 +124,13 @@ def find_expected_sub_dir(sub_dir):
124124
assert located_lib.abs_path == site_packages_path
125125
assert located_lib.found_via == "site-packages"
126126
os.remove(site_packages_path)
127+
find_bitcode_lib_module.locate_bitcode_lib.cache_clear()
127128

128129
located_lib = locate_bitcode_lib(libname)
129130
assert located_lib.abs_path == conda_path
130131
assert located_lib.found_via == "conda"
131132
os.remove(conda_path)
133+
find_bitcode_lib_module.locate_bitcode_lib.cache_clear()
132134

133135
located_lib = locate_bitcode_lib(libname)
134136
assert located_lib.abs_path == cuda_home_path

cuda_pathfinder/tests/test_find_static_lib.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,10 @@
2424

2525
@pytest.fixture
2626
def clear_find_static_lib_cache():
27-
find_static_lib_module.find_static_lib.cache_clear()
27+
find_static_lib_module.locate_static_lib.cache_clear()
2828
get_cuda_path_or_home.cache_clear()
2929
yield
30-
find_static_lib_module.find_static_lib.cache_clear()
30+
find_static_lib_module.locate_static_lib.cache_clear()
3131
get_cuda_path_or_home.cache_clear()
3232

3333

@@ -106,11 +106,13 @@ def test_locate_static_lib_search_order(monkeypatch, tmp_path):
106106
assert located_lib.abs_path == site_packages_path
107107
assert located_lib.found_via == "site-packages"
108108
os.remove(site_packages_path)
109+
find_static_lib_module.locate_static_lib.cache_clear()
109110

110111
located_lib = locate_static_lib("cudadevrt")
111112
assert located_lib.abs_path == conda_path
112113
assert located_lib.found_via == "conda"
113114
os.remove(conda_path)
115+
find_static_lib_module.locate_static_lib.cache_clear()
114116

115117
located_lib = locate_static_lib("cudadevrt")
116118
assert located_lib.abs_path == cuda_home_path

0 commit comments

Comments
 (0)