35 template<
typename T_Type, u
int32_t T_w
idth>
36 struct alignas(alpaka::internal::optimalAlignment<T_Type, T_width, Alignment<sizeof(T_Type) * T_width>>())
37 EmuSimd :
protected std::array<T_Type, T_width>
39 using BaseType = std::array<T_Type, T_width>;
41 using value_type =
typename BaseType::value_type;
42 using reference =
typename BaseType::reference;
44 using BaseType::operator[];
46 constexpr EmuSimd() =
default;
48 constexpr EmuSimd(EmuSimd
const& other)
51 for(uint32_t i = 0u; i < T_width; ++i)
52 BaseType::operator[](i) = other[i];
55 constexpr EmuSimd(EmuSimd&&) =
default;
56 constexpr EmuSimd& operator=(EmuSimd&& rhs) =
default;
58 constexpr EmuSimd& operator=(EmuSimd
const& rhs) =
default;
60 constexpr EmuSimd& operator=(T_Type
const value)
62 for(uint32_t i = 0u; i < T_width; i++)
64 asNativeType()[i] = value;
70 template<
typename... T_Args>
71 requires(
sizeof...(T_Args) == T_width && (std::same_as<T_Args, T_Type> && ...))
72 constexpr EmuSimd(T_Args&&... args) : BaseType{std::forward<T_Args>(args)...}
76 constexpr EmuSimd(BaseType
const& base) : BaseType{base}
85 constexpr auto& asNativeType()
87 return static_cast<EmuSimd&
>(*this);
90 constexpr auto const& asNativeType()
const
92 return static_cast<EmuSimd const&
>(*this);
97 static constexpr auto fill(T_Type value)
99 return EmuSimd([&value](uint32_t
const) {
return value; });
103 requires(std::is_invocable_v<F, std::integral_constant<uint32_t, 0u>>)
104 constexpr explicit EmuSimd(F&& generator)
105 : EmuSimd(std::forward<F>(generator), std::make_integer_sequence<uint32_t, T_width>{})
109 constexpr void copyFrom(T_Type
const* data, alpaka::concepts::Alignment
auto alignment)
112 *(
this) = *
reinterpret_cast<ALPAKA_TYPEOF(*this) const*
>(data);
115 for(uint32_t i = 0u; i < T_width; ++i)
116 asNativeType()[i] =
data[i];
120 constexpr void copyTo(
auto* data, alpaka::concepts::Alignment
auto alignment)
const
126 for(uint32_t i = 0u; i < T_width; ++i)
127 data[i] = asNativeType()[i];
131 template<alpaka::concepts::SimdMask Mask, alpaka::concepts::Simd T_Simd>
132 friend struct SimdWhereExpr;
135 constexpr void update(alpaka::concepts::SimdMask
auto const& mask, alpaka::concepts::Simd
auto const& t)
138 if constexpr(std::same_as<MaskType, bool>)
140 for(uint32_t i = 0u; i < T_width; ++i)
141 asNativeType()[i] = (mask[i] ? t[i] : asNativeType()[i]);
145 for(uint32_t i = 0u; i < T_width; ++i)
146 asNativeType()[i] = std::bit_cast<T_Type>(
147 (mask.asNativeType()[i] & std::bit_cast<MaskType>(t[i]))
148 | (~mask.asNativeType()[i] & std::bit_cast<MaskType>(asNativeType()[i])));
153 constexpr void update(alpaka::concepts::SimdMask
auto const& mask, T_Type
const& t)
156 if constexpr(std::same_as<MaskType, bool>)
158 for(uint32_t i = 0u; i < T_width; ++i)
159 asNativeType()[i] = (mask[i] ? t : asNativeType()[i]);
163 for(uint32_t i = 0u; i < T_width; ++i)
164 asNativeType()[i] = std::bit_cast<T_Type>(
165 (mask.asNativeType()[i] & std::bit_cast<MaskType>(t))
166 | (~mask.asNativeType()[i] & std::bit_cast<MaskType>(asNativeType()[i])));
172#define ALPAKA_VECTOR_ASSIGN_OP(op) \
173 constexpr EmuSimd& operator op(EmuSimd const& rhs) \
175 for(uint32_t i = 0u; i < T_width; i++) \
177 asNativeType()[i] op rhs[i]; \
181 constexpr EmuSimd& operator op(T_Type const value) \
183 for(uint32_t i = 0u; i < T_width; i++) \
185 asNativeType()[i] op value; \
195#undef ALPAKA_VECTOR_ASSIGN_OP
198 template<
typename F, uint32_t... Is>
199 constexpr explicit EmuSimd(F&& generator, std::integer_sequence<uint32_t, Is...>)
200 : BaseType{generator(
std::integral_constant<uint32_t, Is>{})...}
205#define ALPAKA_VECTOR_BINARY_OP(typenameOrConcept, op) \
206 template<typenameOrConcept T_Type, uint32_t T_width> \
207 constexpr auto operator op(const EmuSimd<T_Type, T_width>& lhs, const EmuSimd<T_Type, T_width>& rhs) \
209 EmuSimd<T_Type, T_width> ret{}; \
210 for(uint32_t i = 0u; i < T_width; i++) \
211 ret[i] = lhs[i] op rhs[i]; \
214 template<typenameOrConcept T_Type, uint32_t T_width> \
215 constexpr auto operator op(const EmuSimd<T_Type, T_width>& lhs, T_Type rhs) \
217 EmuSimd<T_Type, T_width> ret{}; \
218 for(uint32_t i = 0u; i < T_width; i++) \
219 ret[i] = lhs[i] op rhs; \
222 template<typenameOrConcept T_Type, uint32_t T_width> \
223 constexpr auto operator op(T_Type lhs, const EmuSimd<T_Type, T_width>& rhs) \
225 EmuSimd<T_Type, T_width> ret{}; \
226 for(uint32_t i = 0u; i < T_width; i++) \
227 ret[i] = lhs op rhs[i]; \
242#undef ALPAKA_VECTOR_BINARY_OP
248 template<concepts::Api T_Api,
typename T_Type, u
int32_t T_w
idth>
251 using type = internal::EmuSimd<T_Type, T_width>;
#define ALPAKA_VECTOR_ASSIGN_OP(op)
assign operator
#define ALPAKA_VECTOR_BINARY_OP(typenameOrConcept, op)
binary operators
#define ALPAKA_TYPEOF(...)
Get the type of instance.
decltype(auto) data(auto &&any)
pointer to data of an object
constexpr decltype(auto) get(concepts::SpecializationOf< Dict > auto &t) noexcept
Get the storage type for a SIMD pack.
internal::EmuSimd< T_Type, T_width > type