These are the step by step instructions on Cross-Compiling ArmNN under an x86_64 system to target an Arm64 system. This build flow has been tested with Ubuntu 16.04. The instructions show how to build the ArmNN core library and the Boost, Protobuf, Caffe, Tensorflow, Tflite, Flatbuffer and Compute Libraries necessary for compilation.
sudo apt install crossbuild-essential-arm64
We support protobuf version 3.12.0
git clone -b v3.12.0 https://github.com/google/protobuf.git protobuf cd protobuf git submodule update --init --recursive ./autogen
mkdir x86_64_build cd x86_64_build ../configure --prefix=$HOME/armnn-devenv/google/x86_64_pb_install make install -j16 cd ..
mkdir arm64_build cd arm64_build export CC=aarch64-linux-gnu-gcc \ export CXX=aarch64-linux-gnu-g++ \ ../configure --host=aarch64-linux \ --prefix=$HOME/armnn-devenv/google/arm64_pb_install \ --with-protoc=$HOME/armnn-devenv/google/x86_64_pb_install/bin/protoc make install -j16 cd ..
sudo apt-get install libleveldb-dev libsnappy-dev libopencv-dev libhdf5-serial-dev sudo apt-get install --no-install-recommends libboost-all-dev sudo apt-get install libgflags-dev libgoogle-glog-dev liblmdb-dev sudo apt-get install libopenblas-dev sudo apt-get install libatlas-base-dev
git clone https://github.com/BVLC/caffe.git cd caffe git checkout eeebdab16155d34ff8f5f42137da7df4d1c7eab0 cp Makefile.config.example Makefile.config
#CPU only version: CPU_ONLY := 1 #Add hdf5 and protobuf include and library directories (Replace $HOME with explicit /home/username dir): INCLUDE_DIRS := $(PYTHON_INCLUDE) /usr/local/include /usr/include/hdf5/serial/ $HOME/armnn-devenv/google/x86_64_pb_install/include/ LIBRARY_DIRS := $(PYTHON_LIB) /usr/local/lib /usr/lib /usr/lib/x86_64-linux-gnu/hdf5/serial/ $HOME/armnn-devenv/google/x86_64_pb_install/lib/
export PATH=$HOME/armnn-devenv/google/x86_64_pb_install/bin/:$PATH export LD_LIBRARY_PATH=$HOME/armnn-devenv/google/x86_64_pb_install/lib/:$LD_LIBRARY_PATH
make all make test make runtest # These should all run without errors
tar -zxvf boost_1_64_0.tar.gz cd boost_1_64_0 echo "using gcc : arm : aarch64-linux-gnu-g++ ;" > user_config.jam ./bootstrap.sh --prefix=$HOME/armnn-devenv/boost_arm64_install ./b2 install toolset=gcc-arm link=static cxxflags=-fPIC --with-test --with-log --with-program_options -j32 --user-config=user_config.jam
git clone https://github.com/ARM-software/ComputeLibrary.git cd ComputeLibrary/ git checkout <branch_name> git pull scons arch=arm64-v8a neon=1 opencl=1 embed_kernels=1 extra_cxx_flags="-fPIC" -j8 internal_only=0
For example, if you want to checkout release branch of 20.02:
git checkout branches/arm_compute_20_02 git pull
git clone https://github.com/tensorflow/tensorflow.git cd tensorflow/ git checkout fcc4b966f1265f466e82617020af93670141b009 ../armnn/scripts/generate_tensorflow_protobuf.sh ../tensorflow-protobuf ../google/x86_64_pb_install
wget -O flatbuffers-1.12.0.tar.gz https://github.com/google/flatbuffers/archive/v1.12.0.tar.gz tar xf flatbuffers-1.12.0.tar.gz cd flatbuffers-1.12.0 rm -f CMakeCache.txt mkdir build cd build cmake .. -DFLATBUFFERS_BUILD_FLATC=1 \ -DCMAKE_INSTALL_PREFIX:PATH=$<DIRECTORY_PATH> \ -DFLATBUFFERS_BUILD_TESTS=0 make all install
mkdir build-arm64 cd build-arm64 # Add -fPIC to allow us to use the libraries in shared objects. CXXFLAGS="-fPIC" cmake .. -DCMAKE_C_COMPILER=/usr/bin/aarch64-linux-gnu-gcc \ -DCMAKE_CXX_COMPILER=/usr/bin/aarch64-linux-gnu-g++ \ -DFLATBUFFERS_BUILD_FLATC=1 \ -DCMAKE_INSTALL_PREFIX:PATH=$<DIRECTORY_PATH> \ -DFLATBUFFERS_BUILD_TESTS=0 make all install
git clone https://github.com/onnx/onnx.git cd onnx git fetch https://github.com/onnx/onnx.git 553df22c67bee5f0fe6599cff60f1afc6748c635 && git checkout FETCH_HEAD export LD_LIBRARY_PATH=$<DIRECTORY_PATH>/protobuf-host/lib:$LD_LIBRARY_PATH ../google/x86_64_pb_install/bin/protoc onnx/onnx.proto --proto_path=. --proto_path=../google/x86_64_pb_install/include --cpp_out ../onnx
mkdir tflite cd tflite cp ../tensorflow/tensorflow/lite/schema/schema.fbs . ../flatbuffers-1.12.0/build/flatc -c --gen-object-api --reflect-types --reflect-names schema.fbs
git clone https://github.com/ARM-software/armnn.git cd armnn git checkout <branch_name> git pull mkdir build cd build
For example, if you want to checkout release branch of 20.02:
git checkout branches/armnn_20_02 git pull
#!/bin/bash export CXX=aarch64-linux-gnu-g++ \ export CC=aarch64-linux-gnu-gcc \ cmake .. \ -DARMCOMPUTE_ROOT=$HOME/armnn-devenv/ComputeLibrary \ -DARMCOMPUTE_BUILD_DIR=$HOME/armnn-devenv/ComputeLibrary/build/ \ -DBOOST_ROOT=$HOME/armnn-devenv/boost_arm64_install/ \ -DARMCOMPUTENEON=1 -DARMCOMPUTECL=1 -DARMNNREF=1 \ -DCAFFE_GENERATED_SOURCES=$HOME/armnn-devenv/caffe/build/src \ -DBUILD_CAFFE_PARSER=1 \ -DONNX_GENERATED_SOURCES=$HOME/onnx \ -DBUILD_ONNX_PARSER=1 \ -DTF_GENERATED_SOURCES=$HOME/tensorflow-protobuf \ -DBUILD_TF_PARSER=1 \ -DBUILD_TF_LITE_PARSER=1 \ -DTF_LITE_GENERATED_PATH=$HOME/tflite \ -DFLATBUFFERS_ROOT=$HOME/flatbuffers-arm64 \ -DFLATC_DIR=$HOME/flatbuffers-1.12.0/build \ -DPROTOBUF_ROOT=$HOME/google/x86_64_pb_install \ -DPROTOBUF_ROOT=$HOME/armnn-devenv/google/x86_64_pb_install/ \ -DPROTOBUF_LIBRARY_DEBUG=$HOME/armnn-devenv/google/arm64_pb_install/lib/libprotobuf.so.23.0.0 \ -DPROTOBUF_LIBRARY_RELEASE=$HOME/armnn-devenv/google/arm64_pb_install/lib/libprotobuf.so.23.0.0
-DSAMPLE_DYNAMIC_BACKEND=1 \ -DDYNAMIC_BACKEND_PATHS=$SAMPLE_DYNAMIC_BACKEND_PATH
make -j32
mkdir build
cd build
#!/bin/bash export CXX=aarch64-linux-gnu-g++ \ export CC=aarch64-linux-gnu-gcc \ cmake .. \ -DCMAKE_CXX_FLAGS=--std=c++14 \ -DBOOST_ROOT=$HOME/armnn-devenv/boost_arm64_install/ \ -DBoost_SYSTEM_LIBRARY=$HOME/armnn-devenv/boost_arm64_install/lib/libboost_system.a \ -DARMNN_PATH=$HOME/armnn-devenv/armnn/build/libarmnn.so
make
cd build/ export LD_LIBRARY_PATH=<current_working_directory>
ln -s libprotobuf.so.23.0.0 ./libprotobuf.so.23
./UnitTests Running 567 test cases... *** No errors detected
/usr/local/lib/libboost_log.a: error adding symbols: File in wrong format collect2: error: ld returned 1 exit status CMakeFiles/armnn.dir/build.make:4028: recipe for target 'libarmnn.so' failed make[2]: *** [libarmnn.so] Error 1 CMakeFiles/Makefile2:105: recipe for target 'CMakeFiles/armnn.dir/all' failed make[1]: *** [CMakeFiles/armnn.dir/all] Error 2 Makefile:127: recipe for target 'all' failed make: *** [all] Error 2
virtual memory exhausted: Cannot allocate memory
aarch64-linux-gnu-g++: error: unrecognized command line option ‘-m64’
sudo ./b2 clean
- 32-bit : no - 64-bit : yes - arm : yes
/usr/lib/gcc-cross/aarch64-linux-gnu/5/../../../../aarch64-linux-gnu/bin/ld: warning: libz.so.1, needed by /home/<username>/armNN/usr/lib64/libprotobuf.so.23.0.0, not found (try using -rpath or -rpath-link)
sudo dpkg --add-architecture arm64 sudo apt-get install zlib1g:arm64 sudo apt-get update sudo ldconfig
sudo dpkg -i zlib1g_1.2.8.dfsg-2ubuntu4_arm64.deb
Using sudo apt-get update should add all of the required repos for arm64 but if it does not or you are getting 404 errors the following instructions can be used to add the repos manually:
From stackoverflow: https://askubuntu.com/questions/430705/how-to-use-apt-get-to-download-multi-arch-library/430718
Open /etc/apt/sources.list with your preferred text editor.
Mark all the current (default) repos as [arch=<current_os_arch>], e.g.
deb [arch=amd64] http://archive.ubuntu.com/ubuntu/ xenial main restricted
deb [arch=arm64] http://ports.ubuntu.com/ xenial main restricted deb [arch=arm64] http://ports.ubuntu.com/ xenial-updates main restricted deb [arch=arm64] http://ports.ubuntu.com/ xenial universe deb [arch=arm64] http://ports.ubuntu.com/ xenial-updates universe deb [arch=arm64] http://ports.ubuntu.com/ xenial multiverse deb [arch=arm64] http://ports.ubuntu.com/ xenial-updates multiverse deb [arch=arm64] http://ports.ubuntu.com/ xenial-backports main restricted universe multiverse
sudo apt-get install zlib1g:arm64 sudo apt-get update sudo ldconfig
libarmnnCaffeParser.so: undefined reference to `google::protobuf:*
cc1plus: error: unrecognized command line option ‘-Wno-implicit-fallthrough’ [-Werror]
scons arch=arm64-v8a neon=1 opencl=1 embed_kernels=1 extra_cxx_flags="-fPIC" -j8 internal_only=0 Werror=0