Skip to content

feat(backends): TernaryF32GemvNative SPI + exact FP32×b1.58 dispatch pack (#1138) - #1157

Merged
michalharakal merged 1 commit into
developfrom
feature/1138-ternary-f32-spi-pack
Aug 26, 2026
Merged

michalharakal merged 1 commit into
developfrom
feature/1138-ternary-f32-spi-pack

Conversation

@michalharakal

Copy link
Copy Markdown
Contributor

Phase 2 of #1136 — closes #1138. Builds on #1151.

What

  • TernaryF32GemvNative — array-shaped SPI over the vendored NeoGPU LUT kernel (sibling of BitNetGemvNative; scale NOT applied, inputDim % 4 == 0).
  • TernaryF32GemvKernel — portable reference ViewKernel: FP32 × BITNET_B1_58, codes hoisted, in-band scale applied to output. The correctness oracle and in-kernel fallback — deliberately not a dispatch entry.
  • TernaryF32KernelPack.install(native, capabilities, warn) — registers NativeTernaryF32ViewKernel under the exact key matmul(FP32 dense contiguous × FP32/BITNET_B1_58 blocked_row_major) (capability-free + capability keys, same two-key pattern as TernaryKernelPacks). KernelDispatch.matmul checks the exact key before the requantize branch → the pack short-circuits the int8 adapter with zero dispatcher changes; install(null) warns and registers nothing, keeping today's behavior bit-for-bit.
  • View kernel loops the gemv per activation row (prefill works), falls back to the reference for non-heap / strided / k % 4 != 0.
  • FFM object now implements the SPI (gemvPacked) with an install() helper — the first ternary FFM consumer.

Tests (all green locally, macOS arm64)

  • TernaryF32GemvKernelTest — reference vs decoded-weight matmul (incl. k % 4 != 0 byte-boundary crossing)
  • TernaryF32KernelPackTest — FakeNative: exact key beats requantize path (no AdapterInserted), absence keeps bitnet_gemv/reference serving, per-row looping, odd-k fallback, capability recorded in key
  • TernaryF32FfmPackTest — the REAL vendored kernel behind REAL dispatch at BitNet-2B dims (k=2560): serves the key, no adapter, matches the reference
  • Full jvm suites of backend-api / backend-cpu / backend-native-cpu pass; commonMain cross-compiles (js, linuxX64)

Kernel-support matrix intentionally unchanged — pack-registered kernels aren't KernelProvider accessors (same as bitnet_gemv).

Next: #1139 (JNI + Kotlin/Native bridges), #1140 (I2_S GGUF import).

🤖 Generated with Claude Code

…pack

TernaryF32GemvNative is the array-shaped seam over the vendored NeoGPU LUT
kernel (#1137), sibling of BitNetGemvNative. TernaryF32KernelPack registers
a view kernel under the exact key matmul(FP32 dense × BITNET_B1_58
row-major) — the key KernelDispatch checks before the requantize branch, so
installing the pack short-circuits the int8 adapter with zero dispatcher
changes, and absence leaves today's behavior untouched (a notice, never a
crash; deliberately nothing is registered without the native kernel — the
tuned int8 path beats a Kotlin f32 loop as the portable fallback).

The view kernel loops the gemv per activation row (prefill included),
applies the in-band per-tensor scale the native side never sees, and falls
back to the new TernaryF32GemvKernel reference for non-heap storage,
strided views, or k % 4 != 0 (the sequential packing crosses byte
boundaries between rows then). The reference is pinned against the decoded
matmul; the pack contract against a FakeNative; and the real vendored
kernel against real dispatch in TernaryF32FfmPackTest — the FFM object now
implements the SPI (gemv → gemvPacked) with an install() helper, closing
the "FFM has no ternary consumer" gap.

Kernel-support matrix intentionally unchanged: pack-registered kernels are
not KernelProvider accessors, same as bitnet_gemv.

Refs #1138, #1136

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@michalharakal
michalharakal merged commit 8f82a43 into develop Aug 26, 2026
17 checks passed
@michalharakal
michalharakal deleted the feature/1138-ternary-f32-spi-pack branch August 26, 2026 09:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[ternary-f32] Phase 2: TernaryF32GemvNative SPI + reference ViewKernel + TernaryF32KernelPack

1 participant