Skip to content

Commit a96d9f8

Browse files
authored
cuda.core: add tests for ObjectCode.from_library (NVIDIA#2281)
* initial version of testing ObjectCode.from_library * use pytest parametrize and merge boilerplate code * rephrase to be accurate
1 parent 2780efd commit a96d9f8

4 files changed

Lines changed: 62 additions & 27 deletions

File tree

.github/workflows/build-wheel.yml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -469,7 +469,10 @@ jobs:
469469
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
470470
with:
471471
name: ${{ env.CUDA_CORE_ARTIFACT_NAME }}-test-binaries
472-
path: ${{ env.CUDA_CORE_TEST_BINARIES_DIR }}/*.o
472+
path: |
473+
${{ env.CUDA_CORE_TEST_BINARIES_DIR }}/*.o
474+
${{ env.CUDA_CORE_TEST_BINARIES_DIR }}/*.a
475+
${{ env.CUDA_CORE_TEST_BINARIES_DIR }}/*.lib
473476
if-no-files-found: error
474477

475478
- name: Download cuda.bindings build artifacts from the prior branch

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ cache_nvrtc
2121

2222
# cuda.core test object fixtures built locally / downloaded as CI artifacts
2323
cuda_core/tests/test_binaries/*.o
24+
cuda_core/tests/test_binaries/*.a
25+
cuda_core/tests/test_binaries/*.lib
2426

2527
# CUDA Python specific (auto-generated)
2628
cuda_bindings/cuda/bindings/_bindings/cyruntime.pxd

cuda_core/tests/test_binaries/build_test_binaries.sh

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,10 @@ NVCC="${NVCC:-nvcc}"
1919
"${NVCC}" -dc "${NVCC_EXTRA_FLAGS[@]}" -arch=all-major \
2020
-o "${SCRIPTPATH}/saxpy.o" "${SCRIPTPATH}/saxpy.cu"
2121

22-
ls -lah "${SCRIPTPATH}/saxpy.o"
22+
if [[ "${OS:-}" == "Windows_NT" ]]; then
23+
nvcc -lib -o "${SCRIPTPATH}/saxpy.lib" "${SCRIPTPATH}/saxpy.o"
24+
ls -lah "${SCRIPTPATH}/saxpy.o" "${SCRIPTPATH}/saxpy.lib"
25+
else
26+
nvcc -lib -o "${SCRIPTPATH}/saxpy.a" "${SCRIPTPATH}/saxpy.o"
27+
ls -lah "${SCRIPTPATH}/saxpy.o" "${SCRIPTPATH}/saxpy.a"
28+
fi

cuda_core/tests/test_module.py

Lines changed: 49 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -177,22 +177,26 @@ 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.
180+
def _read_saxpy_rdc(kind: str) -> bytes:
181+
"""Read a pre-built saxpy RDC object or library.
183182
184-
In CI: produced by build stage into a test wheel file.
183+
In CI: produced by the build stage.
185184
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.
185+
saxpy.cu, remove stale RDC files (i.e. saxpy.o, saxpy.a, or saxpy.lib) to force a rebuild.
187186
"""
188187
binaries_dir = Path(__file__).parent / "test_binaries"
189-
obj_path = binaries_dir / "saxpy.o"
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}")
190194

191-
if not obj_path.is_file():
195+
if not rdc_path.is_file():
192196
nvcc_path = find_nvidia_binary_utility("nvcc")
193197
if nvcc_path is None:
194198
pytest.skip(
195-
f"saxpy.o not found at {obj_path} and nvcc is unavailable. "
199+
f"{rdc_path.name} not found at {rdc_path} and nvcc is unavailable. "
196200
"In CI this is downloaded from the build stage."
197201
)
198202
env = os.environ.copy()
@@ -202,8 +206,7 @@ def get_saxpy_object():
202206
check=True,
203207
env=env,
204208
)
205-
206-
return obj_path.read_bytes()
209+
return rdc_path.read_bytes()
207210

208211

209212
def test_get_kernel(init_cuda):
@@ -364,26 +367,47 @@ def test_object_code_load_fatbin_from_file(get_saxpy_fatbin, tmp_path, convert_p
364367
mod_obj.get_kernel("saxpy<double>") # force loading
365368

366369

367-
def test_object_code_load_object(get_saxpy_object):
368-
obj = get_saxpy_object
369-
assert isinstance(obj, bytes)
370-
mod_obj = ObjectCode.from_object(obj)
371-
assert mod_obj.code == obj
372-
assert mod_obj.code_type == "object"
373-
with pytest.raises(RuntimeError, match=r'Unsupported code type "object"'):
370+
@pytest.mark.parametrize(
371+
("kind", "from_fn"),
372+
[
373+
("object", ObjectCode.from_object),
374+
("library", ObjectCode.from_library),
375+
],
376+
)
377+
def test_object_code_load_rdc(kind, from_fn):
378+
data = _read_saxpy_rdc(kind)
379+
assert isinstance(data, bytes)
380+
mod_obj = from_fn(data)
381+
assert mod_obj.code == data
382+
assert mod_obj.code_type == kind
383+
with pytest.raises(RuntimeError, match=rf'Unsupported code type "{kind}"'):
374384
mod_obj.get_kernel("saxpy<float>")
375385

376386

377-
def test_object_code_load_object_from_file(get_saxpy_object, tmp_path):
378-
obj_file = tmp_path / "test.o"
379-
obj_file.write_bytes(get_saxpy_object)
380-
arg = str(obj_file)
381-
mod_obj = ObjectCode.from_object(arg)
387+
@pytest.mark.parametrize(
388+
("kind", "from_fn", "suffix"),
389+
[
390+
("object", ObjectCode.from_object, ".o"),
391+
("library", ObjectCode.from_library, ".lib" if os.name == "nt" else ".a"),
392+
],
393+
)
394+
def test_object_code_load_rdc_from_file(kind, from_fn, suffix, tmp_path):
395+
rdc_file = tmp_path / f"test{suffix}"
396+
rdc_file.write_bytes(_read_saxpy_rdc(kind))
397+
arg = str(rdc_file)
398+
mod_obj = from_fn(arg)
382399
assert mod_obj.code == arg
383-
assert mod_obj.code_type == "object"
400+
assert mod_obj.code_type == kind
384401

385402

386-
def test_object_code_load_object_with_linker(get_saxpy_object, init_cuda):
403+
@pytest.mark.parametrize(
404+
("kind", "from_fn"),
405+
[
406+
("object", ObjectCode.from_object),
407+
("library", ObjectCode.from_library),
408+
],
409+
)
410+
def test_object_code_load_rdc_with_linker(kind, from_fn, init_cuda):
387411
arch = f"sm_{init_cuda.arch}"
388412
kernel_code = Program(
389413
r"""
@@ -397,7 +421,7 @@ def test_object_code_load_object_with_linker(get_saxpy_object, init_cuda):
397421
).compile("cubin")
398422
linked = Linker(
399423
kernel_code,
400-
ObjectCode.from_object(get_saxpy_object),
424+
from_fn(_read_saxpy_rdc(kind)),
401425
options=LinkerOptions(arch=arch),
402426
).link("cubin")
403427
kernel = linked.get_kernel("linked_kernel")

0 commit comments

Comments
 (0)