Release: dev → main (first public release) #258
+23
-2
@@ -69,11 +69,32 @@ def onnx_status(imp=importlib.import_module, load=ctypes.CDLL) -> dict:
|
|||||||
except OSError as e:
|
except OSError as e:
|
||||||
out["device"] = "cpu"
|
out["device"] = "cpu"
|
||||||
out["error"] = str(e)
|
out["error"] = str(e)
|
||||||
else:
|
return out
|
||||||
out["device"] = "cuda"
|
# Loading proves the libraries resolve, NOT that a GPU can be used: on
|
||||||
|
# 2026-09-24 this reported "onnx on GPU" beside torch failing cuInit with
|
||||||
|
# "CUDA unknown error" (a driver update awaiting a reboot). Asking the CUDA
|
||||||
|
# runtime for a device initialises the driver the provider would use.
|
||||||
|
error = _cuda_device_error(load)
|
||||||
|
out["device"] = "cpu" if error else "cuda"
|
||||||
|
if error:
|
||||||
|
out["error"] = error
|
||||||
return out
|
return out
|
||||||
|
|
||||||
|
|
||||||
|
def _cuda_device_error(load=ctypes.CDLL) -> str | None:
|
||||||
|
"""None when the CUDA runtime can reach a device, else why it cannot."""
|
||||||
|
try:
|
||||||
|
cudart = load("libcudart.so.13")
|
||||||
|
except OSError as e:
|
||||||
|
return str(e)
|
||||||
|
count = ctypes.c_int(0)
|
||||||
|
rc = cudart.cudaGetDeviceCount(ctypes.byref(count))
|
||||||
|
if rc != 0:
|
||||||
|
cudart.cudaGetErrorString.restype = ctypes.c_char_p
|
||||||
|
return f"cudaGetDeviceCount: {cudart.cudaGetErrorString(rc).decode()} ({rc})"
|
||||||
|
return None if count.value > 0 else "no CUDA device visible"
|
||||||
|
|
||||||
|
|
||||||
def report() -> dict:
|
def report() -> dict:
|
||||||
"""Check both runtimes, log the result, and keep it for /status."""
|
"""Check both runtimes, log the result, and keep it for /status."""
|
||||||
LAST.clear()
|
LAST.clear()
|
||||||
|
|||||||
@@ -28,15 +28,45 @@ def _imp(mod):
|
|||||||
return lambda name: mod
|
return lambda name: mod
|
||||||
|
|
||||||
|
|
||||||
def test_onnx_on_gpu_when_the_cuda_provider_loads():
|
class _Cudart:
|
||||||
|
"""libcudart as ctypes sees it: cudaGetDeviceCount writes through a pointer."""
|
||||||
|
|
||||||
|
def __init__(self, rc=0, count=1):
|
||||||
|
self.rc = rc
|
||||||
|
self.count = count
|
||||||
|
self.cudaGetErrorString = lambda rc: b"unknown error"
|
||||||
|
|
||||||
|
def cudaGetDeviceCount(self, ref):
|
||||||
|
ref._obj.value = self.count
|
||||||
|
return self.rc
|
||||||
|
|
||||||
|
|
||||||
|
def _loader(calls, cudart):
|
||||||
|
def load(path, mode=0):
|
||||||
|
calls.append(path)
|
||||||
|
return cudart if path == "libcudart.so.13" else None
|
||||||
|
return load
|
||||||
|
|
||||||
|
|
||||||
|
GPU_BUILD = ["CUDAExecutionProvider", "CPUExecutionProvider"]
|
||||||
|
|
||||||
|
|
||||||
|
def test_onnx_on_gpu_when_the_provider_loads_and_a_device_answers():
|
||||||
calls = []
|
calls = []
|
||||||
s = accel.onnx_status(
|
s = accel.onnx_status(
|
||||||
_imp(_ort(["CUDAExecutionProvider", "CPUExecutionProvider"], lambda: calls.append("preload"))),
|
_imp(_ort(GPU_BUILD, lambda: calls.append("preload"))),
|
||||||
load=lambda path, mode=0: calls.append(path),
|
load=_loader(calls, _Cudart()),
|
||||||
)
|
)
|
||||||
assert s["device"] == "cuda"
|
assert s["device"] == "cuda"
|
||||||
assert calls[0] == "preload"
|
assert calls[0] == "preload"
|
||||||
assert calls[-1].endswith("capi/libonnxruntime_providers_cuda.so")
|
assert any(c.endswith("capi/libonnxruntime_providers_cuda.so") for c in calls)
|
||||||
|
|
||||||
|
|
||||||
|
def test_onnx_libraries_loading_is_not_a_gpu_when_cuda_cannot_initialise():
|
||||||
|
"""The 2026-09-24 case: every library resolved, cuInit failed."""
|
||||||
|
s = accel.onnx_status(_imp(_ort(GPU_BUILD)), load=_loader([], _Cudart(rc=999)))
|
||||||
|
assert s["device"] == "cpu"
|
||||||
|
assert "unknown error" in s["error"]
|
||||||
|
|
||||||
|
|
||||||
def test_onnx_listed_but_unloadable_reports_cpu_with_the_reason():
|
def test_onnx_listed_but_unloadable_reports_cpu_with_the_reason():
|
||||||
@@ -44,7 +74,7 @@ def test_onnx_listed_but_unloadable_reports_cpu_with_the_reason():
|
|||||||
if path.endswith("providers_cuda.so"):
|
if path.endswith("providers_cuda.so"):
|
||||||
raise OSError("libcudart.so.13: cannot open shared object file")
|
raise OSError("libcudart.so.13: cannot open shared object file")
|
||||||
|
|
||||||
s = accel.onnx_status(_imp(_ort(["CUDAExecutionProvider", "CPUExecutionProvider"])), load=load)
|
s = accel.onnx_status(_imp(_ort(GPU_BUILD)), load=load)
|
||||||
assert s["device"] == "cpu"
|
assert s["device"] == "cpu"
|
||||||
assert "libcudart.so.13" in s["error"]
|
assert "libcudart.so.13" in s["error"]
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user