androidc++armneonhalf-precision-float

How to use float16 neon intrinsics on Android?


How do I use arm float16 intrinsics on Android?

Consider the following program:

#include <arm_neon.h>

int main(int, char** argv) {
    const float16x8_t a = vdupq_n_f16(1.0F);
    const float16x8_t b = vdupq_n_f16(- 1.0F);
    const float16x8_t c = vaddq_f16(a, b);
}

and the following cmake file:

cmake_minimum_required(VERSION 3.15)
project(test CXX)
add_executable(test main.cpp)

set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g -march=${MARCH}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -march=${MARCH}")
target_compile_options(test PRIVATE -Wall -Wextra -Wpedantic -g)
target_compile_features(test PRIVATE cxx_std_17)

instantiated with the following command:

cmake -DCMAKE_ANDROID_API=26 -DANDROID_PLATTFORM="26"\                             
              -DCMAKE_ANDROID_ARCH_ABI=arm64-v8a \
              -DCMAKE_ANDROID_NDK=/tmp/android-ndk-r25c  \
              -DCMAKE_ANDROID_STL_TYPE=c++_static -DCMAKE_ANDROID_ABI=arm64-v8a\
              -DCMAKE_BUILD_TYPE=Release -DMARCH=armv8.2-a -DCMAKE_SYSTEM_NAME=Android -S . -B build_android

When compiling the program, I get the following error:

/tmp/float16/main.cpp:6:27: error: use of undeclared identifier 'vaddq_f16'
    const float16x8_t c = vaddq_f16(a, b);
                          ^

I understand, that float16 is available with Arm-v8.2. Furthermore, the function vaddq_f161 is guarded by the ifdef #if defined(__ARM_FEATURE_FP16_VECTOR_ARITHMETIC) in arm_neon.h . Under which condition is this flag set to true when compiling a program for Android? The Android ABI notes say that arm64-v8a refers to Arm-v8.0 only. Is there a way to use float16 intrinsics on Android?


Solution

  • To answer the question (and referring to the comments of the question above):

    float16 intrinsics can be used with the option -DMARCH=armv8.2-a+fp16 . See the GCC docs, listing the architecture options.