Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion .github/workflows/build-wheel.yml
Original file line number Diff line number Diff line change
Expand Up @@ -469,7 +469,10 @@ jobs:
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: ${{ env.CUDA_CORE_ARTIFACT_NAME }}-test-binaries
path: ${{ env.CUDA_CORE_TEST_BINARIES_DIR }}/*.o
path: |
${{ env.CUDA_CORE_TEST_BINARIES_DIR }}/*.o
${{ env.CUDA_CORE_TEST_BINARIES_DIR }}/*.a
${{ env.CUDA_CORE_TEST_BINARIES_DIR }}/*.lib
if-no-files-found: error

- name: Download cuda.bindings build artifacts from the prior branch
Expand Down
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ cache_nvrtc

# cuda.core test object fixtures built locally / downloaded as CI artifacts
cuda_core/tests/test_binaries/*.o
cuda_core/tests/test_binaries/*.a
cuda_core/tests/test_binaries/*.lib

# CUDA Python specific (auto-generated)
cuda_bindings/cuda/bindings/_bindings/cyruntime.pxd
Expand Down
8 changes: 7 additions & 1 deletion cuda_core/tests/test_binaries/build_test_binaries.sh
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,10 @@ fi
nvcc -dc "${NVCC_EXTRA_FLAGS[@]}" -arch=all-major \
-o "${SCRIPTPATH}/saxpy.o" "${SCRIPTPATH}/saxpy.cu"

ls -lah "${SCRIPTPATH}/saxpy.o"
if [[ "${OS:-}" == "Windows_NT" ]]; then
nvcc -lib -o "${SCRIPTPATH}/saxpy.lib" "${SCRIPTPATH}/saxpy.o"
ls -lah "${SCRIPTPATH}/saxpy.o" "${SCRIPTPATH}/saxpy.lib"
else
nvcc -lib -o "${SCRIPTPATH}/saxpy.a" "${SCRIPTPATH}/saxpy.o"
ls -lah "${SCRIPTPATH}/saxpy.o" "${SCRIPTPATH}/saxpy.a"
fi
74 changes: 49 additions & 25 deletions cuda_core/tests/test_module.py
Original file line number Diff line number Diff line change
Expand Up @@ -177,30 +177,33 @@ def get_saxpy_fatbin(init_cuda):
return bytes(fatbin), sym_map


@pytest.fixture(scope="module")
def get_saxpy_object():
"""Read the pre-built saxpy.o.
def _read_saxpy_rdc(kind: str) -> bytes:
"""Read a pre-built saxpy RDC object or library.

In CI: produced by build stage into a test wheel file.
In CI: produced by the build stage.
In local dev: auto-built on demand if nvcc is available; if you edit
saxpy.cu, remove the stale saxpy.o to force a rebuild.
saxpy.cu, remove stale RDC files (i.e. saxpy.o, saxpy.a, or saxpy.lib) to force a rebuild.
"""
binaries_dir = Path(__file__).parent / "test_binaries"
obj_path = binaries_dir / "saxpy.o"
if kind == "object":
rdc_path = binaries_dir / "saxpy.o"
elif kind == "library":
rdc_path = binaries_dir / ("saxpy.lib" if os.name == "nt" else "saxpy.a")
else:
raise ValueError(f"unknown saxpy RDC kind: {kind!r}")

if not obj_path.is_file():
if not rdc_path.is_file():
if find_nvidia_binary_utility("nvcc") is None:
pytest.skip(
f"saxpy.o not found at {obj_path} and nvcc is unavailable. "
f"{rdc_path.name} not found at {rdc_path} and nvcc is unavailable. "
"In CI this is downloaded from the build stage."
)
subprocess.run( # noqa: S603
["bash", str(binaries_dir / "build_test_binaries.sh")], # noqa: S607
check=True,
env=os.environ,
)

return obj_path.read_bytes()
return rdc_path.read_bytes()


def test_get_kernel(init_cuda):
Expand Down Expand Up @@ -361,26 +364,47 @@ def test_object_code_load_fatbin_from_file(get_saxpy_fatbin, tmp_path, convert_p
mod_obj.get_kernel("saxpy<double>") # force loading


def test_object_code_load_object(get_saxpy_object):
obj = get_saxpy_object
assert isinstance(obj, bytes)
mod_obj = ObjectCode.from_object(obj)
assert mod_obj.code == obj
assert mod_obj.code_type == "object"
with pytest.raises(RuntimeError, match=r'Unsupported code type "object"'):
@pytest.mark.parametrize(
("kind", "from_fn"),
[
("object", ObjectCode.from_object),
("library", ObjectCode.from_library),
],
)
def test_object_code_load_rdc(kind, from_fn):
data = _read_saxpy_rdc(kind)
assert isinstance(data, bytes)
mod_obj = from_fn(data)
assert mod_obj.code == data
assert mod_obj.code_type == kind
with pytest.raises(RuntimeError, match=rf'Unsupported code type "{kind}"'):
mod_obj.get_kernel("saxpy<float>")


def test_object_code_load_object_from_file(get_saxpy_object, tmp_path):
obj_file = tmp_path / "test.o"
obj_file.write_bytes(get_saxpy_object)
arg = str(obj_file)
mod_obj = ObjectCode.from_object(arg)
@pytest.mark.parametrize(
("kind", "from_fn", "suffix"),
[
("object", ObjectCode.from_object, ".o"),
("library", ObjectCode.from_library, ".lib" if os.name == "nt" else ".a"),
],
)
def test_object_code_load_rdc_from_file(kind, from_fn, suffix, tmp_path):
rdc_file = tmp_path / f"test{suffix}"
rdc_file.write_bytes(_read_saxpy_rdc(kind))
arg = str(rdc_file)
mod_obj = from_fn(arg)
assert mod_obj.code == arg
assert mod_obj.code_type == "object"
assert mod_obj.code_type == kind


def test_object_code_load_object_with_linker(get_saxpy_object, init_cuda):
@pytest.mark.parametrize(
("kind", "from_fn"),
[
("object", ObjectCode.from_object),
("library", ObjectCode.from_library),
],
)
def test_object_code_load_rdc_with_linker(kind, from_fn, init_cuda):
arch = f"sm_{init_cuda.arch}"
kernel_code = Program(
r"""
Expand All @@ -394,7 +418,7 @@ def test_object_code_load_object_with_linker(get_saxpy_object, init_cuda):
).compile("cubin")
linked = Linker(
kernel_code,
ObjectCode.from_object(get_saxpy_object),
from_fn(_read_saxpy_rdc(kind)),
options=LinkerOptions(arch=arch),
).link("cubin")
kernel = linked.get_kernel("linked_kernel")
Expand Down
Loading