From 857fe614abd999a041eea50916b7d5988bc64776 Mon Sep 17 00:00:00 2001 From: Luke Hutton Date: Wed, 17 Apr 2024 19:12:27 +0100 Subject: [PATCH] [Target] Don't register AArch64 target tags without LLVM compiler support (#16897) This commit aims to fix the issue described here: https://github.com/apache/tvm/pull/16425#issuecomment-2059781680 by conditionally registering the target tags based on the availability of the LLVM AArch64 backend. It's possible to extract the targets LLVM has been compiled for using `llvm-config --targets-built`. Change-Id: I20b608aea9ea554b0c0388ee884621305d2d59b9 --- cmake/modules/LLVM.cmake | 1 + cmake/utils/FindLLVM.cmake | 18 ++++++++++++++++++ src/target/parsers/aprofile.cc | 7 ++++--- src/target/tag.cc | 6 +++++- 4 files changed, 28 insertions(+), 4 deletions(-) diff --git a/cmake/modules/LLVM.cmake b/cmake/modules/LLVM.cmake index 6fb74fc1ef6c..f695149975c6 100644 --- a/cmake/modules/LLVM.cmake +++ b/cmake/modules/LLVM.cmake @@ -41,6 +41,7 @@ if(NOT ${USE_LLVM} MATCHES ${IS_FALSE_PATTERN}) if (${TVM_MLIR_VERSION}) add_definitions(-DTVM_MLIR_VERSION=${TVM_MLIR_VERSION}) endif() + add_definitions(-DTVM_LLVM_HAS_AARCH64_TARGET=${TVM_LLVM_HAS_AARCH64_TARGET}) tvm_file_glob(GLOB COMPILER_LLVM_SRCS src/target/llvm/*.cc) list(APPEND TVM_LINKER_LIBS ${LLVM_LIBS}) list(APPEND COMPILER_SRCS ${COMPILER_LLVM_SRCS}) diff --git a/cmake/utils/FindLLVM.cmake b/cmake/utils/FindLLVM.cmake index a6abf25d1532..ab1bce274112 100644 --- a/cmake/utils/FindLLVM.cmake +++ b/cmake/utils/FindLLVM.cmake @@ -64,6 +64,10 @@ macro(find_llvm use_llvm) endif() set(TVM_LLVM_VERSION ${LLVM_VERSION_MAJOR}${LLVM_VERSION_MINOR}) set(TVM_INFO_LLVM_VERSION "${LLVM_VERSION_MAJOR}.${LLVM_VERSION_MINOR}.${LLVM_VERSION_PATCH}") + set(TVM_LLVM_HAS_AARCH64_TARGET 0) + if(DEFINED LLVM_TARGETS_TO_BUILD AND "AArch64" IN_LIST LLVM_TARGETS_TO_BUILD) + set(TVM_LLVM_HAS_AARCH64_TARGET 1) + endif() else() # use llvm config message(STATUS "Use llvm-config=" ${LLVM_CONFIG}) @@ -118,6 +122,13 @@ macro(find_llvm use_llvm) if(NOT "${__llvm_exit_code}" STREQUAL "0") message(FATAL_ERROR "Fatal error executing: ${LLVM_CONFIG} --cmakedir") endif() + execute_process(COMMAND ${LLVM_CONFIG} --targets-built + RESULT_VARIABLE __llvm_exit_code + OUTPUT_VARIABLE __llvm_targets_built + OUTPUT_STRIP_TRAILING_WHITESPACE) + if(NOT "${__llvm_exit_code}" STREQUAL "0") + message(FATAL_ERROR "Fatal error executing: ${LLVM_CONFIG} --targets-built") + endif() cmake_path(SET "__llvm_cmakedir" "${__llvm_cmakedir}") message(STATUS "LLVM cmakedir: ${__llvm_cmakedir}") # map prefix => $ @@ -152,6 +163,12 @@ macro(find_llvm use_llvm) string(REPLACE "$" ${__llvm_prefix} __lib_with_prefix "${__flag}") list(APPEND LLVM_LIBS "${__lib_with_prefix}") endforeach() + # targets built + set(TVM_LLVM_HAS_AARCH64_TARGET 0) + separate_arguments(BUILT_TARGET_LIST NATIVE_COMMAND ${__llvm_targets_built}) + if("AArch64" IN_LIST BUILT_TARGET_LIST) + set(TVM_LLVM_HAS_AARCH64_TARGET 1) + endif() if (${USE_MLIR}) if (EXISTS "${__llvm_libdir}/libMLIRPresburger.a") if (EXISTS "${__llvm_libdir}/libMLIRSupport.a") @@ -203,4 +220,5 @@ macro(find_llvm use_llvm) if (${TVM_LLVM_VERSION} LESS 40) message(FATAL_ERROR "TVM requires LLVM 4.0 or higher.") endif() + message(STATUS "Found TVM_LLVM_HAS_AARCH64_TARGET=" ${TVM_LLVM_HAS_AARCH64_TARGET}) endmacro(find_llvm) diff --git a/src/target/parsers/aprofile.cc b/src/target/parsers/aprofile.cc index f84c7485a018..50b94915dba3 100644 --- a/src/target/parsers/aprofile.cc +++ b/src/target/parsers/aprofile.cc @@ -94,8 +94,8 @@ static TargetFeatures GetFeatures(TargetJSON target) { Array targets = llvm_backend.GetAllLLVMTargets(); if ((IsAArch64(mtriple) && !CheckContains(targets, "aarch64")) || (IsAArch32(mtriple, mcpu) && !CheckContains(targets, "arm"))) { - LOG(WARNING) << "Cannot parse target features. LLVM was not compiled with support for " - "Arm(R)-based targets."; + LOG(WARNING) << "Cannot parse target features for target: " << target + << ". LLVM was not compiled with support for Arm(R)-based targets."; return {}; } @@ -115,7 +115,8 @@ static TargetFeatures GetFeatures(TargetJSON target) { {"has_sme", Bool(has_feature("sme"))}}; #endif - LOG(WARNING) << "Cannot parse Arm(R)-based target features without LLVM support."; + LOG(WARNING) << "Cannot parse Arm(R)-based target features for target " << target + << " without LLVM support."; return {}; } diff --git a/src/target/tag.cc b/src/target/tag.cc index 134278eb311a..9eca3072df0e 100644 --- a/src/target/tag.cc +++ b/src/target/tag.cc @@ -70,6 +70,7 @@ Target TargetTag::AddTag(String name, Map config, bool overri /********** Register Target tags **********/ +#if TVM_LLVM_HAS_AARCH64_TARGET TVM_REGISTER_TARGET_TAG("raspberry-pi/4b-aarch64") .set_config({{"kind", String("llvm")}, {"mtriple", String("aarch64-linux-gnu")}, @@ -130,7 +131,8 @@ TVM_REGISTER_TARGET_TAG("nvidia/jetson-agx-orin-64gb") {"mtriple", String("aarch64-linux-gnu")}, {"mcpu", String("cortex-a78")}, {"num-cores", Integer(12)}}}}); -#endif +#endif // TVM_LLVM_VERSION >= 110 +#endif // TVM_LLVM_HAS_AARCH64_TARGET #define TVM_REGISTER_CUDA_TAG(Name, Arch, SharedMem, RegPerBlock) \ TVM_REGISTER_TARGET_TAG(Name).set_config({ \ @@ -437,9 +439,11 @@ TVM_REGISTER_TAG_AWS_C5("aws/cpu/c5.24xlarge", 48, "cascadelake"); {"mtriple", String("arm64-apple-macos")}, \ {"mcpu", String("apple-latest")}}}}); +#if TVM_LLVM_HAS_AARCH64_TARGET TVM_REGISTER_METAL_GPU_TAG("apple/m1-gpu", 1024, 32768, 32); TVM_REGISTER_METAL_GPU_TAG("apple/m1-gpu-restricted", 256, 32768, 32); TVM_REGISTER_METAL_GPU_TAG("apple/m2-gpu", 1024, 32768, 32); +#endif // TVM_LLVM_HAS_AARCH64_TARGET #undef TVM_REGISTER_METAL_TAG