1111 SUPPORTED_BITCODE_LIBS ,
1212 BitcodeLibNotFoundError ,
1313 find_bitcode_lib ,
14+ find_bitcode_lib_by_name ,
1415 locate_bitcode_lib ,
1516)
1617from cuda .pathfinder ._utils .env_vars import get_cuda_path_or_home
@@ -30,15 +31,17 @@ def _bitcode_lib_filename(libname: str) -> str:
3031@pytest .fixture
3132def clear_find_bitcode_lib_cache ():
3233 find_bitcode_lib_module .find_bitcode_lib .cache_clear ()
34+ find_bitcode_lib_module .find_bitcode_lib_by_name .cache_clear ()
3335 get_cuda_path_or_home .cache_clear ()
3436 yield
3537 find_bitcode_lib_module .find_bitcode_lib .cache_clear ()
38+ find_bitcode_lib_module .find_bitcode_lib_by_name .cache_clear ()
3639 get_cuda_path_or_home .cache_clear ()
3740
3841
39- def _make_bitcode_lib_file (dir_path : Path , libname : str ) -> str :
42+ def _make_bitcode_lib_file (dir_path : Path , filename : str ) -> str :
4043 dir_path .mkdir (parents = True , exist_ok = True )
41- file_path = dir_path / _bitcode_lib_filename ( libname )
44+ file_path = dir_path / filename
4245 file_path .touch ()
4346 return str (file_path )
4447
@@ -92,14 +95,15 @@ def test_locate_bitcode_lib(info_summary_append, libname):
9295@pytest .mark .usefixtures ("clear_find_bitcode_lib_cache" )
9396@pytest .mark .parametrize ("libname" , SUPPORTED_BITCODE_LIBS )
9497def test_locate_bitcode_lib_search_order (monkeypatch , tmp_path , libname ):
98+ filename = _bitcode_lib_filename (libname )
9599 site_packages_lib_dir = _site_packages_bitcode_lib_dir_under (tmp_path / "site-packages" , libname )
96- site_packages_path = _make_bitcode_lib_file (site_packages_lib_dir , libname )
100+ site_packages_path = _make_bitcode_lib_file (site_packages_lib_dir , filename )
97101
98102 conda_prefix = tmp_path / "conda-prefix"
99- conda_path = _make_bitcode_lib_file (_bitcode_lib_dir_under (_conda_anchor (conda_prefix ), libname ), libname )
103+ conda_path = _make_bitcode_lib_file (_bitcode_lib_dir_under (_conda_anchor (conda_prefix ), libname ), filename )
100104
101105 cuda_home = tmp_path / "cuda-home"
102- cuda_home_path = _make_bitcode_lib_file (_bitcode_lib_dir_under (cuda_home , libname ), libname )
106+ cuda_home_path = _make_bitcode_lib_file (_bitcode_lib_dir_under (cuda_home , libname ), filename )
103107
104108 site_packages_sub_dirs = tuple (
105109 tuple (rel_dir .split ("/" )) for rel_dir in _bitcode_lib_info (libname )["site_packages_dirs" ]
@@ -135,6 +139,70 @@ def find_expected_sub_dir(sub_dir):
135139 assert located_lib .found_via == "CUDA_PATH"
136140
137141
142+ @pytest .mark .usefixtures ("clear_find_bitcode_lib_cache" )
143+ @pytest .mark .agent_authored (model = "gpt-5" )
144+ def test_find_bitcode_lib_by_name_search_order (monkeypatch , tmp_path ):
145+ libname = "device"
146+ filename = "libdevice_sm_90.bc"
147+ site_packages_lib_dir = _site_packages_bitcode_lib_dir_under (tmp_path / "site-packages" , libname )
148+ site_packages_path = _make_bitcode_lib_file (site_packages_lib_dir , filename )
149+
150+ conda_prefix = tmp_path / "conda-prefix"
151+ conda_path = _make_bitcode_lib_file (_bitcode_lib_dir_under (_conda_anchor (conda_prefix ), libname ), filename )
152+
153+ cuda_home = tmp_path / "cuda-home"
154+ cuda_home_path = _make_bitcode_lib_file (_bitcode_lib_dir_under (cuda_home , libname ), filename )
155+
156+ site_packages_sub_dirs = tuple (
157+ tuple (rel_dir .split ("/" )) for rel_dir in _bitcode_lib_info (libname )["site_packages_dirs" ]
158+ )
159+
160+ def find_expected_sub_dir (sub_dir ):
161+ assert sub_dir in site_packages_sub_dirs
162+ if sub_dir == site_packages_sub_dirs [0 ]:
163+ return [str (site_packages_lib_dir )]
164+ return []
165+
166+ monkeypatch .setattr (
167+ find_bitcode_lib_module ,
168+ "find_sub_dirs_all_sitepackages" ,
169+ find_expected_sub_dir ,
170+ )
171+ monkeypatch .setenv ("CONDA_PREFIX" , str (conda_prefix ))
172+ monkeypatch .setenv ("CUDA_HOME" , str (cuda_home ))
173+ monkeypatch .delenv ("CUDA_PATH" , raising = False )
174+
175+ assert find_bitcode_lib_by_name (libname , filename ) == site_packages_path
176+ os .remove (site_packages_path )
177+ find_bitcode_lib_by_name .cache_clear ()
178+
179+ assert find_bitcode_lib_by_name (libname , filename ) == conda_path
180+ os .remove (conda_path )
181+ find_bitcode_lib_by_name .cache_clear ()
182+
183+ assert find_bitcode_lib_by_name (libname , filename ) == cuda_home_path
184+
185+
186+ @pytest .mark .usefixtures ("clear_find_bitcode_lib_cache" )
187+ @pytest .mark .agent_authored (model = "gpt-5" )
188+ def test_find_bitcode_lib_by_name_cache_keeps_filenames_separate (monkeypatch , tmp_path ):
189+ lib_dir = _site_packages_bitcode_lib_dir_under (tmp_path / "site-packages" , "device" )
190+ sm80_path = _make_bitcode_lib_file (lib_dir , "libdevice_sm_80.bc" )
191+ sm90_path = _make_bitcode_lib_file (lib_dir , "libdevice_sm_90.bc" )
192+
193+ monkeypatch .setattr (
194+ find_bitcode_lib_module ,
195+ "find_sub_dirs_all_sitepackages" ,
196+ lambda _sub_dir : [str (lib_dir )],
197+ )
198+ monkeypatch .delenv ("CONDA_PREFIX" , raising = False )
199+ monkeypatch .delenv ("CUDA_HOME" , raising = False )
200+ monkeypatch .delenv ("CUDA_PATH" , raising = False )
201+
202+ assert find_bitcode_lib_by_name ("device" , "libdevice_sm_80.bc" ) == sm80_path
203+ assert find_bitcode_lib_by_name ("device" , "libdevice_sm_90.bc" ) == sm90_path
204+
205+
138206@pytest .mark .usefixtures ("clear_find_bitcode_lib_cache" )
139207def test_find_bitcode_lib_not_found_error_includes_cuda_home_directory_listing (monkeypatch , tmp_path ):
140208 cuda_home = tmp_path / "cuda-home"
@@ -162,6 +230,32 @@ def test_find_bitcode_lib_not_found_error_includes_cuda_home_directory_listing(m
162230 assert "README.txt" in message
163231
164232
233+ @pytest .mark .usefixtures ("clear_find_bitcode_lib_cache" )
234+ @pytest .mark .agent_authored (model = "gpt-5" )
235+ def test_find_bitcode_lib_by_name_not_found_error_uses_requested_filename (monkeypatch , tmp_path ):
236+ filename = "libdevice_sm_90.bc"
237+ cuda_home = tmp_path / "cuda-home"
238+ lib_dir = _bitcode_lib_dir_under (cuda_home , "device" )
239+ lib_dir .mkdir (parents = True )
240+ (lib_dir / "libdevice.10.bc" ).touch ()
241+
242+ monkeypatch .setattr (
243+ find_bitcode_lib_module ,
244+ "find_sub_dirs_all_sitepackages" ,
245+ lambda _sub_dir : [],
246+ )
247+ monkeypatch .delenv ("CONDA_PREFIX" , raising = False )
248+ monkeypatch .setenv ("CUDA_HOME" , str (cuda_home ))
249+ monkeypatch .delenv ("CUDA_PATH" , raising = False )
250+
251+ with pytest .raises (BitcodeLibNotFoundError , match = rf'Failure finding "{ filename } "' ) as exc_info :
252+ find_bitcode_lib_by_name ("device" , filename )
253+
254+ message = str (exc_info .value )
255+ assert f"No such file: { lib_dir / filename } " in message
256+ assert "libdevice.10.bc" in message
257+
258+
165259@pytest .mark .usefixtures ("clear_find_bitcode_lib_cache" )
166260def test_find_bitcode_lib_not_found_error_without_cuda_home (monkeypatch ):
167261 monkeypatch .setattr (
@@ -183,3 +277,26 @@ def test_find_bitcode_lib_not_found_error_without_cuda_home(monkeypatch):
183277def test_find_bitcode_lib_invalid_name ():
184278 with pytest .raises (ValueError , match = "Unknown bitcode library" ):
185279 find_bitcode_lib_module .locate_bitcode_lib ("invalid" )
280+
281+
282+ @pytest .mark .parametrize (
283+ "filename" ,
284+ ("" , "." , ".." , "../file.bc" , "subdir/file.bc" , r"subdir\file.bc" , r"C:\lib\file.bc" , "bad\0 name.bc" ),
285+ )
286+ @pytest .mark .agent_authored (model = "gpt-5" )
287+ def test_find_bitcode_lib_by_name_rejects_paths (filename ):
288+ with pytest .raises (ValueError , match = "without a directory" ):
289+ find_bitcode_lib_by_name ("device" , filename )
290+
291+
292+ @pytest .mark .parametrize ("filename" , (None , 90 ))
293+ @pytest .mark .agent_authored (model = "gpt-5" )
294+ def test_find_bitcode_lib_by_name_requires_string (filename ):
295+ with pytest .raises (TypeError , match = "filename must be a string" ):
296+ find_bitcode_lib_by_name ("device" , filename )
297+
298+
299+ @pytest .mark .agent_authored (model = "gpt-5" )
300+ def test_find_bitcode_lib_by_name_invalid_project ():
301+ with pytest .raises (ValueError , match = "Unknown bitcode library" ):
302+ find_bitcode_lib_by_name ("not_a_real_lib" , "libdevice_sm_90.bc" )
0 commit comments