20#include <boost/serialization/utility.hpp>
30 namespace ComputeIndexOwner
38 : use_vector(use_vector)
46 const bool index_range_contiguous,
47 const std::size_t size)
65 const std::size_t start,
66 const std::size_t end,
74 if (
data.empty() && end > start)
85 std::fill(
data.begin() + start,
data.begin() + end, value);
93 std::fill(
data.begin() + start,
data.begin() + end, value);
98 for (
auto i = start; i < end; ++i)
173 std::map<
unsigned int,
178 const auto owned_indices_size_actual =
183 owned_indices_size_actual ==
184 owned_indices.
size(),
196 std::pair<types::global_dof_index, types::global_dof_index>
197 index_range(*interval->begin(), interval->last() + 1);
201 while (index_range.first != index_range.second)
203 Assert(index_range.first < index_range.second,
206 const unsigned int owner =
227 if (owner == my_rank)
233 dic_local_received += next_index - index_range.first;
238 buffers[owner].emplace_back(index_range.first, next_index);
240 index_range.first = next_index;
244#ifdef DEAL_II_WITH_MPI
246 std::vector<MPI_Request> request;
249 if (owned_indices_size_actual == owned_indices.
size())
268 for (
const auto &rank_pair : buffers)
270 request.push_back(MPI_Request());
271 const int ierr = MPI_Isend(rank_pair.second.data(),
272 rank_pair.second.size() * 2,
286 int ierr = MPI_Probe(MPI_ANY_SOURCE, mpi_tag,
comm, &status);
291 ierr = MPI_Get_count(&status,
296 const auto other_rank = status.MPI_SOURCE;
302 std::pair<types::global_dof_index, types::global_dof_index>>
303 buffer(number_amount / 2);
304 ierr = MPI_Recv(buffer.data(),
313 for (
auto interval : buffer)
335 dic_local_received += interval.second - interval.first;
347 using RequestType = std::vector<
348 std::pair<types::global_dof_index, types::global_dof_index>>;
353 std::vector<unsigned int> targets;
354 targets.reserve(buffers.size());
355 for (
const auto &rank_pair : buffers)
356 targets.emplace_back(rank_pair.first);
362 [&buffers](
const unsigned int target_rank) -> RequestType {
363 return buffers.at(target_rank);
367 [&](
const unsigned int source_rank,
368 const RequestType &request) ->
void {
370 for (
auto interval : request)
380 "Multiple processes seem to own the same global index. "
381 "A possible reason is that the sets of locally owned "
382 "indices are not distinct."));
383 Assert(interval.first < interval.second,
389 "The specified interval is not handled by the current process."));
412 if (request.size() > 0)
414 const int ierr = MPI_Waitall(request.size(),
416 MPI_STATUSES_IGNORE);
423 (void)dic_local_received;
459 std::vector<unsigned int> &owning_ranks,
460 const bool track_index_requests)
461 : owned_indices(owned_indices)
462 , indices_to_look_up(indices_to_look_up)
466 , track_index_requests(track_index_requests)
467 , owning_ranks(owning_ranks)
477 const unsigned int other_rank,
480 std::vector<unsigned int> &request_buffer)
482 unsigned int owner_index_guess = 0;
483 for (
const auto &interval : buffer_recv)
484 for (
auto i = interval.first; i < interval.second; ++i)
486 const unsigned int actual_owner =
488 request_buffer.push_back(actual_owner);
500 std::vector<unsigned int>
503 std::vector<unsigned int> targets;
506 unsigned int index = 0;
507 unsigned int owner_index_guess = 0;
523 if (targets.empty() || targets.back() != other_rank)
524 targets.push_back(other_rank);
526 indices.first.push_back(i);
527 indices.second.push_back(index);
542 const unsigned int other_rank,
549 is.
add_indices(indices_i.begin(), indices_i.end());
555 send_buffer.emplace_back(*interval->begin(), interval->last() + 1);
562 const unsigned int other_rank,
563 const std::vector<unsigned int> &recv_buffer)
565 const auto &recv_indices =
568 for (
unsigned int j = 0; j < recv_indices.size(); ++j)
574 std::map<unsigned int, IndexSet>
578 ExcMessage(
"Must enable index range tracking in "
579 "constructor of ConsensusAlgorithmProcess"));
581 std::map<unsigned int, ::IndexSet> requested_indices;
583#ifdef DEAL_II_WITH_MPI
595 std::vector<MPI_Request> send_requests;
606 std::vector<std::vector<types::global_dof_index>> send_data(
608 for (
unsigned int i = 0; i <
requesters.size(); ++i)
617 IndexSet &my_index_set = requested_indices[j.first];
619 for (
const auto &interval : j.second)
620 my_index_set.
add_range(index_offset + interval.first,
621 index_offset + interval.second);
628 send_data[i].push_back(j.first);
629 send_data[i].push_back(j.second.size());
630 for (
const auto &interval : j.second)
632 send_data[i].push_back(interval.first);
633 send_data[i].push_back(interval.second);
636 send_requests.push_back(MPI_Request());
638 MPI_Isend(send_data[i].data(),
645 &send_requests.back());
655 int ierr = MPI_Probe(MPI_ANY_SOURCE, mpi_tag,
comm, &status);
660 ierr = MPI_Get_count(
669 std::pair<types::global_dof_index, types::global_dof_index>>
670 buffer(number_amount / 2);
685 unsigned int offset = 0;
686 while (offset < buffer.size())
692 for (
unsigned int i = offset + 1;
693 i < offset + buffer[offset].second + 1;
695 my_index_set.
add_range(index_offset + buffer[i].first,
696 index_offset + buffer[i].second);
701 IndexSet &index_set = requested_indices[buffer[offset].first];
702 if (index_set.
size() == 0)
706 offset += buffer[offset].second + 1;
711 if (send_requests.size() > 0)
713 const auto ierr = MPI_Waitall(send_requests.size(),
714 send_requests.data(),
715 MPI_STATUSES_IGNORE);
721 for (
const auto &it : requested_indices)
727 "The indices requested from the current "
728 "MPI rank should be locally owned here!"));
734 return requested_indices;
742 const unsigned int rank_of_request,
743 const unsigned int rank_of_owner,
744 unsigned int &owner_index_guess)
753 auto &request =
requesters[owner_index_guess];
754 if (request.empty() || request.back().first != rank_of_request)
755 request.emplace_back(
758 std::pair<types::global_dof_index, types::global_dof_index>>());
760 auto &intervals = request.back().second;
761 if (intervals.empty() || intervals.back().second != index_within_dict)
762 intervals.emplace_back(index_within_dict, index_within_dict + 1);
764 ++intervals.back().second;
IntervalIterator end_intervals() const
size_type n_elements() const
void set_size(const size_type size)
IntervalIterator begin_intervals() const
void subtract_set(const IndexSet &other)
void add_range(const size_type begin, const size_type end)
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< unsigned int > & owning_ranks
const IndexSet & indices_to_look_up
std::vector< std::vector< std::pair< unsigned int, std::vector< std::pair< types::global_dof_index, types::global_dof_index > > > > > requesters
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 types::global_dof_index 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)
std::vector< unsigned int > selector(const std::vector< unsigned int > &targets, const std::function< RequestType(const unsigned int)> &create_request, const std::function< AnswerType(const unsigned int, const RequestType &)> &answer_request, const std::function< void(const unsigned int, const AnswerType &)> &process_answer, const MPI_Comm comm)
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)
const MPI_Datatype mpi_type_id_for_type
::VectorizedArray< Number, width > min(const ::VectorizedArray< Number, width > &, const ::VectorizedArray< Number, width > &)
unsigned int global_dof_index
*braid_SplitCommworld & comm
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