21#include <boost/serialization/utility.hpp>
31 namespace ComputeIndexOwner
39 : use_vector(use_vector)
48 const std::size_t size)
66 const std::size_t start,
67 const std::size_t end,
75 if (
data.empty() && end > start)
86 std::fill(
data.begin() + start,
data.begin() + end, value);
94 std::fill(
data.begin() + start,
data.begin() + end, value);
99 for (
auto i = start; i < end; ++i)
173#ifdef DEAL_II_WITH_MPI
177 std::map<
unsigned int,
188 owned_indices.
size(),
200 std::pair<types::global_dof_index, types::global_dof_index>
201 index_range(*interval->begin(), interval->last() + 1);
210 const unsigned int owner =
231 if (
owner == my_rank)
249 std::vector<MPI_Request> request;
273 request.push_back(MPI_Request());
305 std::pair<types::global_dof_index, types::global_dof_index>>
316 for (
auto interval :
buffer)
351 std::pair<types::global_dof_index, types::global_dof_index>>;
353 ConsensusAlgorithms::selector<RequestType>(
356 std::vector<unsigned int>
targets;
357 targets.reserve(buffers.size());
373 for (
auto interval : request)
383 "Multiple processes seem to own the same global index. "
384 "A possible reason is that the sets of locally owned "
385 "indices are not distinct."));
386 Assert(interval.first < interval.second,
392 "The specified interval is not handled by the current process."));
415 if (request.size() > 0)
435#ifdef DEAL_II_WITH_MPI
464 const IndexSet & indices_to_look_up,
466 std::vector<unsigned int> &owning_ranks,
467 const bool track_index_requests)
468 : owned_indices(owned_indices)
469 , indices_to_look_up(indices_to_look_up)
473 , track_index_requests(track_index_requests)
474 , owning_ranks(owning_ranks)
491 for (
auto i = interval.first; i < interval.second; ++i)
507 std::vector<unsigned int>
510 std::vector<unsigned int>
targets;
513 unsigned int index = 0;
533 indices.first.push_back(i);
534 indices.second.push_back(index);
559 for (
auto interval =
is.begin_intervals();
560 interval !=
is.end_intervals();
562 send_buffer.emplace_back(*interval->begin(), interval->last() + 1);
572 const auto &recv_indices =
575 for (
unsigned int j = 0;
j < recv_indices.
size(); ++
j)
581 std::map<unsigned int, IndexSet>
585 ExcMessage(
"Must enable index range tracking in "
586 "constructor of ConsensusAlgorithmProcess"));
590#ifdef DEAL_II_WITH_MPI
602 std::vector<MPI_Request> send_requests;
613 std::vector<std::vector<unsigned int>> send_data(
requesters.size());
614 for (
unsigned int i = 0; i <
requesters.size(); ++i)
625 for (
const auto &interval :
j.second)
634 send_data[i].push_back(
j.first);
635 send_data[i].push_back(
j.second.
size());
636 for (
const auto &interval :
j.second)
638 send_data[i].push_back(interval.first);
639 send_data[i].push_back(interval.second);
642 send_requests.push_back(MPI_Request());
649 &send_requests.back());
669 std::vector<std::pair<unsigned int, unsigned int>>
buffer(
684 unsigned int offset = 0;
691 for (
unsigned int i = offset + 1;
692 i < offset +
buffer[offset].second + 1;
701 if (index_set.
size() == 0)
705 offset +=
buffer[offset].second + 1;
710 if (send_requests.size() > 0)
713 send_requests.data(),
726 "The indices requested from the current "
727 "MPI rank should be locally owned here!"));
754 request.emplace_back(
756 std::vector<std::pair<unsigned int, unsigned int>>());
758 auto &intervals = request.back().second;
762 ++intervals.back().second;
value_type * data() const noexcept
IntervalIterator end_intervals() const
size_type n_elements() const
void set_size(const size_type size)
IntervalIterator begin_intervals() const
void add_indices(const ForwardIterator &begin, const ForwardIterator &end)
const unsigned int my_rank
virtual std::vector< unsigned int > compute_targets() override
virtual void answer_request(const unsigned int other_rank, const std::vector< std::pair< types::global_dof_index, types::global_dof_index > > &buffer_recv, std::vector< unsigned int > &request_buffer) override
virtual void read_answer(const unsigned int other_rank, const std::vector< unsigned int > &recv_buffer) override
virtual void create_request(const unsigned int other_rank, std::vector< std::pair< types::global_dof_index, types::global_dof_index > > &send_buffer) override
std::vector< std::vector< std::pair< unsigned int, std::vector< std::pair< unsigned int, unsigned int > > > > > requesters
std::vector< unsigned int > & owning_ranks
const IndexSet & indices_to_look_up
std::map< unsigned int, std::pair< std::vector< types::global_dof_index >, std::vector< unsigned int > > > indices_to_look_up_by_dict_rank
const IndexSet & owned_indices
std::map< unsigned int, IndexSet > get_requesters()
ConsensusAlgorithmsPayload(const IndexSet &owned_indices, const IndexSet &indices_to_look_up, const MPI_Comm comm, std::vector< unsigned int > &owning_ranks, const bool track_index_requests=false)
void append_index_origin(const unsigned int index_within_dictionary, const unsigned int rank_of_request, const unsigned int rank_of_owner, unsigned int &owner_index_guess)
const bool track_index_requests
index_type & operator[](const std::size_t index)
bool entry_has_been_set(const std::size_t index) const
void reinit(const bool use_vector, const bool index_range_contiguous, const std::size_t size)
FlexibleIndexStorage(const bool use_vector=true)
static const index_type invalid_index_value
void fill(const std::size_t start, const std::size_t end, const index_type &value)
std::map< std::size_t, index_type > data_map
std::vector< index_type > data
#define DEAL_II_NAMESPACE_OPEN
#define DEAL_II_NAMESPACE_CLOSE
static ::ExceptionBase & ExcNotImplemented()
#define Assert(cond, exc)
#define AssertDimension(dim1, dim2)
#define AssertThrowMPI(error_code)
#define AssertIndexRange(index, range)
static ::ExceptionBase & ExcInternalError()
static ::ExceptionBase & ExcMessage(std::string arg1)
#define AssertThrow(cond, exc)
T sum(const T &t, const MPI_Comm mpi_communicator)
unsigned int n_mpi_processes(const MPI_Comm mpi_communicator)
unsigned int this_mpi_process(const MPI_Comm mpi_communicator)
::VectorizedArray< Number, width > min(const ::VectorizedArray< Number, width > &, const ::VectorizedArray< Number, width > &)
unsigned int global_dof_index
std::vector< unsigned int > actually_owning_rank_list
FlexibleIndexStorage actually_owning_ranks
unsigned int dof_to_dict_rank(const types::global_dof_index i)
types::global_dof_index get_index_offset(const unsigned int rank)
types::global_dof_index locally_owned_size
types::global_dof_index dofs_per_process
unsigned int n_dict_procs_in_owned_indices
static constexpr unsigned int sparsity_factor
unsigned int stride_small_size
static constexpr unsigned int range_minimum_grain_size
std::pair< types::global_dof_index, types::global_dof_index > local_range
void reinit(const IndexSet &owned_indices, const MPI_Comm comm)
void partition(const IndexSet &owned_indices, const MPI_Comm comm)
unsigned int get_owning_rank_index(const unsigned int rank_in_owned_indices, const unsigned int guess=0)
types::global_dof_index size
#define DEAL_II_DOF_INDEX_MPI_TYPE