Eager execution: backends and kernels
The eager path is DirectCpuExecutionContext โ DefaultCpuOps* โ KernelRegistry โ KernelProvider,
distinct from the StableHLO/IREE export path. This page is the hand-authored overview; its
companion kernel ร platform matrix is generated from
the registered providers and gated against drift.
This page covers the provider tier โ who can compute what, on which platform. The generic path
selects differently, on a declared descriptor of the operands rather than on dtype and priority:
see Kernel SPI and the selection algorithm for
KernelDispatch, the ViewKernelPack SPI, and how a call site is matched to a kernel.
Legend: โ available ยท โ missing.
Kernel ร provider (matmul, FP32 activations)
| Weight format | Scalar (all targets) | Panama (JVM) | Native FFM (JVM) | Native JNI (Android) | Native cinterop (K/N) |
|---|---|---|---|---|---|
FP32 |
โ |
โ |
โ |
โ |
โ |
BF16 |
โ |
โ |
โ |
โ |
โ |
Q8_0 |
โ |
โ |
โ |
โ |
โ |
Q4_0 |
โ |
โ |
โ |
โ |
โ |
Q4_K |
โ |
โ |
โ |
โ |
โ |
Q6_K |
โ |
โ |
โ |
โ |
โ |
Q5_K |
โ |
โ |
โ |
โ |
โ |
Q5_1 |
โ |
โ |
โ |
โ |
โ |
Q5_0 |
โ |
โ |
โ |
โ |
โ |
TQ2_0 / BitNet b1.58 (int8 activations) |
โ |
โ |
โ |
โ NEON |
โ |
BitNet b1.58 (exact FP32 activations, vendored NeoGPU kernel) |
โ |
โ FFM |
โ |
โ JNI + fused lm_head |
โ K/N cinterop |
BITNET_PLANES (multi-plane ternary packing) |
โ |
via kernel pack |
โ |
via kernel pack |
via kernel pack |
Q2_K / Q3_K / Q8_K / IQ4 |
โ (dequant to FP32 only) |
โ |
โ |
โ |
โ |
Resolution is by priority: Native (100 โ whichever of FFM/JNI/cinterop applies to the target) โ Panama (50, JVM only) โ Scalar (0). The best available provider that carries the kernel wins; otherwise it cascades down. At most one native tier is compiled into a given target, so the native columns are mutually exclusive per platform rather than stacked.
Packed weights reach a kernel through the registry by declaring their block order; a canonical weight is relayouted once, not per call.
Platform ร what runs
| Target | Providers available | Notes |
|---|---|---|
JVM |
Scalar + Panama + Native-FFM |
Full SIMD/native acceleration. |
Android |
Scalar + Native-JNI |
Panama ( |
Kotlin/Native โ linux x64/arm64 |
Scalar + Native-cinterop |
Static archive embedded in the klib; manual |
Kotlin/Native โ macOS/iOS |
Scalar + Apple Accelerate + Native-cinterop |
Accelerate covers dense FP32 and reductions; cinterop covers packed quant with runtime |
JS / WASM (Js, Wasi) |
Scalar |
No SIMD. |
Packed-quant matmul works on every target: those formats have a commonMain scalar kernel and
DefaultCpuOpsBase dispatches packed weights through the registry.
Gaps
-
Native FFM Q6_K โ the only packed format the FFM C kernel set does not cover.
-
Native JNI dense FP32/BF16 โ the Android JNI provider has no GEMM shim, so dense ops fall through to scalar there whichever
.sotier loaded (SKaiNET#920). -
Dense FP32/BF16 SIMD on Kotlin/Native linux โ still the scalar floor; Apple has Accelerate (SKaiNET#722, #910).
-
Other GGML quant formats (Q2_K, Q3_K, Q8_K, IQ4_NL/XS) โ loadable via dequantization to FP32, no packed matmul kernel on any provider.
-
Non-CPU eager backends (IREE, Metal, GPU) โ the
KernelProviderSPI anticipates them, none are implemented for the eager path. The compiled path (DSL โ StableHLO โ IREE) does reach GPU on Android via Vulkan, but that is a separate pipeline.