From 8c6390c2b5278adbcb4954efa09ccdee51df8b10 Mon Sep 17 00:00:00 2001 From: Syed Wajahat Abbas Naqvi Date: Wed, 5 Nov 2025 14:54:35 +0100 Subject: [PATCH] feat: Single ISA CMake build Resolves: COMPMID-8547 Change-Id: I82d3e74b28284a4052a2042f47d2eff896cc9c38 Signed-off-by: Syed Wajahat Abbas Naqvi --- CMakeLists.txt | 206 +++++++++++++++++---- CMakePresets.json | 34 ++++ cmake/compilers/setup.cmake | 100 ++++++++-- tests/validation/NEON/ConvolutionLayer.cpp | 6 +- 4 files changed, 286 insertions(+), 60 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index fe29e6108e..5b6fc70e72 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -49,11 +49,24 @@ option(ARM_COMPUTE_ENABLE_CODE_COVERAGE "Enable code coverage." OFF) option(ARM_COMPUTE_ENABLE_SANITIZERS "Enable sanitizers." OFF) option(ARM_COMPUTE_USE_LIBCXX "Use libcxx instead of the default stdlib." OFF) -# * Set architecture. -set(ARM_COMPUTE_ARCH armv8-a CACHE STRING "Architecture (march) for core library.") -set(ARM_COMPUTE_CORE_FP16_ARCH armv8.2-a+fp16 CACHE STRING "Architecture (march) for core library that require fp16 support.") -set(ARM_COMPUTE_SVE_ARCH armv8.2-a+sve+fp16+dotprod CACHE STRING "Architecture (march) for sve library.") -set(ARM_COMPUTE_SVE2_ARCH armv8.6-a+sve2+fp16+dotprod CACHE STRING "Architecture (march) for sve2 library.") +# * Build mode: multi-ISA (default) or single-ISA +option(ACL_MULTI_ISA "Build Multi-ISA as default" ON) +set(ACL_ARCH_ISA "armv8.6-a" CACHE STRING "Architecture (armv8-a, armv8.2-a, armv8.6-a)") +set_property(CACHE ACL_ARCH_ISA PROPERTY STRINGS armv8-a armv8.2-a armv8.6-a) +set(ACL_ARCH_FEATURES "" CACHE STRING "Comma separated features list (sve,sve2,sme2)") + +# * Arch features +option(ACL_BUILD_SVE "Enable SVE support" OFF) +option(ACL_BUILD_SVE2 "Enable SVE2 support" OFF) +option(ACL_BUILD_SME2 "Enable SME2 support" OFF) + +# * Arch feature probing for single-ISA +include(CheckCXXCompilerFlag) +check_cxx_compiler_flag("-march=armv8-a" ACL_HAS_MARCH_V8A) +check_cxx_compiler_flag("-march=armv8.2-a+fp16+dotprod" ACL_HAS_MARCH_V82_F16_DOT) +check_cxx_compiler_flag("-march=armv8.6-a+sve+sve2+fp16+dotprod+i8mm" ACL_HAS_MARCH_V86_ALL) +check_cxx_compiler_flag("-march=armv8.2-a" ACL_HAS_MARCH_V82_BASE) +check_cxx_compiler_flag("-march=armv8.6-a" ACL_HAS_MARCH_V86_BASE) # * Set variables. set(ARM_COMPUTE_C_STANDARD 99 CACHE STRING "C Standard to use for the library.") @@ -72,6 +85,57 @@ include(${CMAKE_CURRENT_LIST_DIR}/cmake/configurations.cmake) include(${CMAKE_CURRENT_LIST_DIR}/cmake/compilers/setup.cmake) include(${CMAKE_CURRENT_LIST_DIR}/cmake/version.cmake) +if(ACL_ARCH_ISA STREQUAL "armv8-a" AND (ACL_MULTI_ISA OR ACL_BUILD_SVE OR ACL_BUILD_SVE2 OR ACL_BUILD_SME2)) + message(FATAL_ERROR + "Invalid configuration: '${ACL_ARCH_ISA}' does not support requested features" + ) +endif() + +# * Print build configuration +if(ACL_MULTI_ISA) + message(STATUS "Multi-ISA build selected.") + message(STATUS "Building ACL libraries: core, core_fp16, sve, sve2.") +else() + message(STATUS "Single-ISA build selected: ${ACL_ARCH_ISA}") + if(NOT "${ACL_ARCH_FEATURES}" STREQUAL "") + message(STATUS "Requested features: ${ACL_ARCH_FEATURES}") + endif() + set(libs "core") + if(NOT (ACL_ARCH_ISA STREQUAL "armv8-a")) + string(APPEND libs ", core_fp16") + endif() + if(ACL_BUILD_SVE) + string(APPEND libs ", sve") + endif() + if(ACL_BUILD_SVE2) + string(APPEND libs ", sve2") + endif() + message(STATUS "Building ACL libraries: ${libs}.") +endif() + +# * Set architecture. +if(ACL_MULTI_ISA) + set(ARM_COMPUTE_ARCH "-march=armv8-a") + set(ARM_COMPUTE_CORE_FP16_ARCH "-march=armv8.2-a+fp16+dotprod") + set(ARM_COMPUTE_SVE_ARCH "-march=armv8.2-a+sve+fp16+dotprod") + set(ARM_COMPUTE_SVE2_ARCH "-march=armv8.6-a+sve2+fp16+dotprod+i8mm") +else() + set(ACL_MARCH "") + if(ACL_BUILD_SME2 OR ACL_BUILD_SVE2) + set(ACL_MARCH "+sve2+fp16+dotprod+i8mm") + elseif(ACL_BUILD_SVE) + set(ACL_MARCH "+sve+fp16+dotprod") + elseif(ACL_ARCH_ISA STREQUAL "armv8.2-a" OR ACL_ARCH_ISA STREQUAL "armv8.6-a") + set(ACL_MARCH "+fp16+dotprod") + endif() + + set(ARM_COMPUTE_ARCH "-march=${ACL_ARCH_ISA}${ACL_MARCH}" CACHE STRING "Architecture (march) for core library.") + set(ARM_COMPUTE_CORE_FP16_ARCH "-march=${ACL_ARCH_ISA}${ACL_MARCH}" CACHE STRING "Architecture (march) for core library with fp16 support.") + set(ARM_COMPUTE_SVE_ARCH "-march=${ACL_ARCH_ISA}${ACL_MARCH}" CACHE STRING "Architecture (march) for SVE library.") + set(ARM_COMPUTE_SVE2_ARCH "-march=${ACL_ARCH_ISA}${ACL_MARCH}" CACHE STRING "Architecture (march) for SVE2 library.") + message(STATUS "Using arch: ${ARM_COMPUTE_ARCH}") +endif() + if(ARM_COMPUTE_ENABLE_OPENMP) find_package(OpenMP REQUIRED) endif() @@ -126,25 +190,33 @@ set( ${CMAKE_CURRENT_LIST_DIR}/src/core/NEON/kernels/arm_gemm/merges ) -add_library(arm_compute_sve OBJECT) -set_target_properties( - arm_compute_sve - PROPERTIES - COMPILE_OPTIONS "${ARM_COMPUTE_SVE_ARCH};${ARM_COMPUTE_COMMON_CCXX_FLAGS}" - COMPILE_DEFINITIONS "${ARM_COMPUTE_DEFINES}" - INCLUDE_DIRECTORIES "${ARM_COMPUTE_SVE_COMMON_INCLUDE}" - LINK_LIBRARIES "${ARM_COMPUTE_LINK_LIBS}" -) +if(ACL_MULTI_ISA OR ACL_BUILD_SVE) + add_library(arm_compute_sve OBJECT) + set_target_properties( + arm_compute_sve + PROPERTIES + COMPILE_OPTIONS "${ARM_COMPUTE_SVE_ARCH};${ARM_COMPUTE_COMMON_CCXX_FLAGS}" + COMPILE_DEFINITIONS "${ARM_COMPUTE_DEFINES}" + INCLUDE_DIRECTORIES "${ARM_COMPUTE_SVE_COMMON_INCLUDE}" + LINK_LIBRARIES "${ARM_COMPUTE_LINK_LIBS}" + ) +else() + add_library(arm_compute_sve OBJECT EXCLUDE_FROM_ALL) +endif() -add_library(arm_compute_sve2 OBJECT) -set_target_properties( - arm_compute_sve2 - PROPERTIES - COMPILE_OPTIONS "${ARM_COMPUTE_SVE2_ARCH};${ARM_COMPUTE_COMMON_CCXX_FLAGS}" - COMPILE_DEFINITIONS "${ARM_COMPUTE_DEFINES}" - INCLUDE_DIRECTORIES "${ARM_COMPUTE_SVE_COMMON_INCLUDE}" - LINK_LIBRARIES "${ARM_COMPUTE_LINK_LIBS}" -) +if(ACL_MULTI_ISA OR ACL_BUILD_SVE2) + add_library(arm_compute_sve2 OBJECT) + set_target_properties( + arm_compute_sve2 + PROPERTIES + COMPILE_OPTIONS "${ARM_COMPUTE_SVE2_ARCH};${ARM_COMPUTE_COMMON_CCXX_FLAGS}" + COMPILE_DEFINITIONS "${ARM_COMPUTE_DEFINES}" + INCLUDE_DIRECTORIES "${ARM_COMPUTE_SVE_COMMON_INCLUDE}" + LINK_LIBRARIES "${ARM_COMPUTE_LINK_LIBS}" + ) +else() + add_library(arm_compute_sve2 OBJECT EXCLUDE_FROM_ALL) +endif() add_library(arm_compute_core OBJECT) set_target_properties( @@ -156,15 +228,19 @@ set_target_properties( LINK_LIBRARIES "${ARM_COMPUTE_LINK_LIBS}" ) -add_library(arm_compute_core_fp16 OBJECT) -set_target_properties( - arm_compute_core_fp16 - PROPERTIES - COMPILE_OPTIONS "${ARM_COMPUTE_CORE_FP16_ARCH};${ARM_COMPUTE_COMMON_CCXX_FLAGS}" - COMPILE_DEFINITIONS "${ARM_COMPUTE_DEFINES}" - INCLUDE_DIRECTORIES "${ARM_COMPUTE_INCLUDE}" - LINK_LIBRARIES "${ARM_COMPUTE_LINK_LIBS}" -) +if(NOT (ACL_ARCH_ISA STREQUAL "armv8-a")) + add_library(arm_compute_core_fp16 OBJECT) + set_target_properties( + arm_compute_core_fp16 + PROPERTIES + COMPILE_OPTIONS "${ARM_COMPUTE_CORE_FP16_ARCH};${ARM_COMPUTE_COMMON_CCXX_FLAGS}" + COMPILE_DEFINITIONS "${ARM_COMPUTE_DEFINES}" + INCLUDE_DIRECTORIES "${ARM_COMPUTE_INCLUDE}" + LINK_LIBRARIES "${ARM_COMPUTE_LINK_LIBS}" + ) +else() + add_library(arm_compute_core_fp16 OBJECT EXCLUDE_FROM_ALL) +endif() add_library(arm_compute_graph ${ARM_COMPUTE_LIB_BUILD_TYPE}) set_target_properties( @@ -176,14 +252,52 @@ set_target_properties( LINK_LIBRARIES "${ARM_COMPUTE_LINK_LIBS}$,;arm_compute,>" ) -add_library( - arm_compute - ${ARM_COMPUTE_LIB_BUILD_TYPE} - $ - $ - $ - $ -) +if(ACL_MULTI_ISA) + add_library(arm_compute ${ARM_COMPUTE_LIB_BUILD_TYPE} + $ + $ + $ + $ + ) +else() + set(lib_objs $) + + if(ACL_ARCH_ISA STREQUAL "armv8-a") + # base + + elseif(ACL_ARCH_ISA STREQUAL "armv8.2-a") + list(APPEND lib_objs $) + if(ACL_BUILD_SVE) + list(APPEND lib_objs $) + endif() + if(ACL_BUILD_SVE2) + list(APPEND lib_objs $) + endif() + + elseif(ACL_ARCH_ISA STREQUAL "armv8.6-a") + list(APPEND lib_objs $) + if(ACL_BUILD_SVE) + list(APPEND lib_objs $) + endif() + if(ACL_BUILD_SVE2) + list(APPEND lib_objs $) + endif() + + else() + message(FATAL_ERROR "Unsupported ACL_ARCH_ISA='${ACL_ARCH_ISA}'") + endif() + + add_library(arm_compute ${ARM_COMPUTE_LIB_BUILD_TYPE} ${lib_objs}) + set_target_properties(arm_compute PROPERTIES OUTPUT_NAME "arm_compute_${ACL_ARCH_ISA}") +endif() + +if(CMAKE_SYSTEM_NAME STREQUAL "Darwin") + target_compile_options(arm_compute_core PRIVATE -arch arm64) + if(TARGET arm_compute_core_fp16) + target_compile_options(arm_compute_core_fp16 PRIVATE -arch arm64) + endif() +endif() + # Linking to arm_compute[_graph] should automatically bring includes and dependent libs with it foreach(TARGET IN ITEMS arm_compute arm_compute_graph) @@ -197,7 +311,17 @@ foreach(TARGET IN ITEMS arm_compute arm_compute_graph) endforeach() # Linking to this target should automatically bring includes and dependent libs with it. -list(APPEND ARM_COMPUTE_TARGETS arm_compute arm_compute_graph arm_compute_core arm_compute_core_fp16 arm_compute_sve arm_compute_sve2) +set(ARM_COMPUTE_TARGETS arm_compute arm_compute_graph arm_compute_core) + +if(TARGET arm_compute_core_fp16) + list(APPEND ARM_COMPUTE_TARGETS arm_compute_core_fp16) +endif() +if(TARGET arm_compute_sve) + list(APPEND ARM_COMPUTE_TARGETS arm_compute_sve) +endif() +if(TARGET arm_compute_sve2) + list(APPEND ARM_COMPUTE_TARGETS arm_compute_sve2) +endif() # Create an alias targets so that a user can download ArmCompute via FetchContent and # still link to ArmCompute::Core and ArmCompute::Graph. Otherwise these targets would not diff --git a/CMakePresets.json b/CMakePresets.json index 8d7a012b02..2f0b188860 100644 --- a/CMakePresets.json +++ b/CMakePresets.json @@ -22,6 +22,20 @@ "ARM_COMPUTE_BUILD_TESTING": "ON" } }, + { + "name": "single-isa-v86", + "generator": "Ninja Multi-Config", + "displayName": "Single ISA armv8.6-a", + "description": "Builds only the armv8.6-a arch without sve/sve2", + "binaryDir": "${sourceDir}/build/${presetName}", + "cacheVariables": { + "ACL_MULTI_ISA": "OFF", + "ACL_ARCH_ISA": "armv8.6-a", + "ACL_ARCH_FEATURES": "", + "ARM_COMPUTE_BUILD_SHARED_LIB": "ON", + "ARM_COMPUTE_ENABLE_OPENMP": "ON" + } + }, { "name": "release", "generator": "Ninja Multi-Config", @@ -38,6 +52,13 @@ "configuration": "Release", "description": "Builds the CI configuration." }, + { + "name": "single-isa-v86", + "displayName": "Build Single ISA armv8.6-a", + "configurePreset": "single-isa-v86", + "configuration": "Release", + "description": "Builds armv8.6-a configuration without sve/sve2." + }, { "name": "release", "displayName": "Release Build", @@ -60,6 +81,19 @@ } ] }, + { + "name": "single-isa-v86", + "steps": [ + { + "type": "configure", + "name": "single-isa-v86" + }, + { + "type": "build", + "name": "single-isa-v86" + } + ] + }, { "name": "release", "steps": [ diff --git a/cmake/compilers/setup.cmake b/cmake/compilers/setup.cmake index e91ea92aee..e1d77c241f 100644 --- a/cmake/compilers/setup.cmake +++ b/cmake/compilers/setup.cmake @@ -41,17 +41,7 @@ set( # Kernels to build. ARM_COMPUTE_ENABLE_NEON - ARM_COMPUTE_ENABLE_BF16 - ARM_COMPUTE_ENABLE_FP16 - ARM_COMPUTE_ENABLE_I8MM - ARM_COMPUTE_ENABLE_SVE - ARM_COMPUTE_ENABLE_SVE2 - ARM_COMPUTE_ENABLE_SVEF32MM - ARM_COMPUTE_ENABLE_FIXED_FORMAT_KERNELS - ENABLE_SVE - ENABLE_SVE2 ENABLE_NEON - ENABLE_FP16_KERNELS ENABLE_FP32_KERNELS ENABLE_QASYMM8_KERNELS ENABLE_QASYMM8_SIGNED_KERNELS @@ -59,8 +49,90 @@ set( ENABLE_INTEGER_KERNELS ENABLE_NHWC_KERNELS ENABLE_NCHW_KERNELS +) + +if(ACL_MULTI_ISA) + list(APPEND ARM_COMPUTE_DEFINES + ARM_COMPUTE_ENABLE_BF16 + ARM_COMPUTE_ENABLE_FP16 + ARM_COMPUTE_ENABLE_I8MM + ARM_COMPUTE_ENABLE_SVE + ARM_COMPUTE_ENABLE_SVE2 + ARM_COMPUTE_ENABLE_SVEF32MM + ENABLE_SVE + ENABLE_SVE2 + ENABLE_FP16_KERNELS + ARM_COMPUTE_ENABLE_FIXED_FORMAT_KERNELS + ) + +else() + if(ACL_ARCH_ISA STREQUAL "armv8-a") + message(STATUS "Configuring for armv8-a, no FP16/SVE features") + + elseif(ACL_ARCH_ISA STREQUAL "armv8.2-a") + list(APPEND ARM_COMPUTE_DEFINES + ENABLE_FP16_KERNELS + ARM_COMPUTE_ENABLE_FP16 + ) + + elseif(ACL_ARCH_ISA STREQUAL "armv8.6-a") + list(APPEND ARM_COMPUTE_DEFINES + ENABLE_FP16_KERNELS + ARM_COMPUTE_ENABLE_FP16 + ARM_COMPUTE_ENABLE_BF16 + ARM_COMPUTE_ENABLE_I8MM + ) + else() + message(FATAL_ERROR + "Unsupported ACL_ARCH_ISA='${ACL_ARCH_ISA}'. Allowed presets: armv8-a, armv8.2-a, armv8.6-a" + ) + endif() + + # Parse requested feature names + if("${ACL_ARCH_FEATURES}" STREQUAL "") + set(features_list "") + else() + string(TOLOWER "${ACL_ARCH_FEATURES}" features) + string(REPLACE " " "" features "${features}") + string(REPLACE "," ";" features_list "${features}") + endif() + + # Set Options based on features requested + if("sme2" IN_LIST features_list) + set(ACL_BUILD_SME2 ON CACHE BOOL "" FORCE) + set(ACL_BUILD_SVE2 ON CACHE BOOL "" FORCE) + set(ACL_BUILD_SVE ON CACHE BOOL "" FORCE) + elseif("sve2" IN_LIST features_list) + set(ACL_BUILD_SVE2 ON CACHE BOOL "" FORCE) + set(ACL_BUILD_SVE ON CACHE BOOL "" FORCE) + elseif("sve" IN_LIST features_list) + set(ACL_BUILD_SVE ON CACHE BOOL "" FORCE) + endif() + + if(ACL_BUILD_SVE) + list(APPEND ARM_COMPUTE_DEFINES + ARM_COMPUTE_ENABLE_SVE + ENABLE_SVE + ) + endif() + + if(ACL_BUILD_SVE2) + list(APPEND ARM_COMPUTE_DEFINES + ARM_COMPUTE_ENABLE_SVE2 + ENABLE_SVE2 + ) + endif() + + if(ACL_BUILD_SME2) + list(APPEND ARM_COMPUTE_DEFINES + ARM_COMPUTE_ENABLE_SME + ARM_COMPUTE_ENABLE_SME2 + ENABLE_SME + ) + endif() +endif() - # Features controlled by options. +list(APPEND ARM_COMPUTE_DEFINES $<$:ARM_COMPUTE_ASSERTS_ENABLED> $<$:ARM_COMPUTE_CPP_SCHEDULER> $<$:ARM_COMPUTE_LOGGING_ENABLED> @@ -128,9 +200,3 @@ set( ${ARM_COMPUTE_ASAN_COMPILER_FLAG} ${ARM_COMPUTE_CODE_COVERAGE_COMPILER_FLAG} ) - -# Add -march to arch values. -string(PREPEND ARM_COMPUTE_ARCH -march=) -string(PREPEND ARM_COMPUTE_CORE_FP16_ARCH -march=) -string(PREPEND ARM_COMPUTE_SVE_ARCH -march=) -string(PREPEND ARM_COMPUTE_SVE2_ARCH -march=) diff --git a/tests/validation/NEON/ConvolutionLayer.cpp b/tests/validation/NEON/ConvolutionLayer.cpp index a241419c38..9d0acbfb61 100644 --- a/tests/validation/NEON/ConvolutionLayer.cpp +++ b/tests/validation/NEON/ConvolutionLayer.cpp @@ -1014,7 +1014,8 @@ FIXTURE_DATA_TEST_CASE(UC2_2_CpuGemmConv2d_FastMath, combine(make("DataType", {DataType::F32}), make("QueryWeightFormat", {arm_compute::WeightFormat::OHWIo8i4_bf16}))) { - if (Scheduler::get().cpu_info().has_bf16() && (arm_gemm::utils::get_vector_length() == 8)) + if (Scheduler::get().cpu_info().has_bf16() && Scheduler::get().cpu_info().has_sve() && + (arm_gemm::utils::get_vector_length() == 8)) { ARM_COMPUTE_EXPECT(_kernel_found, framework::LogLevel::ERRORS); ARM_COMPUTE_EXPECT_EQUAL(_computed_weight_format, arm_compute::WeightFormat::OHWIo8i4_bf16, @@ -1032,7 +1033,8 @@ FIXTURE_DATA_TEST_CASE(UC2_2_NEGEMMConvolutionLayer_FastMath, combine(make("DataType", {DataType::F32}), make("QueryWeightFormat", {arm_compute::WeightFormat::OHWIo8i4_bf16}))) { - if (Scheduler::get().cpu_info().has_bf16() && (arm_gemm::utils::get_vector_length() == 8)) + if (Scheduler::get().cpu_info().has_bf16() && Scheduler::get().cpu_info().has_sve() && + (arm_gemm::utils::get_vector_length() == 8)) { ARM_COMPUTE_EXPECT(_kernel_found, framework::LogLevel::ERRORS); ARM_COMPUTE_EXPECT(_computed_weight_format == arm_compute::WeightFormat::OHWIo8i4_bf16,