一呼百應, "one call, a hundred responses"
Loading...
Searching...
No Matches
SIMD

Namespaces

namespace  ein::detail
 

Concepts

concept  ein::simd_type
 recognizes any valid simd type
 
concept  ein::has_storage_type
 
concept  ein::has_lifted_operations
 Does this type have operations that semantically correct when lifted to the simd_data_t level?
 
concept  ein::has_simd_type
 ein::simd_data_t<T,N> is defined
 
concept  ein::has_builtin_convertvector
 can we convert simd_data_t<U,N> -> simd_data_t<T,N> automatically using gcc vector extensions?
 
concept  ein::simd_builtin
 is this type one of the types that is handed well automatically by clang/gcc vector extensions?
 
concept  ein::has_mmask
 Do we want to use AVX512's notion of an _mmask8, _mmask16, _mmask32, or _mmask64 for masking operations.
 

Classes

struct  ein::simd< T, N >
 simd primitive definition More...
 
struct  std::tuple_size< ein::simd< T, N > >
 
struct  std::tuple_element< I, ein::simd< T, N > >
 needed to support for std::apply More...
 
struct  ein::detail::storage_type_impl< T >
 
struct  ein::detail::storage_type_impl< bf16 >
 
struct  ein::detail::storage_type_impl< fp16 >
 
struct  ein::detail::si< 128 >
 
struct  ein::detail::ps< 128 >
 
struct  ein::detail::pd< 128 >
 
struct  ein::detail::si< 256 >
 
struct  ein::detail::ps< 256 >
 
struct  ein::detail::pd< 256 >
 
struct  ein::detail::si< 512 >
 
struct  ein::detail::ps< 512 >
 
struct  ein::detail::pd< 512 >
 
struct  ein::detail::simd_intrinsic< float, N >
 
struct  ein::detail::simd_intrinsic< double, N >
 
struct  ein::detail::simd_intrinsic< T, N >
 

Typedefs

template<typename T >
using ein::storage_type
 The type used to store T in a simd_data_t.
 
template<typename T , size_t N>
using ein::simd_data_t = storage_type<T> __attribute__((__vector_size__(N*sizeof(storage_type<T>)),__aligned__(N*sizeof(storage_type<T>))))
 
template<typename T , size_t N>
using ein::simd_intrinsic_t
 Returns the Intel intrinsic type associated with a simd register full of N values of type T.
 
template<size_t N>
using ein::mmask_t
 If AVX512 is enabled returns the type of an n-bit mmask.
 
template<typename T , size_t N>
using ein::simd_mask_t
 What type of mask should I use?
 

Functions

__m128 ein::cast_ps (__m128i a) noexcept
 
__m128 ein::cast_ps (__m128 a) noexcept
 
__m256 ein::cast_ps (__m256i a) noexcept
 
__m256 ein::cast_ps (__m256 a) noexcept
 
__m128d ein::cast_pd (__m128i a) noexcept
 
__m128d ein::cast_pd (__m128d a) noexcept
 
__m256d ein::cast_pd (__m256i a) noexcept
 
__m256d ein::cast_pd (__m256d a) noexcept
 
__m128i ein::cast_si (__m128 a) noexcept
 
__m128i ein::cast_si (__m128d a) noexcept
 
__m128i ein::cast_si (__m128i a) noexcept
 
__m256i ein::cast_si (__m256 a) noexcept
 
__m256i ein::cast_si (__m256d a) noexcept
 
__m256i ein::cast_si (__m256i a) noexcept
 
__m512 ein::cast_ps (__m512i a) noexcept
 
__m512d ein::cast_pd (__m512i a) noexcept
 
__m512 ein::cast_ps (__m512 a) noexcept
 
__m512d ein::cast_pd (__m512d a) noexcept
 
__m512i ein::cast_si (__m512 a) noexcept
 
__m512i ein::cast_si (__m512d a) noexcept
 
__m512i ein::cast_si (__m512i a) noexcept
 

Variables

constexpr size_t ein::max_simd_size = 64
 largest simd register width supported on this platform in bytes
 

argument deduction

template<typename T , size_t N>
requires ( has_simd_type<T,N> && (N % sizeof(T) == 0) )
 ein::simd (T __attribute((__vector_size__(N)))) -> simd< T, N/sizeof(T)>
 guidance when loading data from clang/gcc vector extensions
 
template<typename ... Args>
requires has_simd_type<std::common_type<Args...>, sizeof...(Args)>
 ein::simd (Args &&...) -> simd< std::common_type< Args... >, sizeof...(Args)>
 guidance for loading from arguments
 
template<typename T >
requires has_simd_type<T,max_simd_size/sizeof(T)>
 ein::simd (T) -> simd< T, has_simd_type< T, max_simd_size/sizeof(T)> >
 default to max simd size for broadcast
 

shuffles

template<size_t ... is>
auto ein::shuffle (simd_type auto x)
 create a new simd register with contents drawn from this one
 
template<size_t ... is>
auto ein::shuffle (simd_type auto x, simd_type auto y)
 create a new simd register with contents drawn from these two
 

Detailed Description


Class Documentation

◆ ein::simd

struct ein::simd
template<typename T, size_t N>
requires (has_simd_type<T,N>)
struct ein::simd< T, N >

simd primitive definition

Definition at line 39 of file simd.hpp.

Public Member Functions

constructors
constexpr simd () noexcept=default
 default initialization
 
constexpr simd (simd const &) noexcept=default
 copy construction
 
constexpr simd (simd &&) noexcept=default
 move construction
 
template<std::convertible_to< T > ... Args>
requires (sizeof...(Args) == N)
constexpr simd (Args &&... args) noexcept
 array initialization
 
constexpr simd (T value) noexcept
 broadcast construction
 
constexpr simd (data_t const &data) noexcept
 copy construction from clang/gcc vector intrinsics
 
constexpr simd (data_t &&data) noexcept
 move construction from clang/gcc vector intrinsics
 
constexpr simd (std::initializer_list< T > init)
 initialize the first init .size values from an initializer_list
 
constexpr simd (intrinsic_t const &data) noexcept
 copy construct from the corresponding intel intrinsic type (if different than the gcc/clang one)
 
constexpr simd (intrinsic_t &&data) noexcept
 move construct from the corresponding intel intrinsic type (if different than the gcc/clang one)
 
assignments
ein_reinitializes constexpr simdoperator= (simd &&) noexcept=default
 
ein_reinitializes constexpr simdoperator= (simd const &) noexcept=default
 
template<typename U >
requires (!std::is_same_v<U,T> && has_builtin_convertvector<U,T,N>)
ein_reinitializes constexpr simdoperator= (simd_t< U > other) noexcept
 automatic conversion for types supported by __builtin_convertvector
 
intel compatibility
constexpr operator intrinsic_t & () noexcept
 provide compatibility with Intel intrinsics by freely using this as simd_intrinsic_t<T,N> &
 
constexpr operator intrinsic_t const & () const noexcept
 provide compatibility with Intel intrinsics by freely using this as simd_intrinsic_t<T,N> const &
 
constexpr intrinsic_tit () noexcept
 provide compatibility with Intel intrinsics by freely using this as simd_intrinsic_t<T,N> &
 
constexpr intrinsic_t const & it () const noexcept
 provide compatibility with Intel intrinsics by freely using this as simd_intrinsic_t<T,N> const &
 
iterable
constexpr T & operator[] (std::size_t i) noexcept
 access the element in the i th lane
 
constexpr T const & operator[] (std::size_t i) const noexcept
 access the element in the i th lane
 
constexpr T * begin () noexcept
 start iterator
 
constexpr T * end () noexcept
 end iterator
 
constexpr T const * cbegin () const noexcept
 const start iterator
 
constexpr T const * cend () const noexcept
 const end iterator
 
constexpr T const * begin () const noexcept
 const start iterator
 
constexpr T const * end () const noexcept
 const end iterator
 
constexpr std::reverse_iterator< T * > rbegin () noexcept
 reverse start iterator
 
constexpr std::reverse_iterator< T * > rend () noexcept
 reverse end iterator
 
constexpr std::reverse_iterator< const T * > crbegin () const noexcept
 const reverse start iterator
 
constexpr std::reverse_iterator< const T * > crend () const noexcept
 const reverse end iterator
 
constexpr std::reverse_iterator< const T * > rbegin () const noexcept
 const reverse start iterator
 
constexpr std::reverse_iterator< const T * > rend () const noexcept
 const reverse end iterator
 
shuffles
template<size_t ... is>
requires (((is < N) && ... && has_simd_type<T,sizeof...(is)>) && requires (data_t x) { simd<T,sizeof...(is)>(__builtin_shufflevector(x, is...)); })
constexpr simd< T, sizeof...(is)> shuffle () noexcept
 shuffle selected elements to produce a new simd register
 
template<size_t ... is>
requires (((is < N*2) && ... && has_simd_type<T,sizeof...(is)>) && requires (data_t x) { simd<T,sizeof...(is)>(__builtin_shufflevector(x, x, is...)); })
constexpr simd< T, sizeof...(is)> shuffle (simd< T, N > b) noexcept
 Use elements taken from this and another simd register to construct another. If an index i in is is less than N, it draw from this, otherwise it draws from the i - Nth position in b.
 

Public Attributes

data_t data
 

Private Types

using data_t = simd_data_t<T,N>
 
using mask_t = simd_mask_t<T,N>
 
using intrinsic_t = simd_intrinsic_t<T,N>
 
template<typename U >
using simd_t = simd<U,N>
 
template<typename U >
using cast_t = simd<U,N*sizeof(T)/sizeof(U)>
 
using value_type = T
 

Static Private Attributes

static constexpr size_t bytesize = N*sizeof(T)
 
static constexpr size_t size = N
 

Friends

destructuring
template<size_t I>
requires (I < N)
constexpr T & get (simd &s) noexcept
 enables destructuring reference
 
template<size_t I>
requires (I < N)
constexpr T const & get (simd const &s) noexcept
 enables destructuring constant reference
 
template<size_t I>
requires (I < N)
constexpr T && get (simd &&s) noexcept
 enable destructuring move
 
comparisons
constexpr mask_t operator< (simd x, simd y) noexcept
 
constexpr mask_t operator> (simd x, simd y) noexcept
 
constexpr mask_t operator<= (simd x, simd y) noexcept
 
constexpr mask_t operator>= (simd x, simd y) noexcept
 
constexpr mask_t operator== (simd x, simd y) noexcept
 
constexpr mask_t operator!= (simd x, simd y) noexcept
 
constexpr mask_t operator< (simd a, simd b) noexcept
 
constexpr mask_t operator> (simd a, simd b) noexcept
 
constexpr mask_t operator<= (simd a, simd b) noexcept
 
constexpr mask_t operator>= (simd a, simd b) noexcept
 
constexpr mask_t operator== (simd a, simd b) noexcept
 
constexpr mask_t operator!= (simd a, simd b) noexcept
 
template<CMP imm8>
requires one_of_t<T,float,double> && (size_t(imm8) < max_fp_comparison_predicate)
constexpr mask_t cmp (simd a, simd b) noexcept
 
template<CMPINT imm8>
requires one_of_t<storage_type<T>,uint8_t,int8_t,uint16_t,int16_t,uint32_t,int32_t,uint64_t,int64_t> && has_lifted_operations<T> && (size_t(imm8) < 8uz)
constexpr mask_t cmpint (simd a, simd b) noexcept
 
constexpr mask_t operator== (simd a, simd b) noexcept
 
constexpr mask_t operator/= (simd a, simd b) noexcept
 
constexpr mask_t operator< (simd a, simd b) noexcept
 
constexpr mask_t operator<= (simd a, simd b) noexcept
 
constexpr mask_t operator> (simd a, simd b) noexcept
 
constexpr mask_t operator>= (simd a, simd b) noexcept
 
scalef
constexpr simd scalef (simd x, simd y) noexcept
 
data movement
constexpr void swap (simd &x, simd &y) noexcept
 

operators

constexpr simdoperator+= (simd other) noexcept
 
constexpr simdoperator-= (simd other) noexcept
 
constexpr simdoperator*= (simd other) noexcept
 
constexpr simdoperator/= (simd other) noexcept
 
constexpr simdoperator&= (simd other) noexcept
 
constexpr simdoperator|= (simd other) noexcept
 
constexpr simdoperator^= (simd other) noexcept
 
constexpr simd operator+ () const noexcept
 
constexpr simd operator- () const noexcept
 
constexpr simdoperator-- () noexcept
 --x
 
constexpr simd operator-- (int) noexcept
 x--
 
constexpr simdoperator++ () noexcept
 ++x
 
constexpr simd operator++ (int) noexcept
 x++
 
template<size_t K>
requires (has_lifted_operations<T> && requires (data_t a) { a >>= static_cast<T>(K); })
constexpr simdoperator>>= (imm_t< K >) noexcept
 self-shift right by an immediate value
 
constexpr simdoperator>>= (T y) noexcept
 self-shift right by a scalar
 
constexpr simdoperator>>= (simd y) noexcept
 self-shift right elementwise
 
template<size_t K>
requires (has_lifted_operations<T> && requires (data_t a) { a <<= static_cast<T>(K); })
constexpr simdoperator<<= (imm_t< K >) noexcept
 self-shift left by an immediate constant
 
constexpr simdoperator<<= (T y) noexcept
 self-shift left by a scalar
 
constexpr simdoperator<<= (simd y) noexcept
 self-shift left elementwise
 
constexpr simd operator+ (simd x, simd y) noexcept
 
constexpr simd operator- (simd x, simd y) noexcept
 
constexpr simd operator* (simd x, simd y) noexcept
 
constexpr simd operator/ (simd x, simd y) noexcept
 
template<typename U >
requires (has_lifted_operations<T> && requires (data_t a, data_t b) { a & b; })
constexpr simd operator& (simd x, simd y) noexcept
 
template<typename U >
requires (has_lifted_operations<T> && requires (data_t a, data_t b) { a | b; })
constexpr simd operator| (simd x, simd y) noexcept
 
constexpr simd operator^ (simd x, simd y) noexcept
 
template<size_t K>
requires (has_lifted_operations<T> && requires (data_t a) { a >> static_cast<T>(K); })
constexpr simd operator>> (simd x, imm_t< K >) noexcept
 shift right by an immediate constant
 
constexpr simd operator>> (simd x, T y) noexcept
 shift right by a scalar
 
constexpr simd operator>> (simd x, simd y) noexcept
 shift right elementwise
 
template<size_t K>
requires (has_lifted_operations<T> && requires (data_t a) { a << static_cast<T>(K); })
constexpr simd operator<< (simd x, imm_t< K >) noexcept
 shift left by an immediate constant
 
constexpr simd operator<< (simd x, T y) noexcept
 shift left by a scalar
 
constexpr simd operator<< (simd x, simd y) noexcept
 shift left elementwise
 

Member Typedef Documentation

◆ cast_t

template<typename T , size_t N>
template<typename U >
using ein::simd< T, N >::cast_t = simd<U,N*sizeof(T)/sizeof(U)>
private

Definition at line 50 of file simd.hpp.

◆ data_t

template<typename T , size_t N>
using ein::simd< T, N >::data_t = simd_data_t<T,N>
private

Definition at line 41 of file simd.hpp.

◆ intrinsic_t

template<typename T , size_t N>
using ein::simd< T, N >::intrinsic_t = simd_intrinsic_t<T,N>
private

Definition at line 43 of file simd.hpp.

◆ mask_t

template<typename T , size_t N>
using ein::simd< T, N >::mask_t = simd_mask_t<T,N>
private

Definition at line 42 of file simd.hpp.

◆ simd_t

template<typename T , size_t N>
template<typename U >
using ein::simd< T, N >::simd_t = simd<U,N>
private

Definition at line 47 of file simd.hpp.

◆ value_type

template<typename T , size_t N>
using ein::simd< T, N >::value_type = T
private

Definition at line 52 of file simd.hpp.

Constructor & Destructor Documentation

◆ simd() [1/10]

template<typename T , size_t N>
ein::simd< T, N >::simd ( )
constexprdefaultnoexcept[[always_inline]][[artificial]][[hidden]]

default initialization

◆ simd() [2/10]

template<typename T , size_t N>
ein::simd< T, N >::simd ( simd< T, N > const & )
constexprdefaultnoexcept[[always_inline]][[artificial]][[hidden]]

copy construction

◆ simd() [3/10]

template<typename T , size_t N>
ein::simd< T, N >::simd ( simd< T, N > && )
constexprdefaultnoexcept[[always_inline]][[artificial]][[hidden]]

move construction

◆ simd() [4/10]

template<typename T , size_t N>
template<std::convertible_to< T > ... Args>
requires (sizeof...(Args) == N)
ein::simd< T, N >::simd ( Args &&... args)
inlineconstexprnoexcept[[always_inline]][[artificial]][[hidden]]

array initialization

e.g. simd<float,4>{1.0,2.0,3.0,4.0}

Definition at line 77 of file simd.hpp.

79 : data(std::forward<Args>(args)...) {}
data_t data
Definition simd.hpp:56

◆ simd() [5/10]

template<typename T , size_t N>
ein::simd< T, N >::simd ( T value)
inlineconstexprnoexcept[[always_inline]][[artificial]][[hidden]]

broadcast construction

sets every member of the simd structure to the same value

Definition at line 84 of file simd.hpp.

85 : data(__extension__(data_t){value}) {}
simd_data_t< T, N > data_t
Definition simd.hpp:41

◆ simd() [6/10]

template<typename T , size_t N>
ein::simd< T, N >::simd ( data_t const & data)
inlineconstexprnoexcept[[always_inline]][[artificial]][[hidden]]

copy construction from clang/gcc vector intrinsics

Definition at line 89 of file simd.hpp.

90 : data(data) {}

◆ simd() [7/10]

template<typename T , size_t N>
ein::simd< T, N >::simd ( data_t && data)
inlineconstexprnoexcept[[always_inline]][[artificial]][[hidden]]

move construction from clang/gcc vector intrinsics

Definition at line 94 of file simd.hpp.

95 : data(std::move(data)) {}

◆ simd() [8/10]

template<typename T , size_t N>
ein::simd< T, N >::simd ( std::initializer_list< T > init)
inlineconstexpr[[always_inline]][[artificial]][[hidden]]

initialize the first init .size values from an initializer_list

Todo
use a masked unaligned load

Definition at line 103 of file simd.hpp.

◆ simd() [9/10]

template<typename T , size_t N>
ein::simd< T, N >::simd ( intrinsic_t const & data)
inlineconstexprnoexcept[[always_inline]][[artificial]][[hidden]]

copy construct from the corresponding intel intrinsic type (if different than the gcc/clang one)

Definition at line 114 of file simd.hpp.

116 : data(reinterpret_cast<data_t>(data)) {}

◆ simd() [10/10]

template<typename T , size_t N>
ein::simd< T, N >::simd ( intrinsic_t && data)
inlineconstexprnoexcept[[always_inline]][[artificial]][[hidden]]

move construct from the corresponding intel intrinsic type (if different than the gcc/clang one)

Definition at line 120 of file simd.hpp.

122 : data(reinterpret_cast<data_t>(std::move(data))) {}

Member Function Documentation

◆ begin() [1/2]

template<typename T , size_t N>
T const * ein::simd< T, N >::begin ( ) const
inlineconstexprnoexcept[[nodiscard]][[always_inline]][[artificial]][[const]][[hidden]]

const start iterator

Definition at line 213 of file simd.hpp.

213{ return cbegin(); }
constexpr T const * cbegin() const noexcept
const start iterator
Definition simd.hpp:205

◆ begin() [2/2]

template<typename T , size_t N>
T * ein::simd< T, N >::begin ( )
inlineconstexprnoexcept[[nodiscard]][[always_inline]][[artificial]][[const]][[hidden]]

start iterator

Definition at line 197 of file simd.hpp.

197{ return reinterpret_cast<T*>(&data); }

◆ cbegin()

template<typename T , size_t N>
T const * ein::simd< T, N >::cbegin ( ) const
inlineconstexprnoexcept[[nodiscard]][[always_inline]][[artificial]][[const]][[hidden]]

const start iterator

Definition at line 205 of file simd.hpp.

205{ return reinterpret_cast<T const *>(&data); }

◆ cend()

template<typename T , size_t N>
T const * ein::simd< T, N >::cend ( ) const
inlineconstexprnoexcept[[nodiscard]][[always_inline]][[artificial]][[const]][[hidden]]

const end iterator

Definition at line 209 of file simd.hpp.

209{ return begin() + N; }
constexpr T * begin() noexcept
start iterator
Definition simd.hpp:197

◆ crbegin()

template<typename T , size_t N>
std::reverse_iterator< const T * > ein::simd< T, N >::crbegin ( ) const
inlineconstexprnoexcept[[nodiscard]][[always_inline]][[artificial]][[const]][[hidden]]

const reverse start iterator

Definition at line 229 of file simd.hpp.

229{ return std::reverse_iterator<const T*>(cend()); }
constexpr T const * cend() const noexcept
const end iterator
Definition simd.hpp:209

◆ crend()

template<typename T , size_t N>
std::reverse_iterator< const T * > ein::simd< T, N >::crend ( ) const
inlineconstexprnoexcept[[nodiscard]][[always_inline]][[artificial]][[const]][[hidden]]

const reverse end iterator

Definition at line 233 of file simd.hpp.

233{ return std::reverse_iterator<const T*>(cbegin()); }

◆ end() [1/2]

template<typename T , size_t N>
T const * ein::simd< T, N >::end ( ) const
inlineconstexprnoexcept[[nodiscard]][[always_inline]][[artificial]][[const]][[hidden]]

const end iterator

Definition at line 217 of file simd.hpp.

217{ return cend(); }

◆ end() [2/2]

template<typename T , size_t N>
T * ein::simd< T, N >::end ( )
inlineconstexprnoexcept[[nodiscard]][[always_inline]][[artificial]][[const]][[hidden]]

end iterator

Definition at line 201 of file simd.hpp.

201{ return begin() + N; }

◆ it() [1/2]

template<typename T , size_t N>
intrinsic_t const & ein::simd< T, N >::it ( ) const
inlineconstexprnoexcept[[always_inline]][[artificial]][[const]][[hidden]]

provide compatibility with Intel intrinsics by freely using this as simd_intrinsic_t<T,N> const &

Definition at line 178 of file simd.hpp.

◆ it() [2/2]

template<typename T , size_t N>
intrinsic_t & ein::simd< T, N >::it ( )
inlineconstexprnoexcept[[always_inline]][[artificial]][[const]][[hidden]]

provide compatibility with Intel intrinsics by freely using this as simd_intrinsic_t<T,N> &

Definition at line 170 of file simd.hpp.

◆ operator intrinsic_t &()

template<typename T , size_t N>
ein::simd< T, N >::operator intrinsic_t & ( )
inlineconstexprnoexcept[[always_inline]][[artificial]][[const]][[hidden]]

provide compatibility with Intel intrinsics by freely using this as simd_intrinsic_t<T,N> &

Definition at line 154 of file simd.hpp.

154 {
155 if constexpr (std::is_same_v<intrinsic_t,data_t>) return data;
156 else return reinterpret_cast<intrinsic_t &>(data);
157 }
simd_intrinsic_t< T, N > intrinsic_t
Definition simd.hpp:43

◆ operator intrinsic_t const &()

template<typename T , size_t N>
ein::simd< T, N >::operator intrinsic_t const & ( ) const
inlineconstexprnoexcept[[always_inline]][[artificial]][[const]][[hidden]]

provide compatibility with Intel intrinsics by freely using this as simd_intrinsic_t<T,N> const &

Definition at line 162 of file simd.hpp.

◆ operator&=()

template<typename T , size_t N>
simd & ein::simd< T, N >::operator&= ( simd< T, N > other)
inlineconstexprnoexcept[[always_inline]][[artificial]][[hidden]]

Definition at line 357 of file simd.hpp.

◆ operator*=()

template<typename T , size_t N>
simd & ein::simd< T, N >::operator*= ( simd< T, N > other)
inlineconstexprnoexcept[[always_inline]][[artificial]][[hidden]]

Definition at line 326 of file simd.hpp.

◆ operator+()

template<typename T , size_t N>
simd ein::simd< T, N >::operator+ ( ) const
inlineconstexprnoexcept[[always_inline]][[artificial]][[pure]][[hidden]]

Definition at line 397 of file simd.hpp.

◆ operator++() [1/2]

template<typename T , size_t N>
simd & ein::simd< T, N >::operator++ ( )
inlineconstexprnoexcept[[always_inline]][[artificial]][[hidden]]

++x

Definition at line 434 of file simd.hpp.

◆ operator++() [2/2]

template<typename T , size_t N>
simd ein::simd< T, N >::operator++ ( int )
inlineconstexprnoexcept[[always_inline]][[artificial]][[hidden]]

x++

Definition at line 443 of file simd.hpp.

◆ operator+=()

template<typename T , size_t N>
simd & ein::simd< T, N >::operator+= ( simd< T, N > other)
inlineconstexprnoexcept[[always_inline]][[artificial]][[hidden]]

Definition at line 296 of file simd.hpp.

◆ operator-()

template<typename T , size_t N>
simd ein::simd< T, N >::operator- ( ) const
inlineconstexprnoexcept[[always_inline]][[artificial]][[pure]][[hidden]]

Definition at line 404 of file simd.hpp.

◆ operator--() [1/2]

template<typename T , size_t N>
simd & ein::simd< T, N >::operator-- ( )
inlineconstexprnoexcept[[always_inline]][[artificial]][[hidden]]

--x

Definition at line 415 of file simd.hpp.

◆ operator--() [2/2]

template<typename T , size_t N>
simd ein::simd< T, N >::operator-- ( int )
inlineconstexprnoexcept[[always_inline]][[artificial]][[hidden]]

x--

Definition at line 424 of file simd.hpp.

◆ operator-=()

template<typename T , size_t N>
simd & ein::simd< T, N >::operator-= ( simd< T, N > other)
inlineconstexprnoexcept[[always_inline]][[artificial]][[hidden]]

Definition at line 311 of file simd.hpp.

◆ operator/=()

template<typename T , size_t N>
simd & ein::simd< T, N >::operator/= ( simd< T, N > other)
inlineconstexprnoexcept[[always_inline]][[artificial]][[hidden]]

Definition at line 341 of file simd.hpp.

◆ operator<<=() [1/3]

template<typename T , size_t N>
template<size_t K>
requires (has_lifted_operations<T> && requires (data_t a) { a <<= static_cast<T>(K); })
simd & ein::simd< T, N >::operator<<= ( imm_t< K > )
inlineconstexprnoexcept[[always_inline]][[artificial]][[hidden]]

self-shift left by an immediate constant

Definition at line 536 of file simd.hpp.

◆ operator<<=() [2/3]

template<typename T , size_t N>
simd & ein::simd< T, N >::operator<<= ( simd< T, N > y)
inlineconstexprnoexcept[[always_inline]][[artificial]][[hidden]]

self-shift left elementwise

Definition at line 556 of file simd.hpp.

◆ operator<<=() [3/3]

template<typename T , size_t N>
simd & ein::simd< T, N >::operator<<= ( T y)
inlineconstexprnoexcept[[always_inline]][[artificial]][[hidden]]

self-shift left by a scalar

Definition at line 547 of file simd.hpp.

◆ operator=() [1/3]

template<typename T , size_t N>
ein_reinitializes constexpr simd & ein::simd< T, N >::operator= ( simd< T, N > && )
constexprdefaultnoexcept[[always_inline]][[artificial]][[hidden]]

◆ operator=() [2/3]

template<typename T , size_t N>
ein_reinitializes constexpr simd & ein::simd< T, N >::operator= ( simd< T, N > const & )
constexprdefaultnoexcept[[always_inline]][[artificial]][[hidden]]

◆ operator=() [3/3]

template<typename T , size_t N>
template<typename U >
requires (!std::is_same_v<U,T> && has_builtin_convertvector<U,T,N>)
ein_reinitializes constexpr simd & ein::simd< T, N >::operator= ( simd_t< U > other)
inlineconstexprnoexcept[[always_inline]][[artificial]]

automatic conversion for types supported by __builtin_convertvector

Definition at line 139 of file simd.hpp.

139 {
140 if consteval {
141 for (int i=0;i<N;++i)
142 data[i] = T(other.data[i]);
143 } else {
144 data = __builtin_convertvector(other.data,data_t);
145 }
146 }

◆ operator>>=() [1/3]

template<typename T , size_t N>
template<size_t K>
requires (has_lifted_operations<T> && requires (data_t a) { a >>= static_cast<T>(K); })
simd & ein::simd< T, N >::operator>>= ( imm_t< K > )
inlineconstexprnoexcept[[always_inline]][[artificial]][[hidden]]

self-shift right by an immediate value

Definition at line 508 of file simd.hpp.

◆ operator>>=() [2/3]

template<typename T , size_t N>
simd & ein::simd< T, N >::operator>>= ( simd< T, N > y)
inlineconstexprnoexcept[[always_inline]][[artificial]][[hidden]]

self-shift right elementwise

Definition at line 526 of file simd.hpp.

◆ operator>>=() [3/3]

template<typename T , size_t N>
simd & ein::simd< T, N >::operator>>= ( T y)
inlineconstexprnoexcept[[always_inline]][[artificial]][[hidden]]

self-shift right by a scalar

Definition at line 517 of file simd.hpp.

◆ operator[]() [1/2]

template<typename T , size_t N>
T const & ein::simd< T, N >::operator[] ( std::size_t i) const
inlineconstexprnoexcept[[nodiscard]][[always_inline]][[artificial]][[const]][[hidden]]

access the element in the i th lane

Definition at line 193 of file simd.hpp.

193{ return reinterpret_cast<T const *>(&data)[i]; }

◆ operator[]() [2/2]

template<typename T , size_t N>
T & ein::simd< T, N >::operator[] ( std::size_t i)
inlineconstexprnoexcept[[nodiscard]][[always_inline]][[artificial]][[const]][[hidden]]

access the element in the i th lane

Definition at line 189 of file simd.hpp.

189{ return reinterpret_cast<T *>(&data)[i]; }

◆ operator^=()

template<typename T , size_t N>
simd & ein::simd< T, N >::operator^= ( simd< T, N > other)
inlineconstexprnoexcept[[always_inline]][[artificial]][[hidden]]

Definition at line 389 of file simd.hpp.

◆ operator|=()

template<typename T , size_t N>
simd & ein::simd< T, N >::operator|= ( simd< T, N > other)
inlineconstexprnoexcept[[always_inline]][[artificial]][[hidden]]

Definition at line 373 of file simd.hpp.

◆ rbegin() [1/2]

template<typename T , size_t N>
std::reverse_iterator< const T * > ein::simd< T, N >::rbegin ( ) const
inlineconstexprnoexcept[[nodiscard]][[always_inline]][[artificial]][[const]][[hidden]]

const reverse start iterator

Definition at line 237 of file simd.hpp.

237{ return crbegin(); }
constexpr std::reverse_iterator< const T * > crbegin() const noexcept
const reverse start iterator
Definition simd.hpp:229

◆ rbegin() [2/2]

template<typename T , size_t N>
std::reverse_iterator< T * > ein::simd< T, N >::rbegin ( )
inlineconstexprnoexcept[[nodiscard]][[always_inline]][[artificial]][[const]][[hidden]]

reverse start iterator

Definition at line 221 of file simd.hpp.

221{ return std::reverse_iterator<T*>(end()); }
constexpr T * end() noexcept
end iterator
Definition simd.hpp:201

◆ rend() [1/2]

template<typename T , size_t N>
std::reverse_iterator< const T * > ein::simd< T, N >::rend ( ) const
inlineconstexprnoexcept[[nodiscard]][[always_inline]][[artificial]][[const]][[hidden]]

const reverse end iterator

Definition at line 241 of file simd.hpp.

241{ return crend(); }
constexpr std::reverse_iterator< const T * > crend() const noexcept
const reverse end iterator
Definition simd.hpp:233

◆ rend() [2/2]

template<typename T , size_t N>
std::reverse_iterator< T * > ein::simd< T, N >::rend ( )
inlineconstexprnoexcept[[nodiscard]][[always_inline]][[artificial]][[const]][[hidden]]

reverse end iterator

Definition at line 225 of file simd.hpp.

225{ return std::reverse_iterator<T*>(begin()); }

◆ shuffle() [1/2]

template<typename T , size_t N>
template<size_t ... is>
requires (((is < N) && ... && has_simd_type<T,sizeof...(is)>) && requires (data_t x) { simd<T,sizeof...(is)>(__builtin_shufflevector(x, is...)); })
simd< T, sizeof...(is)> ein::simd< T, N >::shuffle ( )
inlineconstexprnoexcept[[always_inline]][[artificial]]

shuffle selected elements to produce a new simd register

Definition at line 570 of file simd.hpp.

572 { simd<T,sizeof...(is)>(__builtin_shufflevector(x, is...)); }) {
573 if consteval {
574 return { data[is]... };
575 } else {
576 return __builtin_shufflevector(data,is...);
577 }
578 }
constexpr simd() noexcept=default
default initialization

◆ shuffle() [2/2]

template<typename T , size_t N>
template<size_t ... is>
requires (((is < N*2) && ... && has_simd_type<T,sizeof...(is)>) && requires (data_t x) { simd<T,sizeof...(is)>(__builtin_shufflevector(x, x, is...)); })
simd< T, sizeof...(is)> ein::simd< T, N >::shuffle ( simd< T, N > b)
inlineconstexprnoexcept[[always_inline]][[artificial]][[pure]]

Use elements taken from this and another simd register to construct another. If an index i in is is less than N, it draw from this, otherwise it draws from the i - Nth position in b.

Definition at line 584 of file simd.hpp.

586 { simd<T,sizeof...(is)>(__builtin_shufflevector(x, x, is...)); }) {
587 if consteval {
588 return { (is < N ? data[is] : b[is-N])... };
589 } else {
590 return __builtin_shufflevector(data,b.data,is...);
591 }
592 }

Friends And Related Symbol Documentation

◆ cmp

template<typename T , size_t N>
template<CMP imm8>
requires one_of_t<T,float,double> && (size_t(imm8) < max_fp_comparison_predicate)
mask_t cmp ( simd< T, N > a,
simd< T, N > b )
friend

Definition at line 727 of file simd.hpp.

◆ cmpint

template<typename T , size_t N>
template<CMPINT imm8>
requires one_of_t<storage_type<T>,uint8_t,int8_t,uint16_t,int16_t,uint32_t,int32_t,uint64_t,int64_t> && has_lifted_operations<T> && (size_t(imm8) < 8uz)
mask_t cmpint ( simd< T, N > a,
simd< T, N > b )
friend

Definition at line 781 of file simd.hpp.

◆ get [1/3]

template<typename T , size_t N>
template<size_t I>
requires (I < N)
T && get ( simd< T, N > && s)
friend[[always_inline]][[artificial]][[const]][[hidden]]

enable destructuring move

auto && [x,y,z,w] = simd<float,4>(1.0,2.0,3.0,4.0);

Definition at line 279 of file simd.hpp.

◆ get [2/3]

template<typename T , size_t N>
template<size_t I>
requires (I < N)
T & get ( simd< T, N > & s)
friend[[always_inline]][[artificial]][[const]][[hidden]]

enables destructuring reference

auto & [x,y,z,w] = simd<float,4>(1.0,2.0,3.0,4.0);

Definition at line 255 of file simd.hpp.

◆ get [3/3]

template<typename T , size_t N>
template<size_t I>
requires (I < N)
T const & get ( simd< T, N > const & s)
friend[[always_inline]][[artificial]][[const]][[hidden]]

enables destructuring constant reference

auto const & [x,y,z,w] = simd<float,4>(1.0,2.0,3.0,4.0);

Definition at line 267 of file simd.hpp.

◆ operator!= [1/2]

template<typename T , size_t N>
mask_t operator!= ( simd< T, N > a,
simd< T, N > b )
friend[[always_inline]][[artificial]][[pure]]

Definition at line 710 of file simd.hpp.

711 {
712 EIN_COMPARE_OP(!=,ne)
713 }

◆ operator!= [2/2]

template<typename T , size_t N>
mask_t operator!= ( simd< T, N > x,
simd< T, N > y )
friend[[always_inline]][[artificial]][[pure]][[hidden]]

Definition at line 636 of file simd.hpp.

◆ operator&

template<typename T , size_t N>
template<typename U >
requires (has_lifted_operations<T> && requires (data_t a, data_t b) { a & b; })
simd operator& ( simd< T, N > x,
simd< T, N > y )
friend[[always_inline]][[artificial]][[pure]][[hidden]]

Definition at line 350 of file simd.hpp.

◆ operator*

template<typename T , size_t N>
simd operator* ( simd< T, N > x,
simd< T, N > y )
friend[[always_inline]][[artificial]][[pure]][[hidden]]

Definition at line 319 of file simd.hpp.

◆ operator+

template<typename T , size_t N>
simd operator+ ( simd< T, N > x,
simd< T, N > y )
friend[[always_inline]][[artificial]][[pure]][[hidden]]

Definition at line 289 of file simd.hpp.

◆ operator-

template<typename T , size_t N>
simd operator- ( simd< T, N > x,
simd< T, N > y )
friend[[always_inline]][[artificial]][[pure]][[hidden]]

Definition at line 304 of file simd.hpp.

◆ operator/

template<typename T , size_t N>
simd operator/ ( simd< T, N > x,
simd< T, N > y )
friend[[always_inline]][[artificial]][[pure]][[hidden]]

Definition at line 334 of file simd.hpp.

◆ operator/=

template<typename T , size_t N>
mask_t operator/= ( simd< T, N > a,
simd< T, N > b )
friend[[nodiscard]][[always_inline]][[pure]]

Definition at line 897 of file simd.hpp.

◆ operator< [1/3]

template<typename T , size_t N>
mask_t operator< ( simd< T, N > a,
simd< T, N > b )
friend[[always_inline]][[artificial]][[pure]]

Definition at line 685 of file simd.hpp.

686 {
687 EIN_COMPARE_OP(<,lt)
688 }

◆ operator< [2/3]

template<typename T , size_t N>
mask_t operator< ( simd< T, N > a,
simd< T, N > b )
friend[[nodiscard]][[always_inline]][[pure]]

Definition at line 904 of file simd.hpp.

◆ operator< [3/3]

template<typename T , size_t N>
mask_t operator< ( simd< T, N > x,
simd< T, N > y )
friend[[always_inline]][[artificial]][[pure]][[hidden]]

Definition at line 601 of file simd.hpp.

◆ operator<< [1/3]

template<typename T , size_t N>
template<size_t K>
requires (has_lifted_operations<T> && requires (data_t a) { a << static_cast<T>(K); })
simd operator<< ( simd< T, N > x,
imm_t< K >  )
friend[[always_inline]][[artificial]][[pure]][[hidden]]

shift left by an immediate constant

Definition at line 481 of file simd.hpp.

◆ operator<< [2/3]

template<typename T , size_t N>
simd operator<< ( simd< T, N > x,
simd< T, N > y )
friend[[always_inline]][[artificial]][[pure]][[hidden]]

shift left elementwise

Definition at line 497 of file simd.hpp.

◆ operator<< [3/3]

template<typename T , size_t N>
simd operator<< ( simd< T, N > x,
T y )
friend[[always_inline]][[artificial]][[pure]][[hidden]]

shift left by a scalar

Definition at line 489 of file simd.hpp.

◆ operator<= [1/3]

template<typename T , size_t N>
mask_t operator<= ( simd< T, N > a,
simd< T, N > b )
friend[[always_inline]][[artificial]][[pure]]

Definition at line 695 of file simd.hpp.

696 {
697 EIN_COMPARE_OP(<=,le)
698 }

◆ operator<= [2/3]

template<typename T , size_t N>
mask_t operator<= ( simd< T, N > a,
simd< T, N > b )
friend[[nodiscard]][[always_inline]][[pure]]

Definition at line 911 of file simd.hpp.

◆ operator<= [3/3]

template<typename T , size_t N>
mask_t operator<= ( simd< T, N > x,
simd< T, N > y )
friend[[always_inline]][[artificial]][[pure]][[hidden]]

Definition at line 615 of file simd.hpp.

◆ operator== [1/3]

template<typename T , size_t N>
mask_t operator== ( simd< T, N > a,
simd< T, N > b )
friend[[always_inline]][[artificial]][[pure]]

Definition at line 705 of file simd.hpp.

706 {
707 EIN_COMPARE_OP(==,eq)
708 }

◆ operator== [2/3]

template<typename T , size_t N>
mask_t operator== ( simd< T, N > a,
simd< T, N > b )
friend[[nodiscard]][[always_inline]][[pure]]

Definition at line 890 of file simd.hpp.

◆ operator== [3/3]

template<typename T , size_t N>
mask_t operator== ( simd< T, N > x,
simd< T, N > y )
friend[[always_inline]][[artificial]][[pure]][[hidden]]

Definition at line 629 of file simd.hpp.

◆ operator> [1/3]

template<typename T , size_t N>
mask_t operator> ( simd< T, N > a,
simd< T, N > b )
friend[[always_inline]][[artificial]][[pure]]

Definition at line 690 of file simd.hpp.

691 {
692 EIN_COMPARE_OP(>,gt)
693 }

◆ operator> [2/3]

template<typename T , size_t N>
mask_t operator> ( simd< T, N > a,
simd< T, N > b )
friend[[nodiscard]][[always_inline]][[pure]]

Definition at line 918 of file simd.hpp.

◆ operator> [3/3]

template<typename T , size_t N>
mask_t operator> ( simd< T, N > x,
simd< T, N > y )
friend[[always_inline]][[artificial]][[pure]][[hidden]]

Definition at line 608 of file simd.hpp.

◆ operator>= [1/3]

template<typename T , size_t N>
mask_t operator>= ( simd< T, N > a,
simd< T, N > b )
friend[[always_inline]][[artificial]][[pure]]

Definition at line 700 of file simd.hpp.

701 {
702 EIN_COMPARE_OP(>=,ge)
703 }

◆ operator>= [2/3]

template<typename T , size_t N>
mask_t operator>= ( simd< T, N > a,
simd< T, N > b )
friend[[nodiscard]][[always_inline]][[pure]]

Definition at line 925 of file simd.hpp.

◆ operator>= [3/3]

template<typename T , size_t N>
mask_t operator>= ( simd< T, N > x,
simd< T, N > y )
friend[[always_inline]][[artificial]][[pure]][[hidden]]

Definition at line 622 of file simd.hpp.

◆ operator>> [1/3]

template<typename T , size_t N>
template<size_t K>
requires (has_lifted_operations<T> && requires (data_t a) { a >> static_cast<T>(K); })
simd operator>> ( simd< T, N > x,
imm_t< K >  )
friend[[always_inline]][[artificial]][[pure]][[hidden]]

shift right by an immediate constant

Definition at line 454 of file simd.hpp.

◆ operator>> [2/3]

template<typename T , size_t N>
simd operator>> ( simd< T, N > x,
simd< T, N > y )
friend[[always_inline]][[artificial]][[pure]][[hidden]]

shift right elementwise

Definition at line 470 of file simd.hpp.

◆ operator>> [3/3]

template<typename T , size_t N>
simd operator>> ( simd< T, N > x,
T y )
friend[[always_inline]][[artificial]][[pure]][[hidden]]

shift right by a scalar

Definition at line 462 of file simd.hpp.

◆ operator^

template<typename T , size_t N>
simd operator^ ( simd< T, N > x,
simd< T, N > y )
friend[[always_inline]][[artificial]][[pure]][[hidden]]

Definition at line 382 of file simd.hpp.

◆ operator|

template<typename T , size_t N>
template<typename U >
requires (has_lifted_operations<T> && requires (data_t a, data_t b) { a | b; })
simd operator| ( simd< T, N > x,
simd< T, N > y )
friend[[always_inline]][[artificial]][[pure]][[hidden]]

Definition at line 366 of file simd.hpp.

◆ scalef

template<typename T , size_t N>
simd scalef ( simd< T, N > x,
simd< T, N > y )
friend[[always_inline]][[artificial]][[pure]]

Definition at line 940 of file simd.hpp.

◆ swap

template<typename T , size_t N>
void swap ( simd< T, N > & x,
simd< T, N > & y )
friend[[always_inline]][[artificial]]

Definition at line 978 of file simd.hpp.

978 {
979 if consteval {
980 for (int i=0;i<N;++i)
981 swap(x[i],y[i]);
982 } else {
983 swap(x.data,y.data);
984 }
985 }
friend constexpr void swap(simd &x, simd &y) noexcept
Definition simd.hpp:978

Member Data Documentation

◆ bytesize

template<typename T , size_t N>
size_t ein::simd< T, N >::bytesize = N*sizeof(T)
staticconstexprprivate

Definition at line 44 of file simd.hpp.

◆ data

template<typename T , size_t N>
data_t ein::simd< T, N >::data

Definition at line 56 of file simd.hpp.

◆ size

template<typename T , size_t N>
size_t ein::simd< T, N >::size = N
staticconstexprprivate

Definition at line 53 of file simd.hpp.

◆ std::tuple_size< ein::simd< T, N > >

struct std::tuple_size< ein::simd< T, N > >
template<typename T, size_t N>
struct std::tuple_size< ein::simd< T, N > >

Definition at line 1301 of file simd.hpp.

Inheritance diagram for std::tuple_size< ein::simd< T, N > >:
[legend]
Collaboration diagram for std::tuple_size< ein::simd< T, N > >:
[legend]

◆ std::tuple_element< I, ein::simd< T, N > >

struct std::tuple_element< I, ein::simd< T, N > >
template<size_t I, typename T, size_t N>
requires (I < N)
struct std::tuple_element< I, ein::simd< T, N > >

needed to support for std::apply

Definition at line 1306 of file simd.hpp.

Class Members
typedef T type T

◆ ein::detail::storage_type_impl

struct ein::detail::storage_type_impl
template<typename T>
struct ein::detail::storage_type_impl< T >

Definition at line 50 of file simd_data.hpp.

Class Members
typedef T type T

◆ ein::detail::storage_type_impl< bf16 >

struct ein::detail::storage_type_impl< bf16 >

Definition at line 53 of file simd_data.hpp.

Class Members
typedef __bf16 type __bf16

◆ ein::detail::storage_type_impl< fp16 >

struct ein::detail::storage_type_impl< fp16 >

Definition at line 54 of file simd_data.hpp.

Class Members
typedef _Float16 type _Float16

◆ ein::detail::si< 128 >

struct ein::detail::si< 128 >

Definition at line 120 of file simd_data.hpp.

Class Members
typedef __m128i type __m128i

◆ ein::detail::ps< 128 >

struct ein::detail::ps< 128 >

Definition at line 121 of file simd_data.hpp.

Class Members
typedef __m128 type __m128

◆ ein::detail::pd< 128 >

struct ein::detail::pd< 128 >

Definition at line 122 of file simd_data.hpp.

Class Members
typedef __m128d type __m128d

◆ ein::detail::si< 256 >

struct ein::detail::si< 256 >

Definition at line 124 of file simd_data.hpp.

Class Members
typedef __m256i type __m256i

◆ ein::detail::ps< 256 >

struct ein::detail::ps< 256 >

Definition at line 125 of file simd_data.hpp.

Class Members
typedef __m256 type __m256

◆ ein::detail::pd< 256 >

struct ein::detail::pd< 256 >

Definition at line 126 of file simd_data.hpp.

Class Members
typedef __m256d type __m256d

◆ ein::detail::si< 512 >

struct ein::detail::si< 512 >

Definition at line 129 of file simd_data.hpp.

Class Members
typedef __m512i type __m512i

◆ ein::detail::ps< 512 >

struct ein::detail::ps< 512 >

Definition at line 130 of file simd_data.hpp.

Class Members
typedef __m512 type __m512

◆ ein::detail::pd< 512 >

struct ein::detail::pd< 512 >

Definition at line 131 of file simd_data.hpp.

Class Members
typedef __m512d type __m512d

◆ ein::detail::simd_intrinsic< float, N >

struct ein::detail::simd_intrinsic< float, N >
template<size_t N>
struct ein::detail::simd_intrinsic< float, N >

Definition at line 144 of file simd_data.hpp.

Class Members
typedef typename type type typename ps<N*sizeof(float)*8>::type

◆ ein::detail::simd_intrinsic< double, N >

struct ein::detail::simd_intrinsic< double, N >
template<size_t N>
struct ein::detail::simd_intrinsic< double, N >

Definition at line 149 of file simd_data.hpp.

Class Members
typedef typename type type typename pd<N*sizeof(double)*8>::type

◆ ein::detail::simd_intrinsic< T, N >

struct ein::detail::simd_intrinsic< T, N >
template<not_one_of_t< float, double > T, size_t N>
struct ein::detail::simd_intrinsic< T, N >

Definition at line 178 of file simd_data.hpp.

Class Members
typedef typename type type typename ps<N*sizeof(T)*8>::type

Typedef Documentation

◆ mmask_t

template<size_t N>
using ein::mmask_t

If AVX512 is enabled returns the type of an n-bit mmask.

Definition at line 214 of file simd_data.hpp.

◆ simd_data_t

template<typename T , size_t N>
using ein::simd_data_t = storage_type<T> __attribute__((__vector_size__(N*sizeof(storage_type<T>)),__aligned__(N*sizeof(storage_type<T>))))

Definition at line 97 of file simd_data.hpp.

◆ simd_intrinsic_t

template<typename T , size_t N>
using ein::simd_intrinsic_t

Returns the Intel intrinsic type associated with a simd register full of N values of type T.

this can differ from the preferred type used by clang/gcc vector extensions.

Definition at line 188 of file simd_data.hpp.

◆ simd_mask_t

template<typename T , size_t N>
using ein::simd_mask_t

What type of mask should I use?

Definition at line 221 of file simd_data.hpp.

◆ storage_type

template<typename T >
using ein::storage_type

The type used to store T in a simd_data_t.

Definition at line 60 of file simd_data.hpp.

Function Documentation

◆ cast_pd() [1/6]

__m128d ein::cast_pd ( __m128d a)
noexcept[[nodiscard]][[always_inline]][[const]][[artificial]]

Definition at line 244 of file simd_data.hpp.

245{ return a; }
246
248__m256d cast_pd(__m256i a) noexcept { return _mm256_castsi256_pd(a); }
249
251__m256d cast_pd(__m256d a) noexcept { return a; }
252
254__m128i cast_si(__m128 a) noexcept { return _mm_castps_si128(a); }
255
257__m128i cast_si(__m128d a) noexcept { return _mm_castpd_si128(a); }
258
260__m128i cast_si(__m128i a) noexcept { return a; }
261
263__m256i cast_si(__m256 a) noexcept { return _mm256_castps_si256(a); }
264
266__m256i cast_si(__m256d a) noexcept { return _mm256_castpd_si256(a); }
267
269__m256i cast_si(__m256i a) noexcept { return a; }
270
271#ifdef __AVX512F__
272
274__m512 cast_ps(__m512i a) noexcept { return _mm512_castsi512_ps(a); }
275
277__m512d cast_pd(__m512i a) noexcept { return _mm512_castsi512_pd(a); }
278
280__m512 cast_ps(__m512 a) noexcept { return a; }
281
283__m512d cast_pd(__m512d a) noexcept { return a; }
284
286__m512i cast_si(__m512 a) noexcept { return _mm512_castps_si512(a); }
287
289__m512i cast_si(__m512d a) noexcept { return _mm512_castpd_si512(a); }
290
292__m512i cast_si(__m512i a) noexcept { return a; }
293
294#if defined(__AVX512FP16__) && defined(__AVX512VL__)
295__m128i cast_si(__m128ph a) noexcept { return _mm_castph_si128(a); }
296__m128 cast_ps(__m128ph a) noexcept { return _mm_castph_ps(a); }
297__m128d cast_pd(__m128ph a) noexcept { return _mm_castph_pd(a); }
298__m128ph cast_ph(__m128ph a) noexcept { return a; }
299
300__m256i cast_si(__m256ph a) noexcept { return _mm256_castph_si256(a); }
301__m256 cast_ps(__m256ph a) noexcept { return _mm256_castph_ps(a); }
302__m256d cast_pd(__m256ph a) noexcept { return _mm256_castph_pd(a); }
303__m256ph cast_ph(__m256ph a) noexcept { return a; }
304
305__m512i cast_si(__m512ph a) noexcept { return _mm512_castph_si512(a); }
306__m512 cast_ps(__m512ph a) noexcept { return _mm512_castph_ps(a); }
307__m512d cast_pd(__m512ph a) noexcept { return _mm512_castph_pd(a); }
308__m512ph cast_ph(__m512ph a) noexcept { return a; }
309
310__m128ph cast_ph(__m128 a) noexcept { return _mm_castps_ph(a); }
311__m256ph cast_ph(__m256 a) noexcept { return _mm256_castps_ph(a); }
312__m512ph cast_ph(__m512 a) noexcept { return _mm512_castps_ph(a); }
313
314__m128ph cast_ph(__m128i a) noexcept { return _mm_castsi128_ph(a); }
315__m256ph cast_ph(__m256i a) noexcept { return _mm256_castsi256_ph(a); }
316__m512ph cast_ph(__m512i a) noexcept { return _mm512_castsi512_ph(a); }
317
318__m128ph cast_ph(__m128d a) noexcept { return _mm_castpd_ph(a); }
319__m256ph cast_ph(__m256d a) noexcept { return _mm256_castpd_ph(a); }
320__m512ph cast_ph(__m512d a) noexcept { return _mm512_castpd_ph(a); }
321#endif // __AVX512FP16__ && __AVX512VL__
322
323#endif // __AVX512F__
324
326} // namespace ein
327
328#if defined(EIN_TESTING) || defined(EIN_TESTING_SIMD_DATA)
329#include <string_view>
330#include "types.hpp"
331
332TEMPLATE_TEST_CASE("simd_data","[simd_data]",int8_t,uint8_t,int16_t,uint16_t,int32_t,uint32_t,int64_t,uint64_t,float,double) {
333 using namespace ein;
334
335 constexpr size_t N128 = 16/sizeof(TestType);
336 constexpr size_t N256 = 32/sizeof(TestType);
337#ifdef __AVX512F__
338 constexpr size_t N512 = 64/sizeof(TestType);
339#endif
340 SECTION("has_simd_data") {
341 STATIC_REQUIRE(has_simd_type<TestType,N128>);
342 STATIC_REQUIRE(has_simd_type<TestType,N256>);
343#ifdef __AVX512F__
344 STATIC_REQUIRE(has_simd_type<TestType,N512>);
345#endif
346 }
347 SECTION("simd_data_t") {
348 using d128 = simd_data_t<TestType,N128>;
349 using d256 = simd_data_t<TestType,N256>;
350#ifdef __AVX512F__
351 using d512 = simd_data_t<TestType,N512>;
352#endif
353 SECTION("has the right size") {
354 CHECK(sizeof(d128) == 16);
355 CHECK(sizeof(d256) == 32);
356#ifdef __AVX512F__
357 CHECK(sizeof(d512) == 64);
358#endif
359 }
360 d128 x128{TestType{}};
361 d256 x256{TestType{}};
362#ifdef __AVX512F__
363 d512 x512{TestType{}};
364#endif
365 SECTION("can be indexed at the right type") {
366 STATIC_REQUIRE(std::is_same_v<std::remove_cvref_t<decltype(x128[0])>, storage_type<TestType>>);
367 STATIC_REQUIRE(std::is_same_v<std::remove_cvref_t<decltype(x256[0])>, storage_type<TestType>>);
368#ifdef __AVX512F__
369 STATIC_REQUIRE(std::is_same_v<std::remove_cvref_t<decltype(x512[0])>, storage_type<TestType>>);
370#endif
371 }
372 SECTION("can be indexed with the right value") {
373 CHECK(x128[0] == storage_type<TestType>{});
374 CHECK(x256[0] == storage_type<TestType>{});
375#ifdef __AVX512F__
376 CHECK(x512[0] == storage_type<TestType>{});
377#endif
378 }
379 }
380
381 SECTION("simd_intrinsic_t") {
384#ifdef __AVX512F__
386#endif
387
388 [[maybe_unused]] t128 x128{};
389 [[maybe_unused]] t256 x256{};
390#ifdef __AVX512F__
391 [[maybe_unused]] t512 x512{};
392#endif
393
394// SECTION("cast_ps") {
395// CHECK(sizeof(cast_ps(x128)) == sizeof(x128));
396// CHECK(sizeof(cast_ps(x256)) == sizeof(x256));
397// #ifdef __AVX512F__
398// CHECK(sizeof(cast_ps(x512)) == sizeof(x512));
399// #endif
400// }
401
402// SECTION("cast_si") {
403// CHECK(sizeof(cast_si(x128)) == sizeof(x128));
404// CHECK(sizeof(cast_si(x256)) == sizeof(x256));
405// #ifdef __AVX512F__
406// CHECK(sizeof(cast_si(x512)) == sizeof(x512));
407// #endif
408// }
409
410// SECTION("cast_pd") {
411// CHECK(sizeof(cast_pd(x128)) == sizeof(x128));
412// CHECK(sizeof(cast_pd(x256)) == sizeof(x256));
413// #ifdef __AVX512F__
414// CHECK(sizeof(cast_pd(x512)) == sizeof(x512));
415// #endif
416// }
417 }
418}
419
420#endif
#define ein_artificial
[[artificial]].
Definition common.hpp:220
#define ein_inline
inline [[always_inline]]
Definition common.hpp:188
#define ein_nodiscard
C++17 [[nodiscard]].
Definition common.hpp:165
#define ein_const
[[const]] is not const
Definition common.hpp:84
__m128d cast_pd(__m128i a) noexcept
__m128 cast_ps(__m128i a) noexcept
typename detail::simd_intrinsic< T, N >::type simd_intrinsic_t
Returns the Intel intrinsic type associated with a simd register full of N values of type T.
storage_type< T > __attribute__((__vector_size__(N *sizeof(storage_type< T >)), __aligned__(N *sizeof(storage_type< T >)))) simd_data_t
Definition simd_data.hpp:97
__m128i cast_si(__m128 a) noexcept
typename detail::storage_type_impl< T >::type storage_type
The type used to store T in a simd_data_t.
Definition simd_data.hpp:60
Definition cpuid.cpp:16

◆ cast_pd() [2/6]

__m128d ein::cast_pd ( __m128i a)
noexcept[[nodiscard]][[always_inline]][[const]][[artificial]]

Definition at line 241 of file simd_data.hpp.

◆ cast_pd() [3/6]

__m256d ein::cast_pd ( __m256d a)
noexcept[[nodiscard]][[always_inline]][[const]][[artificial]]

Definition at line 250 of file simd_data.hpp.

◆ cast_pd() [4/6]

__m256d ein::cast_pd ( __m256i a)
noexcept[[nodiscard]][[always_inline]][[const]][[artificial]]

Definition at line 247 of file simd_data.hpp.

◆ cast_pd() [5/6]

__m512d ein::cast_pd ( __m512d a)
noexcept[[nodiscard]][[always_inline]][[const]][[artificial]]

Definition at line 282 of file simd_data.hpp.

◆ cast_pd() [6/6]

__m512d ein::cast_pd ( __m512i a)
noexcept[[nodiscard]][[always_inline]][[const]][[artificial]]

Definition at line 276 of file simd_data.hpp.

◆ cast_ps() [1/6]

__m128 ein::cast_ps ( __m128 a)
noexcept[[nodiscard]][[always_inline]][[const]][[artificial]]

Definition at line 232 of file simd_data.hpp.

◆ cast_ps() [2/6]

__m128 ein::cast_ps ( __m128i a)
noexcept[[nodiscard]][[always_inline]][[const]][[artificial]]

Definition at line 229 of file simd_data.hpp.

◆ cast_ps() [3/6]

__m256 ein::cast_ps ( __m256 a)
noexcept[[nodiscard]][[always_inline]][[const]][[artificial]]

Definition at line 238 of file simd_data.hpp.

◆ cast_ps() [4/6]

__m256 ein::cast_ps ( __m256i a)
noexcept[[nodiscard]][[always_inline]][[const]][[artificial]]

Definition at line 235 of file simd_data.hpp.

◆ cast_ps() [5/6]

__m512 ein::cast_ps ( __m512 a)
noexcept[[nodiscard]][[always_inline]][[const]][[artificial]]

Definition at line 279 of file simd_data.hpp.

◆ cast_ps() [6/6]

__m512 ein::cast_ps ( __m512i a)
noexcept[[nodiscard]][[always_inline]][[const]][[artificial]]

Definition at line 273 of file simd_data.hpp.

◆ cast_si() [1/9]

__m128i ein::cast_si ( __m128 a)
noexcept[[nodiscard]][[always_inline]][[const]][[artificial]]

Definition at line 253 of file simd_data.hpp.

◆ cast_si() [2/9]

__m128i ein::cast_si ( __m128d a)
noexcept[[nodiscard]][[always_inline]][[const]][[artificial]]

Definition at line 256 of file simd_data.hpp.

◆ cast_si() [3/9]

__m128i ein::cast_si ( __m128i a)
noexcept[[nodiscard]][[always_inline]][[const]][[artificial]]

Definition at line 259 of file simd_data.hpp.

◆ cast_si() [4/9]

__m256i ein::cast_si ( __m256 a)
noexcept[[nodiscard]][[always_inline]][[const]][[artificial]]

Definition at line 262 of file simd_data.hpp.

◆ cast_si() [5/9]

__m256i ein::cast_si ( __m256d a)
noexcept[[nodiscard]][[always_inline]][[const]][[artificial]]

Definition at line 265 of file simd_data.hpp.

◆ cast_si() [6/9]

__m256i ein::cast_si ( __m256i a)
noexcept[[nodiscard]][[always_inline]][[const]][[artificial]]

Definition at line 268 of file simd_data.hpp.

◆ cast_si() [7/9]

__m512i ein::cast_si ( __m512 a)
noexcept[[nodiscard]][[always_inline]][[const]][[artificial]]

Definition at line 285 of file simd_data.hpp.

◆ cast_si() [8/9]

__m512i ein::cast_si ( __m512d a)
noexcept[[nodiscard]][[always_inline]][[const]][[artificial]]

Definition at line 288 of file simd_data.hpp.

◆ cast_si() [9/9]

__m512i ein::cast_si ( __m512i a)
noexcept[[nodiscard]][[always_inline]][[const]][[artificial]]

Definition at line 291 of file simd_data.hpp.

◆ shuffle() [1/2]

template<size_t ... is>
auto ein::shuffle ( simd_type auto x)
[[always_inline]][[artificial]][[pure]]

create a new simd register with contents drawn from this one

Definition at line 1243 of file simd.hpp.

1243 {
1244 return x.template shuffle<is...>();
1245}
auto shuffle(simd_type auto x)
create a new simd register with contents drawn from this one
Definition simd.hpp:1243

References ein::shuffle().

Referenced by ein::shuffle(), and ein::shuffle().

Here is the caller graph for this function:

◆ shuffle() [2/2]

template<size_t ... is>
auto ein::shuffle ( simd_type auto x,
simd_type auto y )
[[always_inline]][[artificial]][[pure]]

create a new simd register with contents drawn from these two

Definition at line 1250 of file simd.hpp.

1250 {
1251 return x.template shuffle<is...>(y);
1252}

References ein::shuffle().

◆ simd() [1/3]

template<typename ... Args>
requires has_simd_type<std::common_type<Args...>, sizeof...(Args)>
ein::simd ( Args && ...) -> simd< std::common_type< Args... >, sizeof...(Args)>

guidance for loading from arguments

References ein::max_simd_size.

◆ simd() [2/3]

template<typename T , size_t N>
requires ( has_simd_type<T,N> && (N % sizeof(T) == 0) )
ein::simd ( T __attribute(__vector_size__(N))) -> simd< T, N/sizeof(T)>

guidance when loading data from clang/gcc vector extensions

◆ simd() [3/3]

template<typename T >
requires has_simd_type<T,max_simd_size/sizeof(T)>
ein::simd ( T ) -> simd< T, has_simd_type< T, max_simd_size/sizeof(T)> >

default to max simd size for broadcast

Warning
this may be removed in the future.

References ein::max_simd_size.

Variable Documentation

◆ max_simd_size

size_t ein::max_simd_size = 64
constexpr

largest simd register width supported on this platform in bytes

Definition at line 41 of file simd_data.hpp.

Referenced by ein::simd(), and ein::simd().