pub struct Vulkan;Expand description
The Vulkan backend (ferrox-vulkan) — one kernel wide.
ferrox-vulkan is the vulkan-beachhead GO/NO-GO slice, not a
backend: a single hand-emitted SPIR-V Q8_0 matvec, checked against a
scalar twin and run on a real device through MoltenVK. See
docs/plans/vulkan-beachhead-verdict.md.
This impl is what wiring that slice into the seam costs, and it is deliberately not more than the slice supports:
- Q8_0 and nothing else.
Vulkan::matvec_kernelnames one kind; every other kind reports no kernel, which is the honest answer and is what makes the registry say “NO KERNEL … falls back to CPU apply_cpu” instead of quietly running slow. - No GEMM at all.
Vulkan::gemm_supportedis false for every kind. There is nomul_mmshader, andapply_batch_with_actshas no Vulkan arm, so a batched prefill runs on the host —Vulkan::GEMM_FALLBACKsays exactly that. - No performance claim.
q8_0_matvecrebuilds its entire pipeline per call. Nothing here may be reported as a measured capability; the verdict says so and this comment repeats it because the code is now reachable.
Trait Implementations§
Source§impl BackendCaps for Vulkan
impl BackendCaps for Vulkan
Source§const GEMM_FALLBACK: &'static str = "CPU apply_batch"
const GEMM_FALLBACK: &'static str = "CPU apply_batch"
There is no Vulkan batch entry point of any kind:
apply_gpu_batch is #[cfg(feature = "metal")] and
apply_batch_with_acts has a CUDA arm and a Metal arm. So a
prefill against a Vulkan-resident kind runs on the host, and
this names the host path rather than inventing a GPU one.
Source§fn matvec_kernel(kind: QuantKind) -> Option<&'static str>
fn matvec_kernel(kind: QuantKind) -> Option<&'static str>
Exactly one kind, because there is exactly one shader:
ferrox_vulkan::q8_0_shader.
Everything else must report None rather than something
plausible. A capability table that over-claims is how a kind ends
up “supported” with no kernel behind it, which this repo has now
paid for twice (IQ4_XS prefill, Q5_0 decode). The guard test
checks this against [vulkan_matvec_launch] for all 21 kinds.
Source§fn gemm_supported(_kind: QuantKind) -> bool
fn gemm_supported(_kind: QuantKind) -> bool
No kind, for any kind. The beachhead emitted one matvec shader
and deliberately no mul_mm; the verdict puts a real GEMM in
vulkan-prefill-gemm, which is where the backend decision
actually lives.
This is the one place the Metal invariant
(every_metal_matvec_kind_also_has_a_metal_gemm: matvec set ==
GEMM set) is knowingly not held, and it is held open rather than
papered over: Q8_0 decodes on Vulkan and prefills on the CPU,
the registry records the split by name, and ferrox bench would
show it.
Source§const ID: Backend = Backend::Vulkan
const ID: Backend = Backend::Vulkan
crate::kernel_registry reports this backend. Dispatch and
observability read the same constant, so a backend cannot be
dispatched to under one name and reported under another.Auto Trait Implementations§
impl Freeze for Vulkan
impl RefUnwindSafe for Vulkan
impl Send for Vulkan
impl Sync for Vulkan
impl Unpin for Vulkan
impl UnsafeUnpin for Vulkan
impl UnwindSafe for Vulkan
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more