53 template<
typename T,
typename T_ValueType = alpaka::NotRequired, u
int32_t T_dim = alpaka::notRequiredDim>
55 && (std::same_as<T_ValueType, trait::GetValueType_t<std::decay_t<T>>>
56 || std::same_as<T_ValueType, alpaka::NotRequired>)
64 template<
typename T,
typename T_ValueType = alpaka::NotRequired>
67 || std::same_as<T_ValueType, alpaka::NotRequired>);
74 template<
typename T,
typename T_ValueType = alpaka::NotRequired>
76 && (std::same_as<T_ValueType, trait::GetValueType_t<std::decay_t<T>>>
77 || std::same_as<T_ValueType, alpaka::NotRequired>);
84 template<
typename T,
typename T_RequiredComponent>
87 template<
typename T,
typename T_RequiredComponent>
97 template<
typename T_Type, u
int32_t T_dim>
102 using BaseType::operator[];
105 template<
typename... T_Args>
117 template<
typename T, T... T_values>
122 static consteval uint32_t dim()
124 return sizeof...(T_values);
127 constexpr T
operator[](std::integral
auto const idx)
const
130 T result = std::get<0>(std::forward_as_tuple(T_values...));
132 if constexpr(
dim() > 1u)
134 [[maybe_unused]]
bool _ = std::apply(
135 [idx, &result](
auto&&,
auto&&... values)
constexpr
139 return ((idx == i++ && (result = values,
true)) || ...);
141 std::forward_as_tuple(T_values...));
147 static constexpr auto fill()
149 using IotaSeq = std::make_integer_sequence<T,
dim()>;
150 return integerSequenceToCVec(IotaSeq{}, [](
auto&&)
constexpr {
return T_value; });
154 template<T... T_indices>
155 static constexpr auto integerSequenceToCVec(
156 std::integer_sequence<T, T_indices...>,
157 auto const op = std::identity{})
159 return CVec<T, op(T_indices)...>{};
164 struct TemplateSignatureStorage : std::false_type
168 template<
typename T_Type, T_Type... T_values>
169 struct TemplateSignatureStorage<CVec<T_Type, T_values...>> : std::true_type
174 constexpr bool TemplateSignatureStorage_v = TemplateSignatureStorage<T>::value;
177 template<
typename T_Type, u
int32_t T_dim,
typename T_Storage = alpaka::ArrayStorage<T_Type, T_dim>>
178 struct Vec :
private T_Storage
192 static_assert(T_dim > 0u);
194 constexpr Vec() =
default;
203 std::enable_if_t<std::is_invocable_v<F, std::integral_constant<uint32_t, 0u>>, uint32_t> = 0u>
204 constexpr explicit Vec(F&& generator)
205 :
Vec(
std::forward<F>(generator),
std::make_integer_sequence<uint32_t, T_dim>{})
210 template<
typename F, uint32_t... Is>
211 constexpr explicit Vec(F&& generator, std::integer_sequence<uint32_t, Is...>)
212 :
Storage{generator(
std::integral_constant<uint32_t, Is>{})...}
233 template<
typename... T_Args>
234 requires(std::is_convertible_v<T_Args, T_Type> && ...)
235 constexpr
Vec(T_Args const&... args) :
Storage(static_cast<T_Type>(args)...)
239 constexpr Vec(
Vec const& other) =
default;
241 constexpr Vec(T_Storage
const& other) : T_Storage{other}
247 template<
typename T_OtherStorage>
249 :
Vec([&](uint32_t const i) constexpr { return other[i]; })
254 template<uint32_t T_deferDim = T_dim, typename = typename std::enable_if<T_deferDim == 1u>::type>
255 constexpr explicit operator type()
260 static consteval uint32_t
dim()
273 if constexpr(
requires { detail::TemplateSignatureStorage_v<T_Storage>; })
275 return UniVec([=](uint32_t
const) {
return static_cast<T_Type
>(value); });
279 return Vec([=](uint32_t
const) {
return static_cast<T_Type
>(value); });
285 static constexpr auto fill()
requires requires { T_Storage::template
fill<T_v>(); }
299 for(uint32_t i = 0u; i < T_dim; i++)
300 invertedVec[T_dim - 1 - i] = (*
this)[i];
310 return Vec([
this](uint32_t
const i)
constexpr {
return -(*this)[i]; });
313#define ALPAKA_VECTOR_ASSIGN_OP(op) \
314 template<typename T_OtherStorage> \
315 constexpr Vec& operator op(Vec<T_Type, T_dim, T_OtherStorage> const& rhs) \
317 for(uint32_t i = 0u; i < T_dim; i++) \
319 if constexpr(requires { unWrapp((*this)[i]) op rhs[i]; }) \
321 unWrapp((*this)[i]) op rhs[i]; \
325 (*this)[i] op rhs[i]; \
330 constexpr Vec& operator op(concepts::LosslesslyConvertible<T_Type> auto const value) \
332 for(uint32_t i = 0u; i < T_dim; i++) \
334 if constexpr(requires { unWrapp((*this)[i]) op value; }) \
336 unWrapp((*this)[i]) op value; \
340 (*this)[i] op value; \
356#undef ALPAKA_VECTOR_ASSIGN_OP
358 constexpr decltype(
auto)
operator[](std::integral
auto const idx)
360 return Storage::operator[](idx);
363 constexpr decltype(
auto)
operator[](std::integral
auto const idx)
const
365 return Storage::operator[](idx);
368#define ALPAKA_NAMED_ARRAY_ACCESS(functionName, indexPos) \
373 constexpr decltype(auto) functionName() requires((indexPos) < T_dim) \
375 return (*this)[indexPos]; \
377 constexpr decltype(auto) functionName() const requires((indexPos) < T_dim) \
379 return (*this)[indexPos]; \
393#undef ALPAKA_NAMED_ARRAY_ACCESS
395 constexpr decltype(
auto)
back()
397 return (*
this)[T_dim - 1u];
400 constexpr decltype(
auto) back()
const
402 return (*
this)[T_dim - 1u];
412 template<u
int32_t T_numElements>
415 static_assert(T_numElements <= T_dim);
417 for(uint32_t i = 0u; i < T_numElements; i++)
418 result[T_numElements - 1u - i] = (*
this)[T_dim - 1u - i];
427 constexpr Vec<T_Type, T_dim - 1u>
eraseBack() const requires(T_dim > 1u)
429 constexpr auto reducedDim = T_dim - 1u;
431 for(uint32_t i = 0u; i < reducedDim; i++)
432 result[i] = (*this)[i];
444 template<u
int32_t T_numElements>
447 static_assert(T_numElements <= T_dim);
449 for(uint32_t i = 0u; i < T_numElements; i++)
450 result[T_numElements - 1u - i] = (*
this)[(T_dim + startIdx - i) % T_dim];
460 template<u
int32_t T_elementIdx = 0>
464 result[T_elementIdx] = value;
480 result.ref(selection) = value;
490 template<uint32_t T_elementIdx = T_dim - 1u>
494 result[T_elementIdx] = value;
505 template<std::
integral auto dimToRemove>
506 constexpr Vec<
type, T_dim - 1u>
remove() const requires(T_dim >= 2u)
508 Vec<
type, T_dim - 1u> result{};
509 for(
int i = 0u; i < static_cast<int>(T_dim - 1u); ++i)
512 int const sourceIdx = i >=
static_cast<int>(dimToRemove) ? i + 1 : i;
513 result[i] = (*this)[sourceIdx];
524 type result = (*this)[0];
525 for(uint32_t i = 1u; i < T_dim; i++)
526 result *= (*
this)[i];
536 type result = (*this)[0];
537 for(uint32_t i = 1u; i < T_dim; i++)
538 result += (*
this)[i];
550 template<
typename T_OtherStorage>
554 for(uint32_t i = 0u; i < T_dim; i++)
555 result = result && ((*
this)[i] == rhs[i]);
567 template<
typename T_OtherStorage>
570 return !((*this) == rhs);
573 template<
typename T_OtherStorage>
577 for(uint32_t d = 0u; d < T_dim; d++)
578 result[d] = std::min((*
this)[d], rhs[d]);
595 std::string
toString(std::string
const separator =
",", std::string
const enclosings =
"{}")
const
597 std::string locale_enclosing_begin;
598 std::string locale_enclosing_end;
599 size_t enclosing_dim = enclosings.size();
601 if(enclosing_dim > 0)
604 locale_enclosing_begin = enclosings[0 % enclosing_dim];
605 locale_enclosing_end = enclosings[1 % enclosing_dim];
608 std::stringstream stream;
609 stream << locale_enclosing_begin << (*this)[0];
611 for(uint32_t i = 1u; i < T_dim; ++i)
612 stream << separator << (*
this)[i];
613 stream << locale_enclosing_end;
618 template<
typename T, T... T_values>
619 constexpr auto operator[](
Vec<T,
sizeof...(T_values), detail::CVec<T, T_values...>>
const v)
const
622 return Vec<T_Type, InType::dim()>{(*this)[T_values]...};
625 template<
typename T, T... T_values>
626 constexpr auto ref(
Vec<T,
sizeof...(T_values), detail::CVec<T, T_values...>>
const v)
629 using ArrayType = std::array<
ALPAKA_TYPEOF(std::ref((*
this)[T{0}])),
sizeof...(T_values)>;
630 auto array = ArrayType{std::ref((*
this)[T_values])...};
634 template<
typename T, T... T_values>
635 constexpr auto ref(
Vec<T,
sizeof...(T_values), detail::CVec<T, T_values...>>
const v)
const
638 using ArrayType = std::array<
ALPAKA_TYPEOF(std::ref((*
this)[T{0}])),
sizeof...(T_values)>;
639 auto array = ArrayType{std::ref((*
this)[T_values])...};
651 [[nodiscard]]
constexpr auto reduce(
auto&& reduceFunc)
const
652 ->
decltype(reduceFunc(std::declval<type>(), std::declval<type>()))
665 template<u
int32_t T_start = 0u, u
int32_t T_end = dim()>
666 [[nodiscard]]
constexpr auto reduce_range(
auto&& reduceFunc)
const
667 ->
decltype(reduceFunc(std::declval<type>(), std::declval<type>()))
670 constexpr uint32_t size = T_end - T_start;
672 if constexpr(size == 1u)
674 return (*
this)[T_start];
678 auto result = (*this)[T_start];
679 for(uint32_t i = T_start + 1u; i < T_end; ++i)
681 result = reduceFunc(result, (*
this)[i]);
686 constexpr uint32_t mid = T_start + size / 2u;
696 template<std::
size_t I,
typename T_Type, u
int32_t T_dim,
typename T_Storage>
697 constexpr auto get(Vec<T_Type, T_dim, T_Storage>
const& v)
702 template<std::
size_t I,
typename T_Type, u
int32_t T_dim,
typename T_Storage>
703 constexpr decltype(
auto) get(Vec<T_Type, T_dim, T_Storage>& v)
708 template<
typename Type>
712 static constexpr uint32_t
T_dim = 0;
714 template<
typename OtherType>
740 static constexpr Vec create(Type)
745 static_assert(
sizeof(Type) != 0 &&
false);
750 template<
typename T_1,
typename... T_Args>
752 ->
Vec<T_1, uint32_t(
sizeof...(T_Args) + 1u),
ArrayStorage<T_1, uint32_t(
sizeof...(T_Args) + 1u)>>;
754 template<
typename Type, u
int32_t T_dim,
typename T_Storage>
766#define ALPAKA_VECTOR_BINARY_OP(typenameOrConcept, resultScalarType, op) \
767 template<typenameOrConcept T_Type, uint32_t T_dim, typename T_Storage, typename T_OtherStorage> \
768 constexpr auto operator op( \
769 const Vec<T_Type, T_dim, T_Storage>& lhs, \
770 const Vec<T_Type, T_dim, T_OtherStorage>& rhs) \
775 Vec<resultScalarType, T_dim> result{}; \
776 for(uint32_t i = 0u; i < T_dim; i++) \
777 result[i] = lhs[i] op rhs[i]; \
782 typenameOrConcept T_Type, \
783 concepts::LosslesslyConvertible<T_Type> T_ValueType, \
785 typename T_Storage> \
786 constexpr auto operator op(const Vec<T_Type, T_dim, T_Storage>& lhs, T_ValueType rhs) \
791 Vec<resultScalarType, T_dim> result{}; \
792 for(uint32_t i = 0u; i < T_dim; i++) \
793 result[i] = lhs[i] op rhs; \
797 typenameOrConcept T_Type, \
798 concepts::LosslesslyConvertible<T_Type> T_ValueType, \
800 typename T_Storage> \
801 constexpr auto operator op(T_ValueType lhs, const Vec<T_Type, T_dim, T_Storage>& rhs) \
806 Vec<resultScalarType, T_dim> result{}; \
807 for(uint32_t i = 0u; i < T_dim; i++) \
808 result[i] = lhs op rhs[i]; \
833#undef ALPAKA_VECTOR_BINARY_OP
847 template<std::
integral T_IntegralType,
typename T_Storage,
typename T_OtherStorage, u
int32_t T_dim>
852 T_IntegralType linearIdx{idx[0]};
853 for(uint32_t d = 1u; d < T_dim; ++d)
854 linearIdx = linearIdx * dim[d - 1u] + idx[d];
859 template<std::
integral T_IntegralType,
typename T_Storage,
typename T_OtherStorage, u
int32_t T_dim>
864 return linearize(dim.template rshrink<T_dim - 1u>(), idx);
867 template<std::
integral T_IntegralType,
typename T_Storage,
typename T_OtherStorage>
869 Vec<T_IntegralType, 1u, T_Storage>
const&,
870 Vec<T_IntegralType, 1u, T_OtherStorage>
const& idx)
888 template<std::
integral T_IntegralType,
typename T_Storage, u
int32_t T_dim>
891 T_IntegralType linearIdx)
requires(T_dim >= 2u)
893 constexpr uint32_t reducedDim = T_dim - 1u;
895 pitchExtents.
back() = extents.back();
896 for(uint32_t d = 1u; d < T_dim - 1u; ++d)
897 pitchExtents[reducedDim - 1u - d] = extents[T_dim - 1u - d] * pitchExtents[reducedDim - d];
900 for(uint32_t d = 0u; d < T_dim - 1u; ++d)
902 result[d] = linearIdx / pitchExtents[d];
903 linearIdx -= pitchExtents[d] * result[d];
905 result[T_dim - 1u] = linearIdx;
909 template<std::
integral T_IntegralType,
typename T_Storage>
910 constexpr Vec<T_IntegralType, 1u>
mapToND(
911 Vec<T_IntegralType, 1u, T_Storage>
const& extents,
912 T_IntegralType linearIdx)
914 alpaka::unused(extents);
922 template<
typename T_Type, u
int32_t T_dim,
typename T_Storage>
923 struct IsVector<
Vec<T_Type, T_dim, T_Storage>> : std::true_type
927 template<
typename T_Type, uint32_t T_dim, T_Type... T_values>
928 struct IsCVector<
Vec<T_Type, T_dim, detail::
CVec<T_Type, T_values...>>> : std::true_type
935 template<
typename T_Type, u
int32_t T_dim,
typename T_Storage>
938 static constexpr uint32_t value = T_dim;
944 template<std::
integral T>
950 template<
typename T_Type, u
int32_t T_dim,
typename T_Storage>
959 template<
typename T_Type, u
int32_t T_dim,
typename T_Storage>
960 struct GetValueType<
Vec<T_Type, T_dim, T_Storage>>
968 consteval auto getVec(T
const& any)
970 return trait::getVec_t<T>{
any};
975 template<
typename T_To,
typename T_Type, u
int32_t T_dim,
typename T_Storage>
976 struct PCast::Op<T_To,
alpaka::
Vec<T_Type, T_dim, T_Storage>>
978 constexpr auto operator()(
auto&& input)
const
979 requires std::convertible_to<T_Type, T_To> && (!std::same_as<T_To, T_Type>)
982 {
return static_cast<T_To
>(input[idx]); });
985 constexpr decltype(
auto)
operator()(
auto&& input)
const requires std::same_as<T_To, T_Type>
987 return std::forward<decltype(input)>(input);
995 template<concepts::Vector T_Vector0, concepts::Vector T_Vector1>
999 return (a + b - T_Vector0::fill(1)) / b;
1002 template<concepts::Vector T_Vector0, concepts::Vector T_Vector1>
1003 requires(std::is_same_v<trait::GetValueType_t<T_Vector0>, trait::GetValueType_t<T_Vector1>>)
1004 [[nodiscard]]
ALPAKA_FN_HOST_ACC constexpr concepts::Vector
auto divExZero(T_Vector0 a, T_Vector1 b)
1009 for(uint32_t d = 0u; d < a.dim(); ++d)
1010 tmp[d] = std::max(tmp[d], ValueType{1u});
1017 template<
typename T_Type, u
int32_t T_dim,
typename T_Storage>
1018 struct tuple_size<
alpaka::
Vec<T_Type, T_dim, T_Storage>>
1020 static constexpr std::size_t value = T_dim;
1023 template<std::
size_t I,
typename T_Type, u
int32_t T_dim,
typename T_Storage>
1024 struct tuple_element<I,
alpaka::
Vec<T_Type, T_dim, T_Storage>>
1026 using type = T_Type;
#define ALPAKA_NAMED_ARRAY_ACCESS(functionName, laneIdx)
#define ALPAKA_VECTOR_ASSIGN_OP(op)
assign operator
#define ALPAKA_VECTOR_BINARY_OP(typenameOrConcept, op)
binary operators
#define ALPAKA_VECTOR_BINARY_OP(typenameOrConcept, resultScalarType, op)
#define ALPAKA_NAMED_ARRAY_ACCESS(functionName, indexPos)
#define ALPAKA_VECTOR_ASSIGN_OP(op)
#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_TYPEOF(...)
Get the type of instance.
#define ALPAKA_FORWARD(instance)
Perfectly forward an instance as argument.
Concept to check if a type is a CVector.
Concept to check if a type is a vector or a specific other type.
Concept to check if a type is a vector or scalar variable.
Concept to check if a type is a vector.
constexpr bool any(alpaka::onAcc::concepts::Acc auto const &acc, int32_t predicate)
Evaluates predicate for all active threads of the warp.
typename GetVec< T >::type getVec_t
typename GetValueType< T >::type GetValueType_t
constexpr uint32_t notRequiredDim
ALPAKA_FN_HOST_ACC constexpr auto divCeil(Integral a, Integral b) -> Integral
Returns the ceiling of a / b, as integer.
std::ostream & operator<<(std::ostream &os, concepts::BoundaryDirection auto const &bd)
constexpr T_IntegralType linearize(Vec< T_IntegralType, T_dim - 1u, T_Storage > const &dim, Vec< T_IntegralType, T_dim, T_OtherStorage > const &idx)
Give the linear index of an N-dimensional index within an N-dimensional index space.
Vec< T, sizeof...(T_values), detail::CVec< T, T_values... > > CVec
A vector with compile-time known values.
ALPAKA_FN_HOST_ACC Vec(T_1, T_Args...) -> Vec< T_1, uint32_t(sizeof...(T_Args)+1u), ArrayStorage< T_1, uint32_t(sizeof...(T_Args)+1u)> >
constexpr bool isVector_v
constexpr bool isConvertible_v
consteval auto getVec(T const &any)
constexpr bool isCVector_v
constexpr Vec< T_IntegralType, T_dim > mapToND(Vec< T_IntegralType, T_dim, T_Storage > const &extents, T_IntegralType linearIdx)
Maps a linear index to an N-dimensional index.
Array storge for vector data.
constexpr ArrayStorage(std::array< T_Type, T_dim > const &data)
constexpr ArrayStorage(T_Args &&... args)
std::array< T_Type, T_dim > BaseType
static constexpr uint32_t T_dim
constexpr bool operator==(Vec const &) const
== comparison operator.
constexpr bool operator!=(Vec const &) const
!= comparison operator.
constexpr Vec operator-() const
constexpr decltype(auto) y()
constexpr Vec< type, T_dim - 1u > remove() const
constexpr Vec(T_Storage const &other)
constexpr decltype(auto) z()
static constexpr auto fill(concepts::Convertible< T > auto const &value)
constexpr Vec(F &&generator)
Initialize via a generator expression.
static consteval uint32_t dim()
constexpr decltype(auto) back()
constexpr Vec revert() const
constexpr bool operator==(Vec< BoundaryType, T_dim, T_OtherStorage > const &rhs) const
constexpr type sum() const
alpaka::ArrayStorage< BoundaryType, T_dim > Storage
constexpr Vec< BoundaryType, T_dim > assign(BoundaryType const &value) const
constexpr Vec toRT() const
constexpr Vec< BoundaryType, T_numElements > rshrink() const
constexpr type product() const
constexpr Vec & operator=(Vec const &)=default
constexpr decltype(auto) w()
constexpr Vec< BoundaryType, T_dim - 1u > eraseBack() const
std::string toString(std::string const separator=",", std::string const enclosings="{}") const
constexpr Vec(Vec< T_Type, T_dim, T_OtherStorage > const &other)
constructor allows changing the storage policy
static constexpr auto fill()
constexpr bool operator!=(Vec< BoundaryType, T_dim, T_OtherStorage > const &rhs) const
Vec< BoundaryType, T_dim > UniVec
constexpr auto reduce(auto &&reduceFunc) const -> decltype(reduceFunc(std::declval< type >(), std::declval< type >()))
constexpr decltype(auto) operator[](std::integral auto const idx)
constexpr decltype(auto) x()
constexpr Vec< BoundaryType, T_dim > rAssign(BoundaryType const &value) const
constexpr Vec & operator=(Vec &&)=default
constexpr Vec(Vec const &other)=default
alpaka::Vec< T_Type, T_dim, T_Storage > type