Misc. bug: Hexagon session fails when /vendor/lib64 is on LD_LIBRARY_PATH (Termux, SM8850)
Nobody has claimed this yet.
Assessment
- Difficulty
- 1/5
- Estimated time
- Under an hour
- Newbie friendliness
- 88/100
- Issue type
- Documentation
- Clarity
- Clearly specified
- Activity status
- Active
- Domain
- documentation, mobile-dev
Research direction
Start with docs/backend/snapdragon/README.md and compare its documented library-path setup with scripts/snapdragon/adb/run-cli.sh:69-72 and the Termux reproduction in the issue. Document the warning about keeping /vendor/lib64 off LD_LIBRARY_PATH when using non-adb execution, and verify that the guidance matches the existing adb scripts.
Written by the indexing model from the issue text.
Description
Name and Version
version: 0.2.0-dev (build 1, commit f280b26)
built with Clang 21.0.0 for Android aarch64
Built in ghcr.io/snapdragon-toolchain/arm64-android:v0.7, preset arm64-android-snapdragon-release, cmake 3.31.6.
Operating systems
Other? (Please let us know in description)
Which llama.cpp modules do you know to be affected?
libllama (core library), llama-bench, llama-cli
Command line
GGML_HEX_VERBOSE=1 LD_LIBRARY_PATH=$PWD/lib:/vendor/lib64 ADSP_LIBRARY_PATH=$PWD/lib \
./bin/llama-bench -m gguf/Llama-3.2-1B-Instruct-Q4_0.gguf -dev HTP0 -ngl 99 -p 32 -n 8
Problem description & steps to reproduce
I run llama.cpp from Termux instead of the adb scripts. If /vendor/lib64 is on LD_LIBRARY_PATH, the Hexagon backend can't open a session. Take it off and it works. Nothing else changes between the two runs.
/vendor/lib64 is on there because of OpenCL. libggml-opencl.so has a hard NEEDED on libOpenCL.so, that lives in /vendor/lib64, and Termux's linker won't load it from an absolute path unless the directory is on LD_LIBRARY_PATH. So I can have OpenCL or I can have Hexagon, not both.
Device is a OnePlus 15 (CPH2747), Snapdragon 8 Elite Gen 5 (SM8850), Hexagon v81, Android 16 (SDK 36), OxygenOS CPH2747_16.0.9.400(EX01). No root.
With /vendor/lib64:
ggml_opencl: device: 'QUALCOMM Adreno(TM) 840 (OpenCL 3.0 Adreno(TM) 840)'
ggml-hex: Loading driver libcdsprpc.so
ggml-hex: FastRPC capability query failed (err 114)
ggml-hex: failed to query HTP version (err 114) defaulting to v73
ggml-hex: Hexagon Arch version v73
ggml-hex: HTP0 allocating new session
ggml-hex: failed to open session 0 : error 0x72
ggml-hex: failed to create device/session 0
ggml/src/ggml-backend.cpp:569: GGML_ASSERT(device) failed
2: ggml_abort
3: ggml_backend_dev_description
4: ggml_backend_dev_by_name
7: _Z11llama_benchiPPc
Exit 134. Same command without that one path element:
ggml_opencl: platform IDs not available.
ggml-hex: Hexagon Arch version v81
ggml-hex: HTP0 hwinfo: threads 8, hvx 8, hmx 1, vtcm 8 MB
ggml-hex: HTP0 new session : session-id 0 domain-id 3 uri file:///libggml-htp-v81.so?htp_iface_skel_handle_invoke&_modver=1.0&_dom=cdsp&_session=0
| llama 1B Q4_0 | 729.75 MiB | 1.24 B | OpenCL,HTP | 99 | HTP0 | pp32 | 698.21 ± 95.79 |
Why the path does that
/dev/fastrpc-cdsp here is crw-rw-r-- system system, so an app uid can't open it. libcdsprpc.so expects that and asks the vendor.qti.hardware.dsp.IDspService HAL for an fd instead. Turning on its tracing (setprop vendor.fastrpc.debug.trace 1) shows the fallback dying:
fastrpc_apps_user.c:5866: open_device_node: no access to default device of domain 3, open thru HAL, (sess_id 0)
dsp-client: DspClient.cpp (61): DspClient: AIDL HAL not found, using HIDL interface
dsp-client: DspClient.cpp (101): Error: DspClient: unable to acquire dspservice instance
dsp-client: DspClient.cpp (161): Error: openSession: IDspManager session is NULL
dsp-client: DspClient.cpp (226): Error: open_hal_session: failed to open session, error -1
"AIDL HAL not found" isn't true. /vendor/bin/dspservice is up and service list has vendor.qti.hardware.dsp.IDspService/default. The lookup itself is what the library path breaks. Same process, same uid, one variable:
isDeclared: True getService: 0xb400... (no LD_LIBRARY_PATH)
isDeclared: False getService: 0x0 (LD_LIBRARY_PATH=/vendor/lib64)
How far this goes
Probably not very. #23821 has someone running LD_LIBRARY_PATH=./lib:/vendor/lib64 ... -dev HTP0 on Android quite happily. My guess is it only hurts devices where the app uid can't open the fastrpc node, so libcdsprpc has to use the HAL in the first place. If your fastrpc permissions are looser the fallback never runs and the extra path element does nothing.
The adb scripts are fine. scripts/snapdragon/adb/run-cli.sh:69-72 sets only the package lib, same as its siblings:
adb $adbserial $adbhost shell " \
cd $basedir; ulimit -c unlimited; \
LD_LIBRARY_PATH=$basedir/$branch/lib \
ADSP_LIBRARY_PATH=$basedir/$branch/lib \
I pushed the same build to /data/local/tmp and ran it that way as uid 2000 to check. Both backends came up, OpenCL included, with no /vendor/lib64 anywhere:
ggml_opencl: device: 'QUALCOMM Adreno(TM) 840 (OpenCL 3.0 Adreno(TM) 840)'
ggml-hex: Hexagon Arch version v81
ggml-hex: HTP0 new session : session-id 0 domain-id 3 ... _dom=nsp1000&_session=0
| llama 1B Q4_0 | OpenCL,HTP | 99 | HTP0 | pp32 | 657.70 ± 117.13 |
So your documented path is fine. This is a Termux problem.
What would have helped
One line in docs/backend/snapdragon/README.md: if you're not using the adb scripts, keep /vendor/lib64 off LD_LIBRARY_PATH, it can break FastRPC's HAL fallback. Cost me a day.
What I do instead is copy libcdsprpc.so, vendor.qti.hardware.dsp@1.0.so, vendor.qti.hardware.dsp-V1-ndk.so, libvmmem.so and libOpenCL.so into the package's own lib/. Both backends survive that.
The abort is a different problem and already has a fix open at #20983. I've left this reproduction there too.
Two things I checked so I don't waste your time: the arch-query failure isn't the fatal bit, ggml-hexagon.cpp:4404 logs and carries on at v73 on purpose. And I'm not going to guess at an AEE name for 0x72 since AEEStdErr.h isn't in the tree, though 114 == 0x72 so those two lines are probably the same status printed with %d and %x.
First Bad Commit
Didn't bisect, only tested f280b26.
Disclosure: I used an AI assistant to help collect the logs and track this down to the linker path. Every command and result above ran on my device and I checked them.
- Dominant language
- C++
- Stars
- 129k
- Forks
- 23.5k
- Avg merge
- 2d 11h
- Merged PRs (30d)
- 411
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from ggml-org/llama.cpp
-
bug-unconfirmed
Difficulty 2/5 1-3 hours Newbie friendliness 76/100
-
bug-unconfirmed
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 86/100
-
bug-unconfirmed
Difficulty 1/5 Under an hour Newbie friendliness 90/100
-
/v1/responses: reasoning item with "summary": null rejected as "Cannot determine type of 'item'" Open
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
All issues in ggml-org/llama.cpp
Similar issues
-
Difficulty 1/5 Under an hour Newbie friendliness 90/100
AXERA-TECH/ax-llm#77 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 74/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 74/100
NVIDIA/cuda-samples#453 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
infiniflow/infinity#3502 ·
-
level/task module/gcp type/bug
Difficulty 2/5 1-3 hours Newbie friendliness 85/100