From 5d1e97f625efb15ca93091e33d83cafdb4bbd691 Mon Sep 17 00:00:00 2001 From: Saqib Khan <11544614+saqibkh@users.noreply.github.com> Date: Fri, 23 Oct 2026 10:29:45 -0500 Subject: [PATCH] arch: Fix get_cuda_version when nvcc is missing The finally block read out.returncode even when run() had raised FileNotFoundError, so out was unbound. Use else instead, so the function returns None, and have CudaCompiler.std treat None as a pre-CUDA 13 toolkit. --- devito/arch/archinfo.py | 2 +- devito/arch/compiler.py | 3 ++- tests/test_arch.py | 24 ++++++++++++++++++++++++ 3 files changed, 27 insertions(+), 2 deletions(-) diff --git a/devito/arch/archinfo.py b/devito/arch/archinfo.py index 53de39e892..a9165f9af6 100644 --- a/devito/arch/archinfo.py +++ b/devito/arch/archinfo.py @@ -575,7 +575,7 @@ def get_cuda_version(): out = run(nvc_version_command, capture_output=True, text=True) except (FileNotFoundError, CalledProcessError): pass - finally: + else: if out.returncode == 0: start = out.stdout.find('release') start = out.stdout.find(',', start) + 1 diff --git a/devito/arch/compiler.py b/devito/arch/compiler.py index d356765636..0daf8131b0 100644 --- a/devito/arch/compiler.py +++ b/devito/arch/compiler.py @@ -809,7 +809,8 @@ def __init_finalize__(self, **kwargs): @property def std(self): # Since CUDA 13, code needs compiling with C++17 standard - _cxxstd = 'c++17' if get_cuda_version().major >= 13 else 'c++14' + cuda_version = get_cuda_version() + _cxxstd = 'c++17' if cuda_version and cuda_version.major >= 13 else 'c++14' return _cxxstd if self._cpp else self._cstd def __lookup_cmds__(self): diff --git a/tests/test_arch.py b/tests/test_arch.py index 40fa913ab9..5bdb68ad86 100644 --- a/tests/test_arch.py +++ b/tests/test_arch.py @@ -6,6 +6,7 @@ from devito import configuration, switchconfig from devito.arch import BLACKWELL, NVIDIAX +from devito.arch.archinfo import get_cuda_version from devito.arch.compiler import ( CudaCompiler, GNUCompiler, compiler_registry, sniff_compiler_version ) @@ -93,3 +94,26 @@ def test_cuda_target(monkeypatch, platform, cc, target): flags = [i for i in compiler.cflags if i.startswith(('-arch=', '-gencode='))] assert flags == [target] + + +def test_get_cuda_version_without_nvcc(monkeypatch): + def missing(*args, **kwargs): + raise FileNotFoundError('nvcc') + + monkeypatch.setattr('devito.arch.archinfo.run', missing) + # `.func` skips the cache + assert get_cuda_version.func() is None + + +def test_cuda_std_without_nvcc(monkeypatch): + def std(version): + with switchconfig(mpi=False), monkeypatch.context() as m: + m.setattr('devito.arch.compiler.get_cuda_version', lambda: version) + m.setattr('devito.arch.compiler.check_cuda_runtime', lambda: None) + return CudaCompiler(platform=NVIDIAX).std + + assert std(Version('13.0')) == 'c++17' + assert std(Version('12.8')) == 'c++14' + # No `nvcc`: fall back to the pre-CUDA 13 standard + assert std(None) == 'c++14' +