Repository navigation
ADFA-6757 | Build the CPU backend per CPU level so phones with dot-product use it - #151
Merged
Merged
Conversation
…ones with dot-product use it The shipped libggml-cpu.so held no SDOT instructions: the cross-compile fell back to basic ARMv8. The backend is now built as four libraries (ARMv8.0, 8.2 dot-product, 8.2 dot-product+fp16, 8.6 with int8 matrix multiply) and llama-android.cpp loads the best one the phone scores, looking beside its own library. The ARMv8.0 build keeps Cortex-A53 phones working. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Vh2DAaJxvRXKRYkgiDqwGQ
The loader listed the directory libllama-android.so came from, which is not a directory when the libraries stay inside an APK (extractNativeLibs=false), so NativeContextFallbackTest found no backend and failed. Bare names let the linker search wherever the library came from. A variant that fails to load now logs dlerror's reason, and PrebuiltAarAbiTest requires all four variants. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Vh2DAaJxvRXKRYkgiDqwGQ
hal-eisen-adfa
approved these changes
Oct 28, 2026
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.
Summary
Fix 5 of ADFA-6757, kept apart from #149 and #150 because it is the only one that changes native code and the prebuilt AAR.
The shipped
libggml-cpu.soholds no dot-product (sdot) instructions.llama-impl/build.gradle.ktssets no ARM level, so the cross-compile falls back to basic ARMv8, and most phones sold in the last several years support dot-product. The model's integer maths for reading the prompt is where it matters.libggml-cpu-android_armv8.0_1,_armv8.2_1(dot-product),_armv8.2_2(dot-product and fp16) and_armv8.6_1(adds int8 matrix multiply), with-DGGML_BACKEND_DL=ON -DGGML_CPU_ALL_VARIANTS=ON. The fork's existing Android variant list does the work. Checked withllvm-objdump:armv8.0_1has 0sdot,armv8.2_*have 418,armv8.6_1also has 116smmla.llama-android.cpploads the best one at start-up (load_cpu_backend, called frombackend_init). It tries the variants by name, best first; ggml refuses one that scores zero on the phone, and each needs everything the next one does, so the first to load is the best supported. Bare names let the linker find them in the IDE's extracted plugin directory and inside an APK alike. It runs once, logs which variant loaded, and logsdlerror's reason for any that did not.armv8.2-a+dotprod, as the ticket says: a Cortex-A53 phone would crash on its first instruction..cgpgoes from 15.66 MB to 17.47 MB (+11.6%); the AAR, where the libraries are compressed, from 2.0 MB to 2.9 MB.PrebuiltAarAbiTestnow requires all four variants instead oflibggml-cpu.so, so an AAR that dropped one fails a test. It still checks the source hash and 16 KB alignment, and both pass.Measured on a Pixel 6 Pro (Android 17)
Same phone, same AI-Core (
de06201, the compact tool set from #150), qwen2.5-coder-1.5b-instruct-q4_k_m, a fresh chat per prompt, one run each. Baseline is AI-Agent-Local built frommain; the other is this branch. Time is from the log line announcing the prompt read to the first parsed output, so it includes writing the reply's first tokens.mainasimddpandfphp. The log showsarmv8.2_2was the one picked, andSystem Info: ... DOTPROD = 1(themainbuild shows none). These timings are from332d7a0; after the review fix (88c9cac) one more "Hello" run took 60.1 s with the same variant.System Infoshows noDOTPROD) and answered "Hello" in 82.6 s, the same asmain. Repeated on88c9cac: each missing variant logsdlopen failed: library ... not found, then ARMv8.0 loads. It shows the baseline build works; it is a subset of the others, so this phone cannot show that a real ARMv8.0 CPU picks it.Review
An independent review (given the diff and the artifacts, not my conclusions) found four issues; I confirmed each and fixed all four in
88c9cac:libllama-android.so, and this plugin's own APK setsextractNativeLibs="false", soNativeContextFallbackTest(connectedDebugAndroidTest) found no backend: on the Pixel it failed withload_model() failedandbackends: none loaded from …/base.apk!/lib/arm64-v8a. The installed plugin was not affected, because CoGo extracts the libraries. Variants are now loaded by name, and the test passes on the Pixel.NATIVE-BUILD.md.dlopenerrors. The loader now logsdlerror.It also confirmed: no variant can execute an instruction the CPU lacks before its score is checked (the scoring code is plain ARMv8.0); nothing assumes a linked-in CPU backend; all nine libraries are 16 KB aligned; and a rebuild from the submodule and committed flags gives the same four variants.
Not verified
llama-benchon the Pixel 7 and a run on an ARMv8.0 phone. I had neither, so the first is replaced by the in-app Pixel 6 Pro numbers above, and the second by the single-variant test.armv8.6_1(int8 matrix multiply) variant never ran. The Pixel 6 Pro lacks that feature; its library loaded and scored without crashing, but no phone here exercised it..cgpbuilds clean (revision=88c9cacbfeb7,revision_source=git, nine arm64 libraries and nothing else), but I didn't install it.27.0.12077973), asNATIVE-BUILD.mdalready says is not ideal.Things a reviewer should know
.cppandbuild.gradle.ktschanges and the AAR contents (unzip -l, thenllvm-objdump -don each variant, asNATIVE-BUILD.mdnow describes).avc: granted { execute }audit lines for them; they are not denials.mainand does not touch ADFA-6757 | Keep the local prompt cache across chat titles; size generation threads to the fast cores #149 or ADFA-6757 | Offer a small on-device model a compact tool set #150's files.Test plan
testDebugUnitTest: 243 tests, 0 failuresassemblePlugin(release, clean tree,revision_source=git);uv run --directory tools/addons addons --root "$PWD" checkexits 0connectedDebugAndroidTest(NativeContextFallbackTest) on the Pixel 6 Pro: passes (it failed before88c9cac)llama-bench, an ARMv8.0 phone, and a phone with int8 matrix multiply🤖 Generated with Claude Code
https://claude.ai/code/session_01Vh2DAaJxvRXKRYkgiDqwGQ