Merge pull request #5210 from akva2/move_parallel_split_to_cpp

MPIPartitionFromFile: move implementation to generic translation unit
This commit is contained in:
Markus Blatt 2024-02-19 16:44:35 +01:00 committed by GitHub
commit ae9ddfbea4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 80 additions and 77 deletions

View File

@ -38,86 +38,12 @@
#include <opm/models/blackoil/blackoilproperties.hh>
#include <array>
#include <filesystem>
#include <fstream>
#include <functional>
#include <iterator>
#include <memory>
#include <stdexcept>
#include <tuple>
#include <unordered_map>
#include <vector>
#include <fmt/format.h>
#if HAVE_MPI
namespace Opm { namespace details {
class MPIPartitionFromFile
{
public:
explicit MPIPartitionFromFile(const std::filesystem::path& partitionFile)
: partitionFile_(partitionFile)
{}
std::vector<int> operator()(const Dune::CpGrid& grid) const;
private:
std::filesystem::path partitionFile_{};
};
inline std::vector<int>
MPIPartitionFromFile::operator()(const Dune::CpGrid& grid) const
{
std::ifstream pfile { this->partitionFile_ };
auto partition = std::vector<int> {
std::istream_iterator<int> { pfile },
std::istream_iterator<int> {}
};
const auto nc =
static_cast<std::vector<int>::size_type>(grid.size(0));
if (partition.size() == nc) {
// Input is one process ID for each active cell
return partition;
}
if (partition.size() == 3 * nc) {
// Partition file is of the form
//
// Process_ID Cartesian_Idx NLDD_Domain
//
// with one row for each active cell. Select first column.
auto g2l = std::unordered_map<int, int>{};
auto locCell = 0;
for (const auto& globCell : grid.globalCell()) {
g2l.insert_or_assign(globCell, locCell++);
}
auto filtered_partition = std::vector<int>(nc);
for (auto c = 0*nc; c < nc; ++c) {
auto pos = g2l.find(partition[3*c + 1]);
if (pos != g2l.end()) {
filtered_partition[pos->second] = partition[3*c + 0];
}
}
return filtered_partition;
}
throw std::invalid_argument {
fmt::format("Partition file '{}' with {} values does "
"not match CpGrid instance with {} cells",
this->partitionFile_.generic_string(),
partition.size(), nc)
};
}
}} // namespace Opm::details
#endif // HAVE_MPI
namespace Opm {
template <class TypeTag>
class EclCpGridVanguard;

View File

@ -52,20 +52,74 @@
#include <ebos/femcpgridcompat.hh>
#endif //HAVE_DUNE_FEM
#include <algorithm>
#include <cassert>
#include <fstream>
#include <iterator>
#include <numeric>
#include <optional>
#include <sstream>
#include <stdexcept>
#include <string>
#include <tuple>
#include <vector>
#include <fmt/format.h>
namespace Opm {
#if HAVE_MPI
namespace details {
std::vector<int>
MPIPartitionFromFile::operator()(const Dune::CpGrid& grid) const
{
std::ifstream pfile { this->partitionFile_ };
auto partition = std::vector<int> {
std::istream_iterator<int> { pfile },
std::istream_iterator<int> {}
};
const auto nc =
static_cast<std::vector<int>::size_type>(grid.size(0));
if (partition.size() == nc) {
// Input is one process ID for each active cell
return partition;
}
if (partition.size() == 3 * nc) {
// Partition file is of the form
//
// Process_ID Cartesian_Idx NLDD_Domain
//
// with one row for each active cell. Select first column.
auto g2l = std::unordered_map<int, int>{};
auto locCell = 0;
for (const auto& globCell : grid.globalCell()) {
g2l.insert_or_assign(globCell, locCell++);
}
auto filtered_partition = std::vector<int>(nc);
for (auto c = 0*nc; c < nc; ++c) {
auto pos = g2l.find(partition[3*c + 1]);
if (pos != g2l.end()) {
filtered_partition[pos->second] = partition[3*c + 0];
}
}
return filtered_partition;
}
throw std::invalid_argument {
fmt::format("Partition file '{}' with {} values does "
"not match CpGrid instance with {} cells",
this->partitionFile_.generic_string(),
partition.size(), nc)
};
}
}
#endif
std::optional<std::function<std::vector<int> (const Dune::CpGrid&)>> externalLoadBalancer;
template<class ElementMapper, class GridView, class Scalar>

View File

@ -36,6 +36,10 @@
#include <optional>
#include <vector>
#if HAVE_MPI
#include <filesystem>
#endif
namespace Opm {
class EclipseState;
class Schedule;
@ -45,6 +49,25 @@ namespace Opm {
namespace Opm {
#if HAVE_MPI
namespace details {
class MPIPartitionFromFile
{
public:
explicit MPIPartitionFromFile(const std::filesystem::path& partitionFile)
: partitionFile_(partitionFile)
{}
std::vector<int> operator()(const Dune::CpGrid& grid) const;
private:
std::filesystem::path partitionFile_{};
};
} // namespace Opm::details
#endif // HAVE_MPI
/// \brief optional functor returning external load balancing information
///
/// If it is set then this will be used during loadbalance.