# Saver Tutorial: Save execution sequence with Saver and replay on a backend This tutorial describes how to use the QNN Saver backend to capture the execution sequence of QNN APIs. The captured output can then be compiled and replayed on any QNN backend. ## Linux ### Generating saver\_output.c saver\_output.c is an artifact produced by running a model on the Saver backend. A model in a source framework can be converted into a `model.cpp` and `model.bin` using the [QNN Converters](https://docs.qualcomm.com/doc/80-63442-50/topic/converters.html). Sample `model.cpp` and `model.bin` files are located in `${QNN_SDK_ROOT}/examples/QNN/converter/models/`. `model.cpp` and `model.bin` are used to create a `model.so` via `qnn-model-lib-generator`. $ ${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/converter/model_libs # This can be any path Copy to clipboard This will produce the following artifacts: - `${QNN_SDK_ROOT}/examples/QNN/converter/model_libs/aarch64-android/libqnn_model_float.so` - `${QNN_SDK_ROOT}/examples/QNN/converter/model_libs/x86_64-linux-clang/libqnn_model_float.so` The resulting `model.so` can be run on the Saver backend using `qnn-net-run`: $ 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/libQnnSaver.so \ --model ${QNN_SDK_ROOT}/examples/QNN/converter/model_libs/x86_64-linux-clang/libqnn_model_float.so \ --input_list input_list_float.txt Copy to clipboard This will produce the following artifacts: - `./saver_output/saver_output.c` - `./saver_output/params.bin` See Tutorial: Converting and executing a CNN model with QNN for more information on converting a model from a source framework into the QNN shared library format. Alternatively, the following script performs the steps described above and can be used for convenience. $ cd ${QNN_SDK_ROOT}/examples/QNN/NetRun/linux-x86_64 $ ./linux-qnn-net-run.sh -b saver Copy to clipboard This will produce a quantized `saver_output.c` and `params.bin` in `${QNN_SDK_ROOT}/examples/QNN/NetRun/linux-x86_64/saver_output/quantized/` for replay on DSP or HTP backends, and a non-quantized `saver_output.c` and `params.bin` in `${QNN_SDK_ROOT}/examples/QNN/NetRun/linux-x86_64/saver_output/non_quantized/` for replay on CPU or GPU backends. ### Compiling saver\_output.c To compile saver\_output.c for replay on a backend, use the `Makefile` located in `${QNN_SDK_ROOT}/examples/QNN/Saver`. This makefile can be used to compile saver\_output.c for the specified QNN backend on a compatible platform. Note - Compiling for x86 targets requires clang. - Compiling for Android targets requires Android NDK. - Compiling for DSP/HTP backends on Android targets requires Hexagon SDK. Refer to [Setup](https://docs.qualcomm.com/doc/80-63442-50/topic/setup.html) to set the appropriate environment variables. With `saver_output.c` located in the same directory as `Makefile`, run `make all` to compile for all QNN backends on supported targets. $ cp ./saver_output/saver_output.c ${QNN_SDK_ROOT}/examples/QNN/Saver $ cp ./saver_output/params.bin ${QNN_SDK_ROOT}/examples/QNN/Saver $ cd ${QNN_SDK_ROOT}/examples/QNN/Saver $ make x86 android Copy to clipboard This will produce a folder for each target: - `./x86_64-linux-clang` - `./aarch64-android` These folders will contain one executable for each backend available on the target named `saver_output_`. To create executables for all backends on a specific target, run `make `. Valid options for <target> are **x86** or **aarch64**. To create an executable for a specific backend on a specific target, run `make _`. Valid options for <backend> are **cpu** or **htp** for <target>=x86, and **cpu**, **gpu**, **dsp**, **hta**, or **htp** for <target>=aarch64. ### Replaying saver\_output.c on x86 To replay on x86 backends, set LD\_LIBRARY\_PATH to point to the desired QNN backend library and run the executable. Ensure `params.bin` is in the current working directory. $ cd ${QNN_SDK_ROOT}/examples/QNN/Saver $ export QNN_BACKEND= # where is QnnCpu or QnnHtp $ export LD_LIBRARY_PATH=${QNN_SDK_ROOT}/lib/x86_64-linux-clang:$LD_LIBRARY_PATH $ ./x86_64-linux-clang/saver_output_${QNN_BACKEND} [--logging ] # optionally enable logging Copy to clipboard ### Replaying saver\_output.c on Android #### Replay on QNN CPU, QNN HTA, or QNN GPU Backend Make a directory on device, push QNN backend library, `saver_output.c` executable, and `params.bin`: $ export QNN_BACKEND= # where is QnnCpu, QnnHta, or QnnGpu $ adb shell "mkdir /data/local/tmp/saver" $ adb push ${QNN_SDK_ROOT}/lib/aarch64-android/lib${QNN_BACKEND}.so /data/local/tmp/saver $ adb push ${QNN_SDK_ROOT}/examples/QNN/Saver/aarch64-android/saver_output_${QNN_BACKEND} /data/local/tmp/saver $ adb push ./saver_output/params.bin /data/local/tmp/saver Copy to clipboard Set LD\_LIBRARY\_PATH on device and execute $ adb shell $ cd /data/local/tmp/saver $ export LD_LIBRARY_PATH=/data/local/tmp/saver:$LD_LIBRARY_PATH $ ./saver_output_${QNN_BACKEND} [-l ] # optionally enable logging Copy to clipboard #### Replay on QNN DSP or QNN HTP Backend Make a directory on device, push QNN backend stub/skel, `saver_output.c` executable, and `params.bin`: $ export QNN_BACKEND= # where is QnnDsp or QnnHtp $ export HEXAGON_ARCH= # based on device $ adb shell "mkdir data/local/tmp/saver" $ adb push ${QNN_SDK_ROOT}/lib/aarch64-android/lib${QNN_BACKEND}.so /data/local/tmp/saver $ adb push ${QNN_SDK_ROOT}/lib/aarch64-android/lib${QNN_BACKEND}${HEXAGON_ARCH^}Stub.so /data/local/tmp/saver $ adb push ${QNN_SDK_ROOT}/lib/hexagon-${HEXAGON_ARCH}/unsigned/lib${QNN_BACKEND}${HEXAGON_ARCH^}Skel.so /data/local/tmp/saver $ adb push ${QNN_SDK_ROOT}/lib/aarch64-android/libQnnHtpPrepare.so /data/local/tmp/saver # if QNN_BACKEND=QnnHtp $ adb push ${QNN_SDK_ROOT}/examples/QNN/Saver/aarch64-android/saver_output_${QNN_BACKEND} /data/local/tmp/saver $ adb push ${QNN_SDK_ROOT}/examples/QNN/Saver/params.bin /data/local/tmp/saver Copy to clipboard Set LD\_LIBRARY\_PATH and ADSP\_LIBRARY\_PATH on device and execute: $ adb shell $ cd /data/local/tmp/saver $ export LD_LIBRARY_PATH=/data/local/tmp/saver:$LD_LIBRARY_PATH $ export ADSP_LIBRARY_PATH=/data/local/tmp/saver:$ADSP_LIBRARY_PATH $ ./saver_output_${QNN_BACKEND} [-l ] # optionally enable logging Copy to clipboard ## Windows ### Setup The tutorial assumes general setup instructions have been followed at [Setup](https://docs.qualcomm.com/doc/80-63442-50/topic/setup.html). Please use “x86\_x64 Cross Tools Command Prompt for VS 2022” to set QNN\_SDK\_ROOT: $ set QNN_SDK_ROOT=\path\to\QNN_SDK_ROOT Copy to clipboard ### Build Please use “x86\_x64 Cross Tools Command Prompt for VS 2022” in this step. #### Generate Model For CPU, generate a non-quantized model: **For Windows native/x86\_x64 PC developers** $ cd "%QNN_SDK_ROOT%\examples\QNN\Saver" $ mkdir model && cd model $ xcopy "%QNN_SDK_ROOT%\examples\QNN\converter\models\qnn_model_float.cpp" . $ xcopy "%QNN_SDK_ROOT%\examples\QNN\converter\models\qnn_model_float.bin" . $ py -3 "%QNN_SDK_ROOT%\bin\x86_64-windows-msvc\qnn-model-lib-generator" ^ -c .\qnn_model_float.cpp ^ -b .\qnn_model_float.bin ^ -o .\model_libs ^ -t windows-x86_64 Copy to clipboard After executing commands from above, you should be able to see: - `%QNN_SDK_ROOT%\examples\QNN\Saver\model\model_libs\x64\qnn_model_float.dll` **For Windows on Snapdragon developers** $ cd "%QNN_SDK_ROOT%\examples\QNN\Saver" $ mkdir model && cd model $ xcopy "%QNN_SDK_ROOT%\examples\QNN\converter\models\qnn_model_float.cpp" . $ xcopy "%QNN_SDK_ROOT%\examples\QNN\converter\models\qnn_model_float.bin" . $ py -3 "%QNN_SDK_ROOT%\bin\aarch64-windows-msvc\qnn-model-lib-generator" ^ -c .\qnn_model_float.cpp ^ -b .\qnn_model_float.bin ^ -o .\model_libs ^ -t windows-aarch64 Copy to clipboard After executing commands from above, you should be able to see: - `%QNN_SDK_ROOT%\examples\QNN\Saver\model\model_libs\ARM64\qnn_model_float.dll` For DSP and HTP, generate a quantized model: **For Windows native/x86\_x64 PC developers** $ cd "%QNN_SDK_ROOT%\examples\QNN\Saver" $ mkdir model && cd model $ xcopy "%QNN_SDK_ROOT%\examples\QNN\converter\models\qnn_model_8bit_quantized.cpp" . $ xcopy "%QNN_SDK_ROOT%\examples\QNN\converter\models\qnn_model_8bit_quantized.bin" . $ py -3 "%QNN_SDK_ROOT%\bin\x86_64-windows-msvc\qnn-model-lib-generator" ^ -c .\qnn_model_8bit_quantized.cpp ^ -b .\qnn_model_8bit_quantized.bin ^ -o .\model_libs ^ -t windows-x86_64 Copy to clipboard After executing commands from above, you should be able to see: - `%QNN_SDK_ROOT%\examples\QNN\Saver\model\model_libs\x64\qnn_model_8bit_quantized.dll` **For Windows on Snapdragon developers** $ cd "%QNN_SDK_ROOT%\examples\QNN\Saver" $ mkdir model && cd model $ xcopy "%QNN_SDK_ROOT%\examples\QNN\converter\models\qnn_model_8bit_quantized.cpp" . $ xcopy "%QNN_SDK_ROOT%\examples\QNN\converter\models\qnn_model_8bit_quantized.bin" . $ py -3 "%QNN_SDK_ROOT%\bin\aarch64-windows-msvc\qnn-model-lib-generator" ^ -c .\qnn_model_8bit_quantized.cpp ^ -b .\qnn_model_8bit_quantized.bin ^ -o .\model_libs ^ -t windows-aarch64 Copy to clipboard After executing commands from above, you should be able to see: - `%QNN_SDK_ROOT%\examples\QNN\Saver\model\model_libs\ARM64\qnn_model_8bit_quantized.dll` #### Generate saver\_output.c and params.bin Please check the path of <model>.dll and replace in the below commands: $ cd "%QNN_SDK_ROOT%\examples\QNN\Saver" $ mkdir source && cd source $ xcopy "%QNN_SDK_ROOT%\examples\QNN\converter\models\input_data_float" .\input_data_float /i $ xcopy "%QNN_SDK_ROOT%\examples\QNN\converter\models\input_list_float.txt" . $ xcopy "%QNN_SDK_ROOT%\examples\QNN\Saver\model\model_libs\x64\.dll" . $ "%QNN_SDK_ROOT%\bin\x86_64-windows-msvc\qnn-net-run.exe" ^ --backend "%QNN_SDK_ROOT%\lib\x86_64-windows-msvc\QnnSaver.dll" ^ --model .dll ^ --input_list .\input_list_float.txt Copy to clipboard After executing commands from above, you should be able to see: - `%QNN_SDK_ROOT%\examples\QNN\Saver\source\saver_output\saver_output.c` - `%QNN_SDK_ROOT%\examples\QNN\Saver\source\saver_output\params.bin` #### Build saver\_output.c Please choose one target between [x64, ARM64] as the parameter of “-A” config. Executables for all backends on the target named `saver_output_` will be generated. $ cd "%QNN_SDK_ROOT%\examples\QNN\Saver" $ xcopy "%QNN_SDK_ROOT%\examples\QNN\Saver\source\saver_output\saver_output.c" . $ mkdir build && cd build $ cmake -S ../ -B ./ -T ClangCL -A [x64, ARM64] $ cmake --build ./ --config Release Copy to clipboard To generate an executable for a specific backend, please use below command to build. Valid options for <backend> are cpu for <target>=x64, and cpu, dsp, or htp for <target>=ARM64. $ cmake --build ./ --config Release --target [cpu, dsp, htp] Copy to clipboard After executing commands from above, you should be able to see: - `%QNN_SDK_ROOT%\examples\QNN\Saver\build\Release\saver_output_.exe` ### Run Please use “Command Prompt” to execute, and ensure the `params.bin` is the same file generated in [build](https://docs.qualcomm.com/doc/80-63442-50/topic/saver_tutorial.html#build). #### For CPU Run on x86. Please push below files to a folder: - `%QNN_SDK_ROOT%\examples\QNN\Saver\build\Release\saver_output_QnnCpu.exe` - `%QNN_SDK_ROOT%\lib\x86_64-windows-msvc\QnnCpu.dll` - `%QNN_SDK_ROOT%\examples\QNN\Saver\source\saver_output\params.bin` To execute: $ .\saver_output_QnnCpu.exe [--logging ] # optionally enable logging Copy to clipboard Run on aarch64. Please push below files to device: > > > - `%QNN_SDK_ROOT%\examples\QNN\Saver\build\Release\saver_output_QnnCpu.exe` > - `%QNN_SDK_ROOT%\lib\aarch64-windows-msvc\QnnCpu.dll` > - `%QNN_SDK_ROOT%\examples\QNN\Saver\source\saver_output\params.bin` To execute: $ .\saver_output_QnnCpu.exe [--logging ] # optionally enable logging Copy to clipboard #### For DSP Run on aarch64. Please push below files to device: - `%QNN_SDK_ROOT%\examples\QNN\Saver\build\Release\saver_output_QnnDsp.exe` - `%QNN_SDK_ROOT%\lib\aarch64-windows-msvc\QnnDsp.dll` - `%QNN_SDK_ROOT%\lib\aarch64-windows-msvc\QnnDspV66Stub.dll` - `%QNN_SDK_ROOT%\lib\hexagon-v66\unsigned\libQnnDspV66Skel.so` - `%QNN_SDK_ROOT%\examples\QNN\Saver\source\saver_output\params.bin` To execute: $ .\saver_output_QnnDsp.exe [--logging ] # optionally enable logging Copy to clipboard #### For HTP Run on aarch64. Please push below files to device: - `%QNN_SDK_ROOT%\examples\QNN\Saver\build\Release\saver_output_QnnHtp.exe` - `%QNN_SDK_ROOT%\lib\aarch64-windows-msvc\QnnHtp.dll` - `%QNN_SDK_ROOT%\lib\aarch64-windows-msvc\QnnHtpPrepare.dll` - `%QNN_SDK_ROOT%\lib\aarch64-windows-msvc\QnnHtpStub.dll` - `%QNN_SDK_ROOT%\lib\hexagon-v68\unsigned\libQnnHtpSkel.so` - `%QNN_SDK_ROOT%\examples\QNN\Saver\source\saver_output\params.bin` To execute: $ .\saver_output_QnnHtp.exe [--logging ] # optionally enable logging Copy to clipboard Last Published: Oct 10, 2025 [Previous Topic Building and running qnn-sample-app](https://docs.qualcomm.com/bundle/publicresource/80-63442-50/topics/sample_app.md) [Next Topic Advanced](https://docs.qualcomm.com/bundle/publicresource/80-63442-50/topics/tutorials.md)