You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Add a production-oriented, vendor-neutral GPU backend that implements virtio_accel_core::Accelerator over Vulkan compute, executing device-neutral TOSA 1.0 programs on
any conformant Vulkan 1.x implementation without leaking Vulkan types into the portable crates.
The crate name and support row are already staked: README.md carries a Vulkan / Planned row
(added in 4d1b6638), and the workspace table reserves virtio-accel-vulkan.
Why this backend is different from the existing four
Core ML, OpenVINO, Hexagon, and XDNA each bind one vendor's runtime to one vendor's silicon. Vulkan
is the first target where one adapter covers many vendors — RADV (AMD), ANV (Intel), NVIDIA,
Mali, and software implementations — because the vendor-specific part lives below a standard API
that the host OS already ships. Three consequences worth stating up front, because they change the
shape of the work relative to the XDNA map (#78):
A hardware-free CI lane is possible. Mesa's lavapipe is a conformant software Vulkan
implementation. Unlike every other backend, the conformance suite and the numerical corpus can
plausibly run in CI on a GPU-less runner, in the same spirit as the OpenVINO CPU plugin lane
(.github/workflows/ci.yml, job openvino-host-test). This should be a first-class goal, not an
afterthought — it is the strongest verification asset this backend has.
Nonblocking completion is native.vkGetFenceStatus / vkGetSemaphoreCounterValue are
genuinely nonblocking status reads. Both HRX (Decide the execution-model mapping and event-bridge spec #85) and QAIRT needed a dedicated worker thread to
bridge a blocking synchronize into poll_event; Vulkan may not need one at all. That has to be
proven, not assumed, but if it holds it removes the single most delicate piece of machinery the
other two backends carry.
Device loss is specified.VK_ERROR_DEVICE_LOST is an explicit, normative signal with
defined propagation, which maps directly onto the instance-poisoning / BackendDiscardRequired
contract instead of relying on a watchdog whose timeout must be reasoned against a kernel TDR.
Note the deliberate overlap with OpenVINO: it already enumerates Intel GPUs. This backend's claim is vendor neutrality and no vendor runtime dependency, not "the first GPU." On an Intel host both
may be present and OpenVINO will likely be faster; that is fine and should be documented rather than
arbitrated in code.
Scope
Add a separate host-native crate virtio-accel-vulkan, structurally following virtio-accel-openvino (the template named by Wayfinder map: AMD XDNA NPU backend #78) — lib.rs / lower.rs / native.rs / ffi.rs, with the portable admission surface always compiled.
Probe Vulkan at build time and compile a RuntimeUnavailable placeholder otherwise, following the va_openvino / va_hexagon / va_xdna cfg pattern (va_vulkan). Explicit configuration only;
no scanning of standard locations.
Enumerate physical devices and report an honest identity, advertising AcceleratorClass::GPU
— which already exists (crates/virtio-accel-core/src/lib.rs:47), so no portable-crate change
is required for device class.
Accept virtio-accel-tosa artifacts, validate/analyze with the shared TOSA layer, and lower a
documented initial operator/dtype subset to SPIR-V compute.
Implement contexts, provider-owned buffers, programs, queues, submissions, events, transfers,
release, and recovery through the shared Accelerator contract.
Bind the exact provider allocation for program-visible buffers. No submission-time bounce
buffers; read_buffer/write_buffer remain the only copy boundaries.
Preserve rejected-vs-indeterminate submission/release semantics, stable nonblocking polling,
timeout behavior, and device-loss reporting. Advertise EVENT_CANCELLATION only if it can be
implemented honestly (Vulkan has no cancel primitive — expect not to advertise it, matching
Hexagon and XDNA).
Confine unsafe FFI to an audited boundary; add SAFETY.md and register the audited exception in ci/check-release-policy.py (which today lists the coreml/openvino/hexagon/xdna confinement
markers at lines 79-91).
Add a backend-local end-to-end example; update the workspace table, support matrix, portability
guide, architecture notes, performance evidence, and release policy.
Open decisions (candidate wayfinder tickets)
Unlike #75, whose implementation tips were decided constraints backed by prior research, the
items below are genuinely open. They are the natural decision tickets for a wayfinder map in the
shape of #78. Recommended framing for each is given, but none is settled.
Vulkan binding strategy. The workspace convention is a small hand-written ffi.rs declaring
only the validated subset (OpenVINO's is 171 lines; XDNA's Decide crate layout, HRX FFI boundary, and build-time probe #83 decided "declare only the
hardware-validated HRX subset"). Vulkan's surface is far larger than any prior target, so the
honest options are: a hand-written minimal subset (convention-consistent, more work), ash
(thin, unsafe, widely used, adds a dependency to a std adapter crate only), or a safe wrapper
like vulkano (heavier, more opinionated). This is the highest-leverage decision in the map
because it sets the size of the audited unsafe surface and therefore the shape of SAFETY.md.
Program representation: TOSA→SPIR-V, and whether SPIR-V is also accepted directly. ArtifactFormat is an opaque NonZeroU32 that each backend may define for itself — TOSA is 0x544f_5341 (crates/virtio-accel-tosa/src/artifact.rs:7), Core ML defines its own 0x434d_4c50, the mock backend 0x5641_4d4b. So accepting SPIR-V under a backend-defined
format id is architecturally permitted. Recommendation: TOSA-only for v1 (it is what the
shared corpus and conformance oracles are built on, and it keeps the guest device-neutral); treat
a SPIR-V-direct format as a deliberate follow-on, decided on its own merits, not smuggled in.
Lowering mechanism — and whether a compiler subprocess is needed at all. XDNA required a
bounded out-of-process compiler (Decide the compiler-helper subprocess contract #84) because aiecc is Python. Vulkan likely does not:
per-operator SPIR-V compute shaders can be authored once, checked into the crate as precompiled
SPIR-V, and specialized at load_program via specialization constants for shapes/tiling —
no toolchain on the serving host, no subprocess, no Python. If that holds it is a significant
simplification over both XDNA and Hexagon, and it should be validated early because it determines
whether this backend has a build-time toolchain dependency at all.
First numerical tier. Candidate: FP32 as the base (universally supported), FP16 gated on VK_KHR_shader_float16_int8, INT8 gated on VK_KHR_shader_integer_dot_product. FP8 has no
portable Vulkan path and should be rejected loudly at admission. Per the principle recorded in Decide the first advertised numerical tier #82: guest-chosen tiers, never host knobs — and reject rather than silently widen.
Memory-domain mapping. Vulkan memory types map unusually cleanly onto the three domains: Host → HOST_VISIBLE | HOST_COHERENT, Device → DEVICE_LOCAL, Shared → DEVICE_LOCAL | HOST_VISIBLE (resizable-BAR). Worth confirming that ReBAR availability is
probed and SHARED_MEMORY advertised only when the memory type actually exists, rather than
assumed.
Execution/event model. Whether vkGetFenceStatus alone satisfies nonblocking poll_event
without a worker thread, how a bounded preallocated command-buffer/fence pool is sized so
guest-controlled work cannot create unbounded host queue depth, and how finite timeouts are
handled pre-admission.
CI strategy. Which software implementation (lavapipe vs SwiftShader), which distro
packages pin it, and how much of the mandatory conformance set plus the numerical corpus can run
without a GPU. Also: whether a documented manual hardware lane is enough for real-GPU evidence,
as Build the AMD XDNA NPU backend #75 blessed for XDNA rather than exposing a self-hosted runner on a public repo.
Acceptance criteria
The workspace builds and tests on hosts with no Vulkan SDK; the native path enables only when
detected or explicitly requested.
On a Vulkan host, the backend enumerates a device as AcceleratorClass::GPU and completes the
documented TOSA example end to end.
Every mandatory case in virtio-accel-conformance passes; capability-conditional skips carry
explicit reasons.
Every advertised operator/dtype case from the shared numerical corpus executes and matches its
oracle.
Tests prove exact direct binding of caller-owned allocations, with no submission-time staging.
Native resources are released exactly once across teardown, completion, failure, and discard;
diagnostics return to baseline after each conformance case.
A GPU-less CI lane runs the mandatory conformance set against a software Vulkan
implementation, and the required driver/runtime versions plus reproducible hardware commands
are documented for the real-GPU lane.
The README Vulkan row changes from Planned only for capabilities demonstrated by tests.
Non-goals
Changes to the wire ABI or the portable Accelerator contract to mirror a Vulkan concept.
External-memory / DMA-BUF import, cross-process sharing, or new synchronization primitives.
The negotiated external-memory handoff is designed but deliberately unassigned (Design a negotiated external-memory handoff extension for heterogeneous schedules #113, closed; docs/plans/issue-113-external-memory-handoff.md — "design complete; protocol values and
implementation intentionally unassigned") and its implementation is tracked separately by protocol: implement the negotiated external-memory handoff extension #119.
A Vulkan backend is the most natural eventual consumer of that extension — VK_KHR_external_memory_fd
is exactly the mechanism it anticipates — but v1 of this backend must ride the Protocol 1.0
baseline (device-owned buffers plus bounded explicit transfers) and must not front-run it.
Graphics/rendering, swapchains, or scanout. This is a compute backend; anything display-facing
is separate work with its own ownership and synchronization questions.
Full TOSA operator coverage, or low-precision tiers beyond what is implemented and tested.
CPU fallback inside the Vulkan backend. A software Vulkan implementation is a test target
selected by the host's ICD, never a silent fallback chosen by this crate.
Suggested phasing
The XDNA precedent is to land a scaffold first and grow it under decision tickets. Mirroring crates/virtio-accel-xdna (landed dd3edf1b / 06954b77 for #86):
Scaffold — Cargo.toml, build.rs probe setting va_vulkan, always-compiled lower.rs
holding the advertised Target constants, an InitError::RuntimeUnavailable placeholder, README.md, SAFETY.md outline, #![forbid(unsafe_code)] while no FFI exists.
FFI + lifecycle — instance/device/queue creation, buffers, and a passthrough/identity program
proving artifact load, direct binding, coherence, nonblocking completion, and teardown.
First operator tier — MATMUL, then the rest of the advertised subset, with golden
hardware-free lowering tests.
Conformance + CI — the software-Vulkan lane, then documented hardware evidence.
Motivation beyond this repository
A vendor-neutral Vulkan backend is what lets a virtio-accel consumer reach an AMD GPU without
anyone porting AMD's driver stack. In the kore microkernel's case the intended shape is: real
Linux in a guest with the GPU passed through, stock amdgpu + Mesa/RADV inside it, and this crate
as an ordinary host process terminating the accelerator protocol — no AMD-specific adapter, and the
same crate covering Intel and Mali hosts unchanged. That consumer is out of scope here and imposes
no requirement on this design; it is recorded only as the reason vendor neutrality is worth paying
for over an AMD-specific backend.
Goal
Add a production-oriented, vendor-neutral GPU backend that implements
virtio_accel_core::Acceleratorover Vulkan compute, executing device-neutral TOSA 1.0 programs onany conformant Vulkan 1.x implementation without leaking Vulkan types into the portable crates.
The crate name and support row are already staked:
README.mdcarries aVulkan/Plannedrow(added in
4d1b6638), and the workspace table reservesvirtio-accel-vulkan.Why this backend is different from the existing four
Core ML, OpenVINO, Hexagon, and XDNA each bind one vendor's runtime to one vendor's silicon. Vulkan
is the first target where one adapter covers many vendors — RADV (AMD), ANV (Intel), NVIDIA,
Mali, and software implementations — because the vendor-specific part lives below a standard API
that the host OS already ships. Three consequences worth stating up front, because they change the
shape of the work relative to the XDNA map (#78):
lavapipeis a conformant software Vulkanimplementation. Unlike every other backend, the conformance suite and the numerical corpus can
plausibly run in CI on a GPU-less runner, in the same spirit as the OpenVINO CPU plugin lane
(
.github/workflows/ci.yml, jobopenvino-host-test). This should be a first-class goal, not anafterthought — it is the strongest verification asset this backend has.
vkGetFenceStatus/vkGetSemaphoreCounterValuearegenuinely nonblocking status reads. Both HRX (Decide the execution-model mapping and event-bridge spec #85) and QAIRT needed a dedicated worker thread to
bridge a blocking
synchronizeintopoll_event; Vulkan may not need one at all. That has to beproven, not assumed, but if it holds it removes the single most delicate piece of machinery the
other two backends carry.
VK_ERROR_DEVICE_LOSTis an explicit, normative signal withdefined propagation, which maps directly onto the instance-poisoning /
BackendDiscardRequiredcontract instead of relying on a watchdog whose timeout must be reasoned against a kernel TDR.
Note the deliberate overlap with OpenVINO: it already enumerates Intel GPUs. This backend's claim is
vendor neutrality and no vendor runtime dependency, not "the first GPU." On an Intel host both
may be present and OpenVINO will likely be faster; that is fine and should be documented rather than
arbitrated in code.
Scope
virtio-accel-vulkan, structurally followingvirtio-accel-openvino(the template named by Wayfinder map: AMD XDNA NPU backend #78) —lib.rs/lower.rs/native.rs/ffi.rs, with the portable admission surface always compiled.RuntimeUnavailableplaceholder otherwise, following theva_openvino/va_hexagon/va_xdnacfg pattern (va_vulkan). Explicit configuration only;no scanning of standard locations.
AcceleratorClass::GPU— which already exists (
crates/virtio-accel-core/src/lib.rs:47), so no portable-crate changeis required for device class.
virtio-accel-tosaartifacts, validate/analyze with the shared TOSA layer, and lower adocumented initial operator/dtype subset to SPIR-V compute.
release, and recovery through the shared
Acceleratorcontract.buffers;
read_buffer/write_bufferremain the only copy boundaries.timeout behavior, and device-loss reporting. Advertise
EVENT_CANCELLATIONonly if it can beimplemented honestly (Vulkan has no cancel primitive — expect not to advertise it, matching
Hexagon and XDNA).
SAFETY.mdand register the audited exception inci/check-release-policy.py(which today lists the coreml/openvino/hexagon/xdna confinementmarkers at lines 79-91).
guide, architecture notes, performance evidence, and release policy.
Open decisions (candidate wayfinder tickets)
Unlike #75, whose implementation tips were decided constraints backed by prior research, the
items below are genuinely open. They are the natural decision tickets for a wayfinder map in the
shape of #78. Recommended framing for each is given, but none is settled.
ffi.rsdeclaringonly the validated subset (OpenVINO's is 171 lines; XDNA's Decide crate layout, HRX FFI boundary, and build-time probe #83 decided "declare only the
hardware-validated HRX subset"). Vulkan's surface is far larger than any prior target, so the
honest options are: a hand-written minimal subset (convention-consistent, more work),
ash(thin, unsafe, widely used, adds a dependency to a
stdadapter crate only), or a safe wrapperlike
vulkano(heavier, more opinionated). This is the highest-leverage decision in the mapbecause it sets the size of the audited unsafe surface and therefore the shape of
SAFETY.md.ArtifactFormatis an opaqueNonZeroU32that each backend may define for itself — TOSA is0x544f_5341(crates/virtio-accel-tosa/src/artifact.rs:7), Core ML defines its own0x434d_4c50, the mock backend0x5641_4d4b. So accepting SPIR-V under a backend-definedformat id is architecturally permitted. Recommendation: TOSA-only for v1 (it is what the
shared corpus and conformance oracles are built on, and it keeps the guest device-neutral); treat
a SPIR-V-direct format as a deliberate follow-on, decided on its own merits, not smuggled in.
bounded out-of-process compiler (Decide the compiler-helper subprocess contract #84) because
aieccis Python. Vulkan likely does not:per-operator SPIR-V compute shaders can be authored once, checked into the crate as precompiled
SPIR-V, and specialized at
load_programvia specialization constants for shapes/tiling —no toolchain on the serving host, no subprocess, no Python. If that holds it is a significant
simplification over both XDNA and Hexagon, and it should be validated early because it determines
whether this backend has a build-time toolchain dependency at all.
VK_KHR_shader_float16_int8, INT8 gated onVK_KHR_shader_integer_dot_product. FP8 has noportable Vulkan path and should be rejected loudly at admission. Per the principle recorded in
Decide the first advertised numerical tier #82: guest-chosen tiers, never host knobs — and reject rather than silently widen.
Host→HOST_VISIBLE | HOST_COHERENT,Device→DEVICE_LOCAL,Shared→DEVICE_LOCAL | HOST_VISIBLE(resizable-BAR). Worth confirming that ReBAR availability isprobed and
SHARED_MEMORYadvertised only when the memory type actually exists, rather thanassumed.
vkGetFenceStatusalone satisfies nonblockingpoll_eventwithout a worker thread, how a bounded preallocated command-buffer/fence pool is sized so
guest-controlled work cannot create unbounded host queue depth, and how finite timeouts are
handled pre-admission.
lavapipevs SwiftShader), which distropackages pin it, and how much of the mandatory conformance set plus the numerical corpus can run
without a GPU. Also: whether a documented manual hardware lane is enough for real-GPU evidence,
as Build the AMD XDNA NPU backend #75 blessed for XDNA rather than exposing a self-hosted runner on a public repo.
Acceptance criteria
detected or explicitly requested.
AcceleratorClass::GPUand completes thedocumented TOSA example end to end.
virtio-accel-conformancepasses; capability-conditional skips carryexplicit reasons.
oracle.
stable terminal polling,
VK_ERROR_DEVICE_LOSThandling, and rejected/indeterminate ownershippaths.
diagnostics return to baseline after each conformance case.
implementation, and the required driver/runtime versions plus reproducible hardware commands
are documented for the real-GPU lane.
Plannedonly for capabilities demonstrated by tests.Non-goals
Acceleratorcontract to mirror a Vulkan concept.The negotiated external-memory handoff is designed but deliberately unassigned (Design a negotiated external-memory handoff extension for heterogeneous schedules #113, closed;
docs/plans/issue-113-external-memory-handoff.md— "design complete; protocol values andimplementation intentionally unassigned") and its implementation is tracked separately by protocol: implement the negotiated external-memory handoff extension #119.
A Vulkan backend is the most natural eventual consumer of that extension —
VK_KHR_external_memory_fdis exactly the mechanism it anticipates — but v1 of this backend must ride the Protocol 1.0
baseline (device-owned buffers plus bounded explicit transfers) and must not front-run it.
is separate work with its own ownership and synchronization questions.
selected by the host's ICD, never a silent fallback chosen by this crate.
Suggested phasing
The XDNA precedent is to land a scaffold first and grow it under decision tickets. Mirroring
crates/virtio-accel-xdna(landeddd3edf1b/06954b77for #86):Cargo.toml,build.rsprobe settingva_vulkan, always-compiledlower.rsholding the advertised
Targetconstants, anInitError::RuntimeUnavailableplaceholder,README.md,SAFETY.mdoutline,#![forbid(unsafe_code)]while no FFI exists.proving artifact load, direct binding, coherence, nonblocking completion, and teardown.
hardware-free lowering tests.
Motivation beyond this repository
A vendor-neutral Vulkan backend is what lets a
virtio-accelconsumer reach an AMD GPU withoutanyone porting AMD's driver stack. In the
koremicrokernel's case the intended shape is: realLinux in a guest with the GPU passed through, stock
amdgpu+ Mesa/RADV inside it, and this crateas an ordinary host process terminating the accelerator protocol — no AMD-specific adapter, and the
same crate covering Intel and Mali hosts unchanged. That consumer is out of scope here and imposes
no requirement on this design; it is recorded only as the reason vendor neutrality is worth paying
for over an AMD-specific backend.