Skip to content

Commit

Permalink
Fix #36 - Separate ARM and ARM SVE tags and add SVE2 detectors
Browse files Browse the repository at this point in the history
  • Loading branch information
jfalcou authored Feb 1, 2024
1 parent 2aa8a82 commit 5bd922c
Show file tree
Hide file tree
Showing 6 changed files with 114 additions and 55 deletions.
14 changes: 8 additions & 6 deletions .github/workflows/unit.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ jobs:
- { comp: gcc , arch: x86_osx, mode: Release }
steps:
- name: Fetch current branch
uses: actions/checkout@v3
uses: actions/checkout@v4.1.1
- name: Running CMake for ${{ matrix.cfg.comp }} in ${{ matrix.cfg.mode }} mode
run: |
mkdir build && cd build
Expand All @@ -55,7 +55,7 @@ jobs:

steps:
- name: Fetch current branch
uses: actions/checkout@v3
uses: actions/checkout@v4.1.1
- name: Running CMake for MSVC ${{ matrix.cfg.mode }}
run: |
mkdir build && cd build
Expand All @@ -80,7 +80,7 @@ jobs:

steps:
- name: Fetch current branch
uses: actions/checkout@v3
uses: actions/checkout@v4.1.1
- name: Running CMake for Clang CL ${{ matrix.cfg.mode }}
run: |
mkdir build && cd build
Expand Down Expand Up @@ -109,7 +109,7 @@ jobs:
- { comp: clang , arch: wasm, mode: Release }
steps:
- name: Fetch current branch
uses: actions/checkout@v3
uses: actions/checkout@v4.1.1
- name: Running CMake for ${{ matrix.cfg.comp }} in ${{ matrix.cfg.mode }} mode
run: |
mkdir build && cd build
Expand All @@ -135,7 +135,7 @@ jobs:
- { comp: clang , arch: x86, mode: Release }
steps:
- name: Fetch current branch
uses: actions/checkout@v3
uses: actions/checkout@v4.1.1
- name: Running CMake for ${{ matrix.cfg.comp }} in ${{ matrix.cfg.mode }} mode
run: |
mkdir build && cd build
Expand Down Expand Up @@ -163,11 +163,13 @@ jobs:
- { comp: gcc , arch: aarch64 , opts: -Wno-psabi, mode: Release }
- { comp: gcc , arch: aarch64.sve , opts: -Wno-psabi, mode: Debug }
- { comp: gcc , arch: aarch64.sve , opts: -Wno-psabi, mode: Release }
- { comp: gcc , arch: aarch64.sve2, opts: -Wno-psabi, mode: Debug }
- { comp: gcc , arch: aarch64.sve2, opts: -Wno-psabi, mode: Release }
- { comp: gcc , arch: ppc64 , opts: -Wno-psabi, mode: Debug }
- { comp: gcc , arch: ppc64 , opts: -Wno-psabi, mode: Release }
steps:
- name: Fetch current branch
uses: actions/checkout@v3
uses: actions/checkout@v4.1.1
- name: Running CMake for ${{ matrix.cfg.comp }} in ${{ matrix.cfg.mode }} mode
run: |
mkdir build && cd build
Expand Down
58 changes: 37 additions & 21 deletions include/spy.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -793,26 +793,32 @@ namespace avx512
#endif
}
}
#if !defined(SPY_SIMD_DETECTED) && defined(__ARM_FEATURE_SVE)
#if defined(__ARM_FEATURE_SVE2) || 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_
# define SPY_SIMD_IS_ARM_FLEXIBLE_SVE_CARDINAL
# 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_
# define SPY_SIMD_IS_ARM_FIXED_SVE_CARDINAL
# elif(__ARM_FEATURE_SVE_BITS == 256)
# define SPY_SIMD_IS_ARM_FIXED_SVE
# define SPY_SIMD_DETECTED ::spy::detail::simd_version::fixed_sve_
# define SPY_SIMD_IS_ARM_FIXED_SVE_CARDINAL
# elif(__ARM_FEATURE_SVE_BITS == 512)
# define SPY_SIMD_IS_ARM_FIXED_SVE
# define SPY_SIMD_DETECTED ::spy::detail::simd_version::fixed_sve_
# define SPY_SIMD_IS_ARM_FIXED_SVE_CARDINAL
# elif(__ARM_FEATURE_SVE_BITS == 1024)
# define SPY_SIMD_IS_ARM_FIXED_SVE
# define SPY_SIMD_DETECTED ::spy::detail::simd_version::fixed_sve_
# define SPY_SIMD_IS_ARM_FIXED_SVE_CARDINAL
# else
# error "[SPY] - No support for non-power of 2 SVE cardinals"
# endif
# endif
#endif
#if !defined(SPY_SIMD_DETECTED) && 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)
# 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__)
# define SPY_SIMD_IS_ARM_ASIMD
# define SPY_SIMD_DETECTED ::spy::detail::simd_version::asimd_
Expand Down Expand Up @@ -867,7 +873,7 @@ namespace avx512
#endif
namespace spy::detail
{
enum class simd_isa { undefined_ = -1, x86_ = 1000, ppc_ = 2000, arm_ = 3000, wasm_ = 4000 };
enum class simd_isa { undefined_ = -1, x86_ = 1000, ppc_ = 2000, arm_ = 3000, arm_sve_ = 3500, wasm_ = 4000 };
enum class simd_version { undefined_ = -1
, sse1_ = 1110, sse2_ = 1120, sse3_ = 1130, ssse3_ = 1131
, sse41_ = 1141, sse42_ = 1142
Expand All @@ -879,10 +885,12 @@ 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, fixed_sve_ = 5100
, sve_ = 5000, sve2_ = 5500
, simd128_ = 6000
};
template<simd_isa InsSetArch = simd_isa::undefined_, simd_version Version = simd_version::undefined_>
template< simd_isa InsSetArch = simd_isa::undefined_
, simd_version Version = simd_version::undefined_
>
struct simd_info
{
static constexpr auto isa = InsSetArch;
Expand All @@ -896,7 +904,7 @@ 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::fixed_sve_ )
else if constexpr(Version >= simd_version::sve_)
{
#if defined(__ARM_FEATURE_SVE_BITS)
return __ARM_FEATURE_SVE_BITS;
Expand All @@ -906,6 +914,7 @@ namespace spy::detail
}
else return -1;
}();
static constexpr bool has_fixed_cardinal() { return width != -1; }
friend std::ostream& operator<<(std::ostream& os, simd_info const&)
{
if constexpr ( Version == simd_version::simd128_ ) os << "WASM SIMD128";
Expand All @@ -930,10 +939,15 @@ namespace spy::detail
}
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. bits)";
else if constexpr ( Version == simd_version::fixed_sve_) os << "ARM SVE ("
<< simd_info::width
<< " bits)";
else if constexpr ( Version >= simd_version::sve_ )
{
if constexpr ( Version == simd_version::sve2_ ) os << "ARM SVE2 (";
else os << "ARM SVE (";
constexpr auto fc = has_fixed_cardinal();
if constexpr(fc) os << simd_info::width;
else os << "dyn.";
os << " 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)";
Expand Down Expand Up @@ -1017,11 +1031,13 @@ namespace spy
constexpr inline auto vsx_3_01_ = ppc_simd_info<detail::simd_version::vsx_3_01_>{};
template<detail::simd_version V = detail::simd_version::undefined_>
using arm_simd_info = detail::simd_info<detail::simd_isa::arm_,V>;
template<detail::simd_version V = detail::simd_version::undefined_>
using sve_simd_info = detail::simd_info<detail::simd_isa::arm_sve_,V>;
constexpr inline auto arm_simd_ = arm_simd_info<>{};
constexpr inline auto neon_ = arm_simd_info<detail::simd_version::neon_ >{};
constexpr inline auto asimd_ = arm_simd_info<detail::simd_version::asimd_>{};
constexpr inline auto sve_ = arm_simd_info<detail::simd_version::sve_>{};
constexpr inline auto fixed_sve_ = arm_simd_info<detail::simd_version::fixed_sve_>{};
constexpr inline auto sve_ = sve_simd_info<detail::simd_version::sve_>{};
constexpr inline auto sve2_ = sve_simd_info<detail::simd_version::sve2_>{};
}
#include <cstddef>
namespace spy::detail
Expand Down
35 changes: 25 additions & 10 deletions src/spy/simd.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@

namespace spy::detail
{
enum class simd_isa { undefined_ = -1, x86_ = 1000, ppc_ = 2000, arm_ = 3000, wasm_ = 4000 };
enum class simd_isa { undefined_ = -1, x86_ = 1000, ppc_ = 2000, arm_ = 3000, arm_sve_ = 3500, wasm_ = 4000 };

enum class simd_version { undefined_ = -1
, sse1_ = 1110, sse2_ = 1120, sse3_ = 1130, ssse3_ = 1131
Expand All @@ -28,15 +28,18 @@ 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, fixed_sve_ = 5100
, sve_ = 5000, sve2_ = 5500
, simd128_ = 6000
};

template<simd_isa InsSetArch = simd_isa::undefined_, simd_version Version = simd_version::undefined_>
template< simd_isa InsSetArch = simd_isa::undefined_
, simd_version Version = simd_version::undefined_
>
struct simd_info
{
static constexpr auto isa = InsSetArch;
static constexpr auto version = Version;

static constexpr std::ptrdiff_t width = []()
{
if constexpr( Version == simd_version::simd128_
Expand All @@ -46,7 +49,7 @@ 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::fixed_sve_ )
else if constexpr(Version >= simd_version::sve_)
{
#if defined(__ARM_FEATURE_SVE_BITS)
return __ARM_FEATURE_SVE_BITS;
Expand All @@ -57,6 +60,8 @@ namespace spy::detail
else return -1;
}();

static constexpr bool has_fixed_cardinal() { return width != -1; }

friend std::ostream& operator<<(std::ostream& os, simd_info const&)
{
if constexpr ( Version == simd_version::simd128_ ) os << "WASM SIMD128";
Expand All @@ -81,10 +86,17 @@ namespace spy::detail
}
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. bits)";
else if constexpr ( Version == simd_version::fixed_sve_) os << "ARM SVE ("
<< simd_info::width
<< " bits)";
else if constexpr ( Version >= simd_version::sve_ )
{
if constexpr ( Version == simd_version::sve2_ ) os << "ARM SVE2 (";
else os << "ARM SVE (";

constexpr auto fc = has_fixed_cardinal();
if constexpr(fc) os << simd_info::width;
else os << "dyn.";

os << " bits)";
}
else return os << "Undefined SIMD instructions set";

if constexpr (spy::supports::fma_) os << " (with FMA3 support)";
Expand Down Expand Up @@ -195,9 +207,12 @@ namespace spy
template<detail::simd_version V = detail::simd_version::undefined_>
using arm_simd_info = detail::simd_info<detail::simd_isa::arm_,V>;

template<detail::simd_version V = detail::simd_version::undefined_>
using sve_simd_info = detail::simd_info<detail::simd_isa::arm_sve_,V>;

constexpr inline auto arm_simd_ = arm_simd_info<>{};
constexpr inline auto neon_ = arm_simd_info<detail::simd_version::neon_ >{};
constexpr inline auto asimd_ = arm_simd_info<detail::simd_version::asimd_>{};
constexpr inline auto sve_ = arm_simd_info<detail::simd_version::sve_>{};
constexpr inline auto fixed_sve_ = arm_simd_info<detail::simd_version::fixed_sve_>{};
constexpr inline auto sve_ = sve_simd_info<detail::simd_version::sve_>{};
constexpr inline auto sve2_ = sve_simd_info<detail::simd_version::sve2_>{};
}
29 changes: 18 additions & 11 deletions src/spy/simd/arm.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,29 +7,36 @@
//==================================================================================================
#pragma once

#if !defined(SPY_SIMD_DETECTED) && defined(__ARM_FEATURE_SVE)
#if defined(__ARM_FEATURE_SVE2) || 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
# define SPY_SIMD_DETECTED ::spy::detail::simd_version::sve_
# define SPY_SIMD_IS_ARM_FLEXIBLE_SVE_CARDINAL
// 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
# define SPY_SIMD_DETECTED ::spy::detail::simd_version::fixed_sve_
# define SPY_SIMD_IS_ARM_FIXED_SVE_CARDINAL
# elif(__ARM_FEATURE_SVE_BITS == 256)
# define SPY_SIMD_IS_ARM_FIXED_SVE
# define SPY_SIMD_DETECTED ::spy::detail::simd_version::fixed_sve_
# define SPY_SIMD_IS_ARM_FIXED_SVE_CARDINAL
# elif(__ARM_FEATURE_SVE_BITS == 512)
# define SPY_SIMD_IS_ARM_FIXED_SVE
# define SPY_SIMD_DETECTED ::spy::detail::simd_version::fixed_sve_
# define SPY_SIMD_IS_ARM_FIXED_SVE_CARDINAL
# elif(__ARM_FEATURE_SVE_BITS == 1024)
# define SPY_SIMD_IS_ARM_FIXED_SVE
# define SPY_SIMD_DETECTED ::spy::detail::simd_version::fixed_sve_
# define SPY_SIMD_IS_ARM_FIXED_SVE_CARDINAL
# else
# error "[SPY] - No support for non-power of 2 SVE cardinals"
# endif
# endif
#endif

#if !defined(SPY_SIMD_DETECTED) && 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)
# 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__)
# define SPY_SIMD_IS_ARM_ASIMD
# define SPY_SIMD_DETECTED ::spy::detail::simd_version::asimd_
Expand Down
20 changes: 13 additions & 7 deletions test/simd.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
int main()
{
std::cout << "Supported SIMD instructions set: " << spy::simd_instruction_set << std::endl;
std::cout << "Supported SIMD instructions set: " << typeid(spy::simd_instruction_set).name() << std::endl;
std::cout << "Check that X86 SIMD extension detection is correct: " << std::endl;
{
std::cout << "X86 SIMD status: " << std::boolalpha << (spy::simd_instruction_set == spy::x86_simd_) << std::endl;
Expand Down Expand Up @@ -50,14 +51,19 @@ int main()
std::cout << "ARM SIMD status: " << std::boolalpha << (spy::simd_instruction_set == spy::arm_simd_ ) << std::endl;
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_);
if constexpr(spy::simd_instruction_set >= spy::fixed_sve_)
{
std::cout << " - fixed size: " << spy::simd_instruction_set.width << " bits" << std::endl;
}
else if constexpr(spy::simd_instruction_set >= spy::sve_)

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_)
{
std::cout << " - flexible size" << std::endl;
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 << std::endl;
Expand Down
13 changes: 13 additions & 0 deletions test/toolchain/gcc.aarch64.sve2.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
##==================================================================================================
## SPY - C++ Informations Broker
## Copyright : SPY Project Contributors
## SPDX-License-Identifier: BSL-1.0
##==================================================================================================
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR arm)

set(CMAKE_C_COMPILER aarch64-linux-gnu-gcc-12 )
set(CMAKE_CXX_COMPILER aarch64-linux-gnu-g++-12 )
set(CMAKE_CXX_FLAGS "-march=armv8-a+sve2 -msve-vector-bits=512" )

set(CMAKE_CROSSCOMPILING_CMD qemu-aarch64)

0 comments on commit 5bd922c

Please sign in to comment.