diff --git a/test/unit/CMakeLists.txt b/test/unit/CMakeLists.txt index 2c3430570c98..bcd108ff8d4c 100644 --- a/test/unit/CMakeLists.txt +++ b/test/unit/CMakeLists.txt @@ -28,8 +28,8 @@ add_subdirectory("math/") add_subdirectory("mem/buf/") add_subdirectory("mem/copy/") add_subdirectory("mem/fence/") -add_subdirectory("mem/view/") add_subdirectory("mem/p2p/") +add_subdirectory("mem/view/") add_subdirectory("meta/") add_subdirectory("queue/") add_subdirectory("rand/") diff --git a/test/unit/mem/copy/src/BufSlicing.cpp b/test/unit/mem/copy/src/BufSlicing.cpp index 0da58553e069..18e2112e0708 100644 --- a/test/unit/mem/copy/src/BufSlicing.cpp +++ b/test/unit/mem/copy/src/BufSlicing.cpp @@ -1,4 +1,4 @@ -/* Copyright 2022 Axel Huebl, Benjamin Worpitz, Jakob Krude, Bernhard Manfred Gruber, Jan Stephan +/* Copyright 2023 Axel Huebl, Benjamin Worpitz, Jakob Krude, Bernhard Manfred Gruber, Jan Stephan, Andrea Bocci * SPDX-License-Identifier: MPL-2.0 */ @@ -37,7 +37,6 @@ struct TestContainer DevHost const devHost; DevQueue devQueue; - // Constructor TestContainer() : devAcc(alpaka::getDevByIdx(0u)) @@ -46,14 +45,13 @@ struct TestContainer { } - auto createHostBuffer(Vec extents, bool indexed) -> BufHost { BufHost bufHost(alpaka::allocBuf(devHost, extents)); if(indexed) { - TData* const ptr = alpaka::getPtrNative(bufHost); - for(TIdx i(0); i < extents.prod(); ++i) + TData* const ptr = bufHost.data(); + for(TIdx i = 0; i < extents.prod(); ++i) { ptr[i] = static_cast(i); } @@ -61,27 +59,23 @@ struct TestContainer return bufHost; } - auto createDeviceBuffer(Vec extents) -> BufDevice { BufDevice bufDevice(alpaka::allocBuf(devAcc, extents)); return bufDevice; } - auto copyToAcc(BufHost bufHost, BufDevice bufAcc, Vec extents) -> void { alpaka::memcpy(devQueue, bufAcc, bufHost, extents); } - auto copyToHost(BufDevice bufAcc, BufHost bufHost, Vec extents) -> void { alpaka::memcpy(devQueue, bufHost, bufAcc, extents); } - - auto sliceOnDevice(BufDevice bufferToBeSliced, Vec subViewExtents, Vec offsets) -> BufDevice + auto copySliceOnDevice(BufDevice bufferToBeSliced, Vec subViewExtents, Vec offsets) -> BufDevice { BufDevice slicedBuffer = createDeviceBuffer(subViewExtents); // Create a subView with a possible offset. @@ -91,12 +85,19 @@ struct TestContainer return slicedBuffer; } + auto zeroSliceOnDevice(BufDevice bufferToBeSliced, Vec subViewExtents, Vec offsets) -> void + { + // Create a subView with a possible offset. + SubView subView = SubView(bufferToBeSliced, subViewExtents, offsets); + // Fill the subView with zeros. + alpaka::memset(devQueue, subView, 0u); + } auto compareBuffer(BufHost const& bufferA, BufHost const& bufferB, Vec const& extents) const { - TData const* const ptrA = alpaka::getPtrNative(bufferA); - TData const* const ptrB = alpaka::getPtrNative(bufferB); - for(TIdx i(0); i < extents.prod(); ++i) + TData const* const ptrA = bufferA.data(); + TData const* const ptrB = bufferB.data(); + for(TIdx i = 0; i < extents.prod(); ++i) { INFO("Dim: " << TDim::value); INFO("Idx: " << alpaka::core::demangled); @@ -111,57 +112,113 @@ using DataTypes = std::tuple; using TestAccWithDataTypes = alpaka::meta::CartesianProduct; -TEMPLATE_LIST_TEST_CASE("memBufSlicingTest", "[memBuf]", TestAccWithDataTypes) +TEMPLATE_LIST_TEST_CASE("memBufSlicingMemcpyTest", "[memBuf]", TestAccWithDataTypes) { using Acc = std::tuple_element_t<0, TestType>; using Data = std::tuple_element_t<1, TestType>; using Dim = alpaka::Dim; - // fourth-dimension is not supposed to be tested currently - if(Dim::value == 4) + using Idx = alpaka::Idx; + + // Test only buffer slices with up to three dimensions. + if constexpr(Dim::value < 4) { - return; + TestContainer slicingTest; + + auto const extents + = alpaka::createVecFromIndexedFn::template ForExtentBuf>(); + auto const extentsSubView + = alpaka::createVecFromIndexedFn::template ForExtentSubView>(); + auto const offsets + = alpaka::createVecFromIndexedFn::template ForOffset>(); + + // This is the initial buffer. + auto const indexedBuffer = slicingTest.createHostBuffer(extents, true); + + // This buffer will hold the copy of the initial buffer on the device. + auto deviceBuffer = slicingTest.createDeviceBuffer(extents); + + // This buffer will hold the sliced-buffer when it is copied back to the host. + auto resultBuffer = slicingTest.createHostBuffer(extentsSubView, false); + + // Copy the initial buffer to the device. + slicingTest.copyToAcc(indexedBuffer, deviceBuffer, extents); + + // Make a copy of a slice of the buffer on the device. + auto slicedBuffer = slicingTest.copySliceOnDevice(deviceBuffer, extentsSubView, offsets); + + // Copy the slice back to the host. + slicingTest.copyToHost(slicedBuffer, resultBuffer, extentsSubView); + + // Compute the expected content of the slice. + using Dim1 = alpaka::DimInt<1u>; + auto correctResults = slicingTest.createHostBuffer(extentsSubView, false); + Data* const ptr = correctResults.data(); + for(Idx i = 0; i < extentsSubView.prod(); ++i) + { + auto mappedToND = alpaka::mapIdx(alpaka::Vec(i), extentsSubView); + auto addedOffset = mappedToND + offsets; + auto mappedTo1D = alpaka::mapIdx( + addedOffset, + extents)[0]; // take the only element in the vector + ptr[i] = static_cast(mappedTo1D); + } + + // Compare the resultBuffer with the results computed manually. + slicingTest.compareBuffer(resultBuffer, correctResults, extentsSubView); } +} + +TEMPLATE_LIST_TEST_CASE("memBufSlicingMemsetTest", "[memBuf]", TestAccWithDataTypes) +{ + using Acc = std::tuple_element_t<0, TestType>; + using Data = std::tuple_element_t<1, TestType>; + using Dim = alpaka::Dim; using Idx = alpaka::Idx; - TestContainer slicingTest; - auto const extents - = alpaka::createVecFromIndexedFn::template ForExtentBuf>(); + // Test only buffer slices with up to three dimensions. + if constexpr(Dim::value < 4) + { + TestContainer slicingTest; - auto const extentsSubView - = alpaka::createVecFromIndexedFn::template ForExtentSubView>(); - auto const offsets - = alpaka::createVecFromIndexedFn::template ForOffset>(); + auto const extents + = alpaka::createVecFromIndexedFn::template ForExtentBuf>(); + auto const extentsSubView + = alpaka::createVecFromIndexedFn::template ForExtentSubView>(); + auto const offsets + = alpaka::createVecFromIndexedFn::template ForOffset>(); - // This is the initial buffer. - auto const indexedBuffer = slicingTest.createHostBuffer(extents, true); - // This buffer will hold the sliced-buffer when it was copied to the host. - auto resultBuffer = slicingTest.createHostBuffer(extentsSubView, false); + // This is the initial buffer. + auto const indexedBuffer = slicingTest.createHostBuffer(extents, true); - // Copy of the indexBuffer on the deviceSide. - auto deviceBuffer = slicingTest.createDeviceBuffer(extents); + // This buffer will hold the copy of the initial buffer on the device. + auto deviceBuffer = slicingTest.createDeviceBuffer(extents); - // Start: Main-Test - slicingTest.copyToAcc(indexedBuffer, deviceBuffer, extents); + // This buffer will hold a copy of the initial buffer, after a slice has been set to zeroes. + auto resultBuffer = slicingTest.createHostBuffer(extents, false); - auto slicedBuffer = slicingTest.sliceOnDevice(deviceBuffer, extentsSubView, offsets); + // Copy the initial buffer to the device. + slicingTest.copyToAcc(indexedBuffer, deviceBuffer, extents); - slicingTest.copyToHost(slicedBuffer, resultBuffer, extentsSubView); + // Fill a slice of the buffer with zeroes. + slicingTest.zeroSliceOnDevice(deviceBuffer, extentsSubView, offsets); - auto correctResults = slicingTest.createHostBuffer(extentsSubView, false); - Data* ptrNative = alpaka::getPtrNative(correctResults); - using Dim1 = alpaka::DimInt<1u>; + // Copy the buffer back to the host + slicingTest.copyToHost(deviceBuffer, resultBuffer, extents); - for(Idx i(0); i < extentsSubView.prod(); ++i) - { - auto mappedToND = alpaka::mapIdx(alpaka::Vec(i), extentsSubView); - auto addedOffset = mappedToND + offsets; - auto mappedTo1D = alpaka::mapIdx(addedOffset, - extents)[0]; // take the only element in the vector - ptrNative[i] = static_cast(mappedTo1D); - } + // Compute the expected content of the buffer, with a slice set to zeroes. + using Dim1 = alpaka::DimInt<1u>; + auto correctResults = slicingTest.createHostBuffer(extents, true); + Data* const ptr = correctResults.data(); + for(Idx i = 0; i < extents.prod(); ++i) + { + auto mappedToND = alpaka::mapIdx(alpaka::Vec(i), extents); + if((mappedToND >= offsets && mappedToND < offsets + extentsSubView).all()) + ptr[i] = static_cast(0u); + } - // resultBuffer will be compared with the manually computed results. - slicingTest.compareBuffer(resultBuffer, correctResults, extentsSubView); + // Compare the resultBuffer with the results computed manually. + slicingTest.compareBuffer(resultBuffer, correctResults, extentsSubView); + } } #if BOOST_COMP_MSVC || defined(BOOST_COMP_MSVC_EMULATED)