From 0f8d111e26db73c7a7f4bfae37c6788578fb70e6 Mon Sep 17 00:00:00 2001
From: Anna Wellmann <a.wellmann@tu-bs.de>
Date: Thu, 2 Jun 2022 14:09:31 +0000
Subject: [PATCH] Make routine for finding edge nodes to free functions

---
 src/gpu/VirtualFluids_GPU/LBM/Simulation.cpp  |   3 +-
 .../Parameter/EdgeNodeFinder.cpp              | 113 ++++++++++++++++++
 .../Parameter/EdgeNodeFinder.h                |  65 ++++++++++
 .../VirtualFluids_GPU/Parameter/Parameter.cpp |  96 ---------------
 .../VirtualFluids_GPU/Parameter/Parameter.h   |  11 +-
 5 files changed, 182 insertions(+), 106 deletions(-)
 create mode 100644 src/gpu/VirtualFluids_GPU/Parameter/EdgeNodeFinder.cpp
 create mode 100644 src/gpu/VirtualFluids_GPU/Parameter/EdgeNodeFinder.h

diff --git a/src/gpu/VirtualFluids_GPU/LBM/Simulation.cpp b/src/gpu/VirtualFluids_GPU/LBM/Simulation.cpp
index a05554298..b4a0828fb 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 000000000..1134ee0c6
--- /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 000000000..a526c2840
--- /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/Parameter.cpp b/src/gpu/VirtualFluids_GPU/Parameter/Parameter.cpp
index d63fb1d3f..0187cc364 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 6646cdbfb..161fae53b 100644
--- a/src/gpu/VirtualFluids_GPU/Parameter/Parameter.h
+++ b/src/gpu/VirtualFluids_GPU/Parameter/Parameter.h
@@ -610,7 +610,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 +935,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
-- 
GitLab