|
ATLAS Offline Software
|
Go to the documentation of this file.
128 #ifndef CXXUTILS_VEC_H
129 #define CXXUTILS_VEC_H
135 #include <type_traits>
142 #ifndef WANT_VECTOR_FALLBACK
143 # define WANT_VECTOR_FALLBACK 0
146 #if (!HAVE_VECTOR_SIZE_ATTRIBUTE) || WANT_VECTOR_FALLBACK!=0
148 #endif // !HAVE_VECTOR_SIZE_ATTRIBUTE || WANT_VECTOR_FALLBACK
152 namespace vecDetail {
158 template <
typename T,
size_t N>
160 static_assert((
N & (
N - 1)) == 0,
"N must be a power of 2.");
161 static_assert(std::is_arithmetic_v<T>,
"T not an arithmetic type");
163 #if HAVE_VECTOR_SIZE_ATTRIBUTE
175 static auto elt(
const VEC&
v) -> decltype(
v[0]);
177 typedef std::remove_cv_t<std::remove_reference_t<type1>>
type;
186 static auto maskt(
const VEC& v1,
const VEC&
v2) -> decltype(v1 <
v2);
188 typedef std::remove_cv_t<std::remove_reference_t<type1>>
type;
194 namespace bool_pack_helper {
197 template <
bool... bs>
206 template <
typename T,
size_t N>
230 return sizeof(VEC) /
sizeof(ELT);
242 return sizeof(VEC) /
sizeof(ELT);
248 template<
typename VEC,
typename T>
253 #if !HAVE_VECTOR_SIZE_ATTRIBUTE || WANT_VECTOR_FALLBACK
254 constexpr
size_t N = CxxUtils::vec_size<VEC>();
255 for (
size_t i = 0;
i <
N; ++
i) {
269 template<
typename VEC>
275 #if !HAVE_VECTOR_SIZE_ATTRIBUTE || WANT_VECTOR_FALLBACK
276 std::memcpy(dst.m_arr,
src,
sizeof(VEC));
278 std::memcpy(&dst,
src,
sizeof(VEC));
287 template<
typename VEC>
292 #if !HAVE_VECTOR_SIZE_ATTRIBUTE || WANT_VECTOR_FALLBACK
293 std::memcpy(dst,
src.m_arr,
sizeof(VEC));
295 std::memcpy(dst, &
src,
sizeof(VEC));
304 template <
typename VEC>
307 #if !HAVE_VECTOR_SIZE_ATTRIBUTE || WANT_VECTOR_FALLBACK
308 constexpr
size_t N = vec_size<VEC>();
309 for (
size_t i = 0;
i <
N; ++
i) {
321 template<
typename VEC>
324 vmin(VEC& dst,
const VEC&
a,
const VEC&
b)
326 #if !HAVE_VECTOR_SIZE_ATTRIBUTE || WANT_VECTOR_FALLBACK
327 constexpr
size_t N = vec_size<VEC>();
328 for (
size_t i = 0;
i <
N; ++
i) {
340 template<
typename VEC>
343 vmax(VEC& dst,
const VEC&
a,
const VEC&
b)
345 #if !HAVE_VECTOR_SIZE_ATTRIBUTE || WANT_VECTOR_FALLBACK
346 constexpr
size_t N = vec_size<VEC>();
347 for (
size_t i = 0;
i <
N; ++
i) {
359 template<
typename VEC>
364 "vec elements must be of integral type. Aka vec must be "
365 "compatible with a mask");
368 #if !HAVE_VECTOR_SIZE_ATTRIBUTE || WANT_VECTOR_FALLBACK
369 return std::memcmp(
mask.m_arr,
zero.m_arr,
sizeof(VEC)) != 0;
371 return std::memcmp(&
mask, &
zero,
sizeof(VEC)) != 0;
379 template<
typename VEC>
384 "vec elements must be of integral type. Aka vec must be "
385 "compatible with a mask");
388 #if !HAVE_VECTOR_SIZE_ATTRIBUTE || WANT_VECTOR_FALLBACK
389 return std::memcmp(
mask.m_arr,
zero.m_arr,
sizeof(VEC)) == 0;
391 return std::memcmp(&
mask, &
zero,
sizeof(VEC)) == 0;
399 template<
typename VEC>
404 "vec elements must be of integral type. Aka vec must be "
405 "compatible with a mask");
407 #if !HAVE_VECTOR_SIZE_ATTRIBUTE || WANT_VECTOR_FALLBACK
411 return std::memcmp(
mask.m_arr, alltrue.m_arr,
sizeof(VEC)) == 0;
417 return std::memcmp(&
mask, &alltrue,
sizeof(VEC)) == 0;
425 template<
typename VEC1,
typename VEC2>
430 static_assert((vec_size<VEC1>() == vec_size<VEC2>()),
431 "vconvert dst and src have different number of elements");
433 #if !HAVE_CONVERT_VECTOR || WANT_VECTOR_FALLBACK
435 constexpr
size_t N = vec_size<VEC1>();
436 for (
size_t i = 0;
i <
N; ++
i) {
437 dst[
i] =
static_cast<ELT
>(
src[
i]);
440 dst = __builtin_convertvector(
src, VEC1);
449 template<
size_t... Indices,
typename VEC,
typename VEC1>
454 static_assert((
sizeof...(Indices) == vec_size<VEC1>()),
455 "vpermute number of indices different than return vector size");
457 "vpermute type of input and output vector elements differ");
459 Indices >= 0 && Indices < vec_size<VEC>())...>::
value,
460 "vpermute value of a mask index is outside the allowed range");
462 #if !HAVE_VECTOR_SIZE_ATTRIBUTE || WANT_VECTOR_FALLBACK
463 dst = VEC1{
src[Indices]... };
465 dst = __builtin_shufflevector(
src,
src, Indices...);
474 template<
size_t... Indices,
typename VEC,
typename VEC1>
479 (
sizeof...(Indices) == vec_size<VEC1>()),
480 "vpermute2 number of indices different than return vector size");
482 "vpermute2 type of input and output vector elements differ");
483 constexpr
size_t N = vec_size<VEC>();
485 Indices >= 0 && Indices < 2 *
N)...>::
value,
486 "vpermute2 value of a mask index is outside the allowed range");
488 #if !HAVE_VECTOR_SIZE_ATTRIBUTE || WANT_VECTOR_FALLBACK
491 for (
auto index: { Indices... }) {
501 dst = __builtin_shufflevector(src1, src2, Indices...);
507 #endif // not CXXUTILS_VEC_H
Some additional feature test macros.
ATH_ALWAYS_INLINE bool vnone(const VEC &mask)
ATH_ALWAYS_INLINE void vmax(VEC &dst, const VEC &a, const VEC &b)
constexpr ATH_ALWAYS_INLINE size_t vec_size()
Return the number of elements in a vectorized type.
Deduce the element type from a vectorized type.
ATH_ALWAYS_INLINE void vpermute(VEC1 &dst, const VEC &src)
vpermute function.
#define ATH_ALWAYS_INLINE
ATH_ALWAYS_INLINE void vstore(vec_type_t< VEC > *dst, const VEC &src)
typename vecDetail::vec_mask_type< VEC >::type vec_mask_type_t
Define a nice alias for the mask type for a vectorized type.
ATH_ALWAYS_INLINE bool vall(const VEC &mask)
ATH_ALWAYS_INLINE void vconvert(VEC1 &dst, const VEC2 &src)
performs dst is the result of a static cast of each element of src
static auto maskt(const VEC &v1, const VEC &v2) -> decltype(v1< v2)
typename vecDetail::vec_typedef< T, N >::type vec
Define a nice alias for the vectorized type.
ATH_ALWAYS_INLINE void vpermute2(VEC1 &dst, const VEC &src1, const VEC &src2)
vpermute2 function.
check the type and the size of the vector.
std::remove_cv_t< std::remove_reference_t< type1 > > type
std::remove_cv_t< std::remove_reference_t< type1 > > type
std::invoke_result< decltype(elt), const VEC & >::type type1
ATH_ALWAYS_INLINE void vmin(VEC &dst, const VEC &a, const VEC &b)
static auto elt(const VEC &v) -> decltype(v[0])
ATH_ALWAYS_INLINE void vload(VEC &dst, vec_type_t< VEC > const *src)
ATH_ALWAYS_INLINE void vselect(VEC &dst, const VEC &a, const VEC &b, const vec_mask_type_t< VEC > &mask)
Deduce the type of the mask returned by relational operations, for a vectorized type.
__attribute__((always_inline)) inline uint16_t TileCalibDrawerBase
typename vecDetail::vec_type< VEC >::type vec_type_t
Define a nice alias for the element type of a vectorized type.
ATH_ALWAYS_INLINE void vbroadcast(VEC &v, T x)
Copy a scalar to each element of a vectorized type.
ATH_ALWAYS_INLINE bool vany(const VEC &mask)
Fallback vectorized class.
std::is_same< bool_pack< bs..., true >, bool_pack< true, bs... > > all_true
std::invoke_result< decltype(maskt), const VEC &, const VEC & >::type type1
void zero(TH2 *h)
zero the contents of a 2d histogram