From 146eca79f90539754c562f8189cd1966597e24d7 Mon Sep 17 00:00:00 2001 From: Peter Munch Date: Sat, 7 Mar 2020 11:01:05 +0100 Subject: [PATCH] Add default constructor to NoncontiguousPartitioner --- .../base/mpi_noncontiguous_partitioner.h | 14 +++ .../mpi_noncontiguous_partitioner.templates.h | 113 +++++++++++------- 2 files changed, 81 insertions(+), 46 deletions(-) diff --git a/include/deal.II/base/mpi_noncontiguous_partitioner.h b/include/deal.II/base/mpi_noncontiguous_partitioner.h index e04ac51190..1942348c49 100644 --- a/include/deal.II/base/mpi_noncontiguous_partitioner.h +++ b/include/deal.II/base/mpi_noncontiguous_partitioner.h @@ -43,6 +43,12 @@ namespace Utilities : public LinearAlgebra::CommunicationPatternBase { public: + /** + * Default constructor. Requires calling one of the reinit() functions + * to create a valid object. + */ + NoncontiguousPartitioner() = default; + /** * Constructor. Set up point-to-point communication pattern based on the * IndexSets arguments @p indexset_has and @p indexset_want for the MPI @@ -124,6 +130,14 @@ namespace Utilities const IndexSet &indexset_want, const MPI_Comm &communicator) override; + /** + * Initialize the inner data structures. + */ + void + reinit(const std::vector &indices_has, + const std::vector &indices_want, + const MPI_Comm & communicator); + private: /// MPI communicator MPI_Comm communicator; diff --git a/include/deal.II/base/mpi_noncontiguous_partitioner.templates.h b/include/deal.II/base/mpi_noncontiguous_partitioner.templates.h index e8b6ca134f..9fe98cc0db 100644 --- a/include/deal.II/base/mpi_noncontiguous_partitioner.templates.h +++ b/include/deal.II/base/mpi_noncontiguous_partitioner.templates.h @@ -42,60 +42,18 @@ namespace Utilities this->reinit(indexset_has, indexset_want, communicator); } + + template NoncontiguousPartitioner::NoncontiguousPartitioner( const std::vector &indices_has, const std::vector &indices_want, const MPI_Comm & communicator) { - // step 0) determine "number of degrees of freedom" needed for IndexSet - const types::global_dof_index n_dofs = Utilities::MPI::max( - std::max( - [&indices_has]() { - const auto it = max_element(indices_has.begin(), indices_has.end()); - return it == indices_has.end() ? 0 : (*it + 1); - }(), - [&indices_want]() { - const auto it = - max_element(indices_want.begin(), indices_want.end()); - return it == indices_want.end() ? 0 : (*it + 1); - }()), - communicator); - - // step 1) convert vectors to indexsets (sorted!) - IndexSet index_set_has(n_dofs); - index_set_has.add_indices(indices_has.begin(), indices_has.end()); - - IndexSet index_set_want(n_dofs); - index_set_want.add_indices(indices_want.begin(), indices_want.end()); - - // step 2) setup internal data structures with indexset - this->reinit(index_set_has, index_set_want, communicator); - - // step 3) fix inner data structures so that it is sorted as - // in the original vector - { - std::vector temp_map_send( - index_set_has.n_elements()); - - for (types::global_dof_index i = 0; i < indices_has.size(); i++) - temp_map_send[index_set_has.index_within_set(indices_has[i])] = i; - - for (auto &i : send_indices) - i = temp_map_send[i]; - } - - { - std::vector temp_map_recv( - index_set_want.n_elements()); + this->reinit(indices_has, indices_want, communicator); + } - for (types::global_dof_index i = 0; i < indices_want.size(); i++) - temp_map_recv[index_set_want.index_within_set(indices_want[i])] = i; - for (auto &i : recv_indices) - i = temp_map_recv[i]; - } - } template std::pair @@ -104,6 +62,8 @@ namespace Utilities return {send_ranks.size(), recv_ranks.size()}; } + + template types::global_dof_index NoncontiguousPartitioner::memory_consumption() @@ -120,6 +80,8 @@ namespace Utilities MemoryConsumption::memory_consumption(recv_requests); } + + template const MPI_Comm & NoncontiguousPartitioner::get_mpi_communicator() const @@ -127,6 +89,8 @@ namespace Utilities return communicator; } + + template void NoncontiguousPartitioner::reinit(const IndexSet &indexset_has, @@ -212,6 +176,63 @@ namespace Utilities + template + void + NoncontiguousPartitioner::reinit( + const std::vector &indices_has, + const std::vector &indices_want, + const MPI_Comm & communicator) + { + // step 0) determine "number of degrees of freedom" needed for IndexSet + const types::global_dof_index n_dofs = Utilities::MPI::max( + std::max( + [&indices_has]() { + const auto it = max_element(indices_has.begin(), indices_has.end()); + return it == indices_has.end() ? 0 : (*it + 1); + }(), + [&indices_want]() { + const auto it = + max_element(indices_want.begin(), indices_want.end()); + return it == indices_want.end() ? 0 : (*it + 1); + }()), + communicator); + + // step 1) convert vectors to indexsets (sorted!) + IndexSet index_set_has(n_dofs); + index_set_has.add_indices(indices_has.begin(), indices_has.end()); + + IndexSet index_set_want(n_dofs); + index_set_want.add_indices(indices_want.begin(), indices_want.end()); + + // step 2) setup internal data structures with indexset + this->reinit(index_set_has, index_set_want, communicator); + + // step 3) fix inner data structures so that it is sorted as + // in the original vector + { + std::vector temp_map_send( + index_set_has.n_elements()); + + for (types::global_dof_index i = 0; i < indices_has.size(); i++) + temp_map_send[index_set_has.index_within_set(indices_has[i])] = i; + + for (auto &i : send_indices) + i = temp_map_send[i]; + } + + { + std::vector temp_map_recv( + index_set_want.n_elements()); + + for (types::global_dof_index i = 0; i < indices_want.size(); i++) + temp_map_recv[index_set_want.index_within_set(indices_want[i])] = i; + + for (auto &i : recv_indices) + i = temp_map_recv[i]; + } + } + + template template void -- 2.39.5