61 typename alpaka::trait::GetSimdStorageType<
decltype(
thisApi()), T_Type, T_width>::type>
66 template<
typename T_Type, u
int32_t T_w
idth,
typename T_Storage>
73 template<concepts::SimdMask T_Mask, concepts::Simd T_Simd>
76 template<
typename T_Type, u
int32_t T_w
idth,
typename T_Storage>
77 struct Simd :
private T_Storage
80 using type =
typename T_Storage::value_type;
92 static_assert(T_width > 0u);
94 constexpr Simd() =
default;
96 using Storage::asNativeType;
107 return static_cast<Storage&
>(*this);
112 return static_cast<Storage const&
>(*this);
127 std::enable_if_t<std::is_invocable_v<F, std::integral_constant<uint32_t, 0u>>, uint32_t> = 0u>
129 :
Simd(
std::forward<F>(generator),
std::make_integer_sequence<uint32_t, T_width>{})
146 template<
typename... T_Args>
147 requires((std::is_convertible_v<T_Args, T_Type> && ...) && (
sizeof...(T_Args) == T_width))
154 constexpr Simd(T_Storage
const& other) : T_Storage{other}
160 template<
typename T_OtherStorage>
162 :
Simd([&](uint32_t const i) constexpr { return other[i]; })
170 constexpr explicit operator type()
requires(T_width == 1u)
183 Storage::copyFrom(data, alignment);
188 Storage::copyTo(data, alignment);
204 return Simd{Storage::fill(
static_cast<T_Type
>(value))};
215 for(uint32_t i = 0u; i < T_width; i++)
216 invertedSimd[T_width - 1 - i] = (*
this)[i];
226 return Simd([
this](uint32_t
const i)
constexpr {
return -(*this)[i]; });
232#define ALPAKA_VECTOR_ASSIGN_OP(op) \
233 template<typename T_OtherStorage> \
234 constexpr Simd& operator op(Simd<T_Type, T_width, T_OtherStorage> const& rhs) \
236 this->asStorage() op rhs.asStorage(); \
239 constexpr Simd& operator op(concepts::LosslesslyConvertible<T_Type> auto const value) \
241 this->asStorage() op static_cast<T_Type>(value); \
251#undef ALPAKA_VECTOR_ASSIGN_OP
275#define ALPAKA_NAMED_ARRAY_ACCESS(functionName, laneIdx) \
276 constexpr reference functionName() requires(T_width >= laneIdx + 1) \
278 return (*this)[laneIdx]; \
280 constexpr type functionName() const requires(T_width >= laneIdx + 1) \
282 return (*this)[laneIdx]; \
329#undef ALPAKA_NAMED_ARRAY_ACCESS
338 template<u
int32_t T_numElements>
341 static_assert(T_numElements <= T_width);
343 for(uint32_t i = 0u; i < T_numElements; i++)
344 result[T_numElements - 1u - i] = (*
this)[T_width - 1u - i];
353 constexpr Simd<T_Type, T_width - 1u>
eraseBack() const requires(T_width > 1u)
355 constexpr auto reducedDim = T_width - 1u;
357 for(uint32_t i = 0u; i < reducedDim; i++)
358 result[i] = (*this)[i];
370 template<u
int32_t T_numElements>
373 static_assert(T_numElements <= T_width);
375 for(uint32_t i = 0u; i < T_numElements; i++)
376 result[T_numElements - 1u - i] = (*
this)[(T_width + startIdx - i) % T_width];
387 template<std::
integral auto laneIdxToRemove>
391 for(
int i = 0u; i < static_cast<int>(T_width - 1u); ++i)
394 int const sourceIdx = i >=
static_cast<int>(laneIdxToRemove) ? i + 1 : i;
395 result[i] = (*this)[sourceIdx];
406 return reduce(std::multiplies{});
415 return reduce(std::plus{});
426 [[nodiscard]]
constexpr auto reduce(
auto&& reduceFunc)
const
427 ->
decltype(reduceFunc(std::declval<type>(), std::declval<type>()))
432 template<
typename T_OtherStorage>
436 for(uint32_t d = 0u; d < T_width; d++)
437 result[d] = std::min((*
this)[d], rhs[d]);
454 std::string
toString(std::string
const separator =
",", std::string
const enclosings =
"{}")
const
456 std::string locale_enclosing_begin;
457 std::string locale_enclosing_end;
458 size_t enclosingLaneIdx = enclosings.size();
460 if(enclosingLaneIdx > 0)
463 locale_enclosing_begin = enclosings[0 % enclosingLaneIdx];
464 locale_enclosing_end = enclosings[1 % enclosingLaneIdx];
467 std::stringstream stream;
468 stream << locale_enclosing_begin << (*this)[0];
470 for(uint32_t i = 1u; i < T_width; ++i)
471 stream << separator << (*
this)[i];
472 stream << locale_enclosing_end;
477 template<
typename F, uint32_t... Is>
478 constexpr explicit Simd(F&& generator, std::integer_sequence<uint32_t, Is...>)
479 : Storage{generator(
std::integral_constant<uint32_t, Is>{})...}
490 template<u
int32_t T_start = 0u, u
int32_t T_end = w
idth()>
491 [[nodiscard]]
constexpr auto reduce_range(
auto&& reduceFunc)
const
492 ->
decltype(reduceFunc(std::declval<type>(), std::declval<type>()))
495 constexpr uint32_t size = T_end - T_start;
497 if constexpr(size == 1u)
499 return (*
this)[T_start];
503 auto result = (*this)[T_start];
504 for(uint32_t i = T_start + 1u; i < T_end; ++i)
506 result = reduceFunc(result, (*
this)[i]);
511 constexpr uint32_t mid = T_start + size / 2u;
520 template<concepts::SimdMask Mask, concepts::Simd T_Simd>
524 template<std::
size_t I,
typename T_Type, u
int32_t T_w
idth,
typename T_Storage>
530 template<std::
size_t I,
typename T_Type, u
int32_t T_w
idth,
typename T_Storage>
536 template<
typename Type, u
int32_t T_w
idth,
typename T_Storage>
543 template<
typename T_1,
typename... T_Args>
549#define ALPAKA_VECTOR_BINARY_OP(typenameOrConcept, op) \
550 template<typenameOrConcept T_Type, uint32_t T_width, typename T_Storage, typename T_OtherStorage> \
551 constexpr auto operator op( \
552 const Simd<T_Type, T_width, T_Storage>& lhs, \
553 const Simd<T_Type, T_width, T_OtherStorage>& rhs) \
555 using StoreageType = ALPAKA_TYPEOF(lhs.asStorage() op rhs.asStorage()); \
556 return Simd<T_Type, T_width, StoreageType>(lhs.asStorage() op rhs.asStorage()); \
559 typenameOrConcept T_Type, \
560 concepts::LosslesslyConvertible<T_Type> T_ValueType, \
562 typename T_Storage> \
563 constexpr auto operator op(const Simd<T_Type, T_width, T_Storage>& lhs, T_ValueType rhs) \
565 using StoreageType = ALPAKA_TYPEOF(lhs.asStorage() op static_cast<T_Type>(rhs)); \
566 return Simd<T_Type, T_width, StoreageType>(lhs.asStorage() op static_cast<T_Type>(rhs)); \
569 typenameOrConcept T_Type, \
570 concepts::LosslesslyConvertible<T_Type> T_ValueType, \
572 typename T_Storage> \
573 constexpr auto operator op(T_ValueType lhs, const Simd<T_Type, T_width, T_Storage>& rhs) \
575 using StoreageType = ALPAKA_TYPEOF(static_cast<T_Type>(lhs) op rhs.asStorage()); \
576 return Simd<T_Type, T_width, StoreageType>(static_cast<T_Type>(lhs) op rhs.asStorage()); \
590#undef ALPAKA_VECTOR_BINARY_OP
593#define ALPAKA_VECTOR_BINARY_CMP_OP(typenameOrConcept, op) \
594 template<typenameOrConcept T_Type, uint32_t T_width, typename T_Storage, typename T_OtherStorage> \
595 constexpr auto operator op( \
596 const Simd<T_Type, T_width, T_Storage>& lhs, \
597 const Simd<T_Type, T_width, T_OtherStorage>& rhs) \
599 using StoreageType = ALPAKA_TYPEOF(lhs.asStorage() op rhs.asStorage()); \
600 return SimdMask<T_Type, T_width, StoreageType>(lhs.asStorage() op rhs.asStorage()); \
603 typenameOrConcept T_Type, \
604 concepts::LosslesslyConvertible<T_Type> T_ValueType, \
606 typename T_Storage> \
607 constexpr auto operator op(const Simd<T_Type, T_width, T_Storage>& lhs, T_ValueType rhs) \
609 using StoreageType = ALPAKA_TYPEOF(lhs.asStorage() op static_cast<T_Type>(rhs)); \
610 return SimdMask<T_Type, T_width, StoreageType>(lhs.asStorage() op static_cast<T_Type>(rhs)); \
613 typenameOrConcept T_Type, \
614 concepts::LosslesslyConvertible<T_Type> T_ValueType, \
616 typename T_Storage> \
617 constexpr auto operator op(T_ValueType lhs, const Simd<T_Type, T_width, T_Storage>& rhs) \
619 using StoreageType = ALPAKA_TYPEOF(static_cast<T_Type>(lhs) op rhs.asStorage()); \
620 return SimdMask<T_Type, T_width, StoreageType>(static_cast<T_Type>(lhs) op rhs.asStorage()); \
630#undef ALPAKA_VECTOR_BINARY_CMP_OP
637 template<
typename T_Type, u
int32_t T_w
idth,
typename T_Storage>
640 static constexpr uint32_t
value = T_width;
643 template<
typename T_Type, u
int32_t T_w
idth,
typename T_Storage>
652 template<
typename T_To,
typename T_Type, u
int32_t T_w
idth,
typename T_Storage>
653 struct PCast::Op<T_To,
alpaka::
Simd<T_Type, T_width, T_Storage>>
655 constexpr auto operator()(
auto&& input)
const
656 requires std::convertible_to<T_Type, T_To> && (!std::same_as<T_To, T_Type>)
659 [&](uint32_t idx)
constexpr {
return static_cast<T_To
>(input[idx]); });
662 constexpr decltype(
auto)
operator()(
auto&& input)
const requires std::same_as<T_To, T_Type>
664 return std::forward<decltype(input)>(input);
672 template<
typename T_Type, u
int32_t T_w
idth,
typename T_Storage>
673 struct tuple_size<
alpaka::
Simd<T_Type, T_width, T_Storage>>
675 static constexpr std::size_t value = T_width;
678 template<std::
size_t I,
typename T_Type, u
int32_t T_w
idth,
typename T_Storage>
679 struct tuple_element<I,
alpaka::
Simd<T_Type, T_width, T_Storage>>
#define ALPAKA_NAMED_ARRAY_ACCESS(functionName, laneIdx)
#define ALPAKA_VECTOR_BINARY_CMP_OP(typenameOrConcept, op)
binary operators
#define ALPAKA_VECTOR_ASSIGN_OP(op)
assign operator
#define ALPAKA_VECTOR_BINARY_OP(typenameOrConcept, op)
binary operators
#define ALPAKA_FN_HOST_ACC
All functions that can be used on an accelerator have to be attributed with ALPAKA_FN_ACC or ALPAKA_F...
#define ALPAKA_FORWARD(instance)
Perfectly forward an instance as argument.
Concept to check for an alignment object.
std::ostream & operator<<(std::ostream &os, concepts::BoundaryDirection auto const &bd)
constexpr auto thisApi()
provides the API used during the execution of the current code path
constexpr decltype(auto) get(concepts::SpecializationOf< Dict > auto &t) noexcept
ALPAKA_FN_HOST_ACC Simd(T_1, T_Args...) -> Simd< T_1, uint32_t(sizeof...(T_Args)+1u)>
Simd< T_Type, T_width > UniSimd
std::string toString(std::string const separator=",", std::string const enclosings="{}") const
create string out of the SIMD pack
constexpr Simd< type, T_numElements > rshrink(std::integral auto const startIdx) const
Shrink the number of elements of a vector.
constexpr auto reduce(auto &&reduceFunc) const -> decltype(reduceFunc(std::declval< type >(), std::declval< type >()))
ALPAKA_FN_HOST_ACC Simd(F &&generator)
Initialize via a generator expression.
static consteval uint32_t width()
Number of components/lanes in the SIMD pack.
constexpr Simd< type, T_width - 1u > remove() const
Removes a component.
constexpr Simd & operator=(Simd &&)=default
constexpr auto & asStorage()
static cast the instance to the storage type
friend struct SimdWhereExpr
constexpr Simd(Simd const &other)=default
constexpr Simd toRT() const
static constexpr auto fill(concepts::Convertible< T_Type > auto value)
Creates a Simd where all lanes are set to the same value.
constexpr Simd< T_Type, T_width - 1u > eraseBack() const
Shrink the SIMD pack.
constexpr Simd< T_Type, T_numElements > rshrink() const
Shrink the number of elements of a vector.
constexpr type product() const
Returns product of all components.
constexpr auto min(Simd< T_Type, T_width, T_OtherStorage > const &rhs) const
constexpr type operator[](std::integral auto const idx) const
access a lane by index
constexpr auto const & asStorage() const
static cast the instance to the storage type
constexpr type sum() const
Returns sum of all components.
constexpr Simd(T_Storage const &other)
constexpr reference operator[](std::integral auto const idx)
access a lane by index
constexpr void copyTo(auto *data, concepts::Alignment auto alignment) const
constexpr Simd & operator=(Simd const &)=default
typename T_Storage::value_type type
typename T_Storage::reference reference
type is an implementation detail, can be a proxy type.
ALPAKA_FN_HOST_ACC Simd(T_Args const &... args)
Constructor for SIMD pack.
constexpr Simd operator-() const
constexpr Simd revert() const
constexpr void copyFrom(T_Type const *data, concepts::Alignment auto alignment)
constexpr Simd(Simd< T_Type, T_width, T_OtherStorage > const &other)
constructor allows changing the storage policy
static constexpr uint32_t value