simvx.graphics.gpu_gate¶
GPU capability gating for the test suite: a single 3-state policy.
The engine’s tests fall into three buckets when a Vulkan GPU is involved, and collapsing “could not run” into “passed” is the one outcome we never allow (a green-but-empty GPU lane silently hides regressions). The three states:
AVAILABLE – a usable Vulkan device is present; the test runs.
ABSENT – no
vulkanbinding, no Vulkan driver behind the loader, or no Vulkan-capable device. By default the test skips (so contributors and CI hosts without a GPU stay green), unless--require-gpuis passed – then absence is a failure, because that flag means the caller (the GPU CI lane,tools/run_benchmarks.py) asked to exercise the GPU and an empty run must not look green.BROKEN – a device is present but initialisation raises. This is a real defect, not an absence, so it is always a failure, regardless of
--require-gpu. The distinction is drawn by- func:
classify_init_failure: a loader that reports no driver, and an instance that enumerates no suitable device, are both absences; everything else that raises on the way to a device is a defect.
A test that needs a GPU is identified by the vulkan marker.
- mod:
simvx.graphics.pytest_pluginauto-applies that marker to any test requesting a GPU fixture (:data:GPU_FIXTURES), so “uses a GPU fixture” and “is a GPU test” are the same thing and nothing has to be remembered per test. The runtime guard (:func:ungated_gpu_error_hint) catches the residual case – a test that builds its own device without gating – by recognising the absent-device error.
This module holds the pure decision logic so it is unit-testable and monkeypatchable without a GPU; the plugin’s hooks are thin wrappers over it.
Module Contents¶
Classes¶
Functions¶
Forget the cached probe result (test helper). |
|
Detect GPU status once per process. Returns |
|
Map an exception raised while bringing a device up to ABSENT or BROKEN. |
|
True if the test requests a GPU fixture (so it should be |
|
Map |
|
Resolve the run/skip/fail decision for one test (probes the GPU on demand). |
|
Return an actionable hint if a non-GPU-gated test errored from a missing GPU. |
Data¶
API¶
- simvx.graphics.gpu_gate.__all__¶
[‘GPU_FIXTURES’, ‘VULKAN_MARKER’, ‘GpuStatus’, ‘Decision’, ‘probe_gpu’, ‘classify_init_failure’, ‘re…
- simvx.graphics.gpu_gate.GPU_FIXTURES¶
‘frozenset(…)’
- simvx.graphics.gpu_gate.VULKAN_MARKER¶
‘vulkan’
- class simvx.graphics.gpu_gate.GpuStatus¶
Bases:
enum.Enum- AVAILABLE¶
‘available’
- ABSENT¶
‘absent’
- BROKEN¶
‘broken’
- __new__(value)¶
- __repr__()¶
- __str__()¶
- __dir__()¶
- __format__(format_spec)¶
- __hash__()¶
- __reduce_ex__(proto)¶
- __deepcopy__(memo)¶
- __copy__()¶
- name()¶
- value()¶
- class simvx.graphics.gpu_gate.Decision¶
Bases:
enum.Enum- RUN¶
‘run’
- SKIP¶
‘skip’
- FAIL¶
‘fail’
- __new__(value)¶
- __repr__()¶
- __str__()¶
- __dir__()¶
- __format__(format_spec)¶
- __hash__()¶
- __reduce_ex__(proto)¶
- __deepcopy__(memo)¶
- __copy__()¶
- name()¶
- value()¶
- simvx.graphics.gpu_gate.reset_cache() None¶
Forget the cached probe result (test helper).
- simvx.graphics.gpu_gate.probe_gpu() tuple[simvx.graphics.gpu_gate.GpuStatus, str]¶
Detect GPU status once per process. Returns
(status, human_reason).
- simvx.graphics.gpu_gate.classify_init_failure(exc: BaseException) tuple[simvx.graphics.gpu_gate.GpuStatus, str]¶
Map an exception raised while bringing a device up to ABSENT or BROKEN.
Absence has three spellings and they arrive from three different layers. The device selector raises :class:
RuntimeErrorwith one of- Data:
_ABSENT_MARKERSonce it has an instance and finds nothing behind it; the loader raises a binding exception from :data:_ABSENT_EXCEPTIONSwhen it cannot even create the instance because no driver is installed; and the windowing backend raises one of :data:_ABSENT_WINDOWING_MARKERSwhen there is no display to open a window on in the first place. All three mean “no GPU here”, so all three skip (or fail under--require-gpu). Anything else is a device that came far enough to fail, which is a defect.
- simvx.graphics.gpu_gate.needs_gpu(fixturenames) bool¶
True if the test requests a GPU fixture (so it should be
vulkan-marked).
- simvx.graphics.gpu_gate.decide(status: simvx.graphics.gpu_gate.GpuStatus, reason: str, require_gpu: bool) tuple[simvx.graphics.gpu_gate.Decision, str]¶
Map
(probe status, --require-gpu)to a run/skip/fail decision + message.
- simvx.graphics.gpu_gate.apply_gate(is_vulkan_marked: bool, require_gpu: bool) tuple[simvx.graphics.gpu_gate.Decision, str]¶
Resolve the run/skip/fail decision for one test (probes the GPU on demand).
This is the exact decision the
conftestpytest_runtest_setuphook applies; the hook only maps the result ontopytest.skip/pytest.fail. Non-GPU tests (notvulkan-marked) always run.
- simvx.graphics.gpu_gate.ungated_gpu_error_hint(report_text: str, is_vulkan_marked: bool) str | None¶
Return an actionable hint if a non-GPU-gated test errored from a missing GPU.
The auto-marker covers every test that uses a GPU fixture; this is the safety net for a test that builds its own device without gating. On a GPU-less host such a test errors with the absent-device message instead of skipping, which reads as a real bug. We recognise that and tell the author how to gate it. Returns
Nonefor a correctly-gated test or an unrelated failure.