From b235859bccb4e12a5bb56ad15e8be575ba670a10 Mon Sep 17 00:00:00 2001
From: Tobias Meisel <tobias.meisel@ufz.de>
Date: Tue, 15 Dec 2020 13:05:58 +0100
Subject: [PATCH] [MeL/IO] Add generic abstraction layer for parallel and
 serial file IO

---
 MeshLib/CMakeLists.txt              |  5 +++
 MeshLib/IO/XDMF/mpi/partition.cpp   | 57 +++++++++++++++++++++++++++++
 MeshLib/IO/XDMF/partition.h         | 19 ++++++++++
 MeshLib/IO/XDMF/posix/partition.cpp | 14 +++++++
 4 files changed, 95 insertions(+)
 create mode 100644 MeshLib/IO/XDMF/mpi/partition.cpp
 create mode 100644 MeshLib/IO/XDMF/partition.h
 create mode 100644 MeshLib/IO/XDMF/posix/partition.cpp

diff --git a/MeshLib/CMakeLists.txt b/MeshLib/CMakeLists.txt
index 59188234505..24a835276ee 100644
--- a/MeshLib/CMakeLists.txt
+++ b/MeshLib/CMakeLists.txt
@@ -14,6 +14,11 @@ append_source_files(SOURCES IO/Legacy)
 append_source_files(SOURCES IO/VtkIO)
 if(OGS_USE_XDMF)
     append_source_files(SOURCES IO/XDMF)
+    if(OGS_USE_PETSC)
+        append_source_files(SOURCES IO/XDMF/mpi)
+    else()
+        append_source_files(SOURCES IO/XDMF/posix)
+    endif()
 endif()
 append_source_files(SOURCES MeshQuality)
 append_source_files(SOURCES Vtk)
diff --git a/MeshLib/IO/XDMF/mpi/partition.cpp b/MeshLib/IO/XDMF/mpi/partition.cpp
new file mode 100644
index 00000000000..b626e4fc902
--- /dev/null
+++ b/MeshLib/IO/XDMF/mpi/partition.cpp
@@ -0,0 +1,57 @@
+/**
+ * \file
+ * \author Tobias Meisel
+ * \date   2020-12-08
+ * \brief  Function specific to execution with MPI!!
+ * \copyright Copyright (c) 2012-2020, OpenGeoSys Community
+ * (http://www.opengeosys.org) Distributed under a Modified BSD License. See
+ * accompanying file LICENSE.txt or http://www.opengeosys.org/project/license
+ */
+
+#include <mpi.h>
+
+#include <deque>
+#include <numeric>
+
+#include "../fileIO.h"
+#include "BaseLib/Logging.h"
+
+namespace MeshLib::IO
+{
+bool isFileManager()
+{
+    int mpi_rank;
+    MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);
+    return mpi_rank == 0;
+}
+
+std::pair<std::size_t, std::size_t> getPartitionInfo(std::size_t const size)
+{
+    MPI_Comm const mpi_comm = MPI_COMM_WORLD;
+    int mpi_size;
+    int mpi_rank;
+    MPI_Comm_size(mpi_comm, &mpi_size);
+    MPI_Comm_rank(mpi_comm, &mpi_rank);
+
+    std::vector<std::size_t> partition_sizes;
+    partition_sizes.resize(mpi_size);
+
+    MPI_Allgather(&size,
+                  1,
+                  MPI_UNSIGNED_LONG,
+                  partition_sizes.data(),
+                  1,
+                  MPI_UNSIGNED_LONG,
+                  mpi_comm);
+
+    // the first partition's offset is zero, offsets for subsequent
+    // partitions are the accumulated sum of all preceding size (excluding
+    // own size)
+    std::vector<std::size_t> partition_offsets(1, 0);
+    std::partial_sum(partition_sizes.begin(),
+                     partition_sizes.end(),
+                     back_inserter(partition_offsets));
+
+    return {partition_offsets[mpi_rank], partition_offsets.back()};
+}
+}  // namespace MeshLib::IO
diff --git a/MeshLib/IO/XDMF/partition.h b/MeshLib/IO/XDMF/partition.h
new file mode 100644
index 00000000000..95b8b042f99
--- /dev/null
+++ b/MeshLib/IO/XDMF/partition.h
@@ -0,0 +1,19 @@
+/**
+ * \file
+ * \author Tobias Meisel
+ * \date   2020-12-08
+ * \brief  Dispatches functions specific to execution plattform (w/o MPI)
+ * \copyright Copyright (c) 2012-2020, OpenGeoSys Community
+ * (http://www.opengeosys.org) Distributed under a Modified BSD License. See
+ * accompanying file LICENSE.txt or http://www.opengeosys.org/project/license
+ */
+
+#pragma once
+
+#include <utility>
+
+namespace MeshLib::IO
+{
+std::pair<std::size_t, std::size_t> getPartitionInfo(std::size_t const size);
+bool isFileManager();
+}  // namespace MeshLib::IO
diff --git a/MeshLib/IO/XDMF/posix/partition.cpp b/MeshLib/IO/XDMF/posix/partition.cpp
new file mode 100644
index 00000000000..2a3d98df675
--- /dev/null
+++ b/MeshLib/IO/XDMF/posix/partition.cpp
@@ -0,0 +1,14 @@
+#include "../partition.h"
+
+namespace MeshLib::IO
+{
+bool isFileManager()
+{
+    return true;
+}
+
+std::pair<std::size_t, std::size_t> getPartitionInfo(std::size_t const size)
+{
+    return {0, size};
+}
+}  // namespace MeshLib::IO
\ No newline at end of file
-- 
GitLab