Repository navigation
perf(native-cpu): run the ternary f32 GEMV on the shared row pool (+19% BitNet decode on A78C) - #1359
Merged
Merged
Conversation
The vendored NeoGPU proj creates and joins 4 pthreads per call once N >= 512 — ~210 calls per BitNet 2B4T decode step. The adapter now drives the vendored kernel from skainet_run_rows in < 512-row slices, so each slice runs inline on a pool thread. The vendored file stays byte-identical; per-row results are unchanged. Cortex-A78C (Ventuno Q, 4 cores): q/o 654 -> 309 us, k/v 251 -> 84 us, gate/up/down ~1.4 -> ~0.8 ms; BitNet 2B4T JVM decode 1.90 -> 2.26 tok/s with byte-identical greedy output. Refs #1357 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
michalharakal
added a commit
that referenced
this pull request
Oct 21, 2026
CHANGELOG [0.62.0] - 2026-10-21 with the parity headline over #1363, #1364, #1368, #1369, #1426, #1427, #1428 and #1430, plus entries for the operator coverage matrix (#1370), the BitNet decode allocation and threading fixes (#1359, #1360, #1361, #1362), the ClassificationSupport extraction (#1429) and the toolchain bumps (Kotlin 2.4.21, kotest 6.2.6, Gradle 9.8.1). VERSION_NAME, CITATION, Antora version, README bom coordinate, What's New and contributors, Android tutorial coordinates; regenerated operator and kernel-support matrices; SKEEP-007 rollout step 3 marked shipped.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
skainet_ternary_f32_gemv(the BitNet b1.58 /BITNET_B1_58projection) called the vendored NeoGPUhs_ml_ternary_f32_projdirectly. That function creates and joins 4 pthreads on every call onceN >= 512, which is about 210 calls per BitNet 2B4T decode step. It's the create/join patternskainet_row_threads.cdocuments as the slow one (#1195).The adapter now drives the vendored kernel from the shared row pool (
skainet_run_rows) in slices of < 512 rows, so each slice stays below NeoGPU'sTHREAD_THRESHOLDand runs inline on a pool thread.threaded_regime_matches_single_row_calls_exactly(outputDim 2048, partial slice included) covers it; its comment is updated.hs_ml_lmhead_stage1always threads and has no inline entry point. Pooling it as well needs an upstream NeoGPU change; it was worth about +6 % more in my experiment below.Measurements: Arduino Ventuno Q, 4× Cortex-A78C,
taskset -c 0-3Microbenchmark of the vendored kernel at the real 2B4T shapes, weights streamed from DRAM (harness):
End to end:
skainet-cli, JVM (Temurin 21),microsoft/bitnet-b1.58-2B-4T-ggufI2_S, 128 greedy tokens:52f57d1d…52f57d1d…(byte-identical)Tests
:skainet-backends:skainet-backend-native-cpu:jvmTest --tests '*Ternary*'on linux-x86_64 passes 13/13:NativeTernaryF32GemvKernelTest10,TernaryPlanesFfmTest2,TernaryF32FfmPackTest1.libskainet_kernels.sofor linux-arm64 from this branch and ran it on the board (numbers above).skainet_row_threads.c, so the Android AAR links unchanged.Refs #1357
🤖 Generated with Claude Code