@@ -177,57 +177,33 @@ def get_saxpy_fatbin(init_cuda):
177177 return bytes (fatbin ), sym_map
178178
179179
180- @pytest .fixture (scope = "module" )
181- def get_saxpy_object ():
182- """Read the pre-built saxpy.o.
183-
184- In CI: produced by build stage into a test wheel file.
185- In local dev: auto-built on demand if nvcc is available; if you edit
186- saxpy.cu, remove the stale saxpy.o to force a rebuild.
187- """
188- binaries_dir = Path (__file__ ).parent / "test_binaries"
189- obj_path = binaries_dir / "saxpy.o"
190-
191- if not obj_path .is_file ():
192- if find_nvidia_binary_utility ("nvcc" ) is None :
193- pytest .skip (
194- f"saxpy.o not found at { obj_path } and nvcc is unavailable. "
195- "In CI this is downloaded from the build stage."
196- )
197- subprocess .run ( # noqa: S603
198- ["bash" , str (binaries_dir / "build_test_binaries.sh" )], # noqa: S607
199- check = True ,
200- env = os .environ ,
201- )
180+ def _read_saxpy_rdc (kind : str ) -> bytes :
181+ """Read a pre-built saxpy RDC object or library.
202182
203- return obj_path .read_bytes ()
204-
205-
206- @pytest .fixture (scope = "module" )
207- def get_saxpy_library ():
208- """Read the pre-built saxpy.a (Linux) or saxpy.lib (Windows).
209-
210- In CI: produced by build stage alongside saxpy.o.
183+ In CI: produced by the build stage.
211184 In local dev: auto-built on demand if nvcc is available; if you edit
212- saxpy.cu, remove stale saxpy.o / saxpy.a to force a rebuild.
185+ saxpy.cu, remove stale RDC files to force a rebuild.
213186 """
214187 binaries_dir = Path (__file__ ).parent / "test_binaries"
215- lib_name = "saxpy.lib" if os .name == "nt" else "saxpy.a"
216- lib_path = binaries_dir / lib_name
188+ if kind == "object" :
189+ rdc_path = binaries_dir / "saxpy.o"
190+ elif kind == "library" :
191+ rdc_path = binaries_dir / ("saxpy.lib" if os .name == "nt" else "saxpy.a" )
192+ else :
193+ raise ValueError (f"unknown saxpy RDC kind: { kind !r} " )
217194
218- if not lib_path .is_file ():
195+ if not rdc_path .is_file ():
219196 if find_nvidia_binary_utility ("nvcc" ) is None :
220197 pytest .skip (
221- f"{ lib_name } not found at { lib_path } and nvcc is unavailable. "
198+ f"{ rdc_path . name } not found at { rdc_path } and nvcc is unavailable. "
222199 "In CI this is downloaded from the build stage."
223200 )
224201 subprocess .run ( # noqa: S603
225202 ["bash" , str (binaries_dir / "build_test_binaries.sh" )], # noqa: S607
226203 check = True ,
227204 env = os .environ ,
228205 )
229-
230- return lib_path .read_bytes ()
206+ return rdc_path .read_bytes ()
231207
232208
233209def test_get_kernel (init_cuda ):
@@ -388,86 +364,47 @@ def test_object_code_load_fatbin_from_file(get_saxpy_fatbin, tmp_path, convert_p
388364 mod_obj .get_kernel ("saxpy<double>" ) # force loading
389365
390366
391- def test_object_code_load_object (get_saxpy_object ):
392- obj = get_saxpy_object
393- assert isinstance (obj , bytes )
394- mod_obj = ObjectCode .from_object (obj )
395- assert mod_obj .code == obj
396- assert mod_obj .code_type == "object"
397- with pytest .raises (RuntimeError , match = r'Unsupported code type "object"' ):
398- mod_obj .get_kernel ("saxpy<float>" )
399-
400-
401- def test_object_code_load_object_from_file (get_saxpy_object , tmp_path ):
402- obj_file = tmp_path / "test.o"
403- obj_file .write_bytes (get_saxpy_object )
404- arg = str (obj_file )
405- mod_obj = ObjectCode .from_object (arg )
406- assert mod_obj .code == arg
407- assert mod_obj .code_type == "object"
408-
409-
410- def test_object_code_load_object_with_linker (get_saxpy_object , init_cuda ):
411- arch = f"sm_{ init_cuda .arch } "
412- kernel_code = Program (
413- r"""
414- extern __device__ float saxpy_step(float a, float x, float y);
415- extern "C" __global__ void linked_kernel(float a, float x, float y, float* out) {
416- if (threadIdx.x == 0 && blockIdx.x == 0) *out = saxpy_step(a, x, y);
417- }
418- """ ,
419- "c++" ,
420- ProgramOptions (relocatable_device_code = True , arch = arch ),
421- ).compile ("cubin" )
422- linked = Linker (
423- kernel_code ,
424- ObjectCode .from_object (get_saxpy_object ),
425- options = LinkerOptions (arch = arch ),
426- ).link ("cubin" )
427- kernel = linked .get_kernel ("linked_kernel" )
428-
429- stream = init_cuda .create_stream ()
430- host_buf = cuda .core .LegacyPinnedMemoryResource ().allocate (4 )
431- result = np .from_dlpack (host_buf ).view (np .float32 )
432- result [:] = 0.0
433- dev_buf = init_cuda .memory_resource .allocate (4 , stream = init_cuda .default_stream )
434-
435- cuda .core .launch (
436- stream ,
437- cuda .core .LaunchConfig (grid = 1 , block = 1 ),
438- kernel ,
439- np .float32 (2.0 ),
440- np .float32 (3.0 ),
441- np .float32 (4.0 ),
442- dev_buf ,
443- )
444- dev_buf .copy_to (host_buf , stream = stream )
445- stream .sync ()
446-
447- assert result [0 ] == 10.0
448-
449-
450- def test_object_code_load_library (get_saxpy_library ):
451- lib = get_saxpy_library
452- assert isinstance (lib , bytes )
453- mod_obj = ObjectCode .from_library (lib )
454- assert mod_obj .code == lib
455- assert mod_obj .code_type == "library"
456- with pytest .raises (RuntimeError , match = r'Unsupported code type "library"' ):
367+ @pytest .mark .parametrize (
368+ ("kind" , "from_fn" ),
369+ [
370+ ("object" , ObjectCode .from_object ),
371+ ("library" , ObjectCode .from_library ),
372+ ],
373+ )
374+ def test_object_code_load_rdc (kind , from_fn ):
375+ data = _read_saxpy_rdc (kind )
376+ assert isinstance (data , bytes )
377+ mod_obj = from_fn (data )
378+ assert mod_obj .code == data
379+ assert mod_obj .code_type == kind
380+ with pytest .raises (RuntimeError , match = rf'Unsupported code type "{ kind } "' ):
457381 mod_obj .get_kernel ("saxpy<float>" )
458382
459383
460- def test_object_code_load_library_from_file (get_saxpy_library , tmp_path ):
461- lib_ext = ".lib" if os .name == "nt" else ".a"
462- lib_file = tmp_path / f"test{ lib_ext } "
463- lib_file .write_bytes (get_saxpy_library )
464- arg = str (lib_file )
465- mod_obj = ObjectCode .from_library (arg )
384+ @pytest .mark .parametrize (
385+ ("kind" , "from_fn" , "suffix" ),
386+ [
387+ ("object" , ObjectCode .from_object , ".o" ),
388+ ("library" , ObjectCode .from_library , ".lib" if os .name == "nt" else ".a" ),
389+ ],
390+ )
391+ def test_object_code_load_rdc_from_file (kind , from_fn , suffix , tmp_path ):
392+ rdc_file = tmp_path / f"test{ suffix } "
393+ rdc_file .write_bytes (_read_saxpy_rdc (kind ))
394+ arg = str (rdc_file )
395+ mod_obj = from_fn (arg )
466396 assert mod_obj .code == arg
467- assert mod_obj .code_type == "library"
397+ assert mod_obj .code_type == kind
468398
469399
470- def test_object_code_load_library_with_linker (get_saxpy_library , init_cuda ):
400+ @pytest .mark .parametrize (
401+ ("kind" , "from_fn" ),
402+ [
403+ ("object" , ObjectCode .from_object ),
404+ ("library" , ObjectCode .from_library ),
405+ ],
406+ )
407+ def test_object_code_load_rdc_with_linker (kind , from_fn , init_cuda ):
471408 arch = f"sm_{ init_cuda .arch } "
472409 kernel_code = Program (
473410 r"""
@@ -481,7 +418,7 @@ def test_object_code_load_library_with_linker(get_saxpy_library, init_cuda):
481418 ).compile ("cubin" )
482419 linked = Linker (
483420 kernel_code ,
484- ObjectCode . from_library ( get_saxpy_library ),
421+ from_fn ( _read_saxpy_rdc ( kind ) ),
485422 options = LinkerOptions (arch = arch ),
486423 ).link ("cubin" )
487424 kernel = linked .get_kernel ("linked_kernel" )
0 commit comments