23#ifndef VECTORCLASS_SVE_FIXED_H
24#define VECTORCLASS_SVE_FIXED_H
31#include <initializer_list>
35#define SVE_INLINE __attribute__((always_inline))
42template <u
int32_t h
int>
46 __asm__ __volatile__(
"prfm PLDL1KEEP, [%0]\n" : :
"r"(addr) :
"memory");
49 __asm__ __volatile__(
"prfm PLDL2KEEP, [%0]\n" : :
"r"(addr) :
"memory");
52 __asm__ __volatile__(
"prfm PLDL3KEEP, [%0]\n" : :
"r"(addr) :
"memory");
55 __asm__ __volatile__(
"prfm PLDL1STRM, [%0]\n" : :
"r"(addr) :
"memory");
58 __asm__ __volatile__(
"prfm PSTL1KEEP, [%0]\n" : :
"r"(addr) :
"memory");
61 __asm__ __volatile__(
"prfm PSTL1KEEP, [%0]\n" : :
"r"(addr) :
"memory");
64 __asm__ __volatile__(
"prfm PSTL2KEEP, [%0]\n" : :
"r"(addr) :
"memory");
67 __asm__ __volatile__(
"prfm PSTL3KEEP, [%0]\n" : :
"r"(addr) :
"memory");
72#define _mm_prefetch(addr, hint) aarch64_do_prefetch<hint>(addr)
75#if !defined(CACHE_LINE_SIZE)
76#define CACHE_LINE_SIZE (64)
79#define SVE_DISPATCH_1ARG(prefix, arg1) \
80 if constexpr (std::is_same_v<T, __fp16>) { \
81 return prefix##_f16(arg1); \
82 } else if constexpr (std::is_same_v<T, __bf16>) { \
83 return prefix##_bf16(arg1); \
84 } else if constexpr (std::is_same_v<T, float>) { \
85 return prefix##_f32(arg1); \
86 } else if constexpr (std::is_same_v<T, double>) { \
87 return prefix##_f64(arg1); \
88 } else if constexpr (std::is_same_v<T, int32_t>) { \
89 return prefix##_s32(arg1); \
90 } else if constexpr (std::is_same_v<T, int64_t>) { \
91 return prefix##_s64(arg1); \
93 static_assert(false, "Unsupported type for SVE dispatching"); \
96#define SVE_DISPATCH_1ARG_PREDICATED_SFX(prefix, suffix, predicate, arg1) \
97 if constexpr (std::is_same_v<T, __fp16>) { \
98 return prefix##_f16##suffix(predicate, arg1); \
99 } else if constexpr (std::is_same_v<T, __bf16>) { \
100 return prefix##_bf16##suffix(predicate, arg1); \
101 } else if constexpr (std::is_same_v<T, float>) { \
102 return prefix##_f32##suffix(predicate, arg1); \
103 } else if constexpr (std::is_same_v<T, double>) { \
104 return prefix##_f64##suffix(predicate, arg1); \
105 } else if constexpr (std::is_same_v<T, int32_t>) { \
106 return prefix##_s32##suffix(predicate, arg1); \
107 } else if constexpr (std::is_same_v<T, int64_t>) { \
108 return prefix##_s64##suffix(predicate, arg1); \
110 static_assert(false, "Unsupported type for SVE dispatching"); \
113#define SVE_DISPATCH_2ARG_PREDICATED_SFX(prefix, suffix, predicate, arg1, arg2) \
114 if constexpr (std::is_same_v<T, __fp16>) { \
115 return prefix##_f16##suffix(predicate, arg1, arg2); \
116 } else if constexpr (std::is_same_v<T, __bf16>) { \
117 return prefix##_bf16##suffix(predicate, arg1, arg2); \
118 } else if constexpr (std::is_same_v<T, float>) { \
119 return prefix##_f32##suffix(predicate, arg1, arg2); \
120 } else if constexpr (std::is_same_v<T, double>) { \
121 return prefix##_f64##suffix(predicate, arg1, arg2); \
122 } else if constexpr (std::is_same_v<T, int32_t>) { \
123 return prefix##_s32##suffix(predicate, arg1, arg2); \
124 } else if constexpr (std::is_same_v<T, int64_t>) { \
125 return prefix##_s64##suffix(predicate, arg1, arg2); \
127 static_assert(false, "Unsupported type for SVE dispatching"); \
130#define SVE_DISPATCH_1ARG_PREDICATED_NOSFX(prefix, predicate, arg1) \
131 if constexpr (std::is_same_v<T, __fp16>) { \
132 return prefix##_f16(predicate, arg1); \
133 } else if constexpr (std::is_same_v<T, __bf16>) { \
134 return prefix##_bf16(predicate, arg1); \
135 } else if constexpr (std::is_same_v<T, float>) { \
136 return prefix##_f32(predicate, arg1); \
137 } else if constexpr (std::is_same_v<T, double>) { \
138 return prefix##_f64(predicate, arg1); \
139 } else if constexpr (std::is_same_v<T, int32_t>) { \
140 return prefix##_s32(predicate, arg1); \
141 } else if constexpr (std::is_same_v<T, int64_t>) { \
142 return prefix##_s64(predicate, arg1); \
144 static_assert(false, "Unsupported type for SVE dispatching"); \
147#define SVE_DISPATCH_2ARG_PREDICATED_NOSFX(prefix, predicate, arg1, arg2) \
148 if constexpr (std::is_same_v<T, __fp16>) { \
149 return prefix##_f16(predicate, arg1, arg2); \
150 } else if constexpr (std::is_same_v<T, __bf16>) { \
151 return prefix##_bf16(predicate, arg1, arg2); \
152 } else if constexpr (std::is_same_v<T, float>) { \
153 return prefix##_f32(predicate, arg1, arg2); \
154 } else if constexpr (std::is_same_v<T, double>) { \
155 return prefix##_f64(predicate, arg1, arg2); \
156 } else if constexpr (std::is_same_v<T, int32_t>) { \
157 return prefix##_s32(predicate, arg1, arg2); \
158 } else if constexpr (std::is_same_v<T, int64_t>) { \
159 return prefix##_s64(predicate, arg1, arg2); \
161 static_assert(false, "Unsupported type for SVE dispatching"); \
165template <
typename T>
struct type {
169template <>
struct type<__fp16> {
172 using vec = svfloat16_t __attribute__((arm_sve_vector_bits(__ARM_FEATURE_SVE_BITS)));
175template <>
struct type<__bf16> {
177 using vec = svbfloat16_t __attribute__((arm_sve_vector_bits(__ARM_FEATURE_SVE_BITS)));
180template <>
struct type<float> {
183 using vec = svfloat32_t __attribute__((arm_sve_vector_bits(__ARM_FEATURE_SVE_BITS)));
186template <>
struct type<int32_t> {
189 using vec = svint32_t __attribute__((arm_sve_vector_bits(__ARM_FEATURE_SVE_BITS)));
192template <>
struct type<double> {
195 using vec = svfloat64_t __attribute__((arm_sve_vector_bits(__ARM_FEATURE_SVE_BITS)));
198template <>
struct type<int64_t> {
201 using vec = svint64_t __attribute__((arm_sve_vector_bits(__ARM_FEATURE_SVE_BITS)));
212template <typename T, typename sve_type_t = typename sve::type<T>::vec>
213SVE_INLINE void svst(
const svbool_t& predicate, T* location,
const sve_type_t& value) {
215 ::svst1(predicate, location, value);
218template <typename T, typename sve_type_t = typename sve::type<T>::vec>
220 return ::svld1(predicate, ptr);
224template <typename T, typename sve_type_t = typename sve::type<T>::vec>
SVE_INLINE sve_type_t
svdup(T value) {
229 if constexpr (
sizeof(T) == 2)
230 return svptrue_b16();
231 else if constexpr (
sizeof(T) == 4)
232 return svptrue_b32();
233 else if constexpr (
sizeof(T) == 8)
234 return svptrue_b64();
236 static_assert(
false,
"Unsupported type for SVE dispatching");
239template <typename T, typename sve_type_t = typename sve::type<T>::vec>
245 if constexpr (
sizeof(T) == 2) {
246 return svwhilele_b16_s32(0,
index);
247 }
else if constexpr (
sizeof(T) == 4) {
248 return svwhilele_b32_s32(0,
index);
249 }
else if constexpr (
sizeof(T) == 8) {
250 return svwhilele_b64_s64(0,
index);
252 static_assert(
false,
"Unsupported type for SVE dispatching");
257template <typename T, typename sve_type_t = typename sve::type<T>::vec>
258SVE_INLINE sve_type_t
svorr(
const svbool_t& predicate,
const sve_type_t& v1,
const sve_type_t& v2) {
262template <typename T, typename sve_type_t = typename sve::type<T>::vec>
267template <typename T, typename sve_type_t = typename sve::type<T>::vec>
268SVE_INLINE sve_type_t
svand(
const svbool_t& predicate,
const sve_type_t& v1,
const sve_type_t& v2) {
272template <typename T, typename sve_type_t = typename sve::type<T>::vec>
273SVE_INLINE svbool_t
sveq(
const svbool_t& mask,
const sve_type_t& v1,
const sve_type_t& v2) {
278template <typename T, typename sve_type_t = typename sve::type<T>::vec>
279SVE_INLINE sve_type_t
svadd(
const svbool_t& predicate,
const sve_type_t& lhs,
const sve_type_t& rhs) {
283template <typename T, typename sve_type_t = typename sve::type<T>::vec>
288template <typename T, typename sve_type_t = typename sve::type<T>::vec>
293template <typename T, typename sve_type_t = typename sve::type<T>::vec>
294SVE_INLINE sve_type_t
svmul(
const svbool_t& predicate,
const sve_type_t& lhs,
const sve_type_t& rhs) {
298template <typename T, typename sve_type_t = typename sve::type<T>::vec>
303template <typename T, typename sve_type_t = typename sve::type<T>::vec>
304SVE_INLINE sve_type_t
svsub(
const svbool_t& predicate,
const sve_type_t& lhs,
const sve_type_t& rhs) {
308template <typename T, typename sve_type_t = typename sve::type<T>::vec>
313template <typename T, typename sve_type_t = typename sve::type<T>::vec>
318template <typename T, typename sve_type_t = typename sve::type<T>::vec>
319SVE_INLINE sve_type_t
svdiv(
const svbool_t& predicate,
const sve_type_t& lhs,
const sve_type_t& rhs) {
323template <typename T, typename sve_type_t = typename sve::type<T>::vec>
328template <typename T, typename sve_type_t = typename sve::type<T>::vec>
334template <typename T, typename sve_type_t = typename sve::type<T>::vec>
335SVE_INLINE svbool_t
eq(
const svbool_t& predicate,
const sve_type_t& lhs,
const sve_type_t& rhs) {
339template <typename T, typename sve_type_t = typename sve::type<T>::vec>
340SVE_INLINE svbool_t
neq(
const svbool_t& predicate,
const sve_type_t& lhs,
const sve_type_t& rhs) {
344template <typename T, typename sve_type_t = typename sve::type<T>::vec>
345SVE_INLINE svbool_t
eq_n(
const svbool_t& predicate,
const sve_type_t& lhs,
const T rhs) {
349template <typename T, typename sve_type_t = typename sve::type<T>::vec>
350SVE_INLINE svbool_t
neq_n(
const svbool_t& predicate,
const sve_type_t& lhs,
const T rhs) {
354template <typename T, typename sve_type_t = typename sve::type<T>::vec>
355SVE_INLINE svbool_t
lt(
const svbool_t& predicate,
const sve_type_t& lhs,
const sve_type_t& rhs) {
359template <typename T, typename sve_type_t = typename sve::type<T>::vec>
360SVE_INLINE svbool_t
lt_n(
const svbool_t& predicate,
const sve_type_t& lhs,
const T rhs) {
364template <typename T, typename sve_type_t = typename sve::type<T>::vec>
365SVE_INLINE svbool_t
leq(
const svbool_t& predicate,
const sve_type_t& lhs,
const sve_type_t& rhs) {
369template <typename T, typename sve_type_t = typename sve::type<T>::vec>
370SVE_INLINE svbool_t
leq_n(
const svbool_t& predicate,
const sve_type_t& lhs,
const T rhs) {
374template <typename T, typename sve_type_t = typename sve::type<T>::vec>
375SVE_INLINE svbool_t
gt(
const svbool_t& predicate,
const sve_type_t& lhs,
const sve_type_t& rhs) {
379template <typename T, typename sve_type_t = typename sve::type<T>::vec>
380SVE_INLINE svbool_t
gt_n(
const svbool_t& predicate,
const sve_type_t& lhs,
const T rhs) {
384template <typename T, typename sve_type_t = typename sve::type<T>::vec>
385SVE_INLINE svbool_t
geq(
const svbool_t& predicate,
const sve_type_t& lhs,
const sve_type_t& rhs) {
389template <typename T, typename sve_type_t = typename sve::type<T>::vec>
390SVE_INLINE svbool_t
geq_n(
const svbool_t& predicate,
const sve_type_t& lhs,
const T rhs) {
394template <typename T, typename sve_type_t = typename sve::type<T>::vec>
395SVE_INLINE sve_type_t
svsel(
const svbool_t& predicate,
const sve_type_t& lhs,
const sve_type_t& rhs) {
400template <typename T, typename sve_type_t = typename sve::type<T>::vec>
401SVE_INLINE sve_type_t
svmin(
const svbool_t& predicate,
const sve_type_t& lhs,
const sve_type_t& rhs) {
405template <typename T, typename sve_type_t = typename sve::type<T>::vec>
406SVE_INLINE sve_type_t
svmax(
const svbool_t& predicate,
const sve_type_t& lhs,
const sve_type_t& rhs) {
413template <
typename sve_wrapper_vector_t,
typename predicate_t,
typename lhs_sve_vector_t,
typename rhs_sve_vector_t,
414 std::size_t len,
typename return_sve_vector_t =
typename sve_wrapper_vector_t::sve_vec_t>
415sve_wrapper_vector_t
transform(
const predicate_t& predicate,
const lhs_sve_vector_t* lhs,
const rhs_sve_vector_t* rhs,
416 return_sve_vector_t (*binary_operation)(
const svbool_t&,
const lhs_sve_vector_t&,
417 const rhs_sve_vector_t&)) {
418 return_sve_vector_t ret[len];
420 for (std::size_t
i = 0;
i < len; ++
i) {
421 ret[
i] = binary_operation(predicate.at(
i), lhs[
i], rhs[
i]);
423 return sve_wrapper_vector_t(ret);
426template <
typename sve_wrapper_vector_t,
typename lhs_sve_vector_t,
typename rhs_sve_vector_t, std::size_t len,
427 typename return_sve_vector_t =
typename sve_wrapper_vector_t::sve_vec_t>
428sve_wrapper_vector_t
transform(
const lhs_sve_vector_t* lhs,
const rhs_sve_vector_t* rhs,
429 return_sve_vector_t (*binary_operation)(
const svbool_t&,
const lhs_sve_vector_t&,
430 const rhs_sve_vector_t&)) {
431 return_sve_vector_t ret[len];
434 for (std::size_t
i = 0;
i < len; ++
i) {
435 ret[
i] = binary_operation(all_lanes, lhs[
i], rhs[
i]);
437 return sve_wrapper_vector_t(ret);
440template <
typename sve_wrapper_vector_t,
typename lhs_sve_vector_t, std::size_t len,
441 typename return_sve_vector_t =
typename sve_wrapper_vector_t::sve_vec_t,
442 typename scalar_t =
typename sve_wrapper_vector_t::sve_scalar_t>
443sve_wrapper_vector_t
transform(
const lhs_sve_vector_t* lhs,
const scalar_t rhs,
444 return_sve_vector_t (*binary_operation_with_scalar)(
const svbool_t&,
445 const lhs_sve_vector_t&,
447 return_sve_vector_t ret[len];
450 for (std::size_t
i = 0;
i < len; ++
i) {
451 ret[
i] = binary_operation_with_scalar(all_lanes, lhs[
i], rhs);
453 return sve_wrapper_vector_t(ret);
456template <
typename sve_wrapper_vector_t,
typename operand_vector_t, std::size_t len,
457 typename return_sve_vector_t =
typename sve_wrapper_vector_t::sve_vec_t>
458sve_wrapper_vector_t
transform(
const operand_vector_t* operand,
459 return_sve_vector_t (*unary_operation)(
const svbool_t&,
const operand_vector_t&)) {
460 return_sve_vector_t ret[len];
463 for (std::size_t
i = 0;
i < len; ++
i) {
464 ret[
i] = unary_operation(all_lanes, operand[
i]);
466 return sve_wrapper_vector_t(ret);
469template <
typename sve_wrapper_vector_t,
typename predicate_t,
typename lhs_sve_vector_t, std::size_t len,
470 typename return_sve_vector_t =
typename sve_wrapper_vector_t::sve_vec_t>
471sve_wrapper_vector_t
transform(
const lhs_sve_vector_t* operand,
const predicate_t* predicate,
472 return_sve_vector_t (*unary_operation)(
const svbool_t&,
const lhs_sve_vector_t&)) {
473 return_sve_vector_t ret[len];
475 for (std::size_t
i = 0;
i < len; ++
i) {
476 ret[
i] = unary_operation(predicate[
i], operand[
i]);
478 return sve_wrapper_vector_t(ret);
482template <
typename sve_wrapper_vector_t,
typename predicate_t,
typename lhs_sve_vector_t,
typename rhs_sve_vector_t,
483 std::size_t len,
typename return_sve_vector_t =
typename sve_wrapper_vector_t::sve_vec_t,
484 typename return_scalar_t =
typename sve_wrapper_vector_t::sve_scalar_t>
485sve_wrapper_vector_t
transform(
const lhs_sve_vector_t* lhs,
const rhs_sve_vector_t* rhs,
const predicate_t* predicate,
486 svbool_t (*binary_operation)(
const svbool_t&,
const lhs_sve_vector_t&,
487 const rhs_sve_vector_t&)) {
488 return_sve_vector_t ret[len];
492 for (std::size_t
i = 0;
i < len; ++
i) {
493 auto result_mask = binary_operation(predicate[
i], lhs[
i], rhs[
i]);
496 return sve_wrapper_vector_t(ret);
500template <
typename sve_wrapper_vector_t,
typename lhs_sve_vector_t,
typename rhs_sve_vector_t, std::size_t len,
501 typename return_sve_vector_t =
typename sve_wrapper_vector_t::sve_vec_t,
502 typename return_scalar_t =
typename sve_wrapper_vector_t::sve_scalar_t>
503sve_wrapper_vector_t
transform(
const lhs_sve_vector_t* lhs,
const rhs_sve_vector_t* rhs,
504 svbool_t (*binary_operation)(
const svbool_t&,
const lhs_sve_vector_t&,
505 const rhs_sve_vector_t&)) {
506 return_sve_vector_t ret[len];
511 for (std::size_t
i = 0;
i < len; ++
i) {
512 auto result_mask = binary_operation(all_lanes, lhs[
i], rhs[
i]);
515 return sve_wrapper_vector_t(ret);
518template <
typename sve_wrapper_vector_t,
typename lhs_sve_vector_t, std::size_t len,
519 typename scalar_t =
typename sve_wrapper_vector_t::sve_scalar_t,
520 typename return_sve_vector_t =
typename sve_wrapper_vector_t::sve_vec_t,
521 typename return_scalar_t =
typename sve_wrapper_vector_t::sve_scalar_t>
522sve_wrapper_vector_t
transform(
const lhs_sve_vector_t* lhs,
const scalar_t rhs,
523 svbool_t (*binary_operation_with_scalar)(
const svbool_t&,
const lhs_sve_vector_t&,
525 return_sve_vector_t ret[len];
530 for (std::size_t
i = 0;
i < len; ++
i) {
531 auto result_mask = binary_operation_with_scalar(all_lanes, lhs[
i], rhs);
534 return sve_wrapper_vector_t(ret);
537template <typename T, std::size_t len, std::size_t stride, typename vec_t = typename sve::type<T>::vec>
540 for (std::size_t
i = 0;
i < len; ++
i) {
545template <typename T, std::size_t len, std::size_t stride, typename vec_t = typename sve::type<T>::vec>
548 for (std::size_t
i = 0;
i < len; ++
i) {
582 for (std::size_t
i = 0;
i <
len; ++
i) {
602template <
typename base_t, std::
size_t N>
616 for (std::size_t
i = 0;
i <
len; ++
i) {
617 this->m_data[
i] = data[
i];
626 auto sve_values = this->m_data[
index];
645 static_assert(!std::is_same_v<T, __bf16>,
"Did you know? SVE doesn't support comparison between bf16!");
651 for (std::size_t
i = 0;
i <
len; ++
i)
676 for (std::size_t
i = 0;
i <
len; ++
i) {
677 this->m_data[
i] = data[
i];
682 for (std::size_t
i = 0;
i <
len; ++
i) {
683 this->m_data[
i] = other.m_data[
i];
696 if (values.size() != 1) {
697 const auto* values_ptr = std::data(values);
701 for (std::size_t
i = 0;
i <
len; ++
i) {
702 this->m_data[
i] = sve_value;
709 for (std::size_t
i = 0;
i <
len; ++
i) {
710 this->m_data[
i] = sve_value;
714 template <
typename U,
typename = std::enable_if_t<std::is_arithmetic_v<U>>>
718 for (std::size_t
i = 0;
i <
len; ++
i) {
719 this->m_data[
i] = other.m_data[
i];
724 template <
typename U,
typename = std::enable_if_t<std::is_arithmetic_v<U>>>
727 for (std::size_t
i = 0;
i <
len; ++
i) {
728 this->m_data[
i] = data;
739 const auto* ptr_aligned =
static_cast<const T*
>(__builtin_assume_aligned(ptr,
CACHE_LINE_SIZE));
740 return load(ptr_aligned);
748 auto* destination_aligned =
static_cast<T*
>(__builtin_assume_aligned(destination,
CACHE_LINE_SIZE));
749 store(destination_aligned);
758 static_assert(
sizeof(T) ==
sizeof(conv_t),
"Size should match");
762 sve_conv_vec_t storage[
len];
765 for (std::size_t
i = 0;
i <
len; ++
i) {
766 if constexpr (std::is_same_v<conv_t, float>)
767 storage[
i] = svcvt_f32_s32_x(all_lanes, this->m_data[
i]);
768 else if constexpr (std::is_same_v<conv_t, double>)
769 storage[
i] = svcvt_f64_s64_x(all_lanes, this->m_data[
i]);
770 else if constexpr (std::is_same_v<conv_t, int16_t>)
771 storage[
i] = svcvt_s16_f16_x(all_lanes, this->m_data[
i]);
772 else if constexpr (std::is_same_v<conv_t, int32_t>)
773 storage[
i] = svcvt_s32_f32_x(all_lanes, this->m_data[
i]);
774 else if constexpr (std::is_same_v<conv_t, int64_t>)
775 storage[
i] = svcvt_s64_f64_x(all_lanes, this->m_data[
i]);
776 else if constexpr (std::is_same_v<T, __bf16>)
777 static_assert(
false,
"Cannot cast from bfloat16 vector to s16 vector.");
779 static_assert(
false,
"Unsupported conversion!");
795 template <
typename U,
typename = std::enable_if_t<std::is_arithmetic_v<U>>>
797 auto converted_value = T(value);
813 template <
typename U,
typename = std::enable_if_t<std::is_arithmetic_v<U>>>
815 auto converted_value = T(value);
831 template <
typename U,
typename = std::enable_if_t<std::is_arithmetic_v<U>>>
833 auto converted_value = T(value);
839 static_assert(!std::is_same_v<T, __bf16>,
"Did you know? SVE doesn't support negating a bf16!");
844 static_assert(!std::is_same_v<T, __bf16>,
"Did you know? SVE doesn't support division between bf16!");
850 static_assert(!std::is_same_v<T, __bf16>,
"Did you know? SVE doesn't support division between bf16!");
856 template <
typename U,
typename = std::enable_if_t<std::is_arithmetic_v<U>>>
858 static_assert(!std::is_same_v<T, __bf16>,
"Did you know? SVE doesn't support division between bf16!");
859 auto converted_value = T(value);
884 static_assert(!std::is_same_v<T, __bf16>,
"Did you know? SVE doesn't support comparison between bf16!");
889 template <
typename U,
typename = std::enable_if_t<std::is_arithmetic_v<U>>>
891 static_assert(!std::is_same_v<T, __bf16>,
"Did you know? SVE doesn't support comparison between bf16!");
897 static_assert(!std::is_same_v<T, __bf16>,
"Did you know? SVE doesn't support comparison between bf16!");
902 template <
typename U,
typename = std::enable_if_t<std::is_arithmetic_v<U>>>
904 static_assert(!std::is_same_v<T, __bf16>,
"Did you know? SVE doesn't support comparison between bf16!");
911 static_assert(!std::is_same_v<T, __bf16>,
"Did you know? SVE doesn't support comparison between bf16!");
916 template <
typename U,
typename = std::enable_if_t<std::is_arithmetic_v<U>>>
918 static_assert(!std::is_same_v<T, __bf16>,
"Did you know? SVE doesn't support comparison between bf16!");
924 static_assert(!std::is_same_v<T, __bf16>,
"Did you know? SVE doesn't support comparison between bf16!");
929 template <
typename U,
typename = std::enable_if_t<std::is_arithmetic_v<U>>>
931 static_assert(!std::is_same_v<T, __bf16>,
"Did you know? SVE doesn't support comparison between bf16!");
937 static_assert(!std::is_same_v<T, __bf16>,
"Did you know? SVE doesn't support comparison between bf16!");
942 template <
typename U,
typename = std::enable_if_t<std::is_arithmetic_v<U>>>
944 static_assert(!std::is_same_v<T, __bf16>,
"Did you know? SVE doesn't support comparison between bf16!");
951 static_assert(!std::is_same_v<T, __bf16>,
"Did you know? SVE doesn't support comparison between bf16!");
956 template <
typename U,
typename = std::enable_if_t<std::is_arithmetic_v<U>>>
958 static_assert(!std::is_same_v<T, __bf16>,
"Did you know? SVE doesn't support comparison between bf16!");
970template <
typename T, std::
size_t N>
972 return v1.
select(mask, v2);
975template <
typename T, std::
size_t N,
typename U,
typename = std::enable_if_t<std::is_arithmetic_v<U>>>
980 return v1.
select(mask, v2);
983template <
typename T, std::
size_t N,
typename U,
typename = std::enable_if_t<std::is_arithmetic_v<U>>>
988 return v1.
select(mask, v2);
1004 return vec.template as<float>();
1008 return vec.template as<double>();
1011template <typename real_t, std::size_t N, typename integral_t = typename sve::type<real_t>::integral>
1013 return arg.template as<integral_t>();
1016template <typename real_t, std::size_t N, typename integral_t = typename sve::type<real_t>::integral>
1018 auto res = arg + real_t(0.5);
1019 return arg.template as<integral_t>();
1027template <
typename T, std::
size_t N,
typename U,
typename = std::enable_if_t<std::is_arithmetic_v<U>>>
1032template <
typename T, std::
size_t N,
typename U,
typename = std::enable_if_t<std::is_arithmetic_v<U>>>
1037template <
typename T, std::
size_t N,
typename U,
typename = std::enable_if_t<std::is_arithmetic_v<U>>>
1042template <
typename T, std::
size_t N,
typename U,
typename = std::enable_if_t<std::is_arithmetic_v<U>>>
typename sve::type< T >::scalar sve_scalar_t
T operator[](const std::size_t i) const
static constexpr std::size_t elems_per_vec
static constexpr std::size_t len
sve_scalar_t * leak_ptr() const
typename sve::type< T >::integral sve_integral_t
sve_vec_t m_data[len] __attribute__((aligned(CACHE_LINE_SIZE)))
typename sve::type< T >::vec sve_vec_t
static constexpr std::size_t sve_size_bytes
SVE_INLINE sve_scalar_t reduce() const
SVE_INLINE VecSVE & operator*=(const VecSVE &rhs)
SVE_INLINE VecSVE max(const VecSVE &rhs) const
SVE_INLINE VecSVE(const T value)
SVE_INLINE VecSVEMask< T, N > operator!=(const U &value) const
static constexpr std::size_t elems_per_vec
SVE_INLINE VecSVEMask< T, N > operator>(const VecSVE &rhs) const
SVE_INLINE VecSVEMask< T, N > operator<=(const U &value) const
SVE_INLINE VecSVE & load_a(const T *ptr)
SVE_INLINE void store_a(T *destination) const
SVE_INLINE VecSVE operator*(const VecSVE &rhs) const
SVE_INLINE VecSVE abs() const
SVE_INLINE VecSVE(sve_vec_t *data)
static constexpr std::size_t len
SVE_INLINE VecSVE operator-(const U value) const
SVE_INLINE VecSVE operator/(const U value) const
SVE_INLINE VecSVEMask< T, N > operator==(const U &value) const
SVE_INLINE VecSVE(const VecSVE &other)
SVE_INLINE void store(T *destination) const
SVE_INLINE VecSVE(const T *data)
SVE_INLINE VecSVE & load(const T *ptr)
SVE_INLINE VecSVEMask< T, N > operator<(const VecSVE &rhs) const
SVE_INLINE VecSVE min(const VecSVE &rhs) const
SVE_INLINE VecSVE operator-(const VecSVE &rhs) const
SVE_INLINE VecSVE & operator/=(const VecSVE &rhs) const
SVE_INLINE VecSVE select(const VecSVEMask< T, N > &mask, const VecSVE &rhs) const
SVE_INLINE VecSVE & operator=(const VecSVE< T, N > &other)
SVE_INLINE VecSVE operator*(const U value) const
SVE_INLINE VecSVEMask< T, N > operator==(const VecSVE &rhs) const
SVE_INLINE VecSVE operator+(const VecSVE &rhs) const
SVE_INLINE VecSVE & operator=(const U value)
VecSVE< conv_t, N > as() const
SVE_INLINE VecSVE operator-() const
SVE_INLINE VecSVE & operator+=(const VecSVE &rhs)
SVE_INLINE VecSVE operator/(const VecSVE &rhs) const
SVE_INLINE VecSVEMask< T, N > operator>=(const U &value) const
SVE_INLINE VecSVEMask< T, N > operator<=(const VecSVE &rhs) const
SVE_INLINE VecSVE()=default
SVE_INLINE VecSVE operator+(const U value) const
SVE_INLINE VecSVEMask< T, N > operator<(const U &value) const
SVE_INLINE VecSVE sqrt() const
SVE_INLINE VecSVE(std::initializer_list< T > values)
static constexpr std::size_t sve_size_bytes
SVE_INLINE VecSVEMask< T, N > operator!=(const VecSVE &rhs) const
SVE_INLINE VecSVEMask< T, N > operator>(const U &value) const
SVE_INLINE VecSVE & operator-=(const VecSVE &rhs) const
typename VecSVEBase< T, N >::sve_vec_t sve_vec_t
typename VecSVEBase< T, N >::sve_scalar_t sve_scalar_t
SVE_INLINE VecSVEMask< T, N > operator>=(const VecSVE &rhs) const
static constexpr std::size_t len
SVE_INLINE svbool_t at(std::size_t index) const
typename sve::type< base_t >::integral T
typename VecSVEBase< T, N >::sve_scalar_t sve_scalar_t
SVE_INLINE VecSVEMask operator||(const VecSVEMask &rhs) const
SVE_INLINE VecSVEMask operator!() const
static constexpr std::size_t elems_per_vec
SVE_INLINE VecSVEMask(const T *data)
SVE_INLINE bool all() const
SVE_INLINE VecSVEMask(sve_vec_t *data)
typename VecSVEBase< T, N >::sve_vec_t sve_vec_t
SVE_INLINE bool any() const
SVE_INLINE VecSVEMask operator&&(const VecSVEMask &rhs) const
void load_into(vec_t *dst, const T *src)
sve_wrapper_vector_t transform(const predicate_t &predicate, const lhs_sve_vector_t *lhs, const rhs_sve_vector_t *rhs, return_sve_vector_t(*binary_operation)(const svbool_t &, const lhs_sve_vector_t &, const rhs_sve_vector_t &))
void store_into(T *dst, const vec_t *src)
SVE_INLINE sve_type_t svabs(const svbool_t &predicate, const sve_type_t &operand)
SVE_INLINE svbool_t svtrue()
SVE_INLINE svbool_t gt(const svbool_t &predicate, const sve_type_t &lhs, const sve_type_t &rhs)
SVE_INLINE sve_type_t svadd_n(const svbool_t &predicate, const sve_type_t &lhs, const T rhs)
SVE_INLINE svbool_t leq(const svbool_t &predicate, const sve_type_t &lhs, const sve_type_t &rhs)
SVE_INLINE T svextract(const svbool_t &predicate, const sve_type_t &vec)
SVE_INLINE sve_type_t svdup(T value)
SVE_INLINE sve_type_t svdiv_n(const svbool_t &predicate, const sve_type_t &lhs, const T rhs)
SVE_INLINE sve_type_t svsub_n(const svbool_t &predicate, const sve_type_t &lhs, const T rhs)
SVE_INLINE void svst(const svbool_t &predicate, T *location, const sve_type_t &value)
SVE_INLINE sve_type_t svmul_n(const svbool_t &predicate, const sve_type_t &lhs, const T rhs)
SVE_INLINE sve_type_t svorr(const svbool_t &predicate, const sve_type_t &v1, const sve_type_t &v2)
SVE_INLINE sve_type_t svadd(const svbool_t &predicate, const sve_type_t &lhs, const sve_type_t &rhs)
SVE_INLINE svbool_t eq(const svbool_t &predicate, const sve_type_t &lhs, const sve_type_t &rhs)
SVE_INLINE svbool_t lt_n(const svbool_t &predicate, const sve_type_t &lhs, const T rhs)
SVE_INLINE sve_type_t svsub(const svbool_t &predicate, const sve_type_t &lhs, const sve_type_t &rhs)
SVE_INLINE svbool_t gt_n(const svbool_t &predicate, const sve_type_t &lhs, const T rhs)
SVE_INLINE svbool_t leq_n(const svbool_t &predicate, const sve_type_t &lhs, const T rhs)
SVE_INLINE sve_type_t svmax(const svbool_t &predicate, const sve_type_t &lhs, const sve_type_t &rhs)
SVE_INLINE sve_type_t svmin(const svbool_t &predicate, const sve_type_t &lhs, const sve_type_t &rhs)
SVE_INLINE svbool_t neq(const svbool_t &predicate, const sve_type_t &lhs, const sve_type_t &rhs)
SVE_INLINE svbool_t neq_n(const svbool_t &predicate, const sve_type_t &lhs, const T rhs)
SVE_INLINE svbool_t geq_n(const svbool_t &predicate, const sve_type_t &lhs, const T rhs)
SVE_INLINE sve_type_t svmul(const svbool_t &predicate, const sve_type_t &lhs, const sve_type_t &rhs)
SVE_INLINE svbool_t geq(const svbool_t &predicate, const sve_type_t &lhs, const sve_type_t &rhs)
SVE_INLINE sve_type_t svsel(const svbool_t &predicate, const sve_type_t &lhs, const sve_type_t &rhs)
SVE_INLINE svbool_t pred_from_index(const std::size_t index)
SVE_INLINE T reduce(const svbool_t &predicate, const sve_type_t &vec)
SVE_INLINE sve_type_t svneg(const svbool_t &predicate, const sve_type_t &operand)
SVE_INLINE svbool_t sveq(const svbool_t &mask, const sve_type_t &v1, const sve_type_t &v2)
SVE_INLINE sve_type_t svand(const svbool_t &predicate, const sve_type_t &v1, const sve_type_t &v2)
SVE_INLINE svbool_t eq_n(const svbool_t &predicate, const sve_type_t &lhs, const T rhs)
SVE_INLINE sve_type_t svsqrt(const svbool_t &predicate, const sve_type_t &v1)
SVE_INLINE sve_type_t svld(const svbool_t &predicate, const T *ptr)
SVE_INLINE svbool_t lt(const svbool_t &predicate, const sve_type_t &lhs, const sve_type_t &rhs)
SVE_INLINE sve_type_t svdiv(const svbool_t &predicate, const sve_type_t &lhs, const sve_type_t &rhs)
svbfloat16_t __attribute__((arm_sve_vector_bits(__ARM_FEATURE_SVE_BITS))) vec
svfloat16_t __attribute__((arm_sve_vector_bits(__ARM_FEATURE_SVE_BITS))) vec
svfloat64_t __attribute__((arm_sve_vector_bits(__ARM_FEATURE_SVE_BITS))) vec
svfloat32_t __attribute__((arm_sve_vector_bits(__ARM_FEATURE_SVE_BITS))) vec
svint32_t __attribute__((arm_sve_vector_bits(__ARM_FEATURE_SVE_BITS))) vec
svint64_t __attribute__((arm_sve_vector_bits(__ARM_FEATURE_SVE_BITS))) vec
VecSVE< T, N > operator*(const U lhs, const VecSVE< T, N > &rhs)
SVE_INLINE VecSVE< T, N > min(const VecSVE< T, N > &lhs, const VecSVE< T, N > &rhs)
SVE_INLINE VecSVE< T, N > sqrt(const VecSVE< T, N > &v)
#define SVE_DISPATCH_2ARG_PREDICATED_SFX(prefix, suffix, predicate, arg1, arg2)
SVE_INLINE VecSVE< T, N > select(const VecSVEMask< T, N > &mask, const VecSVE< T, N > &v1, const VecSVE< T, N > &v2)
SVE_INLINE bool horizontal_or(const VecSVEMask< T, N > &vec)
void SVE_INLINE aarch64_do_prefetch(void *addr)
VecSVE< integral_t, N > roundi(const VecSVE< real_t, N > &arg)
static void no_subnormals()
VecSVE< T, N > floor(const VecSVE< T, N > &arg)
VecSVE< float, N > to_float(const VecSVE< other_t, N > &vec)
VecSVE< integral_t, N > truncate_to_int(const VecSVE< real_t, N > &arg)
#define SVE_DISPATCH_1ARG_PREDICATED_NOSFX(prefix, predicate, arg1)
VecSVE< T, N > operator-(U lhs, const VecSVE< T, N > &rhs)
SVE_INLINE bool horizontal_and(const VecSVEMask< T, N > &vec)
VecSVE< T, N > operator+(const U lhs, const VecSVE< T, N > &rhs)
#define SVE_DISPATCH_1ARG(prefix, arg1)
VecSVE< double, N > to_double(const VecSVE< other_t, N > &vec)
SVE_INLINE VecSVE< T, N > max(const VecSVE< T, N > &lhs, const VecSVE< T, N > &rhs)
SVE_INLINE VecSVE< T, N > abs(const VecSVE< T, N > &v)
#define SVE_DISPATCH_2ARG_PREDICATED_NOSFX(prefix, predicate, arg1, arg2)
VecSVE< T, N > operator/(U lhs, const VecSVE< T, N > &rhs)
#define SVE_DISPATCH_1ARG_PREDICATED_SFX(prefix, suffix, predicate, arg1)
T horizontal_add(const VecSVE< T, N > &vec)