diff --git a/src/lib/tsimd/experimental.H b/src/lib/tsimd/experimental.H index 82a1774..8c02d41 100644 --- a/src/lib/tsimd/experimental.H +++ b/src/lib/tsimd/experimental.H @@ -36,57 +36,11 @@ #include namespace simd { +namespace experimental { -// ======================================================================== -// integration of values in simd::Vec -// ======================================================================== - -// example: -// 0 1 2 3 4 5 6 7 -// + - 0 1 2 3 4 5 6 slle(1) -// -------------------------------------- -// 0 0-1 1-2 2-3 3-4 4-5 5-6 6-7 -// + - - 0 0-1 1-2 2-3 3-4 4-5 slle(2) -// -------------------------------------- -// 0 0-1 0-2 0-3 1-4 2-5 3-6 4-7 -// + - - - - 0 0-1 0-2 0-3 slle(4) -// -------------------------------------- -// 0 0-1 0-2 0-3 0-4 0-5 0-6 0-7 -// -// problem: slle has immediate argument, T-SIMD: template parameter - -// primary template -template -struct HInt -{ -public: - static SIMD_INLINE simd::Vec integrate( - const simd::Vec &v) - { - return HInt::integrate( - simd::add(v, simd::slle(v))); - } -}; - -// termination template -template -struct HInt -{ -public: - static SIMD_INLINE simd::Vec integrate( - const simd::Vec &v) - { - return v; - } -}; - -template -static SIMD_INLINE simd::Vec integrate( - const simd::Vec &v) -{ - return HInt::elems>::integrate(v); -} +// put experimental code here +} // namespace experimental } // namespace simd #endif diff --git a/src/lib/tsimd/ext.H b/src/lib/tsimd/ext.H index 4dbb432..4dd4114 100644 --- a/src/lib/tsimd/ext.H +++ b/src/lib/tsimd/ext.H @@ -3268,6 +3268,72 @@ static SIMD_INLINE void transpose( // internal::ext::transpose2inplcLane(rows); } +// ======================================================================== +// integration of values in simd::Vec +// ======================================================================== + +// example: +// 0 1 2 3 4 5 6 7 +// + - 0 1 2 3 4 5 6 slle(1) +// -------------------------------------- +// 0 0-1 1-2 2-3 3-4 4-5 5-6 6-7 +// + - - 0 0-1 1-2 2-3 3-4 4-5 slle(2) +// -------------------------------------- +// 0 0-1 0-2 0-3 1-4 2-5 3-6 4-7 +// + - - - - 0 0-1 0-2 0-3 slle(4) +// -------------------------------------- +// 0 0-1 0-2 0-3 0-4 0-5 0-6 0-7 +// +// problem: slle has immediate argument, T-SIMD: template parameter + +namespace internal { +namespace ext { +// primary template +template +struct HInt +{ +public: + static SIMD_INLINE simd::Vec integrate( + const simd::Vec &v) + { + return HInt::integrate( + simd::add(v, simd::slle(v))); + } +}; + +// termination template +template +struct HInt +{ +public: + static SIMD_INLINE simd::Vec integrate( + const simd::Vec &v) + { + return v; + } +}; +} // namespace ext +} // namespace internal + +/** + * @ingroup group_horizontal + * @brief Integrates the values of a Vec. + * + * This function integrates the values of a Vec, i.e. it computes the + * prefix sum of the elements. + * + * @param[in] v Vec to integrate + * + * @return Vec with integrated values + */ +template +static SIMD_INLINE simd::Vec integrate( + const simd::Vec &v) +{ + return internal::ext::HInt::elems>::integrate(v); +} + // =========================================================================== // setones: set all bits to 1 // =========================================================================== diff --git a/src/test/autotest/serial.H b/src/test/autotest/serial.H index d1eb3c9..0d89540 100644 --- a/src/test/autotest/serial.H +++ b/src/test/autotest/serial.H @@ -2599,6 +2599,21 @@ static SIMD_INLINE uint64_t msb2int(const SerialVec &a) return msb2int(reinterpret(a)); } +// --------------------------------------------------------------------------- +// integrate +// --------------------------------------------------------------------------- +template +static SIMD_INLINE SerialVec integrate(const SerialVec &a) +{ + SerialVec c; + T sum = 0; + for (size_t i = 0; i < c.elements; i++) { + sum += a[i]; + c[i] = sum; + } + return c; +} + } // namespace auto_test } // namespace simd diff --git a/src/test/autotest/test1.C b/src/test/autotest/test1.C index f0aad7e..761dbe5 100644 --- a/src/test/autotest/test1.C +++ b/src/test/autotest/test1.C @@ -202,6 +202,12 @@ int main(int argc, char *argv[]) TestAll::test(repeats1, pattern); TestFloat::test(repeats1, pattern); TestAll::test(repeats1, pattern); + TestInt::test(repeats1, pattern); + + // TODO: integrate produces errors for floating point types because of + // different summation orders. How to fix this? + // TestFloat::test(repeats1, pattern); + // TODO: operators // TODO: Vecs printf("simdvecautotest1 complete\n"); diff --git a/src/test/autotest/wrappers.H b/src/test/autotest/wrappers.H index 21d37fa..7d99b2c 100644 --- a/src/test/autotest/wrappers.H +++ b/src/test/autotest/wrappers.H @@ -2572,6 +2572,26 @@ struct Iota } }; +template +struct Integrate +{ + static SIMD_INLINE std::string name() + { + return t2s("integrate"); + } + + static SIMD_INLINE void randomizeInput(SerialVec &vec) + { + vec.randomize(); + } + + template