Skip to content

Add minimal QNN HTP cDSP test APK#20599

Merged
psiddh merged 1 commit into
pytorch:mainfrom
psiddh:pr-20057
Jun 29, 2026
Merged

Add minimal QNN HTP cDSP test APK#20599
psiddh merged 1 commit into
pytorch:mainfrom
psiddh:pr-20057

Conversation

@psiddh

@psiddh psiddh commented Jun 29, 2026

Copy link
Copy Markdown
Contributor

Standalone Android app that tests whether a regular installed app (untrusted_app SELinux domain) can initialize the QNN HTP backend and open FastRPC to the Hexagon cDSP.

Verified working on Galaxy S23 (SM8550, SELinux enforcing). Supports S23/S24/S25 via skels from Maven com.qualcomm.qti:qnn-runtime.

No QNN SDK headers needed — types are inlined, libs loaded via dlopen/dlsym.

Copilot AI review requested due to automatic review settings June 29, 2026 19:09
@pytorch-bot

pytorch-bot Bot commented Jun 29, 2026

Copy link
Copy Markdown

🔗 Helpful Links

🧪 See artifacts and rendered test results at hud.pytorch.org/pr/pytorch/executorch/20599

Note: Links to docs will display an error until the docs builds have been completed.

⏳ No Failures, 1 Pending

As of commit ade215d with merge base b331ebd (image):
💚 Looks good so far! There are no failures yet. 💚

This comment was automatically generated by Dr. CI and updates every 15 minutes.

@meta-cla meta-cla Bot added the CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. label Jun 29, 2026
@github-actions

Copy link
Copy Markdown

This PR needs a release notes: label

If your change should be included in the release notes (i.e. would users of this library care about this change?), please use a label starting with release notes:. This helps us keep track and include your important work in the next release notes.

To add a label, you can comment to pytorchbot, for example
@pytorchbot label "release notes: none"

For more information, see
https://github.com/pytorch/pytorch/wiki/PyTorch-AutoLabel-Bot#why-categorize-for-release-notes-and-how-does-it-work.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a new standalone Android example app under examples/qualcomm/ intended to validate that an installed app in the untrusted_app SELinux domain can load the QNN HTP runtime and successfully open FastRPC to the Hexagon cDSP (via backendCreate()), using dlopen/dlsym and inlined QNN types (no QNN SDK headers).

Changes:

  • Introduces a minimal Android app UI + JNI implementation that loads libQnnHtp.so, queries providers, and calls logCreate()/backendCreate() while logging results to screen/logcat.
  • Adds a self-contained Gradle/NDK/CMake build setup for the APK plus packaging configuration to keep QNN .so debug symbols intact.
  • Documents how to obtain QNN runtime libraries from Maven and bundle them into the APK.

Reviewed changes

Copilot reviewed 12 out of 13 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
examples/qualcomm/qnn-htp-test/settings.gradle Declares a standalone Gradle project for the example app.
examples/qualcomm/qnn-htp-test/README.md Provides setup instructions, expected outcomes, and device notes for the cDSP/FastRPC test.
examples/qualcomm/qnn-htp-test/gradlew Adds the Gradle wrapper script to build the example consistently.
examples/qualcomm/qnn-htp-test/gradle/wrapper/gradle-wrapper.properties Pins the Gradle distribution used by the wrapper.
examples/qualcomm/qnn-htp-test/gradle.properties Enables AndroidX and sets Gradle JVM args.
examples/qualcomm/qnn-htp-test/build.gradle Configures repositories and Android Gradle Plugin dependency.
examples/qualcomm/qnn-htp-test/app/src/main/jni/qnn_test.cpp Implements JNI entrypoint that loads QNN HTP and attempts backendCreate() while logging diagnostic info.
examples/qualcomm/qnn-htp-test/app/src/main/jni/CMakeLists.txt Builds the JNI shared library and links Android log + dl.
examples/qualcomm/qnn-htp-test/app/src/main/java/com/example/qnntest/MainActivity.java Minimal UI to trigger the JNI test and display logs.
examples/qualcomm/qnn-htp-test/app/src/main/AndroidManifest.xml Declares the app and includes uses-native-library for libcdsprpc.so.
examples/qualcomm/qnn-htp-test/app/build.gradle Android build configuration: SDK levels, NDK/CMake setup, arm64-only, JNI libs packaging.
examples/qualcomm/qnn-htp-test/.gitignore Ignores build outputs and downloaded QNN native libraries.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread examples/qualcomm/qnn-htp-test/app/src/main/jni/qnn_test.cpp Outdated
Comment thread examples/qualcomm/qnn-htp-test/app/src/main/jni/qnn_test.cpp Outdated
Comment thread examples/qualcomm/qnn-htp-test/app/src/main/jni/qnn_test.cpp Outdated
Comment thread examples/qualcomm/qnn-htp-test/app/src/main/jni/qnn_test.cpp Outdated
Copilot AI review requested due to automatic review settings June 29, 2026 19:31

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 12 out of 13 changed files in this pull request and generated 3 comments.

Comment thread examples/qualcomm/qnn-htp-test/app/src/main/jni/qnn_test.cpp Outdated
Comment thread examples/qualcomm/qnn-htp-test/app/src/main/jni/qnn_test.cpp Outdated
Comment on lines +1 to +16
buildscript {
repositories {
google()
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:8.5.2'
}
}

allprojects {
repositories {
google()
mavenCentral()
}
}
Copilot AI review requested due to automatic review settings June 29, 2026 19:39

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 12 out of 13 changed files in this pull request and generated 5 comments.

Comment on lines +99 to +103
if (!fmt) return;
char buf[512];
vsnprintf(buf, sizeof(buf), fmt, argp);
LOGI("[QNN-L%u] %s", level, buf);
if (g_log_ptr) *g_log_ptr << " [QNN-L" << level << "] " << buf << "\n";
Comment on lines +126 to +133
// Step 3: Load QNN HTP
void* htpLib = dlopen("libQnnHtp.so", RTLD_NOW | RTLD_LOCAL);
if (!htpLib) {
log_and_append(log, "FAIL: %s", dlerror());
goto done;
}
log_and_append(log, "[3] libQnnHtp.so: LOADED OK");

Comment on lines +193 to +202
if (err == QNN_SUCCESS) {
log_and_append(log, "========================================");
log_and_append(log, "SUCCESS! backendCreate returned 0");
log_and_append(log, "QNN HTP backend created successfully!");
log_and_append(log, "cDSP FastRPC WORKS from untrusted_app.");
log_and_append(log, "========================================");

// Skip cleanup — handle values like 0x1 are sentinels, not heap ptrs.
// Calling backendFree on them crashes. The process is exiting anyway.
} else {
Comment on lines +231 to +233
cleanup:
dlclose(htpLib);
done:
Comment on lines +150 to +154
// Read struct fields
uint32_t backendId = *(const uint32_t*)(iface + 0);
const char* providerName = *(const char**)(iface + 8);
const uint32_t* coreVer = (const uint32_t*)(iface + 16);
const uint32_t* beVer = (const uint32_t*)(iface + 28);
log_and_append(log, "");
log_and_append(log, "[7] Process: pid=%d uid=%d", getpid(), getuid());

std::string skelPath = std::string(nativeLibDir) + "/libQnnHtpV73Skel.so";

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this intended to be hardcoded to V73?

Standalone Android app that tests whether a regular installed app
(untrusted_app SELinux domain) can initialize the QNN HTP backend
and open FastRPC to the Hexagon cDSP.

Verified working on Galaxy S23 (SM8550, SELinux enforcing).
Supports S23/S24/S25 via skels from Maven com.qualcomm.qti:qnn-runtime.

No QNN SDK headers needed — types are inlined, libs loaded via dlopen/dlsym.

Authored with Claude.
Copilot AI review requested due to automatic review settings June 29, 2026 21:40

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 12 out of 13 changed files in this pull request and generated 7 comments.

@@ -0,0 +1,7 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.11.1-bin.zip
Comment on lines +66 to +69
private void appendLog(String msg) {
Log.i(TAG, msg);
logView.append(msg + "\n");
}
Comment on lines +11 to +15
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

Comment on lines +103 to +107
auto getProviders =
(QnnInterfaceGetProvidersFn)dlsym(htpLib, "QnnInterface_getProviders");
const void** providers = nullptr;
uint32_t numProviders = 0;
Qnn_ErrorHandle_t err = getProviders(&providers, &numProviders);
Comment on lines +139 to +145
log_and_append(log, "[5] logCreate (QNN_LOG_LEVEL_ERROR=1) ...");
QnnLogCreateFn logCreate;
memcpy(&logCreate, iface + OFF_LOG_CREATE, sizeof(logCreate));
void* logHandle = nullptr;
err = logCreate(qnnLogCallback, 1, &logHandle);
log_and_append(log, " result: err=%u handle=%p", err, logHandle);

Comment on lines +152 to +159
log_and_append(
log, "[6] backendCreate(logHandle=%p, config=NULL) ...", logHandle);
log_and_append(log, " (This is the call that opens FastRPC to cDSP)");
QnnBackendCreateFn backendCreate;
memcpy(&backendCreate, iface + OFF_BACKEND_CREATE, sizeof(backendCreate));
void* backendHandle = nullptr;
err = backendCreate(logHandle, nullptr, &backendHandle);

Comment on lines +57 to +61
runOnUiThread(() -> {
appendLog(result);
testButton.setEnabled(true);
testButton.setText("Run QNN HTP Test");
});
@psiddh psiddh merged commit 34a83e5 into pytorch:main Jun 29, 2026
192 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants