blob: 6a9c22ebef3a90f8d70245648d7449f5e8d8f12d [file] [log] [blame]
James Conroy919ec712022-07-13 12:57:53 +01001#!/bin/bash
2#
3# Copyright © 2022 Arm Ltd and Contributors. All rights reserved.
4# SPDX-License-Identifier: MIT
5#
6
7# Script which downloads and builds Arm NN dependencies
8# Perquisite to running build-armnn.sh
9
10set -o nounset # Catch references to undefined variables.
11set -o pipefail # Catch non zero exit codes within pipelines.
12set -o errexit # Catch and propagate non zero exit codes.
13
14rel_path=$(dirname "$0") # relative path from where script is executed to script location
15
16# Download an archive using wget and extract using tar
17# Takes three arguments:
18# 1. Name of dependency being downloaded e.g. Flatbuffers
19# 2. Link to archive
20# 3. Filename given to archive upon downloading
21download_and_extract()
22{
23 cd "$SOURCE_DIR"
24
25 echo -e "\n***** Downloading $1 *****"
26 wget -O "$3" "$2"
27
28 echo -e "\n***** Extracting archive *****"
29 tar -xzf "$3"
30
31 echo -e "\n***** Removing archive *****"
32 rm "$3"
33
34 echo -e "\n***** $1 downloaded *****"
35}
36
37download_protobuf()
38{
39 download_and_extract \
40 "Protobuf" \
41 "https://github.com/protocolbuffers/protobuf/releases/download/v$PROTOBUF_VERSION/protobuf-all-$PROTOBUF_VERSION.tar.gz" \
42 "protobuf-all-$PROTOBUF_VERSION.tar.gz"
43}
44
45build_protobuf()
46{
47 local native_build=$1
48 local build_dir="$PROTOBUF_BUILD_TARGET"
49 local cmake_flags=""
50 local target_arch="$TARGET_ARCH"
51 local additional_cmds=""
52
53 if [ "$native_build" -eq 0 ]; then
54 mkdir -p "$PROTOBUF_BUILD_TARGET"
55 additional_cmds+="--with-protoc=$PROTOCOL_COMPILER_HOST "
56 if [ "$TARGET_ARCH" == "aarch64" ]; then
57 cmake_flags+="$AARCH64_COMPILER_FLAGS"
58 additional_cmds+="--host=aarch64-linux "
59 elif [ "$TARGET_ARCH" == "aarch32" ]; then
60 cmake_flags+="$AARCH32_COMPILER_FLAGS"
61 additional_cmds+="--host=arm-linux "
62 fi
63 else
64 target_arch="$HOST_ARCH"
65 mkdir -p "$PROTOBUF_BUILD_HOST"
66 build_dir="$PROTOBUF_BUILD_HOST"
67 fi
68
69 echo -e "\n***** Building Protobuf for $target_arch ***** "
70
71 cd "$PROTOBUF_BUILD_ROOT"
72
73 # Cleanup any previous cmake files, except actual builds which we keep
74 find . -mindepth 1 -name "*_build" -prune -o -exec rm -rf {} +
75
76 eval "$cmake_flags" \
77 "$PROTOBUF_SRC"/configure --prefix="$build_dir" "$additional_cmds"
78 make install -j "$NUM_THREADS"
79
80 echo -e "\n***** Protobuf built for $target_arch ***** "
81}
82
83download_flatbuffers()
84{
85 download_and_extract \
86 "Flatbuffers" \
87 "https://github.com/google/flatbuffers/archive/v$FLATBUFFERS_VERSION.tar.gz" \
88 "flatbuffers-$FLATBUFFERS_VERSION.tar.gz"
89}
90
91build_flatbuffers()
92{
93 local native_build=$1
94 local build_dir="$FLATBUFFERS_BUILD_TARGET"
95 local target_arch="$TARGET_ARCH"
96
97 local cmake_flags="CXXFLAGS=-fPIC "
98
99 if [ "$native_build" -eq 0 ]; then
100 mkdir -p "$FLATBUFFERS_BUILD_TARGET"
101 if [ "$TARGET_ARCH" == "aarch64" ]; then
102 cmake_flags+="$AARCH64_COMPILER_FLAGS"
103 elif [ "$TARGET_ARCH" == "aarch32" ]; then
104 cmake_flags+="$AARCH32_COMPILER_FLAGS"
105 fi
106 else
107 target_arch="$HOST_ARCH"
108 mkdir -p "$FLATBUFFERS_BUILD_HOST"
109 build_dir="$FLATBUFFERS_BUILD_HOST"
110 fi
111
112 echo -e "\n***** Building flatbuffers for $target_arch *****"
113
114 mkdir -p "$FLATBUFFERS_BUILD_ROOT"
115 cd "$FLATBUFFERS_BUILD_ROOT"
116
117 # Cleanup any previous cmake files, except actual builds which we keep
118 find . -mindepth 1 -name "*_build" -prune -o -exec rm -rf {} +
119
120 eval "$cmake_flags" \
121 cmake -DFLATBUFFERS_BUILD_FLATC=1 \
122 -DCMAKE_INSTALL_PREFIX:PATH="$build_dir" \
123 -DFLATBUFFERS_BUILD_TESTS=0 \
124 "$FLATBUFFERS_SRC"
125 make all install -j "$NUM_THREADS"
126
127 echo -e "\n***** Built flatbuffers for $target_arch *****"
128}
129
130download_tensorflow()
131{
132 cd "$SOURCE_DIR"
133
134 echo -e "\n***** Downloading TensorFlow *****"
135 git clone https://github.com/tensorflow/tensorflow.git
136 cd "$TENSORFLOW_SRC"
137
138 git checkout "$("$ARMNN_SRC"/scripts/get_tensorflow.sh -p)"
139 echo -e "\n***** TensorFlow downloaded *****"
140}
141
142build_tflite()
143{
144 mkdir -p "$TFLITE_BUILD_TARGET"
145 cd "$TFLITE_BUILD_TARGET"
146
147 local target_arch_cmd="" # default is native, no command needed
148 local cmake_flags=""
149
150 case "$TARGET_ARCH" in
151 "aarch64")
152 cmake_flags+="$AARCH64_COMPILER_FLAGS"
153 target_arch_cmd="-DCMAKE_SYSTEM_PROCESSOR=aarch64 "
154
155 if [ "$NATIVE_BUILD" -eq 0 ]; then
156 cmake_flags+="ARMCC_FLAGS='-funsafe-math-optimizations' "
157 fi
158 ;;
159
160 "aarch32")
161 cmake_flags+="$AARCH32_COMPILER_FLAGS"
162 target_arch_cmd="-DCMAKE_SYSTEM_PROCESSOR=armv7 "
163
164 if [ "$NATIVE_BUILD" -eq 0 ]; then
165 cmake_flags+="ARMCC_FLAGS='-march=armv7-a -mfpu=neon-vfpv4 -funsafe-math-optimizations -mfp16-format=ieee' "
166 fi
167 ;;
168 esac
169
170 echo -e "\n***** Building TF Lite for $TARGET_ARCH *****"
171
172 # Cleanup any previous cmake files, except actual builds which we keep
173 find . -mindepth 1 -name "*_build" -prune -o -exec rm -rf {} +
174
175 eval "$cmake_flags" \
176 cmake -DTFLITE_ENABLE_XNNPACK=OFF \
177 "$target_arch_cmd" \
178 "$TFLITE_SRC"
179 cmake --build . -j "$NUM_THREADS"
180
181 echo -e "\n***** Built TF Lite for $TARGET_ARCH *****"
182}
183
184generate_tflite_schema()
185{
186 echo -e "\n***** Generating TF Lite Schema *****"
187 mkdir -p "$TFLITE_BUILD_ROOT"
188 cd "$TFLITE_BUILD_ROOT"
189
190 cp "$SCHEMA_SRC" .
191
192 $FLATC -c --gen-object-api --reflect-types --reflect-names schema.fbs
193
194 echo -e "\n***** Generated TF Lite Schema *****"
195}
196
197download_onnx()
198{
199 download_and_extract \
200 "ONNX" \
201 "https://github.com/onnx/onnx/releases/download/v$ONNX_VERSION/onnx-$ONNX_VERSION.tar.gz" \
202 "onnx-$ONNX_VERSION.tar.gz"
203}
204
205generate_onnx_sources()
206{
207 mkdir -p "$ONNX_BUILD_TARGET"
208 cd "$ONNX_SRC"
209
210 echo -e "\n***** Generating ONNX sources for $TARGET_ARCH *****"
211
212 export LD_LIBRARY_PATH="$PROTOBUF_BUILD_HOST"/lib${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}
213
214 eval "$PROTOCOL_COMPILER_HOST" onnx/onnx.proto \
215 --proto_path=. \
216 --proto_path="$ONNX_SRC" \
217 --proto_path="$PROTOBUF_BUILD_HOST"/include \
218 --cpp_out "$ONNX_BUILD_TARGET"
219
220 echo -e "\n***** Generated ONNX sources for $TARGET_ARCH *****"
221}
222
223download_armnn()
224{
225 cd "$SOURCE_DIR"
226
227 echo -e "\n***** Downloading Arm NN *****"
228
229 # Latest release branch of Arm NN is checked out by default
230 git clone https://github.com/ARM-software/armnn.git armnn
231
232 cd "$ARMNN_SRC"
233 armnn_branch="$(git rev-parse --abbrev-ref HEAD)"
234
235 echo -e "\n***** Arm NN Downloaded: $armnn_branch *****"
236}
237
238download_acl()
239{
240 cd "$SOURCE_DIR"
241
242 echo -e "\n***** Downloading ACL *****"
243
244 git clone https://github.com/ARM-software/ComputeLibrary.git acl
245
246 # Get corresponding release tag for ACL by parsing release branch number for Arm NN
247 local acl_tag=""
248 acl_tag="$(echo "$armnn_branch" | tr '\n' ' ' | sed -e 's/[^0-9]/ /g' -e 's/^ *//g' -e 's/ *$//g' | tr -s ' ' | sed 's/ /./g')"
249
250 cd "$ACL_SRC"
251 git checkout v"$acl_tag"
252
253 echo -e "\n***** ACL Downloaded: $acl_tag *****"
254}
255
256usage()
257{
258 cat <<EOF
259setup-armnn.sh - Download and build Arm NN dependencies in the current directory (ROOT_DIR)
260setup-armnn.sh [OPTION]...
261 --tflite-delegate
262 setup dependencies for the Arm NN TF Lite Delegate
263 --tflite-parser
264 setup dependencies for the Arm NN TF Lite Parser
265 --onnx-parser
266 setup dependencies for the Arm NN ONNX parser
267 --all
268 setup dependencies for all Arm NN components listed above
269 --target-arch=[aarch64|aarch32|x86_64]
270 specify a target architecture (mandatory)
271 --num-threads=<INTEGER>
272 specify number of threads/cores to build dependencies with (optional: defaults to number of online CPU cores on host)
273 -h, --help
274 print brief usage information and exit
275 -x
276 enable shell tracing in this script
277
278At least one dependency flag (e.g. --tflite-delegate) must be provided or else provide --all to setup all dependencies.
279Directories called "source" and "build" will be generated in the current directory (ROOT_DIR) from which this script is called.
280It's recommended to call this script in a directory outside of this Arm NN source repo, to avoid nested repositories.
281
282This script will download the latest release branches of Arm NN and ACL, by default.
283Alternatively, manually create a "source" directory in ROOT_DIR and place custom repositories there.
284Custom repositories in "source" must be named "armnn" and "acl".
285
286Examples:
287Setup for aarch64 with all Arm NN dependencies:
288 <PATH_TO>/setup-armnn.sh --target-arch=aarch64 --all
289Setup for aarch64 with TF Lite Delegate and TF Lite Parser dependencies only:
290 <PATH_TO>/setup-armnn.sh --target-arch=aarch64 --tflite-delegate --tflite-parser
291Setup for aarch32 with all Arm NN dependencies:
292 <PATH_TO>/setup-armnn.sh --target-arch=aarch32 --all
293EOF
294}
295
296# This will catch in validation.sh if not set
297target_arch=""
298
299# Default flag values
300flag_tflite_delegate=0
301flag_tflite_parser=0
302flag_onnx_parser=0
303
304# If --num-threads is not set, the default NUM_THREADS value in common.sh will be used
305num_threads=0
306
307name=$(basename "$0")
308
309# If no options provided, show help
310if [ $# -eq 0 ]; then
311 usage
312 exit 1
313fi
314
315args=$(getopt -ohx -l tflite-delegate,tflite-parser,onnx-parser,all,target-arch:,num-threads:,help -n "$name" -- "$@")
316eval set -- "$args"
317while [ $# -gt 0 ]; do
318 if [ -n "${opt_prev:-}" ]; then
319 eval "$opt_prev=\$1"
320 opt_prev=
321 shift 1
322 continue
323 elif [ -n "${opt_append:-}" ]; then
324 if [ -n "$1" ]; then
325 eval "$opt_append=\"\${$opt_append:-} \$1\""
326 fi
327 opt_append=
328 shift 1
329 continue
330 fi
331 case $1 in
332 --tflite-parser)
333 flag_tflite_parser=1
334 ;;
335
336 --tflite-delegate)
337 flag_tflite_delegate=1
338 ;;
339
340 --onnx-parser)
341 flag_onnx_parser=1
342 ;;
343
344 --all)
345 flag_tflite_delegate=1
346 flag_tflite_parser=1
347 flag_onnx_parser=1
348 ;;
349
350 --target-arch)
351 opt_prev=target_arch
352 ;;
353
354 --num-threads)
355 opt_prev=num_threads
356 ;;
357
358 -h | --help)
359 usage
360 exit 0
361 ;;
362
363 -x)
364 set -x
365 ;;
366
367 --)
368 shift
369 break 2
370 ;;
371
372 esac
373 shift 1
374done
375
376# shellcheck source=common.sh
377source "$rel_path"/common.sh
378
379echo -e "\nINFO: Displaying configuration information before execution of $name"
380echo " target-arch: $TARGET_ARCH"
381echo " host-arch: $HOST_ARCH"
382echo " tflite-delegate: $flag_tflite_delegate"
383echo " tflite-parser: $flag_tflite_parser"
384echo " onnx-parser: $flag_onnx_parser"
385echo " num-threads: $NUM_THREADS"
386echo " root directory: $ROOT_DIR"
387echo "source directory: $SOURCE_DIR"
388echo " build directory: $BUILD_DIR"
389
390if [ "$(git rev-parse --is-inside-work-tree 2> /dev/null)" ]; then
391 echo -e "\n***** WARNING: Running script inside a git repository. To avoid nested repos, call this script from outside of this repo. *****"
392fi
393
394echo -e "\nScript execution will begin in 10 seconds..."
395
396sleep 10
397
398mkdir -p "$SOURCE_DIR"
399mkdir -p "$BUILD_DIR"
400
401if [ -d "$ARMNN_SRC" ]; then
402 echo -e "\n***** Arm NN source repository already located at $ARMNN_SRC. Skipping cloning of Arm NN. *****"
403else
404 download_armnn
405fi
406
407if [ -d "$ACL_SRC" ]; then
408 echo -e "\n***** ACL source repository already located at $ACL_SRC. Skipping cloning of ACL. *****"
409else
410 download_acl
411fi
412
413if [ "$flag_tflite_delegate" -eq 1 ] || [ "$flag_tflite_parser" -eq 1 ]; then
414 download_flatbuffers
415
416 # Host build
417 build_flatbuffers 1
418
419 # Target build for cross compile
420 if [ "$NATIVE_BUILD" -eq 0 ]; then
421 build_flatbuffers 0
422 fi
423
424 download_tensorflow
425fi
426
427if [ "$flag_tflite_parser" -eq 1 ]; then
428 generate_tflite_schema
429fi
430
431if [ "$flag_tflite_delegate" -eq 1 ]; then
432 build_tflite
433fi
434
435if [ "$flag_onnx_parser" -eq 1 ]; then
436 download_protobuf
437
438 # Host build
439 build_protobuf 1
440
441 # Target build for cross compile
442 if [ "$NATIVE_BUILD" -eq 0 ]; then
443 build_protobuf 0
444 fi
445
446 download_onnx
447 generate_onnx_sources
448fi
449
450echo -e "\n***** Arm NN setup complete. Now build with build-armnn.sh. *****\n"
451
452exit 0