Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 10:13:50

0001 // internal header; common parts to multiple UMESIMD backends
0002 #ifndef VECCORE_UMESIMDCOMMON_H
0003 #define VECCORE_UMESIMDCOMMON_H
0004 
0005 namespace vecCore {
0006 
0007 // type traits for UME::SIMD
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 // backend functions for UME::SIMD
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 // UMESIMD_MATH_UNARY_FUNCTION(Abs, abs)  // Generic implementation is faster
0185 
0186 // UMESIMD_MATH_UNARY_FUNCTION(Sin, sin) // broken
0187 // UMESIMD_MATH_UNARY_FUNCTION(Cos, cos) // broken
0188 UMESIMD_MATH_UNARY_FUNCTION(Tan, tan)
0189 UMESIMD_MATH_UNARY_FUNCTION(ATan, atan)
0190 
0191 // UMESIMD_MATH_UNARY_FUNCTION(Exp, exp) // broken
0192 // UMESIMD_MATH_UNARY_FUNCTION(Log, log) // broken
0193 // UMESIMD_MATH_UNARY_FUNCTION(Sqrt, sqrt) // slower than std::sqrt()
0194 // UMESIMD_MATH_UNARY_FUNCTION(Rsqrt, rsqrt) // slower than std::sqrt(1/x)
0195 
0196 UMESIMD_MATH_UNARY_FUNCTION(Round, round)
0197 // UMESIMD_MATH_UNARY_FUNCTION(Floor, floor) // slower than std::floor()
0198 // UMESIMD_MATH_UNARY_FUNCTION(Ceil, ceil) // slower than std::ceil()
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 } // end namespace math
0210 } // end namespace vecCore
0211 
0212 #endif