# How to use the Android NDK to build Arm NN - [Introduction](#introduction) - [Prerequisites](#prerequisites) - [Download Arm NN](#download-arm-nn) - [Build Arm Compute Library](#build-arm-compute-library) - [Build Arm NN](#build-arm-nn) - [Build Arm NN Support Library](#build-arm-nn-support-library) - [Build Arm NN Shim](#build-arm-nn-shim) ## Introduction These are step by step instructions for building the Arm NN shim and support library for NNAPI. This work is currently in an experimental phase. ## Prerequisites The following are required to build the support library * Android NDK r20b * Detailed setup can be found in [BuildGuideAndroidNDK.md](../BuildGuideAndroidNDK.md) * Flatbuffer version 1.12.0 * Detailed setup can be found in [BuildGuideCrossCompilation.md](../BuildGuideCrossCompilation.md) * AOSP Source (Android Open Source Project) * Download the source from the [official website](https://source.android.com/setup/build/downloading) * This guide will use release tag `android12-s1-release` Set environment variables ```bash export AOSP_ROOT= export NDK=/android-ndk-r20b export NDK_TOOLCHAIN_ROOT=$NDK/toolchains/llvm/prebuilt/linux-x86_64 export PATH=$NDK_TOOLCHAIN_ROOT/bin/:$PATH ``` ## Download Arm NN * Clone Arm NN into the AOSP tree: (Requires Git if not previously installed: `sudo apt install git`) ```bash mkdir -p $AOSP_ROOT/vendor/arm/ cd $AOSP_ROOT/vendor/arm/ git clone https://github.com/ARM-software/armnn.git ``` ## Build Arm Compute Library Arm NN provides a script that downloads the version of Arm Compute Library that Arm NN was tested with: ```bash ./armnn/scripts/get_compute_library.sh ``` * Build the Arm Compute Library: (Requires SCons if not previously installed: `sudo apt install scons`) ```bash cd $AOSP_ROOT/vendor/arm/clframework scons arch=arm64-v8a \ toolchain_prefix=aarch64-linux-android- \ compiler_prefix=aarch64-linux-android29- \ neon=1 opencl=1 \ embed_kernels=1 \ build_dir=android-arm64v8a \ extra_cxx_flags="-Wno-parentheses-equality -Wno-missing-braces -fPIC" \ Werror=0 embed_kernels=1 examples=0 \ validation_tests=0 benchmark_tests=0 benchmark_examples=0 os=android -j16 ``` ## Build Arm NN and Serializer * Build Arm NN: (Requires CMake if not previously installed: `sudo apt install cmake`) ```bash mkdir -p $AOSP_ROOT/vendor/arm/armnn/build cd $AOSP_ROOT/vendor/arm/armnn/build CXX=aarch64-linux-android29-clang++ \ CC=aarch64-linux-android29-clang \ CXX_FLAGS="-fPIE -fPIC" cmake .. \ -DCMAKE_ANDROID_NDK=$NDK \ -DCMAKE_SYSTEM_NAME=Android \ -DCMAKE_SYSTEM_VERSION=29 \ -DCMAKE_ANDROID_ARCH_ABI=arm64-v8a \ -DCMAKE_EXE_LINKER_FLAGS="-pie -llog -lz" \ -DARMCOMPUTE_ROOT=$AOSP_ROOT/vendor/arm/clframework/ \ -DARMCOMPUTE_BUILD_DIR=$AOSP_ROOT/vendor/arm/clframework/build/android-arm64v8a/ \ -DARMCOMPUTENEON=1 -DARMCOMPUTECL=1 -DARMNNREF=1 \ -DFLATBUFFERS_ROOT= \ -DFLATC_DIR= \ -DBUILD_ARMNN_SERIALIZER=1 -DBUILD_GATORD_MOCK=0 -DBUILD_BASE_PIPE_SERVER=0 ``` * Run the build ```bash make -j16 ``` ## Build Arm NN Support Library Building the support library requires building some AOSP libraries via the NDK. It should be possible to create a symlink from $AOSP_ROOT to $AOSP_ROOT/vendor/arm/armnn/sl/aosp. However this example will instead clone the necessary AOSP repos and apply some minor patches which were required to get it to build. ```bash cd $AOSP_ROOT/vendor/arm/armnn/shim/sl/ # Call a script which will clone the necessary AOSP repos ./scripts/clone_aosp_libs.sh # Modify the repos by applying patches and 'switching off' Android.bp/.mk files by renaming them ./scripts/modify_aosp_libs.sh # Build the Support Library CMARGS="$CMARGS \ -DCMAKE_TOOLCHAIN_FILE=$NDK/build/cmake/android.toolchain.cmake \ -DANDROID_ABI=arm64-v8a \ -DCMAKE_ANDROID_ARCH_ABI=arm64-v8a \ -DCMAKE_ANDROID_NDK=$NDK \ -DANDROID_PLATFORM=android-29 \ -DARMNN_SOURCE_DIR=$AOSP_ROOT/vendor/arm/armnn/ " mkdir build cd build CXX=aarch64-linux-android29-clang++ \ CC=aarch64-linux-android29-clang \ cmake $CMARGS ../ make ``` ## Build Arm NN Shim By default the Arm NN shim Android.bp is not enabled. Enable it by editing armnn/shim/Android.bp and setting `enabled: true` ```bash cd $AOSP_ROOT source build/envsetup.sh lunch -eng cd vendor/arm/armnn/shim export ARMNN_ANDROID_MK_ENABLE=0 mm ``` The built libraries and manifest file can be found here: $AOSP_ROOT/out/target/product//vendor/lib64/libarmnn_support_library.so $AOSP_ROOT/out/target/product//vendor/bin/hw/android.hardware.neuralnetworks-shim-service-armnn $AOSP_ROOT/out/target/product//vendor/etc/vintf/manifest/android.hardware.neuralnetworks-shim-service-armnn.xml Currently the Arm NN libraries are shared libraries and therefore will need to be pushed to the device: $AOSP_ROOT/vendor/arm/armnn/build/libarmnnSerializer.so $AOSP_ROOT/vendor/arm/armnn/build/libarmnn.so