使用 Android NDK 編譯 Arm NN

Note of Compilation of Arm NN by Android NDK

Posted by imprld01 on Friday, July 8, 2022

目錄


版本對齊

  1. Android API Version:29
  2. System:aarch64、armv7a
  3. Arm NN:branches/armnn_22_05
  4. Android NDK:android-ndk-r20b-linux-x86_64

Dockerfile

FROM ubuntu:18.04
ENV TERM linux
ENV DEBIAN_FRONTEND noninteractive

# Forward system proxy setting
# ARG proxy
# ENV http_proxy $proxy
# ENV https_proxy $proxy

# Basic apt update
RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends locales ca-certificates &&  rm -rf /var/lib/apt/lists/*

# Set the locale to en_US.UTF-8, because the Yocto build fails without any locale set.
RUN locale-gen en_US.UTF-8 && update-locale LC_ALL=en_US.UTF-8 LANG=en_US.UTF-8
ENV LANG en_US.UTF-8
ENV LC_ALL en_US.UTF-8

# Again, off the certificare
RUN echo "check_certificate = off" >> ~/.wgetrc
RUN echo "[global] \n\
trusted-host = pypi.python.org \n \
\t               pypi.org \n \
\t              files.pythonhosted.org" >> /etc/pip.conf

# Get basic packages
RUN apt-get update && apt-get install -y \
    apparmor \
    aufs-tools \
    automake \
    bash-completion \
    btrfs-tools \
    build-essential \
    cmake \
    createrepo \
    curl \
    dpkg-sig \
    g++ \
    gcc \
    git \
    iptables \
    jq \
    libapparmor-dev \
    libc6-dev \
    libcap-dev \
    libsystemd-dev \
    libyaml-dev \
    mercurial \
    net-tools \
    parallel \
    pkg-config \
    python-dev \
    python-mock \
    python-pip \
    python-setuptools \
    python-websocket \
    golang-go \
    iproute2 \
    iputils-ping \
    vim-common \
    vim \
    wget \
    libtool \
    unzip \
    scons \
    curl \
    autoconf \
    libtool \
    build-essential \
    libssl-dev \
    g++ && rm -rf /var/lib/apt/lists/*

#
RUN apt-get update

# Install Cmake 3.23.2
RUN cd /home/ && \
    wget -O cmake-3.23.2.tar.gz https://cmake.org/files/v3.23/cmake-3.23.2.tar.gz && \
    tar -xzf cmake-3.23.2.tar.gz && \
    cd /home/cmake-3.23.2 && \
    ./bootstrap && \
    make && \
    make install
sudo docker build --rm -t imprld01/armnn:v1 . --no-cache
MYPARENT=/my_armnn_scripts/
sudo mkdir -p $MYPARENT/packages/home/
sudo docker run --rm --gpus all --net host -it --shm-size=30g \
                -v $MYPARENT/:/armnn_envs_ndk/ \
                -v $MYPARENT/packages/home/:/home/ \
                imprld01/armnn:v1 bash

編譯步驟

  1. 下載Android NDK,以及TensorFlow、Arm NN、Boost C++:

    #!/bin/bash
    
    # Download the Android NDK and make a standalone toolchain
    mkdir -p /home/armnn-devenv/ && \
        cd /home/armnn-devenv/ && \
        wget https://dl.google.com/android/repository/android-ndk-r20b-linux-x86_64.zip && \
        unzip android-ndk-r20b-linux-x86_64.zip
    
    mkdir -p /home/armnn-devenv/google
    
    # clone tensorflow
    cd /home/armnn-devenv/google/
    git clone https://github.com/tensorflow/tensorflow.git 
    
    # clone armnn
    cd /home/armnn-devenv/
    git clone https://github.com/ARM-software/armnn.git
    cd /home/armnn-devenv/armnn/
    git checkout branches/armnn_22_05
    git pull
    
    # clone the Boost C++ libraries
    mkdir -p /home/armnn-devenv/boost && \
        cd /home/armnn-devenv/boost && \
        wget https://boostorg.jfrog.io/artifactory/main/release/1.64.0/source/boost_1_64_0.tar.bz2 && \
        tar xvf boost_1_64_0.tar.bz2
    
  2. 建置Boost C++與Compute Library

    #!/bin/bash
    
    export NDK=/home/armnn-devenv/android-ndk-r20b
    export NDK_TOOLCHAIN_ROOT=$NDK/toolchains/llvm/prebuilt/linux-x86_64
    export PATH=$NDK_TOOLCHAIN_ROOT/bin/:$PATH
    
    #C_PREFIX=""
    C_PREFIX=eabi
    ANDROID_API=29
    
    AECH_NAME=armv7a
    #AECH_NAME=aarch64
    
    AABI_NAME=armv7a
    #AABI_NAME=arm64-v8a
    
    # Build the Boost C++ libraries
    echo "using gcc : arm : ${AECH_NAME}-linux-android${C_PREFIX}${ANDROID_API}-clang++ ;" > /home/armnn-devenv/boost/user-config.jam && \
        cd /home/armnn-devenv/boost/boost_1_64_0 && \
        ./bootstrap.sh --prefix=/home/armnn-devenv/boost/install && \
        ./b2 install --user-config=/home/armnn-devenv/boost/user-config.jam \
        toolset=gcc-arm link=static cxxflags=-fPIC --with-filesystem \
        --with-test --with-log --with-program_options -j16
    
    # Build the Compute Library
    cd /home/armnn-devenv
    git clone https://github.com/ARM-software/ComputeLibrary.git
    cd ComputeLibrary
    #git checkout $(/home/armnn-devenv/armnn/scripts/get_compute_library.sh -p)
    scons arch=${AABI_NAME} neon=1 opencl=1 embed_kernels=1 cppthreads=1 openmp=0 \
        compiler_prefix="${AECH_NAME}-linux-android${C_PREFIX}${ANDROID_API}-" \
        extra_cxx_flags="-fPIC" \
        extra_link_flags="-fPIC" \
        benchmark_tests=0 validation_tests=0 os=android -j16
    
    • 平台若不支援OpenCL,則調整Compute Library參數opencl=0
  3. 下載並編譯Protobuf,接著生成TensorFlow的Protobuf定義

    #!/bin/bash
    
    export NDK=/home/armnn-devenv/android-ndk-r20b
    export NDK_TOOLCHAIN_ROOT=$NDK/toolchains/llvm/prebuilt/linux-x86_64
    export PATH=$NDK_TOOLCHAIN_ROOT/bin/:$PATH
    
    #C_PREFIX=""
    C_PREFIX=eabi
    ANDROID_API=29
    
    AECH_NAME=armv7a
    #AECH_NAME=aarch64
    
    AABI_NAME=armeabi-v7a
    #AABI_NAME=arm64-v8a
    
    # protobuf
    #mkdir -p /home/armnn-devenv/google && \
    #    cd /home/armnn-devenv/google && \
    #    wget https://github.com/protocolbuffers/protobuf/releases/download/v3.12.0/protobuf-all-3.12.0.tar.gz && \
    #    tar -zxvf protobuf-all-3.12.0.tar.gz
    mkdir -p /home/armnn-devenv/google
    cd /home/armnn-devenv/google
    git clone https://github.com/google/protobuf.git protobuf-3.12.0
    cd protobuf-3.12.0
    ./autogen.sh
    
    cd /home/armnn-devenv/google/protobuf-3.12.0
    mkdir x86_build
    cd x86_build
    CFLAGS="-fPIE -fPIC" \
        CXXFLAGS="-g -std=c++11 -DNDEBUG -lpthread -fno-short-enums -fno-short-enums -lstdc++" \
        LDFLAGS="-pthread -Wl,--no-as-needed -Wl,--whole-archive -lpthread -Wl,--no-whole-archive -static -static-libstdc++" \
        ../configure --prefix=/home/armnn-devenv/google/x86_pb_install && \
        make install -j32
    
    cd /home/armnn-devenv/google/protobuf-3.12.0
    mkdir arm64_build
    cd arm64_build
    CC=$AECH_NAME-linux-android${C_PREFIX}${ANDROID_API}-clang \
        CXX=$AECH_NAME-linux-android${C_PREFIX}${ANDROID_API}-clang++ \
        CFLAGS="-fPIE -fPIC -llog" CXXFLAGS="-fPIE -fPIC -llog" \
        LDFLAGS="-llog -lz -lc++_static" \
        ../configure --host=$AECH_NAME-linux-android${C_PREFIX} \
        --prefix=/home/armnn-devenv/google/arm64_pb_install \
        --enable-cross-compile \
        --with-protoc=/home/armnn-devenv/google/x86_pb_install/bin/protoc && \
        make install -j32
    
    # generate tensorFlow protobuf definitions
    cd /home/armnn-devenv/google/tensorflow/
    git checkout $(/home/armnn-devenv/armnn/scripts/get_tensorflow.sh -p)
    /home/armnn-devenv/armnn/scripts/generate_tensorflow_protobuf.sh \
    /home/armnn-devenv/google/tf_pb /home/armnn-devenv/google/x86_pb_install
    
    • 問題記錄

      錯誤訊息

      ./.libs/libprotoc.so: error: undefined reference to 'descriptor_table_google_2fprotobuf_2fdescriptor_2eproto'
      ./.libs/libprotoc.so: error: undefined reference to 'scc_info_FileDescriptorProto_google_2fprotobuf_2fdescriptor_2eproto'
      

      解決方式:修改armnn-devenv/google/protobuf-3.12.0/src/下的libprotoc.maplibprotobuf.maplibprotobuf-lite.map,記得改完之後,不要執行./autogen.sh,否則修改會被覆蓋掉。

      {
        global:
          extern "C++" {
            *google*;
          };
          scc_info_*;
          descriptor_table_*;
      
        local:
          *;
      };
      
  4. 下載並建置Flatbuffers

    #!/bin/bash
    
    export NDK=/home/armnn-devenv/android-ndk-r20b
    export NDK_TOOLCHAIN_ROOT=$NDK/toolchains/llvm/prebuilt/linux-x86_64
    export PATH=$NDK_TOOLCHAIN_ROOT/bin/:$PATH
    
    #C_PREFIX=""
    C_PREFIX=eabi
    ANDROID_API=29
    
    AECH_NAME=armv7a
    #AECH_NAME=aarch64
    
    # Download Flatbuffers
    cd /home/armnn-devenv && \
        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
    
    cd /home/armnn-devenv && cd flatbuffers-1.12.0 && \
        mkdir build && \
        cd build && \
        cmake .. -DFLATBUFFERS_BUILD_FLATC=1 \
             -DCMAKE_INSTALL_PREFIX:PATH=/home/armnn-devenv/flatbuffers \
             -DFLATBUFFERS_BUILD_TESTS=0 && \
        make all install -j16
    
    cd /home/armnn-devenv && cd flatbuffers-1.12.0  && \
        cp /armnn_envs_ndk/flatbuffers-1.12.0/CMakeLists.txt . && \
        mkdir build-arm64 && \
        cd build-arm64 && \
        CXXFLAGS="-fPIC" CFLAGS="-fPIE -fPIC" && \
        cmake .. -DCMAKE_C_COMPILER=$AECH_NAME-linux-android${C_PREFIX}${ANDROID_API}-clang \
             -DCMAKE_CXX_COMPILER=$AECH_NAME-linux-android${C_PREFIX}${ANDROID_API}-clang++ \
             -DCMAKE_ANDROID_NDK=$NDK \
             -DCMAKE_SYSTEM_VERSION=$ANDROID_API \
             -DCMAKE_SYSTEM_NAME=Android \
             -DFLATBUFFERS_BUILD_FLATC=1 \
             -DCMAKE_INSTALL_PREFIX:PATH=/home/armnn-devenv/flatbuffers-arm64 \
             -DFLATBUFFERS_BUILD_TESTS=0 && \
             make all install -j16
    
  5. 建置TensorFlow Lite

    #!/bin/bash
    
    export NDK=/home/armnn-devenv/android-ndk-r20b
    export NDK_TOOLCHAIN_ROOT=$NDK/toolchains/llvm/prebuilt/linux-x86_64
    export PATH=$NDK_TOOLCHAIN_ROOT/bin/:$PATH
    
    #C_PREFIX=""
    C_PREFIX=eabi
    ANDROID_API=29
    
    AECH_NAME=armv7a
    #AECH_NAME=aarch64
    
    AABI_NAME=armeabi-v7a
    #AABI_NAME=arm64-v8a
    
    # Build TF Lite
    cd /home/armnn-devenv && mkdir -p tflite/build
    cd tflite/build && \
        ARMCC_PREFIX=$AECH_NAME-linux-android${C_PREFIX}${ANDROID_API}- && \
        ARMCC_FLAGS="-funsafe-math-optimizations -fPIC" && \
        ARMCX_FLAGS="-funsafe-math-optimizations -fPIC" && \
        cmake -DCMAKE_C_COMPILER=${ARMCC_PREFIX}clang \
              -DCMAKE_CXX_COMPILER=${ARMCC_PREFIX}clang++ \
              -DCMAKE_C_FLAGS="${ARMCC_FLAGS}" -DCMAKE_CXX_FLAGS="${ARMCX_FLAGS}" \
              -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON  -DCMAKE_SYSTEM_NAME=Android \
              -DCMAKE_TOOLCHAIN_FILE=$NDK/build/cmake/android.toolchain.cmake \
              -DCMAKE_ANDROID_NDK=$NDK \
              -DCMAKE_SYSTEM_VERSION=$ANDROID_API \
              -DANDROID_PLATFORM=android-$ANDROID_API \
              -DTFLITE_ENABLE_XNNPACK=OFF \
              -DCMAKE_SYSTEM_PROCESSOR=$AECH_NAME \
              -DANDROID_ABI=$AABI_NAME \
              -DTFLITE_ENABLE_GPU=OFF \
              -DEIGEN_TEST_CXX11=ON \
              /home/armnn-devenv/google/tensorflow/tensorflow/lite/
    
    cmake --build .
    
  6. 生成TensorFlow Lite的Schema,並建置ONNX

    #!/bin/bash
    
    export NDK=/home/armnn-devenv/android-ndk-r20b
    export NDK_TOOLCHAIN_ROOT=$NDK/toolchains/llvm/prebuilt/linux-x86_64
    export PATH=$NDK_TOOLCHAIN_ROOT/bin/:$PATH
    
    # Generate TF Lite Schema
    cd /home/armnn-devenv && \
        cd tflite && \
        cp /home/armnn-devenv/google/tensorflow/tensorflow/lite/schema/schema.fbs . && \
        /home/armnn-devenv/flatbuffers-1.12.0/build/flatc -c --gen-object-api --reflect-types --reflect-names schema.fbs
    
    # Build onnx
    cd /home/armnn-devenv
    git clone https://github.com/onnx/onnx.git
    cd onnx && \
        git fetch https://github.com/onnx/onnx.git 553df22c67bee5f0fe6599cff60f1afc6748c635 && git checkout FETCH_HEAD && \
        LD_LIBRARY_PATH=/home/armnn-devenv/google/x86_pb_install/lib:$LD_LIBRARY_PATH \
        /home/armnn-devenv/google/x86_pb_install/bin/protoc \
        onnx/onnx.proto --proto_path=. --proto_path=../google/x86_pb_install/include --cpp_out /home/armnn-devenv/onnx
    
  7. 針對Arm NN的單元測試,修改CMakeLists.txt,增加函式庫連結至${TfLite_flatbuffers_LIB}

    if(BUILD_TF_LITE_PARSER)
        target_include_directories(UnitTests SYSTEM PRIVATE "${TF_LITE_SCHEMA_INCLUDE_PATH}")
        target_include_directories(UnitTests SYSTEM PRIVATE "${FLATBUFFERS_INCLUDE_PATH}")
        target_link_libraries(UnitTests ${TfLite_flatbuffers_LIB})
        target_link_libraries(UnitTests armnnTfLiteParser)
    endif()
    
    if(BUILD_ARMNN_SERIALIZER AND ARMNNREF)
        target_include_directories(UnitTests SYSTEM PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/src/armnnSerializer)
        target_include_directories(UnitTests SYSTEM PRIVATE "${FLATBUFFERS_INCLUDE_PATH}")
        target_link_libraries(UnitTests ${TfLite_flatbuffers_LIB})
        target_link_libraries(UnitTests armnnSerializer)
    endif()
    
    • 如果建置Arm NN時,設定-DBUILD_UNIT_TESTS=0,則可以省略此步驟

    • 因為遇到下面錯誤,所以才執行此步驟:

      /home/armnn-devenv/armnn/src/armnnTfLiteParser/test/ParserFlatbuffersFixture.hpp:167: error: undefined reference to 'flatbuffers::Parser::Parse(char const*, char const**, char const*)'
      /home/armnn-devenv/armnn/src/armnnTfLiteParser/test/ParserFlatbuffersFixture.hpp:170: error: undefined reference to 'flatbuffers::Parser::Parse(char const*, char const**, char const*)'
      /home/armnn-devenv/armnn/src/armnnTfLiteParser/test/LoadModel.cpp:203: error: undefined reference to 'flatbuffers::SaveFile(char const*, char const*, unsigned int, bool)'
      /home/armnn-devenv/armnn/src/armnnDeserializer/test/ParserFlatbuffersSerializeFixture.hpp:98: error: undefined reference to 'flatbuffers::Parser::Parse(char const*, char const**, char const*)'
      /home/armnn-devenv/armnn/src/armnnDeserializer/test/ParserFlatbuffersSerializeFixture.hpp:101: error: undefined reference to 'flatbuffers::Parser::Parse(char const*, char const**, char const*)'
      
  8. 針對Arm NN的需求,依需求作修改檔案armnn/delegate/cmake/Modules/FindTfLite.cmake

    find_library(TfLite_throw_delegate_LIB "libabsl_throw_delegate.a"
                 PATH ${TFLITE_LIB_ROOT}/_deps/abseil-cpp-build/absl/base)
    find_library(TfLite_raw_logging_internal_LIB "libabsl_raw_logging_internal.a"
                 PATH ${TFLITE_LIB_ROOT}/_deps/abseil-cpp-build/absl/base)
    
    ## Set TFLITE_FOUND if all libraries are satisfied for static lib
    find_package_handle_standard_args(TfLite DEFAULT_MSG TfLite_LIB TfLite_abseilstrings_LIB TfLite_ruy_LIB TfLite_fftsg_LIB TfLite_fftsg2d_LIB TfLite_farmhash_LIB TfLite_flatbuffers_LIB TfLite_throw_delegate_LIB TfLite_raw_logging_internal_LIB)
    # Set external variables for usage in CMakeLists.txt
    if (TFLITE_FOUND)
        set(TfLite_LIB ${TfLite_LIB} ${TfLite_abseilstrings_LIB} ${TfLite_ruy_LIB} ${TfLite_fftsg_LIB} ${TfLite_fftsg2d_LIB} ${TfLite_farmhash_LIB} ${TfLite_flatbuffers_LIB} ${TfLite_throw_delegate_LIB} ${TfLite_raw_logging_internal_LIB})
    endif ()
    
    • 因為遇到下面錯誤,所以才執行此步驟:

      /home/armnn-devenv/tflite/build/abseil-cpp/absl/strings/numbers.cc:99: error: undefined reference to 'absl::lts_2020_02_25::raw_logging_internal::RawLog(absl::lts_2020_02_25::LogSeverity, char const*, int, char const*, ...)'
      /home/armnn-devenv/tflite/build/abseil-cpp/absl/strings/string_view.h:387: error: undefined reference to 'absl::lts_2020_02_25::base_internal::ThrowStdOutOfRange(char const*)'
      
  9. 建置Arm NN

    #!/bin/bash
    
    export NDK=/home/armnn-devenv/android-ndk-r20b
    export NDK_TOOLCHAIN_ROOT=$NDK/toolchains/llvm/prebuilt/linux-x86_64
    export PATH=$NDK_TOOLCHAIN_ROOT/bin/:$PATH
    
    #C_PREFIX=""
    C_PREFIX=eabi
    ANDROID_API=29
    
    AECH_NAME=armv7a
    #AECH_NAME=aarch64
    
    AABI_NAME=armeabi-v7a
    #AABI_NAME=arm64-v8a
    
    cd /home/armnn-devenv/armnn/
    mkdir build
    cd build && \
        export CXX=$AECH_NAME-linux-android${C_PREFIX}${ANDROID_API}-clang++ && \
        export CC=$AECH_NAME-linux-android${C_PREFIX}${ANDROID_API}-clang && \
        cmake .. \
        -DCMAKE_C_FLAGS="-w -fPIE -fPIC -lc++_shared -I/home/armnn-devenv/google/tensorflow/" \
        -DCMAKE_CXX_FLAGS="-w -fPIE -fPIC -pthread -latomic -lc++_shared -I/home/armnn-devenv/google/tensorflow/" \
        -DBUILD_TESTS=1 -DBUILD_UNIT_TESTS=1 \
        -DCMAKE_ANDROID_NDK=$NDK \
        -DCMAKE_SYSTEM_NAME=Android \
        -DCMAKE_SYSTEM_VERSION=29 \
        -DCMAKE_ANDROID_ARCH_ABI=$AABI_NAME \
        -DCMAKE_SYSROOT=$NDK_TOOLCHAIN_ROOT/sysroot \
        -DCMAKE_ANDROID_STANDALONE_TOOLCHAIN=$NDK_TOOLCHAIN_ROOT \
        -DCMAKE_EXE_LINKER_FLAGS="-pie -llog -lz" \
        -DARMCOMPUTE_ROOT=/home/armnn-devenv/ComputeLibrary/ \
        -DARMCOMPUTE_BUILD_DIR=/home/armnn-devenv/ComputeLibrary/build/ \
        -DBOOST_ROOT=/home/armnn-devenv/boost/install/ \
        -DBoost_LIBRARY_DIR=/home/armnn-devenv/boost/install/lib \
        -DBoost_INCLUDE_DIR=/home/armnn-devenv/boost/install/include \
        -DFLATBUFFERS_ROOT=/home/armnn-devenv/flatbuffers-arm64 \
        -DFLATBUFFERS_INCLUDE_PATH=/home/armnn-devenv/flatbuffers-arm64/include \
        -DFLATBUFFERS_LIBRARY=/home/armnn-devenv/flatbuffers-arm64/lib \
        -DFLATBUFFERS_LIBRARY_DEBUG=/home/armnn-devenv/flatbuffers-arm64/lib/libflatbuffers.a \
        -DFLATBUFFERS_LIBRARY_RELEASE=/home/armnn-devenv/flatbuffers-arm64/lib/libflatbuffers.a \
        -DFLATC_DIR=/home/armnn-devenv/flatbuffers-1.12.0/build \
        -DBUILD_ARMNN_TFLITE_DELEGATE=1 \
        -DTENSORFLOW_ROOT=/home/armnn-devenv/google/tensorflow \
        -DTFLITE_LIB_ROOT=/home/armnn-devenv/tflite/build \
        -DFlatbuffers_LIB=/home/armnn-devenv/flatbuffers-arm64/lib \
        -DFlatbuffers_INCLUDE_DIR=/home/armnn-devenv/flatbuffers-arm64/include \
        -DTfLite_INCLUDE_DIR=/home/armnn-devenv/google/tensorflow/ \
        -DTfLite_Schema_INCLUDE_PATH=/home/armnn-devenv/tflite \
        -DTfLite_LIB=/home/armnn-devenv/tflite/build/libtensorflow-lite.a \
        -DTfLite_abseilstrings_LIB=/home/armnn-devenv/tflite/build/_deps/abseil-cpp-build/absl/strings/libabsl_strings.a \
        -DTfLite_farmhash_LIB=/home/armnn-devenv/tflite/build/_deps/farmhash-build/libfarmhash.a \
        -DTfLite_fftsg_LIB=/home/armnn-devenv/tflite/build/_deps/fft2d-build/libfft2d_fftsg.a \
        -DTfLite_fftsg2d_LIB=/home/armnn-devenv/tflite/build/_deps/fft2d-build/libfft2d_fftsg2d.a \
        -DTfLite_ruy_LIB=/home/armnn-devenv/tflite/build/_deps/ruy-build/libruy.a \
        -DTfLite_flatbuffers_LIB=/home/armnn-devenv/tflite/build/_deps/flatbuffers-build/libflatbuffers.a \
        -DTfLite_throw_delegate_LIB=/home/armnn-devenv/tflite/build/_deps/abseil-cpp-build/absl/base/libabsl_throw_delegate.a \
        -DTfLite_raw_logging_internal_LIB=/home/armnn-devenv/tflite/build/_deps/abseil-cpp-build/absl/base/libabsl_raw_logging_internal.a \
        -DBUILD_TF_LITE_PARSER=1 \
        -DTF_LITE_GENERATED_PATH=/home/armnn-devenv/tflite \
        -DTF_GENERATED_SOURCES=/home/armnn-devenv/google/tf_pb/ \
        -DBUILD_TF_PARSER=1 \
        -DTF_LITE_SCHEMA_INCLUDE_PATH=/home/armnn-devenv/tflite \
        -DBUILD_ONNX_PARSER=1 \
        -DONNX_GENERATED_SOURCES=/home/armnn-devenv/onnx \
        -DARMCOMPUTENEON=1 -DARMCOMPUTECL=1 -DARMNNREF=1 \
        -DPROTOBUF_ROOT=/home/armnn-devenv/google/arm64_pb_install \
        -DPROTOBUF_LIBRARY=/home/armnn-devenv/google/arm64_pb_install/lib \
        -DPROTOBUF_LIBRARY_DEBUG=/home/armnn-devenv/google/arm64_pb_install/lib/libprotobuf.so \
        -DPROTOBUF_LIBRARY_RELEASE=/home/armnn-devenv/google/arm64_pb_install/lib/libprotobuf.so \
        -DBUILD_ARMNN_SERIALIZER=1 -DBUILD_GATORD_MOCK=0 -DBUILD_BASE_PIPE_SERVER=0 \
        -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON && \
        make -j32
    
    • 平台若不支援OpenCL,則調整Arm NN參數-DARMCOMPUTECL=0
  10. 在目標平台上運行UnitTests

    #!/bin/bash
    
    export NDK=/home/armnn-devenv/android-ndk-r20b
    export NDK_TOOLCHAIN_ROOT=$NDK/toolchains/llvm/prebuilt/linux-x86_64
    export PATH=$NDK_TOOLCHAIN_ROOT/bin/:$PATH
    
    apt install -y android-tools-fastboot
    
    adb connect 192.11.22.33:5555
    adb root
    adb connect 192.11.22.33:5555
    adb remount
    adb connect 192.11.22.33:5555
    
    AABI_NAME=armeabi-v7a
    #AABI_NAME=arm64-v8a
    
    TARGET_LIB_PATH=/vendor/lib
    #TARGET_LIB_PATH=/vendor/lib64
    
    # prepare required data and lib
    cd /home/armnn-devenv/armnn/build/
    adb push libarmnn.so /data/local/tmp/
    adb push libarmnnUtils.a /data/local/tmp/
    adb push libarmnnTestUtils.so /data/local/tmp/
    adb push libarmnnOnnxParser.so /data/local/tmp/
    adb push libarmnnSerializer.so /data/local/tmp/
    adb push libtimelineDecoder.so /data/local/tmp/
    adb push libarmnnTfLiteParser.so /data/local/tmp/
    adb push libtimelineDecoderJson.so /data/local/tmp/
    adb push UnitTests /data/local/tmp/
    adb push $NDK/sources/cxx-stl/llvm-libc++/libs/$AABI_NAME/libc++_shared.so /data/local/tmp/
    adb push /home/armnn-devenv/google/arm64_pb_install/lib/libprotobuf.so /data/local/tmp/libprotobuf.so.23.0.0
    adb shell 'ln -s libprotobuf.so.23.0.0 /data/local/tmp/libprotobuf.so.23'
    adb shell 'ln -s libprotobuf.so.23.0.0 /data/local/tmp/libprotobuf.so'
    #
    adb shell mkdir -p /data/local/tmp/src/backends/backendsCommon/test/testSharedObject
    adb push -p /home/armnn-devenv/armnn/build/src/backends/backendsCommon/test/testSharedObject/* /data/local/tmp/src/backends/backendsCommon/test/testSharedObject/
    #
    adb shell mkdir -p /data/local/tmp/src/backends/backendsCommon/test/testDynamicBackend
    adb push -p /home/armnn-devenv/armnn/build/src/backends/backendsCommon/test/testDynamicBackend/* /data/local/tmp/src/backends/backendsCommon/test/testDynamicBackend/
    #
    adb shell mkdir -p /data/local/tmp/src/backends/backendsCommon/test/backendsTestPath1
    adb push -p /home/armnn-devenv/armnn/build/src/backends/backendsCommon/test/backendsTestPath1/* /data/local/tmp/src/backends/backendsCommon/test/backendsTestPath1/
    #
    adb shell mkdir -p /data/local/tmp/src/backends/backendsCommon/test/backendsTestPath2
    adb push -p /home/armnn-devenv/armnn/build/src/backends/backendsCommon/test/backendsTestPath2/Arm_CpuAcc_backend.so /data/local/tmp/src/backends/backendsCommon/test/backendsTestPath2/
    adb shell ln -s Arm_CpuAcc_backend.so /data/local/tmp/src/backends/backendsCommon/test/backendsTestPath2/Arm_CpuAcc_backend.so.1
    adb shell ln -s Arm_CpuAcc_backend.so.1 /data/local/tmp/src/backends/backendsCommon/test/backendsTestPath2/Arm_CpuAcc_backend.so.1.2
    adb shell ln -s Arm_CpuAcc_backend.so.1.2 /data/local/tmp/src/backends/backendsCommon/test/backendsTestPath2/Arm_CpuAcc_backend.so.1.2.3
    adb push -p /home/armnn-devenv/armnn/build/src/backends/backendsCommon/test/backendsTestPath2/Arm_GpuAcc_backend.so /data/local/tmp/src/backends/backendsCommon/test/backendsTestPath2/
    adb shell ln -s nothing /data/local/tmp/src/backends/backendsCommon/test/backendsTestPath2/Arm_no_backend.so
    #
    adb shell mkdir -p /data/local/tmp/src/backends/backendsCommon/test/backendsTestPath3
    #
    adb shell mkdir -p /data/local/tmp/src/backends/backendsCommon/test/backendsTestPath5
    adb push -p /home/armnn-devenv/armnn/build/src/backends/backendsCommon/test/backendsTestPath5/* /data/local/tmp/src/backends/backendsCommon/test/backendsTestPath5/
    #
    adb shell mkdir -p /data/local/tmp/src/backends/backendsCommon/test/backendsTestPath6
    adb push -p /home/armnn-devenv/armnn/build/src/backends/backendsCommon/test/backendsTestPath6/* /data/local/tmp/src/backends/backendsCommon/test/backendsTestPath6/
    #
    adb shell mkdir -p /data/local/tmp/src/backends/backendsCommon/test/backendsTestPath7
    #
    adb shell mkdir -p /data/local/tmp/src/backends/backendsCommon/test/backendsTestPath9
    adb push -p /home/armnn-devenv/armnn/build/src/backends/backendsCommon/test/backendsTestPath9/* /data/local/tmp/src/backends/backendsCommon/test/backendsTestPath9/
    #
    adb shell mkdir -p /data/local/tmp/src/backends/dynamic/reference
    adb push -p /home/armnn-devenv/armnn/build/src/backends/dynamic/reference/Arm_CpuRef_backend.so /data/local/tmp/src/backends/dynamic/reference/
    
    # execute UnitTests
    adb shell 'LD_LIBRARY_PATH=/data/local/tmp:${TARGET_LIB_PATH}:${TARGET_LIB_PATH}/egl /data/local/tmp/UnitTests'
    

Further Reading

  1. Note of Cross Compilation on Arm NN - Arm NN 的交叉編譯筆記

Reference

  1. armnn/BuildGuideAndroidNDK.md at branches/armnn_22_05 · ARM-software/armnn
  2. How did I build Arm NN using Android NDK
  3. Boost C++ Libraries 簡介
  4. https://github.com/boostorg/boost/issues/298
  5. https://github.com/ARM-software/armnn/issues/659
  6. https://github.com/protocolbuffers/protobuf/issues/5144
  7. https://github.com/google/or-tools/issues/2196

comments powered by Disqus