|
5 | 5 | import os |
6 | 6 | import pickle |
7 | 7 | import subprocess |
| 8 | +import sys |
8 | 9 | import warnings |
9 | 10 | from pathlib import Path |
10 | 11 |
|
|
16 | 17 | from cuda.core._program import _can_load_generated_ptx |
17 | 18 | from cuda.core._utils.cuda_utils import CUDAError, driver, handle_return |
18 | 19 | from cuda.core._utils.version import binding_version, driver_version |
19 | | -from cuda.pathfinder import find_nvidia_binary_utility |
20 | 20 |
|
21 | 21 | try: |
22 | 22 | import numba |
@@ -193,22 +193,78 @@ def _read_saxpy_rdc(kind: str) -> bytes: |
193 | 193 | raise ValueError(f"unknown saxpy RDC kind: {kind!r}") |
194 | 194 |
|
195 | 195 | if not rdc_path.is_file(): |
196 | | - nvcc_path = find_nvidia_binary_utility("nvcc") |
197 | | - if nvcc_path is None: |
198 | | - pytest.skip( |
199 | | - f"{rdc_path.name} not found at {rdc_path} and nvcc is unavailable. " |
200 | | - "In CI this is downloaded from the build stage." |
201 | | - ) |
202 | | - env = os.environ.copy() |
203 | | - env["NVCC"] = nvcc_path |
204 | | - subprocess.run( # noqa: S603 |
205 | | - ["bash", str(binaries_dir / "build_test_binaries.sh")], # noqa: S607 |
206 | | - check=True, |
207 | | - env=env, |
208 | | - ) |
| 196 | + _build_saxpy_rdc(binaries_dir) |
209 | 197 | return rdc_path.read_bytes() |
210 | 198 |
|
211 | 199 |
|
| 200 | +def _subprocess_output(result: subprocess.CompletedProcess[str]) -> str: |
| 201 | + sections = [] |
| 202 | + if result.stdout: |
| 203 | + sections.append(f"stdout:\n{result.stdout.rstrip()}") |
| 204 | + if result.stderr: |
| 205 | + sections.append(f"stderr:\n{result.stderr.rstrip()}") |
| 206 | + return "\n".join(sections) or "<no output>" |
| 207 | + |
| 208 | + |
| 209 | +def _host_compiler_is_unavailable(output: str) -> bool: |
| 210 | + normalized = output.lower() |
| 211 | + # Keep these patterns narrow. Unknown nvcc failures should fail the test and |
| 212 | + # expose their diagnostics, not be silently reclassified as environment skips. |
| 213 | + windows_compiler_missing = ( |
| 214 | + "cannot find compiler" in normalized and "cl.exe" in normalized and "in path" in normalized |
| 215 | + ) |
| 216 | + linux_compiler_missing = ( |
| 217 | + "no such file or directory" in normalized and "failed to preprocess host compiler properties" in normalized |
| 218 | + ) |
| 219 | + return windows_compiler_missing or linux_compiler_missing |
| 220 | + |
| 221 | + |
| 222 | +def _build_saxpy_rdc(binaries_dir: Path) -> None: |
| 223 | + """Use nvcc from PATH with the host compiler environment configured by the caller.""" |
| 224 | + try: |
| 225 | + version_result = subprocess.run( |
| 226 | + ["nvcc", "--version"], # noqa: S607 - PATH lookup is the behavior under test. |
| 227 | + capture_output=True, |
| 228 | + text=True, |
| 229 | + errors="replace", |
| 230 | + ) |
| 231 | + except FileNotFoundError: |
| 232 | + pytest.skip("RDC test fixtures are absent and nvcc is not available on PATH") |
| 233 | + |
| 234 | + if version_result.returncode != 0: |
| 235 | + pytest.fail( |
| 236 | + f"nvcc --version failed with exit code {version_result.returncode}\n{_subprocess_output(version_result)}", |
| 237 | + pytrace=False, |
| 238 | + ) |
| 239 | + |
| 240 | + print(version_result.stdout, end="") |
| 241 | + if version_result.stderr: |
| 242 | + print(version_result.stderr, end="", file=sys.stderr) |
| 243 | + |
| 244 | + builder_path = binaries_dir / "build_test_binaries.py" |
| 245 | + build_result = subprocess.run( # noqa: S603 |
| 246 | + [sys.executable, str(builder_path)], |
| 247 | + capture_output=True, |
| 248 | + text=True, |
| 249 | + errors="replace", |
| 250 | + ) |
| 251 | + if build_result.returncode == 0: |
| 252 | + print(build_result.stdout, end="") |
| 253 | + if build_result.stderr: |
| 254 | + print(build_result.stderr, end="", file=sys.stderr) |
| 255 | + return |
| 256 | + |
| 257 | + output = _subprocess_output(build_result) |
| 258 | + if _host_compiler_is_unavailable(output): |
| 259 | + print(output, file=sys.stderr) |
| 260 | + pytest.skip("nvcc is available, but its host compiler is not configured") |
| 261 | + |
| 262 | + pytest.fail( |
| 263 | + f"RDC test fixture build failed with exit code {build_result.returncode}\n{output}", |
| 264 | + pytrace=False, |
| 265 | + ) |
| 266 | + |
| 267 | + |
212 | 268 | def test_get_kernel(init_cuda): |
213 | 269 | kernel = """extern "C" __global__ void ABC() { }""" |
214 | 270 |
|
|
0 commit comments