diff --git a/example/zipIterator/src/zipIterator-main.cpp b/example/zipIterator/src/zipIterator-main.cpp index 61170b6..d93f850 100644 --- a/example/zipIterator/src/zipIterator-main.cpp +++ b/example/zipIterator/src/zipIterator-main.cpp @@ -27,12 +27,12 @@ inline typename std::enable_if::type forEach(std::tuple forEach(t, f); } -template -void printTuple(IteratorTuplePtr tuple) +template +void printTuple(IteratorTupleVal tuple) { - std::cout << "tuple("; + std::cout << "("; int index = 0; - int tupleSize = std::tuple_size{}; + int tupleSize = std::tuple_size{}; forEach(tuple, [&index, tupleSize](auto &x) { std::cout << x << (++index < tupleSize ? ", " : ""); }); std::cout << ")"; } @@ -42,11 +42,6 @@ int main() // Define the accelerator here. Must be one of the enabled accelerators. using TAcc = alpaka::AccCpuSerial, std::uint64_t>; - // Types of the data that will be reduced - using TRed = uint64_t; - using TRedChar = char; - using TRedDouble = double; - // Alpaka index type using Idx = alpaka::Idx; // Alpaka dimension type @@ -81,57 +76,52 @@ int main() QueueAcc queueAcc(devAcc); // allocate memory both on host and device. - auto deviceMem(alpaka::allocBuf(devAcc, extent)); - auto hostMem(alpaka::allocBuf(devHost, extent)); + auto deviceMem(alpaka::allocBuf(devAcc, extent)); + auto hostMem(alpaka::allocBuf(devHost, extent)); // Fill memory on host with numbers from 0...n-1. - TRed* hostNative = alpaka::getPtrNative(hostMem); + uint64_t* hostNative = alpaka::getPtrNative(hostMem); for(Idx i = 0; i < n; ++i) - hostNative[i] = static_cast(i + 1); + hostNative[i] = static_cast(i + 1); // Copy to accelerator. alpaka::memcpy(queueAcc, deviceMem, hostMem, extent); - TRed* deviceNative = alpaka::getPtrNative(deviceMem); + uint64_t* deviceNative = alpaka::getPtrNative(deviceMem); // allocate memory both on host and device. - auto deviceMemChar(alpaka::allocBuf(devAcc, extent)); - auto hostMemChar(alpaka::allocBuf(devHost, extent)); + auto deviceMemChar(alpaka::allocBuf(devAcc, extent)); + auto hostMemChar(alpaka::allocBuf(devHost, extent)); + std::vector chars = { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j' }; // Fill memory on host with char from 'a' to 'j'. - TRedChar* hostNativeChar = alpaka::getPtrNative(hostMemChar); - hostNativeChar[0] = 'a'; - hostNativeChar[1] = 'b'; - hostNativeChar[2] = 'c'; - hostNativeChar[3] = 'd'; - hostNativeChar[4] = 'e'; - hostNativeChar[5] = 'f'; - hostNativeChar[6] = 'g'; - hostNativeChar[7] = 'h'; - hostNativeChar[8] = 'i'; - hostNativeChar[9] = 'j'; + char* hostNativeChar = alpaka::getPtrNative(hostMemChar); + for(Idx i = 0; i < n; ++i) + { + hostNativeChar[i] = chars[i]; + } // Copy to accelerator. alpaka::memcpy(queueAcc, deviceMemChar, hostMemChar, extent); - TRedChar* deviceNativeChar = alpaka::getPtrNative(deviceMemChar); + char* deviceNativeChar = alpaka::getPtrNative(deviceMemChar); // allocate memory both on host and device. - auto deviceMemDouble(alpaka::allocBuf(devAcc, extent)); - auto hostMemDouble(alpaka::allocBuf(devHost, extent)); + auto deviceMemDouble(alpaka::allocBuf(devAcc, extent)); + auto hostMemDouble(alpaka::allocBuf(devHost, extent)); // Fill memory on host with double numbers from 10.12...(n-1 + 10.12). - TRedDouble* hostNativeDouble = alpaka::getPtrNative(hostMemDouble); + double* hostNativeDouble = alpaka::getPtrNative(hostMemDouble); for(Idx i = 0; i < n; ++i) - hostNativeDouble[i] = static_cast(i + 10.12); + hostNativeDouble[i] = static_cast(i + 10.12); // Copy to accelerator. alpaka::memcpy(queueAcc, deviceMemDouble, hostMemDouble, extent); - TRedDouble* deviceNativeDouble = alpaka::getPtrNative(deviceMemDouble); + double* deviceNativeDouble = alpaka::getPtrNative(deviceMemDouble); std::cout << "\nTesting zip iterator in host with tuple\n\n"; - using IteratorTuplePtr = std::tuple; - using IteratorTupleVal = std::tuple; + using IteratorTuplePtr = std::tuple; + using IteratorTupleVal = std::tuple; IteratorTuplePtr zipTuple = std::make_tuple(hostNative, hostNativeChar, hostNativeDouble); vikunja::mem::iterator::ZipIterator zipIter(zipTuple); std::cout << "*zipIter: "; printTuple(*zipIter); std::cout << "\n\n"; - + std::cout << "*++zipIter: "; printTuple(*++zipIter); std::cout << "\n*zipIter: "; @@ -168,12 +158,12 @@ int main() printTuple(*zipIter); std::cout << "\n\n"; - std::cout << "Double the number values of the tuple:\n" - << "zipIter = std::make_tuple(2 * std::get<0>(*zipIter), std::get<1>(*zipIter), 2 * std::get<2>(*zipIter));\n" - << "*zipIter: "; - zipIter = std::make_tuple(2 * std::get<0>(*zipIter), std::get<1>(*zipIter), 2 * std::get<2>(*zipIter)); - printTuple(*zipIter); - std::cout << "\n\n"; + // std::cout << "Double the number values of the tuple:\n" + // << "zipIter = std::make_tuple(2 * std::get<0>(*zipIter), std::get<1>(*zipIter), 2 * std::get<2>(*zipIter));\n" + // << "*zipIter: "; + // zipIter = std::make_tuple(2 * std::get<0>(*zipIter), std::get<1>(*zipIter), 2 * std::get<2>(*zipIter)); + // printTuple(*zipIter); + // std::cout << "\n\n"; std::cout << "*(zipIter + 2): "; printTuple(*(zipIter + 2)); @@ -191,28 +181,39 @@ int main() printTuple(zipIter[2]); std::cout << "\n"; - std::cout << "zipIter[4] (number values has been doubled): "; + // std::cout << "zipIter[4] (number values has been doubled): "; + // printTuple(zipIter[4]); + // std::cout << "\n"; + + // std::cout << "Revert the number values for index 4\n"; + // zipIter = std::make_tuple(std::get<0>(*zipIter) / 2, std::get<1>(*zipIter), std::get<2>(*zipIter) / 2); + + std::cout << "zipIter[4]: "; printTuple(zipIter[4]); std::cout << "\n"; std::cout << "zipIter[6]: "; printTuple(zipIter[6]); std::cout << "\n"; - + std::cout << "zipIter[9]: "; printTuple(zipIter[9]); std::cout << "\n\n" << "-----\n\n"; - // Revert the number values for index 4 - zipIter = std::make_tuple(std::get<0>(*zipIter) / 2, std::get<1>(*zipIter), std::get<2>(*zipIter) / 2); - IteratorTuplePtr deviceZipTuple = std::make_tuple(deviceNative, deviceNativeChar, deviceNativeDouble); vikunja::mem::iterator::ZipIterator deviceZipIter(deviceZipTuple); - auto doubleNum = [] ALPAKA_FN_HOST_ACC(IteratorTupleVal const i) + auto deviceMemResult(alpaka::allocBuf(devAcc, extent)); + auto hostMemResult(alpaka::allocBuf(devHost, extent)); + IteratorTupleVal* hostNativeResultPtr = alpaka::getPtrNative(hostMemResult); + IteratorTupleVal* deviceNativeResultPtr = alpaka::getPtrNative(deviceMemResult); + + auto doubleNum = [] ALPAKA_FN_HOST_ACC(IteratorTupleVal const& t) { - return std::make_tuple(2 * std::get<0>(i), std::get<1>(i), 2 * std::get<2>(i)); + // return std::make_tuple(2 * std::get<0>(t), std::get<1>(t), 2 * std::get<2>(t)); + // return std::make_tuple(static_cast(5), 'e', static_cast(14.12)); + return t; }; vikunja::transform::deviceTransform( @@ -220,26 +221,42 @@ int main() queueAcc, extent[Dim::value - 1u], deviceZipIter, - deviceZipIter, + deviceNativeResultPtr, doubleNum); // Copy the data back to the host for validation. - alpaka::memcpy(queueAcc, hostMem, deviceMem, extent); + alpaka::memcpy(queueAcc, hostMemResult, deviceMemResult, extent); - TRed resultSum = std::accumulate(hostNative, hostNative + extent.prod(), 0); - TRed expectedResult = extent.prod() * (extent.prod() + 1); + std::cout << "Testing accelerator: " << alpaka::getAccName() << " with size: " << extent.prod() << "\n" + << "-----\n"; - std::cout << "Testing accelerator: " << alpaka::getAccName() << " with size: " << extent.prod() << "\n"; - if(expectedResult == resultSum) + bool isTransformSuccess = true; + for(Idx i = 0; i < n; ++i) { - std::cout << "Transform was successful!\n\n"; + std::cout << "n=" << i << " | Expected result: (" + << 2 * (i + 1) << ", " << chars[i] << ", " << 2 * (i + 10.12) + << ") | Actual result: "; + printTuple(hostNativeResultPtr[i]); + + if((2 * (i + 1) == std::get<0>(hostNativeResultPtr[i])) && + (chars[i] == std::get<1>(hostNativeResultPtr[i])) && + (2 * (i + 10.12) == std::get<2>(hostNativeResultPtr[i])) + ) { + std::cout << " | OK\n"; + } + else + { + std::cout << " | NOT OK\n"; + isTransformSuccess = false; + } } + + if(isTransformSuccess) + std::cout << "-----\n" + << "Transform was successful!\n\n"; else - { - std::cout << "Transform was not successful!\n" - << "expected result: " << expectedResult << "\n" - << "actual result: " << resultSum << "\n\n"; - } + std::cout << "-----\n" + << "Transform was NOT successful!\n\n"; return 0; } diff --git a/include/vikunja/mem/iterator/ZipIterator.hpp b/include/vikunja/mem/iterator/ZipIterator.hpp index 99fe9d8..ac1e6d0 100644 --- a/include/vikunja/mem/iterator/ZipIterator.hpp +++ b/include/vikunja/mem/iterator/ZipIterator.hpp @@ -60,7 +60,7 @@ namespace vikunja * @param iteratorTuplePtr The tuple to initialize the iterator with * @param idx The index for the iterator, default 0 */ - ZipIterator(IteratorTuplePtr iteratorTuplePtr, const IdxType& idx = static_cast(0)) + constexpr ZipIterator(IteratorTuplePtr iteratorTuplePtr, const IdxType& idx = static_cast(0)) : mIndex(idx) , mIteratorTuplePtr(iteratorTuplePtr) , mIteratorTupleVal(makeValueTuple(mIteratorTuplePtr)) @@ -75,7 +75,7 @@ namespace vikunja /** * @brief Dereference operator to receive the stored value */ - NODISCARD ALPAKA_FN_INLINE IteratorTupleVal& operator*() + NODISCARD constexpr ALPAKA_FN_INLINE IteratorTupleVal& operator*() { return mIteratorTupleVal; } @@ -83,7 +83,7 @@ namespace vikunja /** * @brief Index operator to get stored value at some given offset from this iterator */ - NODISCARD ALPAKA_FN_INLINE const IteratorTupleVal operator[](const IdxType idx) + NODISCARD constexpr ALPAKA_FN_INLINE const IteratorTupleVal operator[](const IdxType idx) { IteratorTuplePtr tmp = mIteratorTuplePtr; IdxType indexDiff = idx - mIndex; @@ -91,18 +91,18 @@ namespace vikunja return makeValueTuple(tmp); } - NODISCARD ALPAKA_FN_INLINE IteratorTupleVal& operator=(IteratorTupleVal iteratorTupleVal) - { - updateIteratorTupleValue(iteratorTupleVal); - mIteratorTupleVal = makeValueTuple(mIteratorTuplePtr); - return mIteratorTupleVal; - } + // NODISCARD constexpr ALPAKA_FN_INLINE IteratorTupleVal& operator=(IteratorTupleVal iteratorTupleVal) + // { + // updateIteratorTupleValue(iteratorTupleVal); + // mIteratorTupleVal = makeValueTuple(mIteratorTuplePtr); + // return mIteratorTupleVal; + // } #pragma region arithmeticoperators /** * @brief Prefix increment operator */ - NODISCARD ALPAKA_FN_INLINE ZipIterator& operator++() + constexpr ALPAKA_FN_INLINE ZipIterator& operator++() { ++mIndex; forEach(mIteratorTuplePtr, [](auto &x) { ++x; }); @@ -114,7 +114,7 @@ namespace vikunja * @brief Postfix increment operator * @note Use prefix increment operator instead if possible to avoid copies */ - ALPAKA_FN_INLINE ZipIterator operator++(int) + constexpr ZipIterator operator++(int) { ZipIterator tmp = *this; ++mIndex; @@ -126,7 +126,7 @@ namespace vikunja /** * @brief Prefix decrement operator */ - NODISCARD ALPAKA_FN_INLINE ZipIterator& operator--() + constexpr ALPAKA_FN_INLINE ZipIterator& operator--() { --mIndex; forEach(mIteratorTuplePtr, [](auto &x) { --x; }); @@ -138,7 +138,7 @@ namespace vikunja * @brief Postfix decrement operator * @note Use prefix decrement operator instead if possible to avoid copies */ - ALPAKA_FN_INLINE ZipIterator operator--(int) + constexpr ALPAKA_FN_INLINE ZipIterator operator--(int) { ZipIterator tmp = *this; --mIndex; @@ -150,51 +150,25 @@ namespace vikunja /** * @brief Add an index to this iterator */ - NODISCARD ALPAKA_FN_INLINE ZipIterator operator+(const int idx) - { - IteratorTuplePtr tmp = mIteratorTuplePtr; - IdxType indexDiff = mIndex; - forEach(tmp, [indexDiff](auto &x) { x -= indexDiff; }); - return ZipIterator(tmp, mIndex + idx); - } - - /** - * @brief Add an index to this iterator - */ - NODISCARD friend ALPAKA_FN_INLINE ZipIterator operator+(ZipIterator zipIter, const IdxType idx) - { - IteratorTuplePtr tmp = zipIter.mIteratorTuplePtr; - IdxType indexDiff = zipIter.mIndex; - zipIter.forEach(tmp, [indexDiff](auto &x) { x -= indexDiff; }); - return ZipIterator(tmp, zipIter.mIndex + idx); - } - - /** - * @brief Subtract an index from this iterator - */ - NODISCARD ALPAKA_FN_INLINE ZipIterator operator-(const int idx) + NODISCARD constexpr friend ALPAKA_FN_INLINE ZipIterator operator+(ZipIterator zipIter, const IdxType idx) { - IteratorTuplePtr tmp = mIteratorTuplePtr; - IdxType indexDiff = mIndex; - forEach(tmp, [indexDiff](auto &x) { x -= indexDiff; }); - return ZipIterator(tmp, mIndex - idx); + zipIter += idx; + return zipIter; } /** * @brief Subtract an index from this iterator */ - NODISCARD friend ALPAKA_FN_INLINE ZipIterator operator-(ZipIterator zipIter, const IdxType idx) + NODISCARD constexpr friend ALPAKA_FN_INLINE ZipIterator operator-(ZipIterator zipIter, const IdxType idx) { - IteratorTuplePtr tmp = zipIter.mIteratorTuplePtr; - IdxType indexDiff = zipIter.mIndex; - zipIter.forEach(tmp, [indexDiff](auto &x) { x -= indexDiff; }); - return ZipIterator(tmp, zipIter.mIndex - idx); + zipIter -= idx; + return zipIter; } /** * @brief Add an index to this iterator */ - NODISCARD ALPAKA_FN_INLINE ZipIterator& operator+=(const IdxType idx) + constexpr ALPAKA_FN_INLINE ZipIterator& operator+=(const IdxType idx) { mIndex += idx; forEach(mIteratorTuplePtr, [idx](auto &x) { x += idx; }); @@ -205,7 +179,7 @@ namespace vikunja /** * @brief Subtract an index from this iterator */ - NODISCARD ALPAKA_FN_INLINE ZipIterator& operator-=(const IdxType idx) + constexpr ALPAKA_FN_INLINE ZipIterator& operator-=(const IdxType idx) { mIndex -= idx; forEach(mIteratorTuplePtr, [idx](auto &x) { x -= idx; }); @@ -217,79 +191,64 @@ namespace vikunja #pragma region comparisonoperators -// if spaceship operator is available is being used we can use spaceship operator magic #ifdef USESPACESHIP /** * @brief Spaceship operator for comparisons */ - NODISCARD ALPAKA_FN_INLINE auto operator<=>(const ZipIterator& other) const noexcept = default; + NODISCARD constexpr ALPAKA_FN_INLINE auto operator<=>(const ZipIterator& other) const noexcept + { + return mIteratorTuplePtr.operator<=>(other.mIteratorTuplePtr); + } -// if cpp20 *isn't* defined we get to write 70 lines of boilerplate #else /** - * @brief Equality comparison, returns true if the iterators are the same + * @brief Equality comparison, returns true if the index are the same */ - NODISCARD ALPAKA_FN_INLINE bool operator==(const ZipIterator& other) const noexcept + NODISCARD constexpr friend ALPAKA_FN_INLINE bool operator==(const ZipIterator& zipIter, const ZipIterator& other) noexcept { - return mIteratorTuplePtr == other.mIteratorTuplePtr && mIndex == other.mIndex; + return zipIter.mIndex == other.mIndex; } /** * @brief Inequality comparison, negated equality operator */ - NODISCARD ALPAKA_FN_INLINE bool operator!=(const ZipIterator& other) const noexcept + NODISCARD constexpr friend ALPAKA_FN_INLINE bool operator!=(const ZipIterator& zipIter, const ZipIterator& other) noexcept { - return !operator==(other); + return !operator==(zipIter, other); } /** - * @brief Less than comparison, value is checked first, then index + * @brief Less than comparison, index is checked */ - NODISCARD ALPAKA_FN_INLINE bool operator<(const ZipIterator& other) const noexcept + NODISCARD constexpr friend ALPAKA_FN_INLINE bool operator<(const ZipIterator& zipIter, const ZipIterator& other) noexcept { - if(mIteratorTuplePtr < other.mIteratorTuplePtr) - return true; - if(mIteratorTuplePtr > other.mIteratorTuplePtr) - return false; - return mIndex < other.mIndex; + return zipIter.mIndex < other.mIndex; } /** - * @brief Greater than comparison, value is checked first, then index + * @brief Greater than comparison, index is checked */ - NODISCARD ALPAKA_FN_INLINE bool operator>(const ZipIterator& other) const noexcept + NODISCARD constexpr friend ALPAKA_FN_INLINE bool operator>(const ZipIterator& zipIter, const ZipIterator& other) noexcept { - if(mIteratorTuplePtr > other.mIteratorTuplePtr) - return true; - if(mIteratorTuplePtr < other.mIteratorTuplePtr) - return false; - return mIndex > other.mIndex; + return zipIter.mIndex > other.mIndex; } /** - * @brief Less than or equal comparison, value is checked first, then index + * @brief Less than or equal comparison, index is checked */ - NODISCARD ALPAKA_FN_INLINE bool operator<=(const ZipIterator& other) const noexcept + NODISCARD constexpr friend ALPAKA_FN_INLINE bool operator<=(const ZipIterator& zipIter, const ZipIterator& other) noexcept { - if(mIteratorTuplePtr < other.mIteratorTuplePtr) - return true; - if(mIteratorTuplePtr > other.mIteratorTuplePtr) - return false; - return mIndex <= other.mIndex; + return zipIter.mIndex <= other.mIndex; } /** - * @brief Greater than or equal comparison, value is checked first, then index + * @brief Greater than or equal comparison, index is checked */ - NODISCARD ALPAKA_FN_INLINE bool operator>=(const ZipIterator& other) const noexcept + NODISCARD constexpr friend ALPAKA_FN_INLINE bool operator>=(const ZipIterator& zipIter, const ZipIterator& other) noexcept { - if(mIteratorTuplePtr > other.mIteratorTuplePtr) - return true; - if(mIteratorTuplePtr < other.mIteratorTuplePtr) - return false; - return mIndex >= other.mIndex; + return zipIter.mIndex >= other.mIndex; } #endif