Skip to content

Commit 925f674

Browse files
authored
Android demo app tutorial fix for XNNPACK and QNN (#2962) (#3027)
Summary: * Update tutorial due to recent changes. * Clean up setup.sh for app helper lib build. Pull Request resolved: #2962 Reviewed By: cccclai Differential Revision: D55951189 Pulled By: kirklandsign fbshipit-source-id: 2c95e8580145b039f503e7cd99a4003867f8dbb0 (cherry picked from commit 26365f1)
1 parent 212e91f commit 925f674

File tree

4 files changed

+69
-62
lines changed

4 files changed

+69
-62
lines changed

examples/demo-apps/android/ExecuTorchDemo/README.md

Lines changed: 45 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ This guide explains how to setup ExecuTorch for Android using a demo app. The ap
1717
* Refer to [Setting up ExecuTorch](https://pytorch.org/executorch/stable/getting-started-setup) to set up the repo and dev environment.
1818
* Download and install [Android Studio and SDK](https://developer.android.com/studio).
1919
* Supported Host OS: CentOS, macOS Ventura (M1/x86_64). See below for Qualcomm HTP specific requirements.
20-
* *Qualcomm HTP Only[^1]:* To build and run on Qualcomm's AI Engine Direct, please follow [Building and Running ExecuTorch with Qualcomm AI Engine Direct Backend](build-run-qualcomm-ai-engine-direct-backend.md) for hardware and software pre-requisites.
20+
* *Qualcomm HTP Only[^1]:* To build and run on Qualcomm's AI Engine Direct, please follow [Building and Running ExecuTorch with Qualcomm AI Engine Direct Backend](build-run-qualcomm-ai-engine-direct-backend.md) for hardware and software pre-requisites. The version we use for this tutorial is 2.19. The chip we use for this tutorial is SM8450.
2121
:::
2222
::::
2323

@@ -39,7 +39,7 @@ We generate the model file for the ExecuTorch runtime in Android Demo App.
3939
For delegating DeepLab v3 to XNNPACK backend, please do the following to export the model:
4040

4141
```bash
42-
export FLATC_EXECUTABLE=$(realpath third-party/flatbuffers/cmake-out/flatc)
42+
export FLATC_EXECUTABLE=$(realpath third-party/flatbuffers/cmake-android-out/flatc)
4343
python3 -m examples.xnnpack.aot_compiler --model_name="dl3" --delegate
4444
mkdir -p examples/demo-apps/android/ExecuTorchDemo/app/src/main/assets/
4545
cp dl3_xnnpack_fp32.pte examples/demo-apps/android/ExecuTorchDemo/app/src/main/assets/
@@ -54,7 +54,7 @@ For delegating to Qualcomm Hexagon NPU, please follow the tutorial [here](build-
5454
After generating the model, copy the model to `assets` directory.
5555

5656
```bash
57-
python -m examples.qualcomm.scripts.deeplab_v3 -b build_android -m SM8550 -s <adb_connected_device_serial>
57+
python -m examples.qualcomm.scripts.deeplab_v3 -b build_android -m SM8450 -s <adb_connected_device_serial>
5858
cp deeplab_v3/dlv3_qnn.pte examples/demo-apps/android/ExecuTorchDemo/app/src/main/assets/
5959
```
6060

@@ -68,22 +68,20 @@ We build the required ExecuTorch runtime library to run the model.
6868

6969
```bash
7070
export ANDROID_NDK=<path-to-android-ndk>
71-
export BUCK2=/tmp/buck2 # Or your buck path
71+
export ANDROID_ABI=arm64-v8a
7272

73-
rm -rf cmake-out && mkdir cmake-out && cd cmake-out
73+
rm -rf cmake-android-out && mkdir cmake-android-out
7474

7575
# Build the core executorch library
76-
cmake .. -DCMAKE_INSTALL_PREFIX=cmake-out \
76+
cmake . -DCMAKE_INSTALL_PREFIX=cmake-android-out \
7777
-DCMAKE_TOOLCHAIN_FILE="${ANDROID_NDK}/build/cmake/android.toolchain.cmake" \
7878
-DANDROID_ABI="${ANDROID_ABI}" \
79-
-DBUCK2="${BUCK2}" \
8079
-DEXECUTORCH_BUILD_XNNPACK=ON \
81-
-DEXECUTORCH_BUILD_FLATC=OFF \
8280
-DEXECUTORCH_BUILD_EXTENSION_DATA_LOADER=ON \
83-
-DFLATC_EXECUTABLE="${FLATC}" \
84-
-DEXECUTORCH_BUILD_EXTENSION_MODULE=ON
81+
-DEXECUTORCH_BUILD_EXTENSION_MODULE=ON \
82+
-Bcmake-android-out
8583

86-
cmake --build . -j16 --target install
84+
cmake --build cmake-android-out -j16 --target install
8785
```
8886

8987
When we set `EXECUTORCH_BUILD_XNNPACK=ON`, we will build the target [`xnnpack_backend`](https://github.com/pytorch/executorch/blob/main/backends/xnnpack/CMakeLists.txt) which in turn is linked into libexecutorch_jni via [CMake](https://github.com/pytorch/executorch/blob/main/examples/demo-apps/android/jni/CMakeLists.txt).
@@ -93,60 +91,63 @@ When we set `EXECUTORCH_BUILD_XNNPACK=ON`, we will build the target [`xnnpack_ba
9391
```bash
9492

9593
# Build the android extension
96-
cmake ../extension/android -DBUCK2="${BUCK2}" \
97-
-DCMAKE_TOOLCHAIN_FILE=${ANDROID_NDK}/build/cmake/android.toolchain.cmake \
94+
cmake extension/android \
95+
-DCMAKE_TOOLCHAIN_FILE="${ANDROID_NDK}"/build/cmake/android.toolchain.cmake \
9896
-DANDROID_ABI="${ANDROID_ABI}" \
99-
-DCMAKE_INSTALL_PREFIX=cmake-out \
100-
-Bextension/android
97+
-DCMAKE_INSTALL_PREFIX=cmake-android-out \
98+
-Bcmake-android-out/extension/android
10199

102-
cmake --build ./extension/android -j16
100+
cmake --build cmake-android-out/extension/android -j16
103101
```
104102

105103
`libexecutorch_jni.so` wraps up the required XNNPACK Backend runtime library from `xnnpack_backend`, and adds an additional JNI layer using fbjni. This is later exposed to Java app.
106104

107105
#### Qualcomm Hexagon NPU
108106

109-
1. Configure the CMake target for the library with Qualcomm Hexagon NPU (HTP) backend (XNNPACK also included):
107+
1. Build the CMake target for the library with Qualcomm Hexagon NPU (HTP) backend (XNNPACK also included):
110108

111109
```bash
112110
export ANDROID_NDK=<path-to-android-ndk>
113-
export QNN_SDK=<path-to-qnn-sdk>
114-
115-
rm -rf cmake-out && mkdir cmake-out && cd cmake-out
116-
cmake .. \
117-
-DCMAKE_TOOLCHAIN_FILE=$ANDROID_NDK/build/cmake/android.toolchain.cmake \
118-
-DANDROID_ABI=arm64-v8a \
119-
-DBUCK2=/tmp/buck2 \
120-
-DEXECUTORCH_BUILD_ANDROID_JNI=ON \
111+
export ANDROID_ABI=arm64-v8a
112+
export QNN_SDK_ROOT=<path-to-qnn-sdk>
113+
114+
rm -rf cmake-android-out && mkdir cmake-android-out && cd cmake-android-out
115+
cmake . -DCMAKE_INSTALL_PREFIX=cmake-android-out \
116+
-DCMAKE_TOOLCHAIN_FILE="${ANDROID_NDK}/build/cmake/android.toolchain.cmake" \
117+
-DANDROID_ABI="${ANDROID_ABI}" \
121118
-DEXECUTORCH_BUILD_XNNPACK=ON \
122-
-DEXECUTORCH_BUILD_FLATC=OFF \
123119
-DEXECUTORCH_BUILD_QNN=ON \
124-
-DQNN_SDK_ROOT=$QNN_SDK \
125-
-DEXECUTORCH_BUILD_EXTENSION_DATA_LOADER=ON
120+
-DQNN_SDK_ROOT="${QNN_SDK_ROOT}" \
121+
-DEXECUTORCH_BUILD_EXTENSION_DATA_LOADER=ON \
122+
-DEXECUTORCH_BUILD_EXTENSION_MODULE=ON \
123+
-Bcmake-android-out
124+
125+
cmake --build cmake-android-out -j16 --target install
126126
```
127127
Similar to the XNNPACK library, with this setup, we compile `libexecutorch_jni.so` but it adds an additional static library `qnn_executorch_backend` which wraps up Qualcomm HTP runtime library and registers the Qualcomm HTP backend. This is later exposed to Java app.
128128

129129
`qnn_executorch_backend` is built when we turn on CMake option `EXECUTORCH_BUILD_QNN`. It will include the [CMakeLists.txt](https://github.com/pytorch/executorch/blob/main/backends/qualcomm/CMakeLists.txt) from backends/qualcomm where we `add_library(qnn_executorch_backend STATIC)`.
130130

131-
2. Build the libraries:
131+
2. Build the Android extension:
132132

133133
```bash
134-
cmake --build . -j16
134+
cmake extension/android \
135+
-DCMAKE_TOOLCHAIN_FILE="${ANDROID_NDK}"/build/cmake/android.toolchain.cmake \
136+
-DANDROID_ABI="${ANDROID_ABI}" \
137+
-DCMAKE_INSTALL_PREFIX=cmake-android-out \
138+
-Bcmake-android-out/extension/android
139+
140+
cmake --build cmake-android-out/extension/android -j16
135141
```
136142

137143
## Deploying on Device via Demo App
138144

139145
### Steps for Deploying Model via XNNPACK
140146

141147
```bash
142-
mkdir -p ../examples/demo-apps/android/ExecuTorchDemo/app/src/main/jniLibs/arm64-v8a
143-
```
144-
145-
Copy the core libraries:
146-
147-
```bash
148-
cp ./examples/demo-apps/android/jni/libexecutorch_jni.so \
149-
../examples/demo-apps/android/ExecuTorchDemo/app/src/main/jniLibs/arm64-v8a/libexecutorch.so
148+
mkdir -p examples/demo-apps/android/ExecuTorchDemo/app/src/main/jniLibs/arm64-v8a
149+
cp cmake-android-out/extension/android/libexecutorch_jni.so \
150+
examples/demo-apps/android/ExecuTorchDemo/app/src/main/jniLibs/arm64-v8a/libexecutorch.so
150151
```
151152

152153
This allows the Android app to load ExecuTorch runtime with XNNPACK backend as a JNI library. Later, this shared library will be loaded by `NativePeer.java` in Java code.
@@ -160,15 +161,17 @@ mkdir -p ../examples/demo-apps/android/ExecuTorchDemo/app/src/main/jniLibs/arm64
160161
We need to push some additional Qualcomm HTP backend libraries to the app. Please refer to [Qualcomm docs](build-run-qualcomm-ai-engine-direct-backend.md) here.
161162

162163
```bash
163-
cp ${QNN_SDK_ROOT}/lib/aarch64-android/libQnnHtp.so ${QNN_SDK_ROOT}/lib/aarch64-android/libQnnHtpV69Skel.so ${QNN_SDK_ROOT}/lib/aarch64-android/libQnnHtpStub.so ${QNN_SDK_ROOT}/lib/aarch64-android/libQnnSystem.so \
164-
../examples/demo-apps/android/ExecuTorchDemo/app/src/main/jniLibs/arm64-v8a
164+
cp ${QNN_SDK_ROOT}/lib/aarch64-android/libQnnHtp.so ${QNN_SDK_ROOT}/lib/hexagon-v69/unsigned/libQnnHtpV69Skel.so ${QNN_SDK_ROOT}/lib/aarch64-android/libQnnHtpV69Stub.so ${QNN_SDK_ROOT}/lib/aarch64-android/libQnnSystem.so \
165+
examples/demo-apps/android/ExecuTorchDemo/app/src/main/jniLibs/arm64-v8a
165166
```
166167

167168
Copy the core libraries:
168169

169170
```bash
170-
cp ./examples/demo-apps/android/jni/libexecutorch_jni.so \
171-
../examples/demo-apps/android/ExecuTorchDemo/app/src/main/jniLibs/arm64-v8a/libexecutorch.so
171+
cp cmake-android-out/extension/android/libexecutorch_jni.so \
172+
examples/demo-apps/android/ExecuTorchDemo/app/src/main/jniLibs/arm64-v8a/libexecutorch.so
173+
cp cmake-android-out/lib/libqnn_executorch_backend.so \
174+
examples/demo-apps/android/ExecuTorchDemo/app/src/main/jniLibs/arm64-v8a/libqnn_executorch_backend.so
172175
```
173176

174177
## Running the App

examples/demo-apps/android/ExecuTorchDemo/app/build.gradle.kts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,3 +68,12 @@ dependencies {
6868
debugImplementation("androidx.compose.ui:ui-tooling")
6969
debugImplementation("androidx.compose.ui:ui-test-manifest")
7070
}
71+
72+
tasks.register("setup") {
73+
doFirst {
74+
exec {
75+
commandLine("sh", "examples/demo-apps/android/LlamaDemo/setup.sh")
76+
workingDir("../../../../../")
77+
}
78+
}
79+
}
Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,40 @@
11
#!/usr/bin/env bash
2+
# Copyright (c) Meta Platforms, Inc. and affiliates.
23
# All rights reserved.
34
#
4-
# Copyright 2023-2024 Arm Limited and/or its affiliates.
5-
#
65
# This source code is licensed under the BSD-style license found in the
76
# LICENSE file in the root directory of this source tree.
87

98
set -eu
109

11-
# Note: Set up ANDROID_NDK, ANDROID_ABI, BUCK2, and FLATC
12-
cmake . -DCMAKE_INSTALL_PREFIX=cmake-out \
10+
CMAKE_OUT="${CMAKE_OUT:-cmake-out-android}"
11+
# Note: Set up ANDROID_NDK and ANDROID_ABI
12+
cmake . -DCMAKE_INSTALL_PREFIX="${CMAKE_OUT}" \
1313
-DCMAKE_TOOLCHAIN_FILE="${ANDROID_NDK}/build/cmake/android.toolchain.cmake" \
1414
-DANDROID_ABI="${ANDROID_ABI}" \
15-
-DBUCK2="${BUCK2}" \
1615
-DEXECUTORCH_BUILD_XNNPACK=ON \
17-
-DEXECUTORCH_BUILD_FLATC=OFF \
1816
-DEXECUTORCH_BUILD_EXTENSION_DATA_LOADER=ON \
19-
-DFLATC_EXECUTABLE="${FLATC}" \
2017
-DEXECUTORCH_BUILD_EXTENSION_MODULE=ON \
21-
-Bcmake-out
18+
-DEXECUTORCH_BUILD_OPTIMIZED=ON \
19+
-DCMAKE_BUILD_TYPE=Release \
20+
-B"${CMAKE_OUT}"
2221

2322
if [ "$(uname)" == "Darwin" ]; then
2423
CMAKE_JOBS=$(( $(sysctl -n hw.ncpu) - 1 ))
2524
else
2625
CMAKE_JOBS=$(( $(nproc) - 1 ))
2726
fi
28-
cmake --build cmake-out -j "${CMAKE_JOBS}" --target install
27+
cmake --build "${CMAKE_OUT}" -j "${CMAKE_JOBS}" --target install --config Release
2928

30-
cmake extension/android -DBUCK2="${BUCK2}" \
29+
cmake extension/android \
3130
-DCMAKE_TOOLCHAIN_FILE=${ANDROID_NDK}/build/cmake/android.toolchain.cmake \
3231
-DANDROID_ABI="${ANDROID_ABI}" \
33-
-DCMAKE_INSTALL_PREFIX=cmake-out \
34-
-Bcmake-out/extension/android
32+
-DCMAKE_INSTALL_PREFIX="${CMAKE_OUT}" \
33+
-DCMAKE_BUILD_TYPE=Release \
34+
-B"${CMAKE_OUT}"/extension/android
3535

36-
cmake --build cmake-out/extension/android -j "${CMAKE_JOBS}"
36+
cmake --build "${CMAKE_OUT}"/extension/android -j "${CMAKE_JOBS}" --config Release
3737

3838
JNI_LIBS_PATH="examples/demo-apps/android/ExecuTorchDemo/app/src/main/jniLibs"
3939
mkdir -p "${JNI_LIBS_PATH}/${ANDROID_ABI}"
40-
cp cmake-out/extension/android/libexecutorch_jni.so "${JNI_LIBS_PATH}/${ANDROID_ABI}/libexecutorch.so"
40+
cp "${CMAKE_OUT}"/extension/android/libexecutorch_jni.so "${JNI_LIBS_PATH}/${ANDROID_ABI}/"

extension/android/CMakeLists.txt

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -58,14 +58,9 @@ if(EXECUTORCH_BUILD_LLAMA_JNI)
5858
add_library(llama_runner STATIC IMPORTED)
5959
set_property(TARGET llama_runner PROPERTY IMPORTED_LOCATION ${LLAMA_RUNNER_PATH})
6060

61-
set(CUSTOM_OPS_LIB_PATH ${CMAKE_CURRENT_BINARY_DIR}/../../examples/models/llama2/custom_ops/libcustom_ops_lib.a)
62-
add_library(custom_ops_lib STATIC IMPORTED)
63-
set_property(TARGET custom_ops_lib PROPERTY IMPORTED_LOCATION ${CUSTOM_OPS_LIB_PATH})
64-
6561
set(CUSTOM_OPS_PATH ${CMAKE_CURRENT_BINARY_DIR}/../../examples/models/llama2/custom_ops/libcustom_ops.a)
6662
add_library(custom_ops STATIC IMPORTED)
6763
set_property(TARGET custom_ops PROPERTY IMPORTED_LOCATION ${CUSTOM_OPS_PATH})
68-
target_link_options_shared_lib(custom_ops_lib)
6964

7065
if(TARGET pthreadpool)
7166
set(LLAMA_JNI_SRCS jni/jni_layer_llama.cpp ../../backends/xnnpack/threadpool/cpuinfo_utils.cpp)
@@ -82,6 +77,6 @@ if(EXECUTORCH_BUILD_LLAMA_JNI)
8277
endif()
8378
target_include_directories(executorch_llama_jni PRIVATE ${_common_include_directories})
8479
target_link_libraries(executorch_llama_jni ${link_libraries} llama_runner
85-
custom_ops custom_ops_lib cpublas eigen_blas)
80+
custom_ops cpublas eigen_blas)
8681
target_compile_options(executorch_llama_jni PUBLIC ${_common_compile_options})
8782
endif()

0 commit comments

Comments
 (0)