File indexing completed on 2025-01-18 10:13:50
0001
0002 #ifndef VECCORE_UMESIMDCOMMON_H
0003 #define VECCORE_UMESIMDCOMMON_H
0004
0005 namespace vecCore {
0006
0007
0008
0009 template <uint32_t N>
0010 struct TypeTraits<UME::SIMD::SIMDVecMask<N>> {
0011 using MaskType = typename UME::SIMD::SIMDVecMask<N>;
0012 using IndexType = int;
0013 using ScalarType = bool;
0014 static constexpr size_t Size = N;
0015 };
0016
0017 template <typename T, uint32_t N>
0018 struct TypeTraits<UME::SIMD::SIMDVec_f<T, N>> {
0019 using ScalarType = T;
0020 using MaskType = typename UME::SIMD::SIMDVecMask<N>;
0021 using IndexType = typename UME::SIMD::SIMDVec_u<uint32_t, N>;
0022 static constexpr size_t Size = N;
0023 };
0024
0025 template <typename T, uint32_t N>
0026 struct TypeTraits<UME::SIMD::SIMDVec_i<T, N>> {
0027 using ScalarType = T;
0028 using MaskType = typename UME::SIMD::SIMDVecMask<N>;
0029 using IndexType = typename UME::SIMD::SIMDVec_u<uint32_t, N>;
0030 static constexpr size_t Size = N;
0031 };
0032
0033 template <typename T, uint32_t N>
0034 struct TypeTraits<UME::SIMD::SIMDVec_u<T, N>> {
0035 using ScalarType = T;
0036 using MaskType = typename UME::SIMD::SIMDVecMask<N>;
0037 using IndexType = typename UME::SIMD::SIMDVec_u<uint32_t, N>;
0038 static constexpr size_t Size = N;
0039 };
0040
0041
0042
0043 template <uint32_t N>
0044 VECCORE_FORCE_INLINE
0045 bool MaskFull(const UME::SIMD::SIMDVecMask<N> &cond)
0046 {
0047 return cond.hland();
0048 }
0049
0050 template <uint32_t N>
0051 VECCORE_FORCE_INLINE
0052 bool MaskEmpty(const UME::SIMD::SIMDVecMask<N> &cond)
0053 {
0054 return !cond.hlor();
0055 }
0056
0057 template <uint32_t N>
0058 struct IndexingImplementation<UME::SIMD::SIMDVecMask<N>> {
0059 using M = UME::SIMD::SIMDVecMask<N>;
0060
0061 VECCORE_FORCE_INLINE VECCORE_ATT_HOST_DEVICE static bool Get(const M &mask, int i) { return mask[i]; }
0062
0063 VECCORE_FORCE_INLINE VECCORE_ATT_HOST_DEVICE static void Set(M &mask, int i, const bool val)
0064 {
0065 mask.insert(i, val);
0066 }
0067 };
0068
0069 template <typename T, uint32_t N>
0070 struct LoadStoreImplementation<UME::SIMD::SIMDVec_f<T, N>> {
0071 using V = UME::SIMD::SIMDVec_f<T, N>;
0072
0073 template <typename S = Scalar<V>>
0074 static inline void Load(V &v, S const *ptr)
0075 {
0076 v.load(ptr);
0077 }
0078
0079 template <typename S = Scalar<V>>
0080 static inline void Store(V const &v, S *ptr)
0081 {
0082 v.store(ptr);
0083 }
0084 };
0085
0086 template <typename T, uint32_t N>
0087 struct LoadStoreImplementation<UME::SIMD::SIMDVec_i<T, N>> {
0088 using V = UME::SIMD::SIMDVec_i<T, N>;
0089
0090 template <typename S = Scalar<V>>
0091 static inline void Load(V &v, S const *ptr)
0092 {
0093 v.load(ptr);
0094 }
0095
0096 template <typename S = Scalar<V>>
0097 static inline void Store(V const &v, S *ptr)
0098 {
0099 v.store(ptr);
0100 }
0101 };
0102
0103 template <typename T, uint32_t N>
0104 struct LoadStoreImplementation<UME::SIMD::SIMDVec_u<T, N>> {
0105 using V = UME::SIMD::SIMDVec_u<T, N>;
0106
0107 template <typename S = Scalar<V>>
0108 static inline void Load(V &v, S const *ptr)
0109 {
0110 v.load(ptr);
0111 }
0112
0113 template <typename S = Scalar<V>>
0114 static inline void Store(V const &v, S *ptr)
0115 {
0116 v.store(ptr);
0117 }
0118 };
0119
0120 template <uint32_t N>
0121 struct LoadStoreImplementation<UME::SIMD::SIMDVecMask<N>> {
0122 using M = UME::SIMD::SIMDVecMask<N>;
0123
0124 template <typename S = Scalar<M>>
0125 static inline void Load(M &mask, S const *ptr)
0126 {
0127 mask.load(ptr);
0128 }
0129
0130 template <typename S = Scalar<M>>
0131 static inline void Store(M const &mask, S *ptr)
0132 {
0133 mask.store(ptr);
0134 }
0135 };
0136
0137 template <typename T, uint32_t N>
0138 struct MaskingImplementation<UME::SIMD::SIMDVec_f<T, N>> {
0139 using V = UME::SIMD::SIMDVec_f<T, N>;
0140 using M = UME::SIMD::SIMDVecMask<N>;
0141
0142 static inline void Assign(V &dst, M const &mask, V const &src) { dst.assign(mask, src); }
0143
0144 static inline void Blend(V &dst, M const &mask, V const &src1, V const &src2) { dst = src2.blend(mask, src1); }
0145 };
0146
0147 template <typename T, uint32_t N>
0148 struct MaskingImplementation<UME::SIMD::SIMDVec_i<T, N>> {
0149 using V = UME::SIMD::SIMDVec_i<T, N>;
0150 using M = UME::SIMD::SIMDVecMask<N>;
0151
0152 static inline void Assign(V &dst, M const &mask, V const &src) { dst.assign(mask, src); }
0153
0154 static inline void Blend(V &dst, M const &mask, V const &src1, V const &src2) { dst = src2.blend(mask, src1); }
0155 };
0156
0157 template <typename T, uint32_t N>
0158 struct MaskingImplementation<UME::SIMD::SIMDVec_u<T, N>> {
0159 using V = UME::SIMD::SIMDVec_u<T, N>;
0160 using M = UME::SIMD::SIMDVecMask<N>;
0161
0162 static inline void Assign(V &dst, M const &mask, V const &src) { dst.assign(mask, src); }
0163
0164 static inline void Blend(V &dst, M const &mask, V const &src1, V const &src2) { dst = src2.blend(mask, src1); }
0165 };
0166
0167 inline namespace math {
0168
0169 template <typename T, uint32_t N>
0170 VECCORE_FORCE_INLINE
0171 void SinCos(const UME::SIMD::SIMDVec_f<T, N> &x, UME::SIMD::SIMDVec_f<T, N> *s, UME::SIMD::SIMDVec_f<T, N> *c)
0172 {
0173 *s = x.sin();
0174 *c = x.cos();
0175 }
0176
0177 #define UMESIMD_MATH_UNARY_FUNCTION(F, f) \
0178 template <typename T, uint32_t N> \
0179 VECCORE_FORCE_INLINE \
0180 typename UME::SIMD::SIMDVec_f<T, N> \
0181 F(const UME::SIMD::SIMDVec_f<T, N> &x) \
0182 { return x.f(); }
0183
0184
0185
0186
0187
0188 UMESIMD_MATH_UNARY_FUNCTION(Tan, tan)
0189 UMESIMD_MATH_UNARY_FUNCTION(ATan, atan)
0190
0191
0192
0193
0194
0195
0196 UMESIMD_MATH_UNARY_FUNCTION(Round, round)
0197
0198
0199
0200 #undef UMESIMD_MATH_UNARY_FUNCTION
0201
0202 template <typename T, uint32_t N>
0203 VECCORE_FORCE_INLINE
0204 UME::SIMD::SIMDVecMask<N> IsInf(const UME::SIMD::SIMDVec_f<T, N> &x)
0205 {
0206 return x.isinf();
0207 }
0208
0209 }
0210 }
0211
0212 #endif