Skip to content
Merged
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
4 changes: 3 additions & 1 deletion .github/workflows/build-wheel.yml
Original file line number Diff line number Diff line change
Expand Up @@ -463,7 +463,9 @@ jobs:
cuda-path: "./cuda_toolkit_prev"

- name: Build cuda.core test binaries
run: bash ${{ env.CUDA_CORE_TEST_BINARIES_DIR }}/build_test_binaries.sh
run: |
nvcc --version
python "${{ env.CUDA_CORE_TEST_BINARIES_DIR }}/build_test_binaries.py"

- name: Upload cuda.core test binaries
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
Expand Down
56 changes: 56 additions & 0 deletions cuda_core/tests/test_binaries/build_test_binaries.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0
"""Build the relocatable-device-code fixtures used by cuda.core tests."""

from __future__ import annotations

import os
import subprocess
import tempfile
from pathlib import Path


def _run(command: list[str]) -> None:
print(f"+ {subprocess.list2cmdline(command)}")
result = subprocess.run(command) # noqa: S603
if result.returncode != 0:
raise SystemExit(result.returncode)


def main() -> None:
script_dir = Path(__file__).resolve().parent
source_path = script_dir / "saxpy.cu"
final_object_path = script_dir / "saxpy.o"
final_library_path = script_dir / ("saxpy.lib" if os.name == "nt" else "saxpy.a")

nvcc_extra_flags = ["-std=c++17"]
if os.name == "nt":
nvcc_extra_flags.extend(["-Xcompiler", "/Zc:preprocessor"])

with tempfile.TemporaryDirectory(prefix="build_test_binaries-", dir=script_dir) as temp_dir:
temp_dir_path = Path(temp_dir)
object_path = temp_dir_path / final_object_path.name
library_path = temp_dir_path / final_library_path.name

_run(
[
"nvcc",
Comment thread
lijinf2 marked this conversation as resolved.
"-dc",
*nvcc_extra_flags,
"-arch=all-major",
"-o",
str(object_path),
str(source_path),
]
)
_run(["nvcc", "-lib", "-o", str(library_path), str(object_path)])

object_path.replace(final_object_path)
library_path.replace(final_library_path)

for path in (final_object_path, final_library_path):
print(f"{path}: {path.stat().st_size} bytes")


if __name__ == "__main__":
main()
28 changes: 0 additions & 28 deletions cuda_core/tests/test_binaries/build_test_binaries.sh

This file was deleted.

84 changes: 70 additions & 14 deletions cuda_core/tests/test_module.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import os
import pickle
import subprocess
import sys
import warnings
from pathlib import Path

Expand All @@ -16,7 +17,6 @@
from cuda.core._program import _can_load_generated_ptx
from cuda.core._utils.cuda_utils import CUDAError, driver, handle_return
from cuda.core._utils.version import binding_version, driver_version
from cuda.pathfinder import find_nvidia_binary_utility

try:
import numba
Expand Down Expand Up @@ -193,22 +193,78 @@ def _read_saxpy_rdc(kind: str) -> bytes:
raise ValueError(f"unknown saxpy RDC kind: {kind!r}")

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


def _subprocess_output(result: subprocess.CompletedProcess[str]) -> str:
Comment thread
lijinf2 marked this conversation as resolved.
sections = []
if result.stdout:
sections.append(f"stdout:\n{result.stdout.rstrip()}")
if result.stderr:
sections.append(f"stderr:\n{result.stderr.rstrip()}")
return "\n".join(sections) or "<no output>"


def _host_compiler_is_unavailable(output: str) -> bool:
normalized = output.lower()
# Keep these patterns narrow. Unknown nvcc failures should fail the test and
# expose their diagnostics, not be silently reclassified as environment skips.
windows_compiler_missing = (
"cannot find compiler" in normalized and "cl.exe" in normalized and "in path" in normalized
Comment thread
lijinf2 marked this conversation as resolved.
)
Comment thread
lijinf2 marked this conversation as resolved.
linux_compiler_missing = (
"no such file or directory" in normalized and "failed to preprocess host compiler properties" in normalized
)
return windows_compiler_missing or linux_compiler_missing


def _build_saxpy_rdc(binaries_dir: Path) -> None:
"""Use nvcc from PATH with the host compiler environment configured by the caller."""
try:
version_result = subprocess.run(
["nvcc", "--version"], # noqa: S607 - PATH lookup is the behavior under test.
capture_output=True,
text=True,
errors="replace",
)
except FileNotFoundError:
pytest.skip("RDC test fixtures are absent and nvcc is not available on PATH")

if version_result.returncode != 0:
pytest.fail(
f"nvcc --version failed with exit code {version_result.returncode}\n{_subprocess_output(version_result)}",
pytrace=False,
)

print(version_result.stdout, end="")
if version_result.stderr:
print(version_result.stderr, end="", file=sys.stderr)

builder_path = binaries_dir / "build_test_binaries.py"
build_result = subprocess.run( # noqa: S603
[sys.executable, str(builder_path)],
capture_output=True,
text=True,
errors="replace",
)
if build_result.returncode == 0:
print(build_result.stdout, end="")
if build_result.stderr:
print(build_result.stderr, end="", file=sys.stderr)
return

output = _subprocess_output(build_result)
if _host_compiler_is_unavailable(output):
print(output, file=sys.stderr)
pytest.skip("nvcc is available, but its host compiler is not configured")

pytest.fail(
f"RDC test fixture build failed with exit code {build_result.returncode}\n{output}",
pytrace=False,
)


def test_get_kernel(init_cuda):
kernel = """extern "C" __global__ void ABC() { }"""

Expand Down
Loading