/* Copyright 2024 SINTEF AS This file is part of the Open Porous Media project (OPM). OPM is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. OPM is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OPM. If not, see . */ #include #define BOOST_TEST_MODULE TestGpuView #include #include #include #include #include #include #include #include #include #include #include using GpuViewDouble = ::Opm::gpuistl::GpuView; using GpuBufferDouble = ::Opm::gpuistl::GpuBuffer; __global__ void useGpuViewOnGPU(GpuViewDouble a, GpuViewDouble b){ b[0] = a.front(); b[1] = a.back(); b[2] = *a.begin(); b[3] = *(--a.end()); a[0] = a[2]; } BOOST_AUTO_TEST_CASE(TestCreationAndIndexing) { // A simple test to check that we can move data to and from the GPU auto cpubuffer = std::vector({1.0, 2.0, 42.0, 59.9451743, 10.7132692}); auto cubuffer = GpuBufferDouble(cpubuffer); auto gpuview = GpuViewDouble(cubuffer.data(), cubuffer.size()); const auto const_gpuview = GpuViewDouble(cubuffer.data(), cubuffer.size()); auto stdVecOfGpuView = gpuview.asStdVector(); auto const_stdVecOfGpuView = gpuview.asStdVector(); BOOST_CHECK_EQUAL_COLLECTIONS( stdVecOfGpuView.begin(), stdVecOfGpuView.end(), cpubuffer.begin(), cpubuffer.end()); BOOST_CHECK_EQUAL_COLLECTIONS( stdVecOfGpuView.begin(), stdVecOfGpuView.end(), const_stdVecOfGpuView.begin(), const_stdVecOfGpuView.end()); } BOOST_AUTO_TEST_CASE(TestGpuViewOnCPUTypes) { auto buf = std::vector({1.0, 2.0, 42.0, 59.9451743, 10.7132692}); auto cpuview = GpuViewDouble(buf.data(), buf.size()); const auto const_cpuview = GpuViewDouble(buf.data(), buf.size()); // check that indexing a mutable view gives references when indexing it bool correct_type_of_cpu_front = std::is_same_v; bool correct_type_of_cpu_back = std::is_same_v; bool correct_type_of_const_cpu_front = std::is_same_v; bool correct_type_of_const_cpu_back = std::is_same_v; BOOST_CHECK(correct_type_of_cpu_front); BOOST_CHECK(correct_type_of_cpu_back); BOOST_CHECK(correct_type_of_const_cpu_front); BOOST_CHECK(correct_type_of_const_cpu_back); // check that the values are correct BOOST_CHECK(cpuview.front() == buf.front()); BOOST_CHECK(cpuview.back() == buf.back()); } BOOST_AUTO_TEST_CASE(TestGpuViewOnCPUWithSTLIteratorAlgorithm) { auto buf = std::vector({1.0, 2.0, 42.0, 59.9451743, 10.7132692}); auto cpuview = GpuViewDouble(buf.data(), buf.size()); std::sort(buf.begin(), buf.end()); BOOST_CHECK(42.0 == cpuview[3]); } BOOST_AUTO_TEST_CASE(TestGpuViewOnGPU) { auto buf = std::vector({1.0, 2.0, 42.0, 59.9451743, 10.7132692}); auto cubufA = GpuBufferDouble(buf); auto gpuviewA = GpuViewDouble(cubufA.data(), cubufA.size()); auto cubufB = GpuBufferDouble(4); auto gpuviewB = GpuViewDouble(cubufB.data(), cubufB.size()); useGpuViewOnGPU<<<1,1>>>(gpuviewA, gpuviewB); auto vecA = gpuviewA.asStdVector(); auto vecB = gpuviewB.asStdVector(); // checks that front/back/begin/end works BOOST_CHECK(vecB[0] == buf[0]); BOOST_CHECK(vecB[1] == buf[4]); BOOST_CHECK(vecB[2] == buf[0]); BOOST_CHECK(vecB[3] == buf[4]); // checks that view[0] = view[2] works BOOST_CHECK(buf[2] == vecA[0]); }