# Tutorial: Executing a shallow model using custom op package

The following tutorial will demonstrate the use of the QNN API and
QNN tools with an example Op Package. The simulated workflow will use
a shallow network as the model and Relu as an example operation.

The tutorial will use an example shallow network model,
and execute the model using the C++ application general/tools:qnn-net-run.
The execution will show usage on the CPU, GPU, HTP and DSP backends on both host (for CPU)
and device.

The sections of the tutorial are as follows:

1. [Tutorial Setup](https://docs.qualcomm.com/doc/80-63442-10/topic/tutorial1.html#tutorial-setup)
2. [Building Example Op Package](https://docs.qualcomm.com/doc/80-63442-10/topic/tutorial1.html#building-example-op-package)
3. [Building Example Model](https://docs.qualcomm.com/doc/80-63442-10/topic/tutorial1.html#building-example-model)
4. [Executing Example Model](https://docs.qualcomm.com/doc/80-63442-10/topic/tutorial1.html#executing-example-model)

## Tutorial Setup

The tutorial assumes general setup instructions have been followed
at [Setup](https://docs.qualcomm.com/doc/80-63442-10/topic/general_setup.html).

## Building Example Op Package

Sources for an example Op Package, containing the Relu operation, are present for
the CPU, GPU, DSP, and HTP backend.
Each backend has different requirements for building the
Op Package consumable by `qnn-net-run`.

### Compiling for CPU Backend

The CPU Backend Example Op Package is located at:

${QNN_SDK_ROOT}/examples/QNN/OpPackage/CPU
    Copy to clipboard

Building the example Op Package for CPU by default builds
for Linux x86-64 and Android architectures, and has a dependency on the Android NDK Toolchain.
Ensure that `ANDROID_NDK_ROOT` is set. See [Setup](https://docs.qualcomm.com/doc/80-63442-10/topic/general_setup.html) for more information.

To build the example Op Package for CPU:

$ cd ${QNN_SDK_ROOT}/examples/QNN/OpPackage/CPU
    $ make
    Copy to clipboard

This will produce the artifact(s):

- ${QNN\_SDK\_ROOT}/examples/QNN/OpPackage/CPU/libs/&lt;target&gt;/libQnnCpuOpPackageExample.so

Note

The desired architecture can be specified using provided make targets:
cpu\_aarch64-android, cpu\_x86

Note

To compile for only Linux x86-64 architectures replace the command
“make” with “make cpu\_x86”. To compile for only Android architectures replace
the command “make” with “make cpu\_android”.

### Compiling for GPU Backend

The GPU Backend example Op Package is located at:

${QNN_SDK_ROOT}/examples/QNN/OpPackage/GPU
    Copy to clipboard

Compilation of the GPU Op Package has a dependency
on the Android NDK Toolchain. Ensure that `ANDROID_NDK_ROOT` is set.
See [Setup](https://docs.qualcomm.com/doc/80-63442-10/topic/general_setup.html) for more information.

To compile the example GPU Op Package

$ cd ${QNN_SDK_ROOT}/examples/QNN/OpPackage/GPU
    $ make
    Copy to clipboard

This will produce artifact(s):

- ${QNN\_SDK\_ROOT}/examples/QNN/OpPackage/GPU/libs/&lt;target&gt;/libQnnGpuOpPackageExample.so

### Compiling for HTP Backend

The HTP Backend Example Op Package is located at:

${QNN_SDK_ROOT}/examples/QNN/OpPackage/HTP
    Copy to clipboard

#### HTP Emulation x86 Compilation

Compiling the example Op Package for the HTP emulation has dependencies on
clang++ and the Hexagon SDK.

$ export X86_CXX=<path-to-clang++>
    $ export HEXAGON_SDK_ROOT=<path-to-hexagon-sdk>
    $ export QNN_INCLUDE=${QNN_SDK_ROOT}/include/QNN
    Copy to clipboard

To compile the example HTP Emulation Op Package for use on the Linux x86-64 architecture:

$ cd ${QNN_SDK_ROOT}/examples/QNN/OpPackage/HTP
    $ make htp_x86
    Copy to clipboard

This will produce the artifact(s):

- ${QNN\_SDK\_ROOT}/examples/QNN/OpPackage/HTP/build/x86\_64-linux-clang/libQnnHtpOpPackageExample.so

#### HTP Hexagon V68 Compilation

Compiling the example Op Package for the HTP Hexagon V68 has dependencies on
Hexagon SDK.

$ export HEXAGON_SDK_ROOT=<path-to-hexagon-sdk>
    $ export QNN_INCLUDE=${QNN_SDK_ROOT}/include/QNN
    Copy to clipboard

To compile the example HTP Op Package for use on the Hexagon V68 architecture:

$ cd ${QNN_SDK_ROOT}/examples/QNN/OpPackage/HTP
    $ make htp_v68
    Copy to clipboard

This will produce the artifact(s):

- ${QNN\_SDK\_ROOT}/examples/QNN/OpPackage/HTP/build/hexagon-v68/libQnnHtpOpPackageExample.so

#### HTP ARM Compilation

Compiling the example Op Package for the HTP Hexagon V68 has dependencies on
Android NDK.

$ export ANDROID_NDK_ROOT=<path-to-android-ndk>
    $ export QNN_INCLUDE=${QNN_SDK_ROOT}/include/QNN
    Copy to clipboard

To compile the example HTP Op Package for use on the Android ARM architecture:

$ cd ${QNN_SDK_ROOT}/examples/QNN/OpPackage/HTP
    $ make htp_aarch64
    Copy to clipboard

This will produce the artifact(s):

- ${QNN\_SDK\_ROOT}/examples/QNN/OpPackage/HTP/build/aarch64-android/libQnnHtpOpPackageExample.so

### Compiling for DSP Backend

The DSP Backend Example Op Package is located at:

${QNN_SDK_ROOT}/examples/QNN/OpPackage/DSP
    Copy to clipboard

Compiling the example Op Package for the DSP has dependencies on Hexagon SDK.

$ export HEXAGON_SDK_ROOT=<path-to-hexagon-sdk>
    $ export QNN_SDK_ROOT=${QNN_SDK_ROOT}
    Copy to clipboard

To compile the example DSP Op Package:

$ cd ${QNN_SDK_ROOT}/examples/QNN/OpPackage/DSP
    $ make
    Copy to clipboard

This will produce the artifact(s):

- ${QNN\_SDK\_ROOT}/examples/QNN/OpPackage/DSP/build/DSP/libQnnDspOpPackageExample.so

## Building Example Model

The shallow model in this tutorial is post-use of the QNN Converter.
Information on the QNN converter can be found on the [Tools](https://docs.qualcomm.com/doc/80-63442-10/topic/general_tools.html) page.

The model is located at:

${QNN_SDK_ROOT}/examples/QNN/converter/models/qnn_model_float.cpp
    Copy to clipboard

Additionally, for the HTP and DSP backend there is a quantized model

${QNN_SDK_ROOT}/examples/QNN/converter/models/qnn_model_8bit_quantized.cpp
    Copy to clipboard

The remainder of the tutorial will use qnn\_model\_float.cpp. For the quantized model
replace qnn\_model\_float.cpp with qnn\_model\_8bit\_quantized.cpp and qnn\_model\_float.bin with
qnn\_model\_8bit\_quantized.bin.

In order to use the example Op Package, instead of QNN’s default Op Package, the
model must be manually edited to refer to the example. The process is outlined here:

$ vim ${QNN_SDK_ROOT}/examples/QNN/converter/models/qnn_model_float.cpp
    Copy to clipboard

Before:

242   VALIDATE(convReluModel.addNode(
    243                QNN_OPCONFIG_VERSION_1,                              // Op_Config_t Version
    244                "InceptionV3_InceptionV3_Conv2d_1a_3x3_Relu",        // Node Name
    245                "qti.aisw",                                          // Package Name Default
    Copy to clipboard

After:

242   VALIDATE(convReluModel.addNode(
    243                QNN_OPCONFIG_VERSION_1,                             // Op_Config_t Version
    244                "InceptionV3_InceptionV3_Conv2d_1a_3x3_Relu",       // Node Name
    245                "examples.OpPackage",                               // Package Name To Change
    Copy to clipboard

After the appropriate Op Package name has been populated, the model can
be built for the desired target using `qnn-model-lib-generator`. Before
generating the model, ensure `ANDROID_NDK_ROOT` is set. See [Setup](https://docs.qualcomm.com/doc/80-63442-10/topic/general_setup.html)
for more information.

To build the model use:

$ ${QNN_SDK_ROOT}/bin/x86_64-linux-clang/qnn-model-lib-generator \
      -c ${QNN_SDK_ROOT}/examples/QNN/converter/models/qnn_model_float.cpp \
      -b ${QNN_SDK_ROOT}/examples/QNN/converter/models/qnn_model_float.bin \
      -o ${QNN_SDK_ROOT}/examples/QNN/example_libs # This can be any path
    Copy to clipboard

This will produce the following artifact(s):

- ${QNN\_SDK\_ROOT}/examples/QNN/example\_libs/&lt;target&gt;/libqnn\_model\_float.so

Note

Any output path can be used with the -o flag. The remainder of this tutorial
will use ${QNN\_SDK\_ROOT}/examples/QNN/example\_libs to refer to the directory containing model
libraries.

## CPU Backend Execution

### Running CPU Backend on Linux x86

With the libraries discoverable, `qnn-net-run` is used with the following:

$ cd ${QNN_SDK_ROOT}/examples/QNN/converter/models # access input data
    $ ${QNN_SDK_ROOT}/bin/x86_64-linux-clang/qnn-net-run \
                  --backend ${QNN_SDK_ROOT}/lib/x86_64-linux-clang/libQnnCpu.so \
                  --model ${QNN_SDK_ROOT}/examples/QNN/example_libs/x86_64-linux-clang/libqnn_model_float.so \
                  --input_list ${QNN_SDK_ROOT}/examples/QNN/converter/models/input_list_float.txt \
                  --op_packages ${QNN_SDK_ROOT}/examples/QNN/OpPackage/CPU/libs/x86_64-linux-clang/libQnnCpuOpPackageExample.so:QnnOpPackage_interfaceProvider
    Copy to clipboard

Outputs from the run will be located at the default ./output directory.

Note

If full paths are not given to `qnn-net-run`, all libraries must be added to
LD\_LIBRARY\_PATH and be discoverable by the system library loader.

### Running CPU Backend on Android

Running the CPU Backend on an Android target is largely
similar to running on the Linux x86 target.

First, create a directory for the example on device:

# make oppackage if necessary
    $ adb shell "mkdir /data/local/tmp/oppackage"
    $ adb shell "mkdir /data/local/tmp/oppackage/CPU"
    Copy to clipboard

Now push the necessary libraries to device:

$ adb push ${QNN_SDK_ROOT}/lib/aarch64-android/libQnnCpu.so /data/local/tmp/oppackage/CPU
    $ adb push ${QNN_SDK_ROOT}/examples/QNN/OpPackage/CPU/libs/aarch64-android/libQnnCpuOpPackageExample.so /data/local/tmp/oppackage/CPU
    $ adb push ${QNN_SDK_ROOT}/examples/QNN/example_libs/aarch64-android/*.so /data/local/tmp/oppackage/CPU
    Copy to clipboard

Now push the input data and input lists to device:

$ adb push ${QNN_SDK_ROOT}/examples/QNN/converter/models/input_data_float /data/local/tmp/oppackage/CPU
    $ adb push ${QNN_SDK_ROOT}/examples/QNN/converter/models/input_list_float.txt /data/local/tmp/oppackage/CPU
    Copy to clipboard

Push the `qnn-net-run` tool:

$ adb push ${QNN_SDK_ROOT}/bin/aarch64-android/qnn-net-run /data/local/tmp/oppackage/CPU
    Copy to clipboard

Now set up the environment on device:

$ adb shell
    $ cd /data/local/tmp/oppackage/CPU
    $ export LD_LIBRARY_PATH=/data/local/tmp/oppackage/CPU
    Copy to clipboard

Finally, use `qnn-net-run` with the following:

$ ./qnn-net-run --backend libQnnCpu.so --model libqnn_model_float.so --input_list input_list_float.txt --op_packages libQnnCpuOpPackageExample.so:QnnOpPackage_interfaceProvider
    Copy to clipboard

Outputs from the run will be located at the default ./output directory.

## GPU Backend Execution

### Running GPU Backend on Android

Running the GPU Backend on an Android target is largely
similar to running CPU Backend on Android.

First, create a directory for the example on device:

# make oppackage if necessary
    $ adb shell "mkdir /data/local/tmp/oppackage"
    $ adb shell "mkdir /data/local/tmp/oppackage/GPU"
    Copy to clipboard

Now push the necessary libraries to device:

$ adb push ${QNN_SDK_ROOT}/lib/aarch64-android/libQnnGpu.so /data/local/tmp/oppackage/GPU
    $ adb push ${QNN_SDK_ROOT}/examples/QNN/OpPackage/GPU/libs/aarch64-android/libQnnGpuOpPackageExample.so /data/local/tmp/oppackage/GPU
    $ adb push ${QNN_SDK_ROOT}/examples/QNN/example_libs/aarch64-android/*.so /data/local/tmp/oppackage/GPU
    Copy to clipboard

Now push the input data and input lists to device:

$ adb push ${QNN_SDK_ROOT}/examples/QNN/converter/models/input_data_float /data/local/tmp/oppackage/GPU
    $ adb push ${QNN_SDK_ROOT}/examples/QNN/converter/models/input_list_float.txt /data/local/tmp/oppackage/GPU
    Copy to clipboard

Push the `qnn-net-run` tool:

$ adb push ${QNN_SDK_ROOT}/bin/aarch64-android/qnn-net-run /data/local/tmp/oppackage/GPU
    Copy to clipboard

Now set up the environment on device:

$ adb shell
    $ cd /data/local/tmp/oppackage/GPU
    $ export LD_LIBRARY_PATH=/data/local/tmp/oppackage/GPU
    Copy to clipboard

Finally, use `qnn-net-run` with the following:

$ ./qnn-net-run --backend libQnnGpu.so --model libqnn_model_float.so --input_list input_list_float.txt --op_packages libQnnGpuOpPackageExample.so:QnnOpPackage_interfaceProvider
    Copy to clipboard

Outputs from the run will be located at the default ./output directory.

## HTP Backend Execution

### Running HTP Emulation Backend on Linux x86

With the appropriate libraries compiled, `qnn-net-run` is used with the following:

$ cd ${QNN_SDK_ROOT}/examples/QNN/converter/models
    $ ${QNN_SDK_ROOT}/bin/x86_64-linux-clang/qnn-net-run \
                  --backend ${QNN_SDK_ROOT}/lib/x86_64-linux-clang/libQnnHtp.so \
                  --model ${QNN_SDK_ROOT}/examples/QNN/example_libs/x86_64-linux-clang/libqnn_model_8bit_quantized.so \
                  --input_list ${QNN_SDK_ROOT}/examples/QNN/converter/models/input_list_float.txt \
                  --op_packages ${QNN_SDK_ROOT}/examples/QNN/OpPackage/HTP/build/x86_64-linux-clang/libQnnHtpOpPackageExample.so:exampleInterfaceProvider
    Copy to clipboard

Outputs from the run will be located at the default ./output directory.

Note

If full paths are not given to `qnn-net-run`, all libraries must be added to
LD\_LIBRARY\_PATH and be discoverable by the system library loader.

### Running HTP Backend on Android using offline prepared graph

Running the HTP Backend on an Android target is largely similar to running CPU and GPU Backend.
In this tutorial, we first prepare the graph on x86 host, then pass the serialized context binary to the device
HTP Backend to execute. To run the graph on the HTP backend,
the aarch64 version of the OpPackage is needed in addition to the hexagon-v68 version.

Additionally, running the HTP on device can be done with
the generation of a serialized context. This serialized context can be
initialized more efficiently by HTP compared to the original libqnn\_model\_8bit\_quantized.so model.
To generate the context, run:

$ ${QNN_SDK_ROOT}/bin/x86_64-linux-clang/qnn-context-binary-generator \
                  --backend ${QNN_SDK_ROOT}/lib/x86_64-linux-clang/libQnnHtp.so \
                  --model ${QNN_SDK_ROOT}/examples/QNN/example_libs/x86_64-linux-clang/libqnn_model_8bit_quantized.so \
                  --op_packages ${QNN_SDK_ROOT}/examples/QNN/OpPackage/HTP/build/x86_64-linux-clang/libQnnHtpOpPackageExample.so:exampleInterfaceProvider
                  --binary_file qnn_model_8bit_quantized.serialized
    Copy to clipboard

This creates the context at:

- `./output/qnn_model_8bit_quantized.serialized.bin`

First, create a directory for the example on device:

# make oppackage if necessary
    $ adb shell "mkdir /data/local/tmp/oppackage"
    $ adb shell "mkdir /data/local/tmp/oppackage/HTP"
    Copy to clipboard

Now push the necessary libraries to device:

$ adb push ${QNN_SDK_ROOT}/lib/aarch64-android/libQnnHtp.so /data/local/tmp/oppackage/HTP
    $ adb push ${QNN_SDK_ROOT}/lib/aarch64-android/libQnnHtpPrepare.so /data/local/tmp/oppackage/HTP
    $ adb push ${QNN_SDK_ROOT}/lib/aarch64-android/libQnnHtpV68Stub.so /data/local/tmp/oppackage/HTP
    $ adb push ${QNN_SDK_ROOT}/examples/QNN/OpPackage/HTP/build/hexagon-v68/libQnnHtpOpPackageExample.so /data/local/tmp/oppackage/HTP
    $ adb push ${QNN_SDK_ROOT}/examples/QNN/OpPackage/HTP/build/aarch64-android/libQnnHtpOpPackageExample.so /data/local/tmp/oppackage/HTP/libQnnHtpOpPackageExample_Cpu.so
    $ adb push ${QNN_SDK_ROOT}/examples/QNN/example_libs/aarch64-android/*.so /data/local/tmp/oppackage/HTP
    $ adb push ./output/qnn_model_8bit_quantized.serialized.bin /data/local/tmp/oppackage/HTP
    $ # Additionally, the HTP requires Hexagon specific libraries
    $ adb push ${QNN_SDK_ROOT}/lib/hexagon-v68/unsigned/libQnnHtpV68Skel.so /data/local/tmp/oppackage/HTP
    Copy to clipboard

Now push the input data and input lists to device:

$ adb push ${QNN_SDK_ROOT}/examples/QNN/converter/models/input_data_float /data/local/tmp/oppackage/HTP
    $ adb push ${QNN_SDK_ROOT}/examples/QNN/converter/models/input_list_float.txt /data/local/tmp/oppackage/HTP
    Copy to clipboard

Push the `qnn-net-run` tool:

$ adb push ${QNN_SDK_ROOT}/bin/aarch64-android/qnn-net-run /data/local/tmp/oppackage/HTP
    Copy to clipboard

Now set up the environment on device:

$ adb shell
    $ cd /data/local/tmp/oppackage/HTP
    $ export LD_LIBRARY_PATH=/data/local/tmp/oppackage/HTP
    $ export ADSP_LIBRARY_PATH="/data/local/tmp/oppackage/HTP"
    Copy to clipboard

Finally, use `qnn-net-run` with the following:

$ ./qnn-net-run --backend libQnnHtp.so --retrieve_context qnn_model_8bit_quantized.serialized.bin --input_list input_list_float.txt --op_packages libQnnHtpOpPackageExample_Cpu.so:exampleInterfaceProvider:CPU,libQnnHtpOpPackageExample_Htp.so:exampleInterfaceProvider:HTP
    Copy to clipboard

In this case two op packages are passed to qnn-net-run.  The first one,
libQnnHtpOpPackageExample\_Cpu.so, is the ARM aarch64 build of the op package. The second op package,
libQnnHtpOpPackageExample\_Htp.so, is the hexagon v68 build of the same op package.
“:CPU” and “:HTP” are the optional target parameters specifying the target platforms on which
the backend must register the op packages. The “CPU” target indicates that the op package
is compiled for CPU (ARM aarch64).
The “HTP” target indicates that the op package is compiled for HTP on-device.

### Running HTP Backend on Android using on-device prepared graph

In this tutorial we prepare the model on the Android ARM (CPU) side.

First, create a directory for the example on device:

# make oppackage if necessary
    $ adb shell "mkdir /data/local/tmp/oppackage"
    $ adb shell "mkdir /data/local/tmp/oppackage/HTP"
    Copy to clipboard

Now push the necessary libraries to device:

$ adb push ${QNN_SDK_ROOT}/lib/aarch64-android/libQnnHtp.so /data/local/tmp/oppackage/HTP
    $ adb push ${QNN_SDK_ROOT}/lib/aarch64-android/libQnnHtpPrepare.so /data/local/tmp/oppackage/HTP
    $ adb push ${QNN_SDK_ROOT}/lib/aarch64-android/libQnnHtpV68Stub.so /data/local/tmp/oppackage/HTP
    $ adb push ${QNN_SDK_ROOT}/examples/QNN/OpPackage/HTP/build/hexagon-v68/libQnnHtpOpPackageExample.so /data/local/tmp/oppackage/HTP/libQnnHtpOpPackageExample_Htp.so
    $ adb push ${QNN_SDK_ROOT}/examples/QNN/OpPackage/HTP/build/aarch64-android/libQnnHtpOpPackageExample.so /data/local/tmp/oppackage/HTP/libQnnHtpOpPackageExample_Cpu.so
    $ adb push ${QNN_SDK_ROOT}/examples/QNN/example_libs/aarch64-android/*.so /data/local/tmp/oppackage/HTP
    $ # Additionally, the HTP requires Hexagon specific libraries
    $ adb push ${QNN_SDK_ROOT}/lib/hexagon-v68/unsigned/libQnnHtpV68Skel.so /data/local/tmp/oppackage/HTP
    Copy to clipboard

Now push the input data and input lists to device:

$ adb push ${QNN_SDK_ROOT}/examples/QNN/converter/models/input_data_float /data/local/tmp/oppackage/HTP
    $ adb push ${QNN_SDK_ROOT}/examples/QNN/converter/models/input_list_float.txt /data/local/tmp/oppackage/HTP
    Copy to clipboard

Push the `qnn-net-run` tool:

$ adb push ${QNN_SDK_ROOT}/bin/aarch64-android/qnn-net-run /data/local/tmp/oppackage/HTP
    Copy to clipboard

Now set up the environment on device:

$ adb shell
    $ cd /data/local/tmp/oppackage/HTP
    $ export LD_LIBRARY_PATH=/data/local/tmp/oppackage/HTP
    $ export ADSP_LIBRARY_PATH="/data/local/tmp/oppackage/HTP"
    Copy to clipboard

Finally, use `qnn-net-run` with the following:

$ ./qnn-net-run --backend libQnnHtp.so --model libqnn_model_8bit_quantized.so --input_list input_list_float.txt --op_packages libQnnHtpOpPackageExample_Cpu.so:exampleInterfaceProvider:CPU,libQnnHtpOpPackageExample_Htp.so:exampleInterfaceProvider:HTP
    Copy to clipboard

In this case two op packages are passed to qnn-net-run.  The first one,
libQnnHtpOpPackageExample\_Cpu.so, is the ARM aarch64 build of the op package. The second op package,
libQnnHtpOpPackageExample\_Htp.so, is the hexagon v68 build of the same op package.
“:CPU” and “:HTP” are the optional target parameters specifying the target platforms on which
the backend must register the op packages. The “CPU” target indicates that the op package
is compiled for CPU (ARM aarch64).
The “HTP” target indicates that the op package is compiled for HTP on-device.

## DSP Backend Execution

### Running DSP Backend on Android

Running the DSP Backend on an Android target is largely
similar to running HTP Backend on the Android. And the
following assumes running on Hexagon DSP v66 device.

First, create a directory for the example on device:

# make oppackage if necessary
    $ adb shell "mkdir /data/local/tmp/oppackage"
    $ adb shell "mkdir /data/local/tmp/oppackage/DSP"
    Copy to clipboard

Now push the necessary libraries to device:

$ adb push ${QNN_SDK_ROOT}/lib/aarch64-android/libQnnDsp.so /data/local/tmp/oppackage/DSP
    $ adb push ${QNN_SDK_ROOT}/lib/aarch64-android/libQnnDspV66Stub.so /data/local/tmp/oppackage/DSP
    $ adb push ${QNN_SDK_ROOT}/examples/QNN/OpPackage/DSP/build/DSP/libQnnDspOpPackageExample.so /data/local/tmp/oppackage/DSP
    $ adb push ${QNN_SDK_ROOT}/examples/QNN/example_libs/aarch64-android/*.so /data/local/tmp/oppackage/DSP
    $ adb push ${QNN_SDK_ROOT}/examples/QNN/example_libs/aarch64-android/libqnn_model_8bit_quantized.so /data/local/tmp/oppackage/DSP
    $ # Additionally, the DSP requires Hexagon specific libraries
    $ adb push ${QNN_SDK_ROOT}/lib/hexagon-v66/unsigned/libQnnDspV66Skel.so /data/local/tmp/oppackage/DSP
    Copy to clipboard

Now push the input data and input lists to device:

$ adb push ${QNN_SDK_ROOT}/examples/QNN/converter/models/input_data_float /data/local/tmp/oppackage/DSP
    $ adb push ${QNN_SDK_ROOT}/examples/QNN/converter/models/input_list_float.txt /data/local/tmp/oppackage/DSP
    Copy to clipboard

Push the `qnn-net-run` tool:

$ adb push ${QNN_SDK_ROOT}/bin/aarch64-android/qnn-net-run /data/local/tmp/oppackage/DSP
    Copy to clipboard

Now set up the environment on device:

$ adb shell
    $ cd /data/local/tmp/oppackage/DSP
    $ export VENDOR_LIB=/vendor/lib/ # /vendor/lib64/ if aarch64
    $ export LD_LIBRARY_PATH=/data/local/tmp/oppackage/DSP:/vendor/dsp/cdsp:$VENDOR_LIB
    $ export ADSP_LIBRARY_PATH="/data/local/tmp/oppackage/DSP;/vendor/dsp/cdsp;/vendor/lib/rfsa/adsp;/system/lib/rfsa/adsp;/dsp"
    Copy to clipboard

Finally, use `qnn-net-run` with the following:

$ ./qnn-net-run --backend libQnnDsp.so --model libqnn_model_8bit_quantized.so --input_list input_list_float.txt --op_packages libQnnDspOpPackageExample.so:ExampleReluPackageInterfaceProvider
    Copy to clipboard

Last Published: Jun 04, 2026

[Previous Topic
QNN HTP Shared Buffer Tutorial](https://docs.qualcomm.com/bundle/publicresource/80-63442-10/topics/htp_shared_buffer_tutorial.md) [Next Topic
Tutorial: Converting and executing a CNN model with custom operations](https://docs.qualcomm.com/bundle/publicresource/80-63442-10/topics/general_tutorial3.md)