From b28e927ca4ee6ef40818bc46a82a6b9346dcb27b Mon Sep 17 00:00:00 2001 From: Skand Hurkat Date: Thu, 25 May 2023 17:05:30 -0700 Subject: [PATCH] Read AA64ISAR0_EL1 to check dot product support (#16082) ### Description Use an assembly instruction to read the `AA64ISAR0_EL1` register for dot product support. ### Motivation and Context The only reliable way to check for supported instruction extensions in ARM is to query the instruction set attribute registers. [Dot product instructions can be checked using bits 47:44 in the AA64ISAR0_EL1 register](https://developer.arm.com/documentation/ddi0601/2021-12/AArch64-Registers/ID-AA64ISAR0-EL1--AArch64-Instruction-Set-Attribute-Register-0?lang=en#fieldset_0-47_44). On `qemu-aarch64` with the `a64fx` cpu which does not support the dot product instructions, running a quantized BERT-Large (from MLPerf) results in `SIGILL`. With the change, the program continues without using the dot product instructions. Also verified that `S8S8_SDOT` kernels are invoked when running on hardware that supports dot product instructions. --------- Co-authored-by: Skand Hurkat --- onnxruntime/core/mlas/lib/platform.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/onnxruntime/core/mlas/lib/platform.cpp b/onnxruntime/core/mlas/lib/platform.cpp index c52d4f3b0b..305e48096e 100644 --- a/onnxruntime/core/mlas/lib/platform.cpp +++ b/onnxruntime/core/mlas/lib/platform.cpp @@ -55,7 +55,7 @@ MLASCPUIDInfo::MLASCPUIDInfo() #if defined(BUILD_MLAS_NO_ONNXRUNTIME) MLASCPUIDInfo::MLASCPUIDInfo() { - has_arm_neon_dot_ = ((getauxval(AT_HWCAP) & HWCAP_ASIMDDP) != 0); + has_arm_neon_dot_ = ((getauxval(AT_HWCAP) & HWCAP_ASIMDDP) != 0); // raw hack! Need CPUIDInfo implementation for more precise detection has_fp16_ = has_arm_neon_dot_; @@ -447,10 +447,10 @@ Return Value: #if defined(_WIN32) HasDotProductInstructions = (IsProcessorFeaturePresent(PF_ARM_V82_DP_INSTRUCTIONS_AVAILABLE) != 0); -#elif defined(__linux__) - HasDotProductInstructions = MLAS_CPUIDINFO::GetCPUIDInfo().HasArmNeonDot(); #else - HasDotProductInstructions = false; + uint64_t isar0_el1; + asm("mrs %[reg], ID_AA64ISAR0_EL1\n" : [reg] "=r"(isar0_el1) : :); + HasDotProductInstructions = ((isar0_el1 >> 44) & 0xfu) == 0x1u; #endif if (HasDotProductInstructions) {