diff --git a/test/common/cpu_info.cpp b/test/common/cpu_info.cpp index 6fa59677fd6e02d07ca1aa7d2f6657bfa3b61a72..09c9691e1825de40fae7efee0ff8928f460f1b98 100644 --- a/test/common/cpu_info.cpp +++ b/test/common/cpu_info.cpp @@ -26,6 +26,7 @@ namespace kai::test { namespace { #if defined(__aarch64__) && defined(__linux__) +constexpr uint64_t A64_HWCAP2_I8MM = 1UL << 13; constexpr uint64_t A64_HWCAP2_SME = 1UL << 23; constexpr uint64_t A64_HWCAP2_SME2 = 1UL << 37; #endif // defined(__aarch64__) && defined(__linux__) @@ -52,11 +53,13 @@ struct CpuInfo { #if defined(__aarch64__) && defined(__linux__) const uint64_t hwcaps2 = getauxval(AT_HWCAP2); + has_i8mm = (hwcaps2 & A64_HWCAP2_I8MM) != 0; has_sme = (hwcaps2 & A64_HWCAP2_SME) != 0; has_sme2 = (hwcaps2 & A64_HWCAP2_SME2) != 0; #endif // defined(__aarch64__) && defined(__linux__) #if defined(__aarch64__) && defined(__APPLE__) + has_i8mm = get_sysctl_by_name("hw.optional.arm.FEAT_I8MM") == 1; has_sme = get_sysctl_by_name("hw.optional.arm.FEAT_SME") == 1; has_sme2 = get_sysctl_by_name("hw.optional.arm.FEAT_SME2") == 1; #endif // defined(__aarch64__) && defined(__APPLE__) @@ -74,6 +77,10 @@ struct CpuInfo { } // namespace +bool cpu_has_i8mm() { + return CpuInfo::current().has_i8mm; +} + bool cpu_has_sme() { return CpuInfo::current().has_sme; } diff --git a/test/common/cpu_info.hpp b/test/common/cpu_info.hpp index b231ecea2d651f20b6b340ed5fa3a1dadaef1b42..82f013bc9ef375c7cded012cea0bec676297ed9e 100644 --- a/test/common/cpu_info.hpp +++ b/test/common/cpu_info.hpp @@ -8,6 +8,9 @@ namespace kai::test { +/// Returns a value indicating whether the current CPU supports FEAT_I8MM. +bool cpu_has_i8mm(); + /// Returns a value indicating whether the current CPU supports FEAT_SME. bool cpu_has_sme(); diff --git a/test/common/test_suite.hpp b/test/common/test_suite.hpp index e59c0c50a48707b566977a1523155a1dd50c1217..533e06f006c5ff15525de7bc1828fc3e405b1a79 100644 --- a/test/common/test_suite.hpp +++ b/test/common/test_suite.hpp @@ -12,20 +12,21 @@ #include #include -#define UKERNEL_MATMUL_VARIANT(name) \ - { \ - {kai_get_m_step_matmul_##name, \ - kai_get_n_step_matmul_##name, \ - kai_get_mr_matmul_##name, \ - kai_get_nr_matmul_##name, \ - kai_get_kr_matmul_##name, \ - kai_get_sr_matmul_##name, \ - kai_get_lhs_packed_offset_matmul_##name, \ - kai_get_rhs_packed_offset_matmul_##name, \ - kai_get_dst_offset_matmul_##name, \ - kai_get_dst_size_matmul_##name, \ - kai_run_matmul_##name}, \ - "kai_matmul_" #name \ +#define UKERNEL_MATMUL_VARIANT(name) \ + { \ + {kai_get_m_step_matmul_##name, \ + kai_get_n_step_matmul_##name, \ + kai_get_mr_matmul_##name, \ + kai_get_nr_matmul_##name, \ + kai_get_kr_matmul_##name, \ + kai_get_sr_matmul_##name, \ + kai_get_lhs_packed_offset_matmul_##name, \ + kai_get_rhs_packed_offset_matmul_##name, \ + kai_get_dst_offset_matmul_##name, \ + kai_get_dst_size_matmul_##name, \ + kai_run_matmul_##name}, \ + "kai_matmul_" #name \ + std::string(#name).find("i8mm") != std::string::npos, \ } namespace kai::test { @@ -34,6 +35,7 @@ template struct UkernelVariant { T interface; std::string name{}; + bool is_i8mm; }; /// Matrix multiplication shape. diff --git a/test/tests/matmul_clamp_f32_qai8dxp_qsi4c32p_test.cpp b/test/tests/matmul_clamp_f32_qai8dxp_qsi4c32p_test.cpp index 15acde4ed293b514d82c1ffd3230335df2f6d7e0..e80c4d59336a69680aad11367a2d22b7566616d9 100644 --- a/test/tests/matmul_clamp_f32_qai8dxp_qsi4c32p_test.cpp +++ b/test/tests/matmul_clamp_f32_qai8dxp_qsi4c32p_test.cpp @@ -20,6 +20,7 @@ #include "kai/ukernels/matmul/pack/kai_rhs_pack_kxn_qsi4c32p_qsu4c32s1s0.h" #include "kai/ukernels/matmul/pack/kai_rhs_pack_nxk_qsi4c32p_qsu4c32s1s0.h" #include "test/common/bfloat16.hpp" +#include "test/common/cpu_info.hpp" #include "test/common/int4.hpp" #include "test/common/memory.hpp" #include "test/common/round.hpp" @@ -46,6 +47,10 @@ TEST_P(MatMulTest_f32_qmatmul_clamp_f32_qai8dxp_qsi4c32p, EndToEnd_RHS_Transpose auto& [variant_index, matmul_shape] = GetParam(); const auto& ukernel_variant = variants_kai_matmul_clamp_f32_qai8dxp_qsi4c32p.at(variant_index); + if (ukernel_variant.is_i8mm && !cpu_has_i8mm()) { + GTEST_SKIP(); + } + const uint64_t seed = 0; const size_t M = matmul_shape.m; @@ -127,6 +132,10 @@ TEST_P(MatMulTest_f32_qmatmul_clamp_f32_qai8dxp_qsi4c32p, EndToEnd_RHS_NonTransp auto& [variant_index, matmul_shape] = GetParam(); const auto& ukernel_variant = variants_kai_matmul_clamp_f32_qai8dxp_qsi4c32p.at(variant_index); + if (ukernel_variant.is_i8mm && !cpu_has_i8mm()) { + GTEST_SKIP(); + } + const uint64_t seed = 0; const size_t M = matmul_shape.m; diff --git a/test/tests/matmul_clamp_f32_qai8dxp_qsi4cxp_test.cpp b/test/tests/matmul_clamp_f32_qai8dxp_qsi4cxp_test.cpp index 95ff03f43bd15e471f3fe45893675b634877c690..736d54767f4dd0a87a65a9feb6ac862363b5854a 100644 --- a/test/tests/matmul_clamp_f32_qai8dxp_qsi4cxp_test.cpp +++ b/test/tests/matmul_clamp_f32_qai8dxp_qsi4cxp_test.cpp @@ -22,6 +22,7 @@ #include "kai/ukernels/matmul/matmul_clamp_f32_qai8dxp_qsi4cxp/kai_matmul_clamp_f32_qai8dxp_qsi4cxp_interface.h" #include "kai/ukernels/matmul/pack/kai_lhs_quant_pack_qai8dxp_f32.h" #include "kai/ukernels/matmul/pack/kai_rhs_pack_nxk_qsi4cxp_qsu4cxs1s0.h" +#include "test/common/cpu_info.hpp" #include "test/common/int4.hpp" #include "test/common/memory.hpp" #include "test/common/test_suite.hpp" @@ -48,6 +49,10 @@ TEST_P(MatMulTest_f32_qai8dxp4x8_qsi4cxp8x8, EndToEnd) { auto& [variant_index, matmul_shape] = GetParam(); const auto& ukernel_variant = variants_kai_matmul_clamp_f32_qai8dxp_qsi4cxp.at(variant_index); + if (ukernel_variant.is_i8mm && !cpu_has_i8mm()) { + GTEST_SKIP(); + } + const uint64_t seed = 0; const size_t M = matmul_shape.m; diff --git a/test/tests/matmul_clamp_f32_qsi8d32p_qsi4c32p_test.cpp b/test/tests/matmul_clamp_f32_qsi8d32p_qsi4c32p_test.cpp index 8dba1ac3dc7653d9ae8c340c003d7c69b1f8c040..da4465ef1411b50548523ac937e3dcb0f476b978 100644 --- a/test/tests/matmul_clamp_f32_qsi8d32p_qsi4c32p_test.cpp +++ b/test/tests/matmul_clamp_f32_qsi8d32p_qsi4c32p_test.cpp @@ -26,6 +26,10 @@ namespace kai::test { TEST(matmul_clamp_f32_qsi8d32p4x8_qsi4c32p4x8_8x4x32_neon_i8mm, EndToEnd) { + if (!cpu_has_i8mm()) { + GTEST_SKIP(); + } + const std::uint64_t seed = 0; const size_t M = 32;