diff --git a/include/spy/simd.hpp b/include/spy/simd.hpp index fc9434a..be19e8a 100644 --- a/include/spy/simd.hpp +++ b/include/spy/simd.hpp @@ -35,9 +35,10 @@ namespace spy::detail , vsx_ = 3000 , vsx_2_06_ = 3206, vsx_2_07_ = 3207, vsx_3_00_ = 3300, vsx_3_01_ = 3301 , neon_ = 4001, asimd_ = 4002 - , sve_ = 5000, sve2_ = 5500 + , sve_ = 5000, fixed_sve_ = 5100 + , sve2_ = 5500, fixed_sve2_ = 5600 , simd128_ = 6000 - , rvv_ = 7000 + , rvv_ = 7000, fixed_rvv_ = 7500 }; template< simd_isa InsSetArch = simd_isa::undefined_ @@ -57,7 +58,8 @@ namespace spy::detail ) return 128; else if constexpr(Version == simd_version::avx_ || Version == simd_version::avx2_) return 256; else if constexpr(Version == simd_version::avx512_ ) return 512; -else if constexpr( Version == simd_version::rvv_ ) + else if constexpr( Version == simd_version::rvv_ ) return -1; + else if constexpr( Version == simd_version::fixed_rvv_ ) { #if defined(__riscv_v_fixed_vlen) return __riscv_v_fixed_vlen; @@ -67,13 +69,16 @@ else if constexpr( Version == simd_version::rvv_ ) } else if constexpr(Version == simd_version::sve_ || Version == simd_version::sve2_) { + return -1; + } + else if constexpr(Version == simd_version::fixed_sve_ || Version == simd_version::fixed_sve2_) + { #if defined(__ARM_FEATURE_SVE_BITS) return __ARM_FEATURE_SVE_BITS; #else return -1; #endif } - else return -1; }(); @@ -101,28 +106,14 @@ else if constexpr( Version == simd_version::rvv_ ) constexpr auto v = static_cast(Version); os << "PPC VSX with ISA v" << ((v-3000)/100.); } - else if constexpr ( Version == simd_version::neon_ ) os << "ARM NEON"; - else if constexpr ( Version == simd_version::asimd_ ) os << "ARM ASIMD"; - else if constexpr ( Version == simd_version::sve_ || Version == simd_version::sve2_ ) - { - os << "ARM SVE" << (Version == simd_version::sve2_ ? "2" : "") << "("; - - constexpr auto fc = has_fixed_cardinal(); - if constexpr(fc) os << simd_info::width; - else os << "dyn."; - - os << " bits)"; - } - else if constexpr ( Version == simd_version::rvv_ ) - { - os << "RISC-V RVV("; - - constexpr auto fc = has_fixed_cardinal(); - if constexpr(fc) os << simd_info::width; - else os << "dyn."; - - os << " bits)"; - } + else if constexpr ( Version == simd_version::neon_ ) os << "ARM NEON"; + else if constexpr ( Version == simd_version::asimd_ ) os << "ARM ASIMD"; + else if constexpr ( Version == simd_version::sve_ ) os << "ARM SVE (dyn.)"; + else if constexpr ( Version == simd_version::fixed_sve_ ) os << "ARM SVE (" << simd_info::width << " bits)"; + else if constexpr ( Version == simd_version::sve2_ ) os << "ARM SVE2 (dyn.)"; + else if constexpr ( Version == simd_version::fixed_sve2_ ) os << "ARM SVE2 (" << simd_info::width << " bits)"; + else if constexpr ( Version == simd_version::rvv_ ) os << "RISC-V RVV (dyn.)"; + else if constexpr ( Version == simd_version::fixed_rvv_ ) os << "RISC-V RVV (" << simd_info::width << " bits)"; else return os << "Undefined SIMD instructions set"; if constexpr (spy::supports::fma_) os << " (with FMA3 support)"; @@ -298,10 +289,13 @@ namespace spy constexpr inline auto neon_ = arm_simd_info{}; constexpr inline auto asimd_ = arm_simd_info{}; constexpr inline auto sve_ = sve_simd_info{}; + constexpr inline auto fixed_sve_ = sve_simd_info{}; constexpr inline auto sve2_ = sve_simd_info{}; + constexpr inline auto fixed_sve2_ = sve_simd_info{}; template using riscv_simd_info = detail::simd_info; constexpr inline auto riscv_simd_ = riscv_simd_info<> {}; constexpr inline auto rvv_ = riscv_simd_info {}; + constexpr inline auto fixed_rvv_ = riscv_simd_info {}; } diff --git a/include/spy/simd/arm.hpp b/include/spy/simd/arm.hpp index 198f657..f13e3aa 100644 --- a/include/spy/simd/arm.hpp +++ b/include/spy/simd/arm.hpp @@ -7,33 +7,61 @@ //================================================================================================== #pragma once -#if defined(__ARM_FEATURE_SVE2) || defined(__ARM_FEATURE_SVE) +#if defined(__ARM_FEATURE_SVE2) +// Flexible SVE2 has no SVE_BITS or SVE_BITS set at 0 and is set via -march=armv8-a+sve +# if !defined(__ARM_FEATURE_SVE_BITS) || (__ARM_FEATURE_SVE_BITS == 0) +# define SPY_SIMD_IS_ARM_FLEXIBLE_SVE2 +# define SPY_SIMD_DETECTED ::spy::detail::simd_version::sve2_ +// Fixed-size SVE has SVE_BITS set at expected size via -msve-vector-bits +# elif defined(__ARM_FEATURE_SVE_BITS) +# if(__ARM_FEATURE_SVE_BITS == 128) +# define SPY_SIMD_IS_ARM_FIXED_SVE2 +# define SPY_SIMD_DETECTED ::spy::detail::simd_version::fixed_sve2_ +# elif(__ARM_FEATURE_SVE_BITS == 256) +# define SPY_SIMD_IS_ARM_FIXED_SVE2 +# define SPY_SIMD_DETECTED ::spy::detail::simd_version::fixed_sve2_ +# elif(__ARM_FEATURE_SVE_BITS == 512) +# define SPY_SIMD_IS_ARM_FIXED_SVE2 +# define SPY_SIMD_DETECTED ::spy::detail::simd_version::fixed_sve2_ +# elif(__ARM_FEATURE_SVE_BITS == 1024) +# define SPY_SIMD_IS_ARM_FIXED_SVE2 +# define SPY_SIMD_DETECTED ::spy::detail::simd_version::fixed_sve2_ +# else +# error "[SPY] - No support for non-power of 2 SVE-2 cardinals" +# endif +# endif +#endif + +#if !defined(SPY_SIMD_DETECTED) && defined(__ARM_FEATURE_SVE) // Flexible SVE has no SVE_BITS or SVE_BITS set at 0 and is set via -march=armv8-a+sve # if !defined(__ARM_FEATURE_SVE_BITS) || (__ARM_FEATURE_SVE_BITS == 0) -# define SPY_SIMD_IS_ARM_FLEXIBLE_SVE_CARDINAL +# define SPY_SIMD_IS_ARM_FLEXIBLE_SVE +# define SPY_SIMD_DETECTED ::spy::detail::simd_version::sve_ // Fixed-size SVE has SVE_BITS set at expected size via -msve-vector-bits # elif defined(__ARM_FEATURE_SVE_BITS) # if(__ARM_FEATURE_SVE_BITS == 128) -# define SPY_SIMD_IS_ARM_FIXED_SVE_CARDINAL +# define SPY_SIMD_IS_ARM_FIXED_SVE +# define SPY_SIMD_DETECTED ::spy::detail::simd_version::fixed_sve_ # elif(__ARM_FEATURE_SVE_BITS == 256) -# define SPY_SIMD_IS_ARM_FIXED_SVE_CARDINAL +# define SPY_SIMD_IS_ARM_FIXED_SVE +# define SPY_SIMD_DETECTED ::spy::detail::simd_version::fixed_sve_ # elif(__ARM_FEATURE_SVE_BITS == 512) -# define SPY_SIMD_IS_ARM_FIXED_SVE_CARDINAL +# define SPY_SIMD_IS_ARM_FIXED_SVE +# define SPY_SIMD_DETECTED ::spy::detail::simd_version::fixed_sve_ # elif(__ARM_FEATURE_SVE_BITS == 1024) -# define SPY_SIMD_IS_ARM_FIXED_SVE_CARDINAL +# define SPY_SIMD_IS_ARM_FIXED_SVE +# define SPY_SIMD_DETECTED ::spy::detail::simd_version::fixed_sve_ # else # error "[SPY] - No support for non-power of 2 SVE cardinals" # endif # endif #endif -#if !defined(SPY_SIMD_DETECTED) && defined(__ARM_FEATURE_SVE2) +#if defined(__ARM_FEATURE_SVE2) # define SPY_SIMD_IS_ARM_SVE2 -# define SPY_SIMD_DETECTED ::spy::detail::simd_version::sve2_ # define SPY_SIMD_VENDOR ::spy::detail::simd_isa::arm_sve_ -#elif !defined(SPY_SIMD_DETECTED) && defined(__ARM_FEATURE_SVE) +#elif defined(__ARM_FEATURE_SVE) # define SPY_SIMD_IS_ARM_SVE -# define SPY_SIMD_DETECTED ::spy::detail::simd_version::sve_ # define SPY_SIMD_VENDOR ::spy::detail::simd_isa::arm_sve_ #endif diff --git a/include/spy/simd/riscv.hpp b/include/spy/simd/riscv.hpp index f5d950f..fc9fa5d 100644 --- a/include/spy/simd/riscv.hpp +++ b/include/spy/simd/riscv.hpp @@ -10,15 +10,16 @@ #if defined(__riscv_vector) // Flexible RISC-V Vector has no __riscv_v_fixed_vlen defined # if !defined(__riscv_v_fixed_vlen) -# define SPY_SIMD_IS_RISCV_FLEXIBLE_RVV_CARDINAL +# define SPY_SIMD_IS_RISCV_FLEXIBLE_RVV +# define SPY_SIMD_DETECTED ::spy::detail::simd_version::rvv_ // Fixed-size RISC-V Vector has __riscv_v_fixed_vlen #else -# define SPY_SIMD_IS_RISCV_FIXED_RVV_CARDINAL +# define SPY_SIMD_IS_RISCV_FIXED_RVV +# define SPY_SIMD_DETECTED ::spy::detail::simd_version::fixed_rvv_ #endif #endif -#if !defined(SPY_SIMD_DETECTED) && defined(__riscv_vector) +#if defined(__riscv_vector) # define SPY_SIMD_IS_RISCV_RVV # define SPY_SIMD_VENDOR ::spy::detail::simd_isa::riscv_ -# define SPY_SIMD_DETECTED ::spy::detail::simd_version::rvv_ #endif diff --git a/standalone/spy/spy.hpp b/standalone/spy/spy.hpp index 49a90d4..6a80365 100644 --- a/standalone/spy/spy.hpp +++ b/standalone/spy/spy.hpp @@ -909,30 +909,55 @@ namespace avx512 #endif } } -#if defined(__ARM_FEATURE_SVE2) || defined(__ARM_FEATURE_SVE) +#if defined(__ARM_FEATURE_SVE2) # if !defined(__ARM_FEATURE_SVE_BITS) || (__ARM_FEATURE_SVE_BITS == 0) -# define SPY_SIMD_IS_ARM_FLEXIBLE_SVE_CARDINAL +# define SPY_SIMD_IS_ARM_FLEXIBLE_SVE2 +# define SPY_SIMD_DETECTED ::spy::detail::simd_version::sve2_ # elif defined(__ARM_FEATURE_SVE_BITS) # if(__ARM_FEATURE_SVE_BITS == 128) -# define SPY_SIMD_IS_ARM_FIXED_SVE_CARDINAL +# define SPY_SIMD_IS_ARM_FIXED_SVE2 +# define SPY_SIMD_DETECTED ::spy::detail::simd_version::fixed_sve2_ # elif(__ARM_FEATURE_SVE_BITS == 256) -# define SPY_SIMD_IS_ARM_FIXED_SVE_CARDINAL +# define SPY_SIMD_IS_ARM_FIXED_SVE2 +# define SPY_SIMD_DETECTED ::spy::detail::simd_version::fixed_sve2_ # elif(__ARM_FEATURE_SVE_BITS == 512) -# define SPY_SIMD_IS_ARM_FIXED_SVE_CARDINAL +# define SPY_SIMD_IS_ARM_FIXED_SVE2 +# define SPY_SIMD_DETECTED ::spy::detail::simd_version::fixed_sve2_ # elif(__ARM_FEATURE_SVE_BITS == 1024) -# define SPY_SIMD_IS_ARM_FIXED_SVE_CARDINAL +# define SPY_SIMD_IS_ARM_FIXED_SVE2 +# define SPY_SIMD_DETECTED ::spy::detail::simd_version::fixed_sve2_ +# else +# error "[SPY] - No support for non-power of 2 SVE-2 cardinals" +# endif +# endif +#endif +#if !defined(SPY_SIMD_DETECTED) && defined(__ARM_FEATURE_SVE) +# if !defined(__ARM_FEATURE_SVE_BITS) || (__ARM_FEATURE_SVE_BITS == 0) +# define SPY_SIMD_IS_ARM_FLEXIBLE_SVE +# define SPY_SIMD_DETECTED ::spy::detail::simd_version::sve_ +# elif defined(__ARM_FEATURE_SVE_BITS) +# if(__ARM_FEATURE_SVE_BITS == 128) +# define SPY_SIMD_IS_ARM_FIXED_SVE +# define SPY_SIMD_DETECTED ::spy::detail::simd_version::fixed_sve_ +# elif(__ARM_FEATURE_SVE_BITS == 256) +# define SPY_SIMD_IS_ARM_FIXED_SVE +# define SPY_SIMD_DETECTED ::spy::detail::simd_version::fixed_sve_ +# elif(__ARM_FEATURE_SVE_BITS == 512) +# define SPY_SIMD_IS_ARM_FIXED_SVE +# define SPY_SIMD_DETECTED ::spy::detail::simd_version::fixed_sve_ +# elif(__ARM_FEATURE_SVE_BITS == 1024) +# define SPY_SIMD_IS_ARM_FIXED_SVE +# define SPY_SIMD_DETECTED ::spy::detail::simd_version::fixed_sve_ # else # error "[SPY] - No support for non-power of 2 SVE cardinals" # endif # endif #endif -#if !defined(SPY_SIMD_DETECTED) && defined(__ARM_FEATURE_SVE2) +#if defined(__ARM_FEATURE_SVE2) # define SPY_SIMD_IS_ARM_SVE2 -# define SPY_SIMD_DETECTED ::spy::detail::simd_version::sve2_ # define SPY_SIMD_VENDOR ::spy::detail::simd_isa::arm_sve_ -#elif !defined(SPY_SIMD_DETECTED) && defined(__ARM_FEATURE_SVE) +#elif defined(__ARM_FEATURE_SVE) # define SPY_SIMD_IS_ARM_SVE -# define SPY_SIMD_DETECTED ::spy::detail::simd_version::sve_ # define SPY_SIMD_VENDOR ::spy::detail::simd_isa::arm_sve_ #endif #if !defined(SPY_SIMD_DETECTED) && defined(__aarch64__) @@ -999,15 +1024,16 @@ namespace avx512 #endif #if defined(__riscv_vector) # if !defined(__riscv_v_fixed_vlen) -# define SPY_SIMD_IS_RISCV_FLEXIBLE_RVV_CARDINAL +# define SPY_SIMD_IS_RISCV_FLEXIBLE_RVV +# define SPY_SIMD_DETECTED ::spy::detail::simd_version::rvv_ #else -# define SPY_SIMD_IS_RISCV_FIXED_RVV_CARDINAL +# define SPY_SIMD_IS_RISCV_FIXED_RVV +# define SPY_SIMD_DETECTED ::spy::detail::simd_version::fixed_rvv_ #endif #endif -#if !defined(SPY_SIMD_DETECTED) && defined(__riscv_vector) +#if defined(__riscv_vector) # define SPY_SIMD_IS_RISCV_RVV # define SPY_SIMD_VENDOR ::spy::detail::simd_isa::riscv_ -# define SPY_SIMD_DETECTED ::spy::detail::simd_version::rvv_ #endif namespace spy::detail { @@ -1029,9 +1055,10 @@ namespace spy::detail , vsx_ = 3000 , vsx_2_06_ = 3206, vsx_2_07_ = 3207, vsx_3_00_ = 3300, vsx_3_01_ = 3301 , neon_ = 4001, asimd_ = 4002 - , sve_ = 5000, sve2_ = 5500 + , sve_ = 5000, fixed_sve_ = 5100 + , sve2_ = 5500, fixed_sve2_ = 5600 , simd128_ = 6000 - , rvv_ = 7000 + , rvv_ = 7000, fixed_rvv_ = 7500 }; template< simd_isa InsSetArch = simd_isa::undefined_ , simd_version Version = simd_version::undefined_ @@ -1049,7 +1076,8 @@ namespace spy::detail ) return 128; else if constexpr(Version == simd_version::avx_ || Version == simd_version::avx2_) return 256; else if constexpr(Version == simd_version::avx512_ ) return 512; -else if constexpr( Version == simd_version::rvv_ ) + else if constexpr( Version == simd_version::rvv_ ) return -1; + else if constexpr( Version == simd_version::fixed_rvv_ ) { #if defined(__riscv_v_fixed_vlen) return __riscv_v_fixed_vlen; @@ -1059,6 +1087,10 @@ else if constexpr( Version == simd_version::rvv_ ) } else if constexpr(Version == simd_version::sve_ || Version == simd_version::sve2_) { + return -1; + } + else if constexpr(Version == simd_version::fixed_sve_ || Version == simd_version::fixed_sve2_) + { #if defined(__ARM_FEATURE_SVE_BITS) return __ARM_FEATURE_SVE_BITS; #else @@ -1090,24 +1122,14 @@ else if constexpr( Version == simd_version::rvv_ ) constexpr auto v = static_cast(Version); os << "PPC VSX with ISA v" << ((v-3000)/100.); } - else if constexpr ( Version == simd_version::neon_ ) os << "ARM NEON"; - else if constexpr ( Version == simd_version::asimd_ ) os << "ARM ASIMD"; - else if constexpr ( Version == simd_version::sve_ || Version == simd_version::sve2_ ) - { - os << "ARM SVE" << (Version == simd_version::sve2_ ? "2" : "") << "("; - constexpr auto fc = has_fixed_cardinal(); - if constexpr(fc) os << simd_info::width; - else os << "dyn."; - os << " bits)"; - } - else if constexpr ( Version == simd_version::rvv_ ) - { - os << "RISC-V RVV("; - constexpr auto fc = has_fixed_cardinal(); - if constexpr(fc) os << simd_info::width; - else os << "dyn."; - os << " bits)"; - } + else if constexpr ( Version == simd_version::neon_ ) os << "ARM NEON"; + else if constexpr ( Version == simd_version::asimd_ ) os << "ARM ASIMD"; + else if constexpr ( Version == simd_version::sve_ ) os << "ARM SVE (dyn.)"; + else if constexpr ( Version == simd_version::fixed_sve_ ) os << "ARM SVE (" << simd_info::width << " bits)"; + else if constexpr ( Version == simd_version::sve2_ ) os << "ARM SVE2 (dyn.)"; + else if constexpr ( Version == simd_version::fixed_sve2_ ) os << "ARM SVE2 (" << simd_info::width << " bits)"; + else if constexpr ( Version == simd_version::rvv_ ) os << "RISC-V RVV (dyn.)"; + else if constexpr ( Version == simd_version::fixed_rvv_ ) os << "RISC-V RVV (" << simd_info::width << " bits)"; else return os << "Undefined SIMD instructions set"; if constexpr (spy::supports::fma_) os << " (with FMA3 support)"; if constexpr (spy::supports::fma4_) os << " (with FMA4 support)"; @@ -1197,11 +1219,14 @@ namespace spy constexpr inline auto neon_ = arm_simd_info{}; constexpr inline auto asimd_ = arm_simd_info{}; constexpr inline auto sve_ = sve_simd_info{}; + constexpr inline auto fixed_sve_ = sve_simd_info{}; constexpr inline auto sve2_ = sve_simd_info{}; + constexpr inline auto fixed_sve2_ = sve_simd_info{}; template using riscv_simd_info = detail::simd_info; constexpr inline auto riscv_simd_ = riscv_simd_info<> {}; constexpr inline auto rvv_ = riscv_simd_info {}; + constexpr inline auto fixed_rvv_ = riscv_simd_info {}; } #include namespace spy::detail diff --git a/test/unit/simd.cpp b/test/unit/simd.cpp index a517740..54d452f 100644 --- a/test/unit/simd.cpp +++ b/test/unit/simd.cpp @@ -52,17 +52,15 @@ int main() std::cout << "NEON status: " << std::boolalpha << (spy::simd_instruction_set >= spy::neon_ ) << std::endl; std::cout << "ASIMD status: " << std::boolalpha << (spy::simd_instruction_set >= spy::asimd_) << std::endl; - std::cout << "SVE status: " << std::boolalpha << (spy::simd_instruction_set == spy::sve_ ) << std::endl; - std::cout << "SVE2 status: " << std::boolalpha << (spy::simd_instruction_set == spy::sve2_) << std::endl; - if constexpr(spy::simd_instruction_set == spy::sve_ || spy::simd_instruction_set == spy::sve2_) + std::cout << "SVE status: " << std::boolalpha << (spy::simd_instruction_set == spy::sve_ ) << std::endl; + std::cout << "SVE (fixed) status: " << std::boolalpha << (spy::simd_instruction_set == spy::fixed_sve_ ) << std::endl; + std::cout << "SVE2 status: " << std::boolalpha << (spy::simd_instruction_set == spy::sve2_) << std::endl; + std::cout << "SVE2 (fixed) status: " << std::boolalpha << (spy::simd_instruction_set == spy::fixed_sve2_ ) << std::endl; + if constexpr(spy::simd_instruction_set >= spy::sve_ ) { if constexpr(spy::simd_instruction_set.has_fixed_cardinal()) { - std::cout << "SVE uses fixed size: " << spy::simd_instruction_set.width << " bits" << std::endl; - } - else - { - std::cout << "SVE uses flexible size" << std::endl; + std::cout << "SVE register size: " << spy::simd_instruction_set.width << " bits" << std::endl; } } } @@ -95,17 +93,14 @@ int main() std::cout << "Check that RISC-V SIMD extension detection is correct: " << std::endl; { - std::cout << "RISC-V status: " << std::boolalpha << (spy::simd_instruction_set == spy::riscv_simd_ ) << std::endl; - std::cout << "RVV status: " << std::boolalpha << (spy::simd_instruction_set >= spy::rvv_ ) << std::endl; - if constexpr(spy::simd_instruction_set == spy::rvv_) + std::cout << "RISC-V status: " << std::boolalpha << (spy::simd_instruction_set == spy::riscv_simd_) << std::endl; + std::cout << "RVV status: " << std::boolalpha << (spy::simd_instruction_set >= spy::rvv_ ) << std::endl; + std::cout << "RVV (fixed) status: " << std::boolalpha << (spy::simd_instruction_set >= spy::fixed_rvv_ ) << std::endl; + if constexpr(spy::simd_instruction_set >= spy::rvv_ ) { if constexpr(spy::simd_instruction_set.has_fixed_cardinal()) { - std::cout << "RVV uses fixed size: " << spy::simd_instruction_set.width << " bits" << std::endl; - } - else - { - std::cout << "RVV uses flexible size" << std::endl; + std::cout << "RVV register size: " << spy::simd_instruction_set.width << " bits" << std::endl; } } }