ArmNN
 22.02
delegate/BuildGuideNative.md
Go to the documentation of this file.
1 # Delegate build guide introduction
2 
3 The Arm NN Delegate can be found within the Arm NN repository but it is a standalone piece of software. However,
4 it makes use of the Arm NN library. For this reason we have added two options to build the delegate. The first option
5 allows you to build the delegate together with the Arm NN library, the second option is a standalone build
6 of the delegate.
7 
8 This tutorial uses an Aarch64 machine with Ubuntu 18.04 installed that can build all components
9 natively (no cross-compilation required). This is to keep this guide simple.
10 
11 **Table of content:**
12 - [Delegate build guide introduction](#delegate-build-guide-introduction)
13 - [Dependencies](#dependencies)
14  * [Download Arm NN](#download-arm-nn)
15  * [Build Tensorflow Lite for C++](#build-tensorflow-lite-for-c--)
16  * [Build Flatbuffers](#build-flatbuffers)
17  * [Build the Arm Compute Library](#build-the-arm-compute-library)
18  * [Build the Arm NN Library](#build-the-arm-nn-library)
19 - [Build the TfLite Delegate (Stand-Alone)](#build-the-tflite-delegate--stand-alone-)
20 - [Build the Delegate together with Arm NN](#build-the-delegate-together-with-arm-nn)
21 - [Integrate the Arm NN TfLite Delegate into your project](#integrate-the-arm-nn-tflite-delegate-into-your-project)
22 
23 
24 # Dependencies
25 
26 Build Dependencies:
27  * Tensorflow Lite: this guide uses version 2.5.0. Other versions may work.
28  * Flatbuffers 1.12.0
29  * Arm NN 21.11 or higher
30 
31 Required Tools:
32  * Git. This guide uses version 2.17.1. Other versions might work.
33  * pip. This guide uses version 20.3.3. Other versions might work.
34  * wget. This guide uses version 1.17.1. Other versions might work.
35  * zip. This guide uses version 3.0. Other versions might work.
36  * unzip. This guide uses version 6.00. Other versions might work.
37  * cmake 3.16.0 or higher. This guide uses version 3.16.0
38  * scons. This guide uses version 2.4.1. Other versions might work.
39 
40 Our first step is to build all the build dependencies I have mentioned above. We will have to create quite a few
41 directories. To make navigation a bit easier define a base directory for the project. At this stage we can also
42 install all the tools that are required during the build. This guide assumes you are using a Bash shell.
43 ```bash
44 export BASEDIR=~/ArmNNDelegate
45 mkdir $BASEDIR
46 cd $BASEDIR
47 apt-get update && apt-get install git wget unzip zip python git cmake scons
48 ```
49 
50 ## Download Arm NN
51 
52 First clone Arm NN using Git.
53 
54 ```bash
55 cd $BASEDIR
56 git clone "https://review.mlplatform.org/ml/armnn"
57 cd armnn
58 git checkout <branch_name> # e.g. branches/armnn_21_11
59 ```
60 
61 ## Build Tensorflow Lite for C++
62 Tensorflow has a few dependencies on it's own. It requires the python packages pip3, numpy,
63 and also Bazel or CMake which are used to compile Tensorflow. A description on how to build bazel can be
64 found [here](https://docs.bazel.build/versions/master/install-compile-source.html). But for this guide, we will
65 compile with CMake. Depending on your operating system and architecture there might be an easier way.
66 ```bash
67 wget -O cmake-3.16.0.tar.gz https://cmake.org/files/v3.16/cmake-3.16.0.tar.gz
68 tar -xzf cmake-3.16.0.tar.gz -C $BASEDIR/
69 
70 # If you have an older CMake, remove installed in order to upgrade
71 yes | sudo apt-get purge cmake
72 hash -r
73 
74 cd $BASEDIR/cmake-3.16.0
75 ./bootstrap
76 make
77 sudo make install
78 ```
79 
80 ### Download and build Tensorflow Lite
81 Arm NN provides a script, armnn/scripts/get_tensorflow.sh, that can be used to download the version of TensorFlow that Arm NN was tested with:
82 ```bash
83 cd $BASEDIR
84 git clone https://github.com/tensorflow/tensorflow.git
85 cd tensorflow/
86 git checkout $(../armnn/scripts/get_tensorflow.sh -p) # Minimum version required for the delegate is v2.3.1
87 ```
88 
89 Now the build process can be started. When calling "cmake", as below, you can specify a number of build
90 flags. But if you have no need to configure your tensorflow build, you can follow the exact commands below:
91 ```bash
92 mkdir build # You are already inside $BASEDIR/tensorflow at this point
93 cd build
94 cmake $BASEDIR/tensorflow/tensorflow/lite -DTFLITE_ENABLE_XNNPACK=OFF
95 cmake --build . # This will be your DTFLITE_LIB_ROOT directory
96 ```
97 
98 ## Build Flatbuffers
99 Flatbuffers is a memory efficient cross-platform serialization library as
100 described [here](https://google.github.io/flatbuffers/). It is used in tflite to store models and is also a dependency
101 of the delegate. After downloading the right version it can be built and installed using cmake.
102 ```bash
103 cd $BASEDIR
104 wget -O flatbuffers-1.12.0.zip https://github.com/google/flatbuffers/archive/v1.12.0.zip
105 unzip -d . flatbuffers-1.12.0.zip
106 cd flatbuffers-1.12.0
107 mkdir install && mkdir build && cd build
108 # I'm using a different install directory but that is not required
109 cmake .. -DCMAKE_INSTALL_PREFIX:PATH=$BASEDIR/flatbuffers-1.12.0/install
110 make install
111 ```
112 
113 ## Build the Arm Compute Library
114 
115 The Arm NN library depends on the Arm Compute Library (ACL). It provides a set of functions that are optimized for
116 both Arm CPUs and GPUs. The Arm Compute Library is used directly by Arm NN to run machine learning workloads on
117 Arm CPUs and GPUs.
118 
119 It is important to have the right version of ACL and Arm NN to make it work. Arm NN and ACL are developed very closely
120 and released together. If you would like to use the Arm NN version "21.11" you should use the same "21.11" version for
121 ACL too. Arm NN provides a script, armnn/scripts/get_compute_library.sh, that can be used to download the exact version
122 of Arm Compute Library that Arm NN was tested with.
123 
124 To build the Arm Compute Library on your platform, download the Arm Compute Library and checkout the tag that contains
125 the version you want to use. Build it using `scons`.
126 
127 ```bash
128 cd $BASEDIR
129 git clone https://review.mlplatform.org/ml/ComputeLibrary
130 cd ComputeLibrary/
131 git checkout $(../armnn/scripts/get_compute_library.sh -p) # e.g. v21.11
132 # The machine used for this guide only has a Neon CPU which is why I only have "neon=1" but if
133 # your machine has an arm Gpu you can enable that by adding `opencl=1 embed_kernels=1 to the command below
134 scons arch=arm64-v8a neon=1 extra_cxx_flags="-fPIC" benchmark_tests=0 validation_tests=0
135 ```
136 
137 ## Build the Arm NN Library
138 
139 With ACL built we can now continue to build Arm NN. Create a build directory and use `cmake` to build it.
140 ```bash
141 cd $BASEDIR
142 cd armnn
143 mkdir build && cd build
144 # if you've got an arm Gpu add `-DARMCOMPUTECL=1` to the command below
145 cmake .. -DARMCOMPUTE_ROOT=$BASEDIR/ComputeLibrary -DARMCOMPUTENEON=1 -DBUILD_UNIT_TESTS=0
146 make
147 ```
148 
149 # Build the TfLite Delegate (Stand-Alone)
150 
151 The delegate as well as Arm NN is built using `cmake`. Create a build directory as usual and build the delegate
152 with the additional cmake arguments shown below
153 ```bash
154 cd $BASEDIR/armnn/delegate && mkdir build && cd build
155 cmake .. -DCMAKE_BUILD_TYPE=release # A release build rather than a debug build.
156  -DTENSORFLOW_ROOT=$BASEDIR/tensorflow \ # The root directory where tensorflow can be found.
157  -DTFLITE_LIB_ROOT=$BASEDIR/tensorflow/build \ # Directory where tensorflow libraries can be found.
158  -DFLATBUFFERS_ROOT=$BASEDIR/flatbuffers-1.12.0/install \ # Flatbuffers install directory.
159  -DArmnn_DIR=$BASEDIR/armnn/build \ # Directory where the Arm NN library can be found
160  -DARMNN_SOURCE_DIR=$BASEDIR/armnn # The top directory of the Arm NN repository.
161  # Required are the includes for Arm NN
162 make
163 ```
164 
165 To ensure that the build was successful you can run the unit tests for the delegate that can be found in
166 the build directory for the delegate. [Doctest](https://github.com/onqtam/doctest) was used to create those tests. Using test filters you can
167 filter out tests that your build is not configured for. In this case, because Arm NN was only built for Cpu
168 acceleration (CpuAcc), we filter for all test suites that have `CpuAcc` in their name.
169 ```bash
170 cd $BASEDIR/armnn/delegate/build
171 ./DelegateUnitTests --test-suite=*CpuAcc*
172 ```
173 If you have built for Gpu acceleration as well you might want to change your test-suite filter:
174 ```bash
175 ./DelegateUnitTests --test-suite=*CpuAcc*,*GpuAcc*
176 ```
177 
178 # Build the Delegate together with Arm NN
179 
180 In the introduction it was mentioned that there is a way to integrate the delegate build into Arm NN. This is
181 pretty straight forward. The cmake arguments that were previously used for the delegate have to be added
182 to the Arm NN cmake arguments. Also another argument `BUILD_ARMNN_TFLITE_DELEGATE` needs to be added to
183 instruct Arm NN to build the delegate as well. The new commands to build Arm NN are as follows:
184 
185 Download Arm NN if you have not already done so:
186 ```bash
187 cd $BASEDIR
188 git clone "https://review.mlplatform.org/ml/armnn"
189 cd armnn
190 git checkout <branch_name> # e.g. branches/armnn_21_11
191 ```
192 Build Arm NN with the delegate included
193 ```bash
194 cd $BASEDIR
195 cd armnn
196 rm -rf build # Remove any previous cmake build.
197 mkdir build && cd build
198 # if you've got an arm Gpu add `-DARMCOMPUTECL=1` to the command below
199 cmake .. -DARMCOMPUTE_ROOT=$BASEDIR/ComputeLibrary \
200  -DARMCOMPUTENEON=1 \
201  -DBUILD_UNIT_TESTS=0 \
202  -DBUILD_ARMNN_TFLITE_DELEGATE=1 \
203  -DTENSORFLOW_ROOT=$BASEDIR/tensorflow \
204  -DTFLITE_LIB_ROOT=$BASEDIR/tensorflow/build \
205  -DFLATBUFFERS_ROOT=$BASEDIR/flatbuffers-1.12.0/install
206 make
207 ```
208 The delegate library can then be found in `build/armnn/delegate`.
209 
210 # Test the Arm NN delegate using the [TFLite Model Benchmark Tool](https://github.com/tensorflow/tensorflow/tree/master/tensorflow/lite/tools/benchmark)
211 
212 The TFLite Model Benchmark Tool has a useful command line interface to test delegates. We can use this to demonstrate the use of the Arm NN delegate and its options.
213 
214 Some examples of this can be viewed in this [YouTube demonstration](https://www.youtube.com/watch?v=NResQ1kbm-M&t=920s).
215 
216 ## Download the TFLite Model Benchmark Tool
217 
218 Binary builds of the benchmarking tool for various platforms are available [here](https://www.tensorflow.org/lite/performance/measurement#native_benchmark_binary). In this example I will target an aarch64 Linux environment. I will also download a sample uint8 tflite model from the [Arm ML Model Zoo](https://github.com/ARM-software/ML-zoo).
219 
220 ```bash
221 mkdir $BASEDIR/benchmarking
222 cd $BASEDIR/benchmarking
223 # Get the benchmarking binary.
224 wget https://storage.googleapis.com/tensorflow-nightly-public/prod/tensorflow/release/lite/tools/nightly/latest/linux_aarch64_benchmark_model -O benchmark_model
225 # Make it executable.
226 chmod +x benchmark_model
227 # and a sample model from model zoo.
228 wget https://github.com/ARM-software/ML-zoo/blob/master/models/image_classification/mobilenet_v2_1.0_224/tflite_uint8/mobilenet_v2_1.0_224_quantized_1_default_1.tflite?raw=true -O mobilenet_v2_1.0_224_quantized_1_default_1.tflite
229 ```
230 
231 ## Execute the benchmarking tool with the Arm NN delegate
232 You are already at $BASEDIR/benchmarking from the previous stage.
233 ```bash
234 LD_LIBRARY_PATH=../armnn/build ./benchmark_model --graph=mobilenet_v2_1.0_224_quantized_1_default_1.tflite --external_delegate_path="../armnn/build/delegate/libarmnnDelegate.so" --external_delegate_options="backends:CpuAcc;logging-severity:info"
235 ```
236 The "external_delegate_options" here are specific to the Arm NN delegate. They are used to specify a target Arm NN backend or to enable/disable various options in Arm NN. A full description can be found in the parameters of function tflite_plugin_create_delegate.
237 
238 # Integrate the Arm NN TfLite Delegate into your project
239 
240 The delegate can be integrated into your c++ project by creating a TfLite Interpreter and
241 instructing it to use the Arm NN delegate for the graph execution. This should look similiar
242 to the following code snippet.
243 ```objectivec
244 // Create TfLite Interpreter
245 std::unique_ptr<Interpreter> armnnDelegateInterpreter;
246 InterpreterBuilder(tfLiteModel, ::tflite::ops::builtin::BuiltinOpResolver())
247  (&armnnDelegateInterpreter)
248 
249 // Create the Arm NN Delegate
250 armnnDelegate::DelegateOptions delegateOptions(backends);
251 std::unique_ptr<TfLiteDelegate, decltype(&armnnDelegate::TfLiteArmnnDelegateDelete)>
252  theArmnnDelegate(armnnDelegate::TfLiteArmnnDelegateCreate(delegateOptions),
253  armnnDelegate::TfLiteArmnnDelegateDelete);
254 
255 // Instruct the Interpreter to use the armnnDelegate
256 armnnDelegateInterpreter->ModifyGraphWithDelegate(theArmnnDelegate.get());
257 ```
258 
259 For further information on using TfLite Delegates please visit the [tensorflow website](https://www.tensorflow.org/lite/guide)
260 
261 For more details of the kind of options you can pass to the Arm NN delegate please check the parameters of function tflite_plugin_create_delegate.