diff --git a/src/gpu/VirtualFluids_GPU/LBM/Simulation.cpp b/src/gpu/VirtualFluids_GPU/LBM/Simulation.cpp index a055542983381b9f843f18e9c5f069729c329c79..b4a0828fb5f08bc8e5d609492bb109298014c6eb 100644 --- a/src/gpu/VirtualFluids_GPU/LBM/Simulation.cpp +++ b/src/gpu/VirtualFluids_GPU/LBM/Simulation.cpp @@ -10,6 +10,7 @@ #include "Communication/ExchangeData27.h" #include "Parameter/Parameter.h" #include "Parameter/CudaStreamManager.h" +#include "Parameter/EdgeNodeFinder.h" #include "GPU/GPU_Interface.h" #include "basics/utilities/UbFileOutputASCII.h" ////////////////////////////////////////////////////////////////////////// @@ -335,7 +336,7 @@ void Simulation::init(SPtr<Parameter> para, SPtr<GridProvider> gridProvider, std ////////////////////////////////////////////////////////////////////////// if (para->getDevices().size() > 2) { output << "Find indices of edge nodes for multiGPU communication ..."; - para->findEdgeNodesCommMultiGPU(); + vf::gpu::findEdgeNodesCommMultiGPU(para); output << "done.\n"; } ////////////////////////////////////////////////////////////////////////// diff --git a/src/gpu/VirtualFluids_GPU/Parameter/EdgeNodeFinder.cpp b/src/gpu/VirtualFluids_GPU/Parameter/EdgeNodeFinder.cpp new file mode 100644 index 0000000000000000000000000000000000000000..1134ee0c65ecfe30e314c743ac6c22d4f528130d --- /dev/null +++ b/src/gpu/VirtualFluids_GPU/Parameter/EdgeNodeFinder.cpp @@ -0,0 +1,113 @@ +#include "EdgeNodeFinder.h" +#include "Parameter.h" + +namespace vf::gpu +{ +void findEdgeNodesCommMultiGPU(SPtr<Parameter> parameter) +{ + for (int level = 0; level <= parameter->getFine(); level++) { + findEdgeNodesXY(level, parameter); + findEdgeNodesXZ(level, parameter); + findEdgeNodesYZ(level, parameter); + } +} +} // namespace vf::gpu + +namespace +{ +void findEdgeNodesXY(int level, SPtr<Parameter> parameter) +{ + int indexOfProcessNeighborSend; + int indexInSendBuffer; + for (uint i = 0; i < (unsigned int)(parameter->getNumberOfProcessNeighborsX(level, "recv")); i++) { + for (int j = 0; j < parameter->getParH(level)->recvProcessNeighborX[i].numberOfNodes; j++) { + int index = parameter->getParH(level)->recvProcessNeighborX[i].index[j]; + bool foundIndex = + findIndexInSendNodesXY(level, index, indexOfProcessNeighborSend, indexInSendBuffer, parameter); + if (foundIndex) { + parameter->getParH(level)->edgeNodesXtoY.emplace_back(i, j, indexOfProcessNeighborSend, + indexInSendBuffer); + } + } + } +} + +bool findIndexInSendNodesXY(int level, int index, int &indexOfProcessNeighborSend, int &indexInSendBuffer, + SPtr<Parameter> parameter) +{ + for (uint k = 0; k < (unsigned int)(parameter->getNumberOfProcessNeighborsY(level, "send")); k++) { + for (int l = 0; l < parameter->getParH(level)->sendProcessNeighborY[k].numberOfNodes; l++) { + if (parameter->getParH(level)->sendProcessNeighborY[k].index[l] == index) { + indexOfProcessNeighborSend = k; + indexInSendBuffer = l; + return true; + } + } + } + return false; +} + +void findEdgeNodesXZ(int level, SPtr<Parameter> parameter) +{ + int indexOfProcessNeighborSend; + int indexInSendBuffer; + for (uint i = 0; i < (unsigned int)(parameter->getNumberOfProcessNeighborsX(level, "recv")); i++) { + for (int j = 0; j < parameter->getParH(level)->recvProcessNeighborX[i].numberOfNodes; j++) { + int index = parameter->getParH(level)->recvProcessNeighborX[i].index[j]; + bool foundIndex = + findIndexInSendNodesXZ(level, index, indexOfProcessNeighborSend, indexInSendBuffer, parameter); + if (foundIndex) { + parameter->getParH(level)->edgeNodesXtoZ.emplace_back(i, j, indexOfProcessNeighborSend, + indexInSendBuffer); + } + } + } +} + +bool findIndexInSendNodesXZ(int level, int index, int &indexOfProcessNeighborSend, int &indexInSendBuffer, + SPtr<Parameter> parameter) +{ + for (uint k = 0; k < (unsigned int)(parameter->getNumberOfProcessNeighborsZ(level, "send")); k++) { + for (int l = 0; l < parameter->getParH(level)->sendProcessNeighborZ[k].numberOfNodes; l++) { + if (parameter->getParH(level)->sendProcessNeighborZ[k].index[l] == index) { + indexOfProcessNeighborSend = k; + indexInSendBuffer = l; + return true; + } + } + } + return false; +} + +void findEdgeNodesYZ(int level, SPtr<Parameter> parameter) +{ + int indexOfProcessNeighborSend; + int indexInSendBuffer; + for (uint i = 0; i < (unsigned int)(parameter->getNumberOfProcessNeighborsY(level, "recv")); i++) { + for (int j = 0; j < parameter->getParH(level)->recvProcessNeighborY[i].numberOfNodes; j++) { + int index = parameter->getParH(level)->recvProcessNeighborY[i].index[j]; + bool foundIndex = + findIndexInSendNodesYZ(level, index, indexOfProcessNeighborSend, indexInSendBuffer, parameter); + if (foundIndex) { + parameter->getParH(level)->edgeNodesYtoZ.emplace_back(i, j, indexOfProcessNeighborSend, + indexInSendBuffer); + } + } + } +} + +bool findIndexInSendNodesYZ(int level, int index, int &indexOfProcessNeighborSend, int &indexInSendBuffer, + SPtr<Parameter> parameter) +{ + for (uint k = 0; k < (unsigned int)(parameter->getNumberOfProcessNeighborsZ(level, "send")); k++) { + for (int l = 0; l < parameter->getParH(level)->sendProcessNeighborZ[k].numberOfNodes; l++) { + if (parameter->getParH(level)->sendProcessNeighborZ[k].index[l] == index) { + indexOfProcessNeighborSend = k; + indexInSendBuffer = l; + return true; + } + } + } + return false; +} +} // namespace \ No newline at end of file diff --git a/src/gpu/VirtualFluids_GPU/Parameter/EdgeNodeFinder.h b/src/gpu/VirtualFluids_GPU/Parameter/EdgeNodeFinder.h new file mode 100644 index 0000000000000000000000000000000000000000..a526c28409da5153b8a5e28fab9219abfe363b34 --- /dev/null +++ b/src/gpu/VirtualFluids_GPU/Parameter/EdgeNodeFinder.h @@ -0,0 +1,65 @@ +//======================================================================================= +// ____ ____ __ ______ __________ __ __ __ __ +// \ \ | | | | | _ \ |___ ___| | | | | / \ | | +// \ \ | | | | | |_) | | | | | | | / \ | | +// \ \ | | | | | _ / | | | | | | / /\ \ | | +// \ \ | | | | | | \ \ | | | \__/ | / ____ \ | |____ +// \ \ | | |__| |__| \__\ |__| \________/ /__/ \__\ |_______| +// \ \ | | ________________________________________________________________ +// \ \ | | | ______________________________________________________________| +// \ \| | | | __ __ __ __ ______ _______ +// \ | | |_____ | | | | | | | | | _ \ / _____) +// \ | | _____| | | | | | | | | | | \ \ \_______ +// \ | | | | |_____ | \_/ | | | | |_/ / _____ | +// \ _____| |__| |________| \_______/ |__| |______/ (_______/ +// +// This file is part of VirtualFluids. VirtualFluids 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. +// +// VirtualFluids 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 VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>. +// +//! \file EdgeNodeFinder.h +//! \ingroup Parameter +//! \author Anna Wellmann +//! \brief functions for finding edge nodes in the multi-gpu implementation +//! \details Edge nodes are nodes, which are part of the communication in multiple directions +//! \ref master thesis of Anna Wellmann (p. 54-57) + +//======================================================================================= +#ifndef GPU_EDGENODES_H +#define GPU_EDGENODES_H + +#include "Core/DataTypes.h" +#include "basics/PointerDefinitions.h" + +class Parameter; + +namespace vf::gpu +{ + +void findEdgeNodesCommMultiGPU(SPtr<Parameter> parameter); +} + +// anonymous namespace +namespace +{ +static void findEdgeNodesXY(int level, SPtr<Parameter> parameter); +static bool findIndexInSendNodesXY(int level, int index, int &indexOfProcessNeighborSend, int &indexInSendBuffer, + SPtr<Parameter> parameter); +static void findEdgeNodesXZ(int level, SPtr<Parameter> parameter); +static bool findIndexInSendNodesXZ(int level, int index, int &indexOfProcessNeighborSend, int &indexInSendBuffer, + SPtr<Parameter> parameter); +static void findEdgeNodesYZ(int level, SPtr<Parameter> parameter); +static bool findIndexInSendNodesYZ(int level, int index, int &indexOfProcessNeighborSend, int &indexInSendBuffer, + SPtr<Parameter> parameter); +} // namespace + +#endif \ No newline at end of file diff --git a/src/gpu/VirtualFluids_GPU/Parameter/EdgeNodeFinderTest.cpp b/src/gpu/VirtualFluids_GPU/Parameter/EdgeNodeFinderTest.cpp new file mode 100644 index 0000000000000000000000000000000000000000..ac515474c5704cdf1d56b282415b14d50d080376 --- /dev/null +++ b/src/gpu/VirtualFluids_GPU/Parameter/EdgeNodeFinderTest.cpp @@ -0,0 +1,167 @@ +#include <gmock/gmock.h> + +#include <filesystem> + +#include "Parameter.h" +#include "basics/config/ConfigurationFile.h" +#include "EdgeNodeFinder.h" + +static std::shared_ptr<Parameter> initParameterClass() +{ + std::filesystem::path filePath = __FILE__; // assuming that the config file is stored parallel to this file. + filePath.replace_filename("parameterTest.cfg"); + vf::basics::ConfigurationFile config; + config.load(filePath.string()); + return std::make_shared<Parameter>(config, 1, 0); +} + +static bool compareEdgeNodesRecv(std::vector<LBMSimulationParameter::EdgeNodePositions> &actual, + std::vector<std::pair<int, int>> &expected) +{ + for (int i = 0; i < (int)expected.size(); i++) { + if (actual[i].indexOfProcessNeighborRecv != expected[i].first) { + return false; + } + if (actual[i].indexInRecvBuffer != expected[i].second) { + return false; + } + } + return true; +} + +static bool compareEdgeNodesSend(std::vector<LBMSimulationParameter::EdgeNodePositions> &actual, + std::vector<std::pair<int, int>> &expected) +{ + for (int i = 0; i < (int)expected.size(); i++) { + if (actual[i].indexOfProcessNeighborSend != expected[i].first) { + return false; + } + if (actual[i].indexInSendBuffer != expected[i].second) { + return false; + } + } + return true; +} + +class EdgeNodeFinderTest_findEdgeNodes : public testing::Test +{ +protected: + std::shared_ptr<Parameter> para; + int level = 0; + +private: + void SetUp() override + { + para = initParameterClass(); + para->initLBMSimulationParameter(); + } +}; + +TEST_F(EdgeNodeFinderTest_findEdgeNodes, shouldReturnCorrectVectorForXY) +{ + para->parH[level]->recvProcessNeighborX.push_back(ProcessNeighbor27()); + para->parH[level]->sendProcessNeighborY.push_back(ProcessNeighbor27()); + para->parH[level]->sendProcessNeighborY.push_back(ProcessNeighbor27()); + + int numRecvNeighbor = (int)para->parH[level]->recvProcessNeighborX.size() - 1; + int numSendNeighbor = (int)para->parH[level]->sendProcessNeighborY.size() - 1; + + const int sizeRecv = 6; + const int sizeSend = 10; + para->parH[level]->recvProcessNeighborX[numRecvNeighbor].numberOfNodes = sizeRecv; + para->parH[level]->sendProcessNeighborY[numSendNeighbor].numberOfNodes = sizeSend; + + int recvNeighbors[sizeRecv] = { 1, 2, 3, 4, 5, 6 }; + para->parH[level]->recvProcessNeighborX[numRecvNeighbor].index = recvNeighbors; + + int sendNeighbors[sizeSend] = { 20, 1, 21, 22, 6, 23, 5, 24, 25, 26 }; + para->parH[level]->sendProcessNeighborY[numSendNeighbor].index = sendNeighbors; + + vf::gpu::findEdgeNodesCommMultiGPU(para); + + std::vector<std::pair<int, int>> expectedEdgeNodesXtoYRecv = { std::pair(numRecvNeighbor, 0), + std::pair(numRecvNeighbor, 4), + std::pair(numRecvNeighbor, 5) }; + + std::vector<std::pair<int, int>> expectedEdgeNodesXtoYSend = { std::pair(numSendNeighbor, 1), + std::pair(numSendNeighbor, 6), + std::pair(numSendNeighbor, 4) }; + + EXPECT_THAT(para->parH[level]->edgeNodesXtoY.size(), testing::Eq(expectedEdgeNodesXtoYRecv.size())); + EXPECT_TRUE(compareEdgeNodesRecv(para->parH[level]->edgeNodesXtoY, expectedEdgeNodesXtoYRecv)) + << "the edgeNodesXtoY for the receive process do not match the expected nodes"; + EXPECT_TRUE(compareEdgeNodesSend(para->parH[level]->edgeNodesXtoY, expectedEdgeNodesXtoYSend)) + << "the edgeNodesXtoY for the send process do not match the expected nodes"; +} + +TEST_F(EdgeNodeFinderTest_findEdgeNodes, shouldReturnCorrectVectorForXZ) +{ + para->parH[level]->recvProcessNeighborX.push_back(ProcessNeighbor27()); + para->parH[level]->sendProcessNeighborZ.push_back(ProcessNeighbor27()); + para->parH[level]->sendProcessNeighborZ.push_back(ProcessNeighbor27()); + + int numRecvNeighbor = (int)para->parH[level]->recvProcessNeighborX.size() - 1; + int numSendNeighbor = (int)para->parH[level]->sendProcessNeighborZ.size() - 1; + + const int sizeRecv = 10; + const int sizeSend = 6; + para->parH[level]->recvProcessNeighborX[numRecvNeighbor].numberOfNodes = sizeRecv; + para->parH[level]->sendProcessNeighborZ[numSendNeighbor].numberOfNodes = sizeSend; + + int recvNeighbors[sizeRecv] = { 20, 1, 21, 22, 6, 23, 5, 24, 25, 26 }; + para->parH[level]->recvProcessNeighborX[numRecvNeighbor].index = recvNeighbors; + + int sendNeighbors[sizeSend] = { 1, 2, 3, 4, 5, 6 }; + para->parH[level]->sendProcessNeighborZ[numSendNeighbor].index = sendNeighbors; + + vf::gpu::findEdgeNodesCommMultiGPU(para); + + std::vector<std::pair<int, int>> expectedEdgeNodesXtoZRecv = { std::pair(numRecvNeighbor, 1), + std::pair(numRecvNeighbor, 4), + std::pair(numRecvNeighbor, 6) }; + std::vector<std::pair<int, int>> expectedEdgeNodesXtoZSend = { std::pair(numSendNeighbor, 0), + std::pair(numSendNeighbor, 5), + std::pair(numSendNeighbor, 4) }; + + EXPECT_THAT(para->parH[level]->edgeNodesXtoZ.size(), testing::Eq(expectedEdgeNodesXtoZRecv.size())); + EXPECT_TRUE(compareEdgeNodesRecv(para->parH[level]->edgeNodesXtoZ, expectedEdgeNodesXtoZRecv)) + << "the edgeNodesXtoZ for the receive process do not match the expected nodes"; + EXPECT_TRUE(compareEdgeNodesSend(para->parH[level]->edgeNodesXtoZ, expectedEdgeNodesXtoZSend)) + << "the edgeNodesXtoZ for the send process do not match the expected nodes"; +} + +TEST_F(EdgeNodeFinderTest_findEdgeNodes, shouldReturnCorrectVectorForYZ) +{ + para->parH[level]->recvProcessNeighborY.push_back(ProcessNeighbor27()); + para->parH[level]->sendProcessNeighborZ.push_back(ProcessNeighbor27()); + para->parH[level]->sendProcessNeighborZ.push_back(ProcessNeighbor27()); + + const int sizeRecv = 10; + const int sizeSend1 = 6; + const int sizeSend2 = 5; + + para->parH[level]->recvProcessNeighborY[0].numberOfNodes = sizeRecv; + para->parH[level]->sendProcessNeighborZ[0].numberOfNodes = sizeSend1; + para->parH[level]->sendProcessNeighborZ[1].numberOfNodes = sizeSend2; + + int recvNeighbors[sizeRecv] = { 20, 1, 9, 22, 6, 23, 5, 24, 11, 26 }; + para->parH[level]->recvProcessNeighborY[0].index = recvNeighbors; + + int sendNeighbors1[sizeSend1] = { 1, 2, 3, 4, 5, 6 }; + int sendNeighbors2[sizeSend2] = { 7, 8, 9, 10, 11 }; + para->parH[level]->sendProcessNeighborZ[0].index = sendNeighbors1; + para->parH[level]->sendProcessNeighborZ[1].index = sendNeighbors2; + + vf::gpu::findEdgeNodesCommMultiGPU(para); + + std::vector<std::pair<int, int>> expectedEdgeNodesYtoZRecv = { std::pair(0, 1), std::pair(0, 2), std::pair(0, 4), + std::pair(0, 6), std::pair(0, 8) }; + std::vector<std::pair<int, int>> expectedEdgeNodesYtoZSend = { std::pair(0, 0), std::pair(1, 2), std::pair(0, 5), + std::pair(0, 4), std::pair(1, 4) }; + + EXPECT_THAT(para->parH[level]->edgeNodesYtoZ.size(), testing::Eq(expectedEdgeNodesYtoZRecv.size())); + EXPECT_TRUE(compareEdgeNodesRecv(para->parH[level]->edgeNodesYtoZ, expectedEdgeNodesYtoZRecv)) + << "the edgeNodesYtoZ for the receive process do not match the expected nodes"; + EXPECT_TRUE(compareEdgeNodesSend(para->parH[level]->edgeNodesYtoZ, expectedEdgeNodesYtoZSend)) + << "the edgeNodesYtoZ for the send process do not match the expected nodes"; +} \ No newline at end of file diff --git a/src/gpu/VirtualFluids_GPU/Parameter/Parameter.cpp b/src/gpu/VirtualFluids_GPU/Parameter/Parameter.cpp index d63fb1d3f00172cba3fa8a15f449d6eb65199c8a..0187cc364a2ffe61e63e86d029b404d233d00b49 100644 --- a/src/gpu/VirtualFluids_GPU/Parameter/Parameter.cpp +++ b/src/gpu/VirtualFluids_GPU/Parameter/Parameter.cpp @@ -2587,102 +2587,6 @@ bool Parameter::getKernelNeedsFluidNodeIndicesToRun() return this->kernelNeedsFluidNodeIndicesToRun; } -void Parameter::findEdgeNodesCommMultiGPU() -{ - for (uint level = 0; level < parH.size(); level++) { - findEdgeNodesXY(level); - findEdgeNodesXZ(level); - findEdgeNodesYZ(level); - } -} - -void Parameter::findEdgeNodesXY(int level) -{ - int indexOfProcessNeighborSend; - int indexInSendBuffer; - for (uint i = 0; i < (unsigned int)(this->getNumberOfProcessNeighborsX(level, "recv")); i++) { - for (int j = 0; j < parH[level]->recvProcessNeighborX[i].numberOfNodes; j++) { - int index = parH[level]->recvProcessNeighborX[i].index[j]; - bool foundIndex = findIndexInSendNodesXY(level, index, indexOfProcessNeighborSend, indexInSendBuffer); - if (foundIndex) { - this->parH[level]->edgeNodesXtoY.emplace_back(i, j, indexOfProcessNeighborSend, indexInSendBuffer); - } - } - } -} - -bool Parameter::findIndexInSendNodesXY(int level, int index, int &indexOfProcessNeighborSend, int &indexInSendBuffer) -{ - for (uint k = 0; k < (unsigned int)(this->getNumberOfProcessNeighborsY(level, "send")); k++) { - for (int l = 0; l < parH[level]->sendProcessNeighborY[k].numberOfNodes; l++) { - if (parH[level]->sendProcessNeighborY[k].index[l] == index) { - indexOfProcessNeighborSend = k; - indexInSendBuffer = l; - return true; - } - } - } - return false; -} - -void Parameter::findEdgeNodesXZ(int level) -{ - int indexOfProcessNeighborSend; - int indexInSendBuffer; - for (uint i = 0; i < (unsigned int)(this->getNumberOfProcessNeighborsX(level, "recv")); i++) { - for (int j = 0; j < parH[level]->recvProcessNeighborX[i].numberOfNodes; j++) { - int index = parH[level]->recvProcessNeighborX[i].index[j]; - bool foundIndex = findIndexInSendNodesXZ(level, index, indexOfProcessNeighborSend, indexInSendBuffer); - if (foundIndex) { - this->parH[level]->edgeNodesXtoZ.emplace_back(i, j, indexOfProcessNeighborSend, indexInSendBuffer); - } - } - } -} - -bool Parameter::findIndexInSendNodesXZ(int level, int index, int &indexOfProcessNeighborSend, int &indexInSendBuffer) -{ - for (uint k = 0; k < (unsigned int)(this->getNumberOfProcessNeighborsZ(level, "send")); k++) { - for (int l = 0; l < parH[level]->sendProcessNeighborZ[k].numberOfNodes; l++) { - if (parH[level]->sendProcessNeighborZ[k].index[l] == index) { - indexOfProcessNeighborSend = k; - indexInSendBuffer = l; - return true; - } - } - } - return false; -} - -void Parameter::findEdgeNodesYZ(int level) -{ - int indexOfProcessNeighborSend; - int indexInSendBuffer; - for (uint i = 0; i < (unsigned int)(this->getNumberOfProcessNeighborsY(level, "recv")); i++) { - for (int j = 0; j < parH[level]->recvProcessNeighborY[i].numberOfNodes; j++) { - int index = parH[level]->recvProcessNeighborY[i].index[j]; - bool foundIndex = findIndexInSendNodesYZ(level, index, indexOfProcessNeighborSend, indexInSendBuffer); - if (foundIndex) { - this->parH[level]->edgeNodesYtoZ.emplace_back(i, j, indexOfProcessNeighborSend, indexInSendBuffer); - } - } - } -} - -bool Parameter::findIndexInSendNodesYZ(int level, int index, int &indexOfProcessNeighborSend, int &indexInSendBuffer) -{ - for (uint k = 0; k < (unsigned int)(this->getNumberOfProcessNeighborsZ(level, "send")); k++) { - for (int l = 0; l < parH[level]->sendProcessNeighborZ[k].numberOfNodes; l++) { - if (parH[level]->sendProcessNeighborZ[k].index[l] == index) { - indexOfProcessNeighborSend = k; - indexInSendBuffer = l; - return true; - } - } - } - return false; -} - void Parameter::initProcessNeighborsAfterFtoCX(int level) { this->getParH(level)->sendProcessNeighborsAfterFtoCX.resize(this->getParH(level)->sendProcessNeighborX.size()); diff --git a/src/gpu/VirtualFluids_GPU/Parameter/Parameter.h b/src/gpu/VirtualFluids_GPU/Parameter/Parameter.h index 6646cdbfbe70d4be9d35606309b839811cf6ec36..5325c0aeabfbd3f1b5f146605c1309cb35e87543 100644 --- a/src/gpu/VirtualFluids_GPU/Parameter/Parameter.h +++ b/src/gpu/VirtualFluids_GPU/Parameter/Parameter.h @@ -579,7 +579,6 @@ public: void setADKernel(std::string adKernel); // adder - void addActuator(SPtr<PreCollisionInteractor> actuator); void addProbe(SPtr<PreCollisionInteractor> probes); @@ -610,7 +609,9 @@ public: bool getCalcParticle(); bool getWriteVeloASCIIfiles(); bool getCalcPlaneConc(); + //! \returns index of finest level int getFine(); + //! \returns index of coarsest level int getCoarse(); int getParticleBasicLevel(); int getParticleInitLevel(); @@ -933,16 +934,7 @@ public: void initProcessNeighborsAfterFtoCY(int level); void initProcessNeighborsAfterFtoCZ(int level); - void findEdgeNodesCommMultiGPU(); bool useReducedCommunicationAfterFtoC{ true }; - -private: - void findEdgeNodesXY(int level); - bool findIndexInSendNodesXY(int level, int index, int &indexOfProcessNeighborSend, int &indexInSendBuffer); - void findEdgeNodesXZ(int level); - bool findIndexInSendNodesXZ(int level, int index, int &indexOfProcessNeighborSend, int &indexInSendBuffer); - void findEdgeNodesYZ(int level); - bool findIndexInSendNodesYZ(int level, int index, int &indexOfProcessNeighborSend, int &indexInSendBuffer); }; #endif diff --git a/src/gpu/VirtualFluids_GPU/Parameter/ParameterTest.cpp b/src/gpu/VirtualFluids_GPU/Parameter/ParameterTest.cpp index a99c7b11c9cf6bdc5a6c1b29b3eb1d2328facdd4..876cc3c4f7df639f8f8186e09a6291ecb44f5074 100644 --- a/src/gpu/VirtualFluids_GPU/Parameter/ParameterTest.cpp +++ b/src/gpu/VirtualFluids_GPU/Parameter/ParameterTest.cpp @@ -5,7 +5,7 @@ #include <string> #include "Parameter.h" -#include <basics/config/ConfigurationFile.h> +#include "basics/config/ConfigurationFile.h" auto RealEq = [](auto value) { #ifdef VF_DOUBLE_ACCURACY @@ -149,164 +149,4 @@ TEST(ParameterTest, check_all_Parameter_CanBePassedToConstructor) EXPECT_THAT(para.getFine(), testing::Eq(1)); // NOGL - 1 EXPECT_THAT(para.parH.size(), testing::Eq(2)); EXPECT_THAT(para.parD.size(), testing::Eq(2)); -} - -static std::shared_ptr<Parameter> initParameterClass() -{ - std::filesystem::path filePath = __FILE__; // assuming that the config file is stored parallel to this file. - filePath.replace_filename("parameterTest.cfg"); - vf::basics::ConfigurationFile config; - config.load(filePath.string()); - return std::make_shared<Parameter>(config, 1, 0); -} - -static bool compareEdgeNodesRecv(std::vector<LBMSimulationParameter::EdgeNodePositions> &actual, - std::vector<std::pair<int, int>> &expected) -{ - for (int i = 0; i < (int)expected.size(); i++) { - if (actual[i].indexOfProcessNeighborRecv != expected[i].first) { - return false; - } - if (actual[i].indexInRecvBuffer != expected[i].second) { - return false; - } - } - return true; -} - -static bool compareEdgeNodesSend(std::vector<LBMSimulationParameter::EdgeNodePositions> &actual, - std::vector<std::pair<int, int>> &expected) -{ - for (int i = 0; i < (int)expected.size(); i++) { - if (actual[i].indexOfProcessNeighborSend != expected[i].first) { - return false; - } - if (actual[i].indexInSendBuffer != expected[i].second) { - return false; - } - } - return true; -} - -class ParameterTest_findEdgeNodes : public testing::Test -{ -protected: - std::shared_ptr<Parameter> para; - int level = 0; - -private: - void SetUp() override - { - para = initParameterClass(); - para->initLBMSimulationParameter(); - } -}; - -TEST_F(ParameterTest_findEdgeNodes, shouldReturnCorrectVectorForXY) -{ - para->parH[level]->recvProcessNeighborX.push_back(ProcessNeighbor27()); - para->parH[level]->sendProcessNeighborY.push_back(ProcessNeighbor27()); - para->parH[level]->sendProcessNeighborY.push_back(ProcessNeighbor27()); - - int numRecvNeighbor = (int)para->parH[level]->recvProcessNeighborX.size() - 1; - int numSendNeighbor = (int)para->parH[level]->sendProcessNeighborY.size() - 1; - - const int sizeRecv = 6; - const int sizeSend = 10; - para->parH[level]->recvProcessNeighborX[numRecvNeighbor].numberOfNodes = sizeRecv; - para->parH[level]->sendProcessNeighborY[numSendNeighbor].numberOfNodes = sizeSend; - - int recvNeighbors[sizeRecv] = { 1, 2, 3, 4, 5, 6 }; - para->parH[level]->recvProcessNeighborX[numRecvNeighbor].index = recvNeighbors; - - int sendNeighbors[sizeSend] = { 20, 1, 21, 22, 6, 23, 5, 24, 25, 26 }; - para->parH[level]->sendProcessNeighborY[numSendNeighbor].index = sendNeighbors; - - para->findEdgeNodesCommMultiGPU(); - - std::vector<std::pair<int, int>> expectedEdgeNodesXtoYRecv = { std::pair(numRecvNeighbor, 0), - std::pair(numRecvNeighbor, 4), - std::pair(numRecvNeighbor, 5) }; - - std::vector<std::pair<int, int>> expectedEdgeNodesXtoYSend = { std::pair(numSendNeighbor, 1), - std::pair(numSendNeighbor, 6), - std::pair(numSendNeighbor, 4) }; - - EXPECT_THAT(para->parH[level]->edgeNodesXtoY.size(), testing::Eq(expectedEdgeNodesXtoYRecv.size())); - EXPECT_TRUE(compareEdgeNodesRecv(para->parH[level]->edgeNodesXtoY, expectedEdgeNodesXtoYRecv)) - << "the edgeNodesXtoY for the receive process do not match the expected nodes"; - EXPECT_TRUE(compareEdgeNodesSend(para->parH[level]->edgeNodesXtoY, expectedEdgeNodesXtoYSend)) - << "the edgeNodesXtoY for the send process do not match the expected nodes"; -} - -TEST_F(ParameterTest_findEdgeNodes, shouldReturnCorrectVectorForXZ) -{ - para->parH[level]->recvProcessNeighborX.push_back(ProcessNeighbor27()); - para->parH[level]->sendProcessNeighborZ.push_back(ProcessNeighbor27()); - para->parH[level]->sendProcessNeighborZ.push_back(ProcessNeighbor27()); - - int numRecvNeighbor = (int)para->parH[level]->recvProcessNeighborX.size() - 1; - int numSendNeighbor = (int)para->parH[level]->sendProcessNeighborZ.size() - 1; - - const int sizeRecv = 10; - const int sizeSend = 6; - para->parH[level]->recvProcessNeighborX[numRecvNeighbor].numberOfNodes = sizeRecv; - para->parH[level]->sendProcessNeighborZ[numSendNeighbor].numberOfNodes = sizeSend; - - int recvNeighbors[sizeRecv] = { 20, 1, 21, 22, 6, 23, 5, 24, 25, 26 }; - para->parH[level]->recvProcessNeighborX[numRecvNeighbor].index = recvNeighbors; - - int sendNeighbors[sizeSend] = { 1, 2, 3, 4, 5, 6 }; - para->parH[level]->sendProcessNeighborZ[numSendNeighbor].index = sendNeighbors; - - para->findEdgeNodesCommMultiGPU(); - - std::vector<std::pair<int, int>> expectedEdgeNodesXtoZRecv = { std::pair(numRecvNeighbor, 1), - std::pair(numRecvNeighbor, 4), - std::pair(numRecvNeighbor, 6) }; - std::vector<std::pair<int, int>> expectedEdgeNodesXtoZSend = { std::pair(numSendNeighbor, 0), - std::pair(numSendNeighbor, 5), - std::pair(numSendNeighbor, 4) }; - - EXPECT_THAT(para->parH[level]->edgeNodesXtoZ.size(), testing::Eq(expectedEdgeNodesXtoZRecv.size())); - EXPECT_TRUE(compareEdgeNodesRecv(para->parH[level]->edgeNodesXtoZ, expectedEdgeNodesXtoZRecv)) - << "the edgeNodesXtoZ for the receive process do not match the expected nodes"; - EXPECT_TRUE(compareEdgeNodesSend(para->parH[level]->edgeNodesXtoZ, expectedEdgeNodesXtoZSend)) - << "the edgeNodesXtoZ for the send process do not match the expected nodes"; -} - -TEST_F(ParameterTest_findEdgeNodes, shouldReturnCorrectVectorForYZ) -{ - para->parH[level]->recvProcessNeighborY.push_back(ProcessNeighbor27()); - para->parH[level]->sendProcessNeighborZ.push_back(ProcessNeighbor27()); - para->parH[level]->sendProcessNeighborZ.push_back(ProcessNeighbor27()); - - const int sizeRecv = 10; - const int sizeSend1 = 6; - const int sizeSend2 = 5; - - para->parH[level]->recvProcessNeighborY[0].numberOfNodes = sizeRecv; - para->parH[level]->sendProcessNeighborZ[0].numberOfNodes = sizeSend1; - para->parH[level]->sendProcessNeighborZ[1].numberOfNodes = sizeSend2; - - int recvNeighbors[sizeRecv] = { 20, 1, 9, 22, 6, 23, 5, 24, 11, 26 }; - para->parH[level]->recvProcessNeighborY[0].index = recvNeighbors; - - int sendNeighbors1[sizeSend1] = { 1, 2, 3, 4, 5, 6 }; - int sendNeighbors2[sizeSend2] = { 7, 8, 9, 10, 11 }; - para->parH[level]->sendProcessNeighborZ[0].index = sendNeighbors1; - para->parH[level]->sendProcessNeighborZ[1].index = sendNeighbors2; - - para->findEdgeNodesCommMultiGPU(); - - std::vector<std::pair<int, int>> expectedEdgeNodesYtoZRecv = { std::pair(0, 1), std::pair(0, 2), std::pair(0, 4), - std::pair(0, 6), std::pair(0, 8) }; - std::vector<std::pair<int, int>> expectedEdgeNodesYtoZSend = { std::pair(0, 0), std::pair(1, 2), std::pair(0, 5), - std::pair(0, 4), std::pair(1, 4) }; - - EXPECT_THAT(para->parH[level]->edgeNodesYtoZ.size(), testing::Eq(expectedEdgeNodesYtoZRecv.size())); - EXPECT_TRUE(compareEdgeNodesRecv(para->parH[level]->edgeNodesYtoZ, expectedEdgeNodesYtoZRecv)) - << "the edgeNodesYtoZ for the receive process do not match the expected nodes"; - EXPECT_TRUE(compareEdgeNodesSend(para->parH[level]->edgeNodesYtoZ, expectedEdgeNodesYtoZSend)) - << "the edgeNodesYtoZ for the send process do not match the expected nodes"; } \ No newline at end of file