[Mobile] QNN HTP backend fails with QNN_DEVICE_ERROR_INVALID_CONFIG on Snapdragon 8 Elite (SM8750P, ro.board.platform=sun) regardless of soc_model/htp_arch value
Describe the issue
Every attempt to create an OrtSession with the QNN HTP execution provider fails identically at device creation, before GetCapability() ever evaluates model ops. This happens regardless of model precision (tested both fp32 and native fp16 ONNX models) and regardless of every combination of htp_arch / soc_model provider options tried.
Session creation itself does not throw (my app's own try/catch around createSession() never fires), so the Java-level API reports success — but GetCapability() returns zero supported nodes, causing a silent, full fallback to CPUExecutionProvider for 100% of graph nodes. This is confirmed via enableProfiling() traces: every single node across multiple full inference passes shows "provider": "CPUExecutionProvider", and the raw trace JSON contains zero occurrences of the string "QNN" anywhere.
To reproduce
- Build an Android app targeting a Snapdragon 8 Elite (SM8750P) device with onnxruntime-android-qnn 1.27.0
- Create an OrtSession using addQnn() with backend_path=libQnnHtp.so
- Observe logcat during session creation
Provider options tested (all produce the identical error):
| htp_arch | soc_model | enable_htp_fp16_precision | Result |
|---|---|---|---|
| (unset — auto) | (unset) | 1 | INVALID_CONFIG |
| 81 | (unset) | 1 | INVALID_CONFIG |
| 79 | (unset) | 1 | ParseHtpArchitecture] Invalid HTP architecture: 79 (79 not in ORT's enum — only 68/69/73/75/81 valid) → falls back to auto → INVALID_CONFIG |
| 69 | (unset) | 1 | INVALID_CONFIG |
| (unset) | 69 | (unset) | INVALID_CONFIG |
Relevant code:
val qnnOptions = OrtSession.SessionOptions().apply { setIntraOpNumThreads(2) enableProfiling("${context.filesDir}/ort_trace") addQnn(mapOf( "backend_path" to "libQnnHtp.so", "profiling_level" to "detailed", "soc_model" to "69" )) } createdSession = ortEnv!!.createSession(modelBytes, qnnOptions)
ADSP_LIBRAR
Y_PATH is set explicitly before session creation via:
val nativeLibDir = context.applicationInfo.nativeLibraryDir val existingPath = "/odm/lib/rfsa/adsp;/vendor/lib/rfsa/adsp/;/system/lib/rfsa/adsp;/system/vendor/lib/rfsa/adsp;/dsp" android.system.Os.setenv("ADSP_LIBRARY_PATH", "$nativeLibDir;$existingPath", true)
Urgency
high
Platform
Android
OS Version
16 BP2A.250605.031.A3
ONNX Runtime Installation
Released Package
Compiler Version (if 'Built from Source')
No response
Package Name (if 'Released Package')
No response
ONNX Runtime Version or Commit ID
onnxruntime-android-qnn 1.27.0
ONNX Runtime API
Java/Kotlin
Architecture
X64
Execution Provider
NNAPI
Execution Provider Library Version
No response
Source: microsoft/onnxruntime