15#ifndef dealii_mpi_consensus_algorithm_h
16#define dealii_mpi_consensus_algorithm_h
21#include <deal.II/base/mpi.templates.h>
131 namespace ConsensusAlgorithms
157 template <
typename RequestType,
typename AnswerType>
173 virtual std::vector<unsigned int>
202 const RequestType &buffer_recv,
203 AnswerType &request_buffer);
214 const AnswerType &recv_buffer);
232 template <
typename RequestType,
typename AnswerType>
255 std::vector<unsigned int>
281 virtual std::vector<unsigned int>
283 const std::vector<unsigned int> &targets,
284 const std::function<RequestType(
const unsigned int)> &create_request,
285 const std::function<AnswerType(
const unsigned int,
286 const RequestType &)> &answer_request,
287 const std::function<
void(
const unsigned int,
const AnswerType &)>
306 template <
typename RequestType,
typename AnswerType>
326 virtual std::vector<unsigned int>
328 const std::vector<unsigned int> &targets,
329 const std::function<RequestType(
const unsigned int)> &create_request,
330 const std::function<AnswerType(
const unsigned int,
331 const RequestType &)> &answer_request,
332 const std::function<
void(
const unsigned int,
const AnswerType &)>
337#ifdef DEAL_II_WITH_MPI
383 const std::function<
void(
const unsigned int,
const AnswerType &)>
409 const std::function<AnswerType(
const unsigned int,
410 const RequestType &)> &answer_request,
419 const std::vector<unsigned int> &targets,
420 const std::function<RequestType(
const unsigned int)> &create_request,
476 template <
typename RequestType,
typename AnswerType>
477 std::vector<unsigned int>
478 nbx(
const std::vector<unsigned int> &targets,
479 const std::function<RequestType(
const unsigned int)> &create_request,
480 const std::function<AnswerType(
const unsigned int,
481 const RequestType &)> &answer_request,
482 const std::function<
void(
const unsigned int,
const AnswerType &)>
523 template <
typename RequestType>
524 std::vector<unsigned int>
525 nbx(
const std::vector<unsigned int> &targets,
526 const std::function<RequestType(
const unsigned int)> &create_request,
527 const std::function<
void(
const unsigned int,
const RequestType &)>
556 template <
typename RequestType,
typename AnswerType>
576 virtual std::vector<unsigned int>
578 const std::vector<unsigned int> &targets,
579 const std::function<RequestType(
const unsigned int)> &create_request,
580 const std::function<AnswerType(
const unsigned int,
581 const RequestType &)> &answer_request,
582 const std::function<
void(
const unsigned int,
const AnswerType &)>
587#ifdef DEAL_II_WITH_MPI
624 const std::vector<unsigned int> &targets,
625 const std::function<RequestType(
const unsigned int)> &create_request,
634 const unsigned int index,
635 const std::function<AnswerType(
const unsigned int,
636 const RequestType &)> &answer_request,
645 const unsigned int n_targets,
646 const std::function<
void(
const unsigned int,
const AnswerType &)>
716 template <
typename RequestType,
typename AnswerType>
717 std::vector<unsigned int>
718 pex(
const std::vector<unsigned int> &targets,
719 const std::function<RequestType(
const unsigned int)> &create_request,
720 const std::function<AnswerType(
const unsigned int,
721 const RequestType &)> &answer_request,
722 const std::function<
void(
const unsigned int,
const AnswerType &)>
763 template <
typename RequestType>
764 std::vector<unsigned int>
765 pex(
const std::vector<unsigned int> &targets,
766 const std::function<RequestType(
const unsigned int)> &create_request,
767 const std::function<
void(
const unsigned int,
const RequestType &)>
776 template <
typename RequestType,
typename AnswerType>
791 virtual std::vector<unsigned int>
793 const std::vector<unsigned int> &targets,
794 const std::function<RequestType(
const unsigned int)> &create_request,
795 const std::function<AnswerType(
const unsigned int,
796 const RequestType &)> &answer_request,
797 const std::function<
void(
const unsigned int,
const AnswerType &)>
836 template <
typename RequestType,
typename AnswerType>
837 std::vector<unsigned int>
839 const std::vector<unsigned int> &targets,
840 const std::function<RequestType(
const unsigned int)> &create_request,
841 const std::function<AnswerType(
const unsigned int,
const RequestType &)>
843 const std::function<
void(
const unsigned int,
const AnswerType &)>
876 template <
typename RequestType>
877 std::vector<unsigned int>
879 const std::vector<unsigned int> &targets,
880 const std::function<RequestType(
const unsigned int)> &create_request,
881 const std::function<
void(
const unsigned int,
const RequestType &)>
899 template <
typename RequestType,
typename AnswerType>
921 virtual std::vector<unsigned int>
923 const std::vector<unsigned int> &targets,
924 const std::function<RequestType(
const unsigned int)> &create_request,
925 const std::function<AnswerType(
const unsigned int,
926 const RequestType &)> &answer_request,
927 const std::function<
void(
const unsigned int,
const AnswerType &)>
982 template <
typename RequestType,
typename AnswerType>
983 std::vector<unsigned int>
985 const std::vector<unsigned int> &targets,
986 const std::function<RequestType(
const unsigned int)> &create_request,
987 const std::function<AnswerType(
const unsigned int,
const RequestType &)>
989 const std::function<
void(
const unsigned int,
const AnswerType &)>
1030 template <
typename RequestType>
1031 std::vector<unsigned int>
1033 const std::vector<unsigned int> &targets,
1034 const std::function<RequestType(
const unsigned int)> &create_request,
1035 const std::function<
void(
const unsigned int,
const RequestType &)>
1044 template <
typename RequestType,
typename AnswerType>
1045 std::vector<unsigned int>
1046 nbx(
const std::vector<unsigned int> &targets,
1047 const std::function<RequestType(
const unsigned int)> &create_request,
1048 const std::function<AnswerType(
const unsigned int,
1049 const RequestType &)> &answer_request,
1050 const std::function<
void(
const unsigned int,
const AnswerType &)>
1055 targets, create_request, answer_request, process_answer,
comm);
1060 template <
typename RequestType>
1061 std::vector<unsigned int>
1062 nbx(
const std::vector<unsigned int> &targets,
1063 const std::function<RequestType(
const unsigned int)> &create_request,
1064 const std::function<
void(
const unsigned int,
const RequestType &)>
1073 using EmptyType = std::tuple<>;
1075 return nbx<RequestType, EmptyType>(
1079 [&process_request](
const unsigned int source_rank,
1080 const RequestType &request) -> EmptyType {
1081 process_request(source_rank, request);
1089 [](
const unsigned int ,
1090 const EmptyType & ) {},
1096 template <
typename RequestType,
typename AnswerType>
1097 std::vector<unsigned int>
1098 pex(
const std::vector<unsigned int> &targets,
1099 const std::function<RequestType(
const unsigned int)> &create_request,
1100 const std::function<AnswerType(
const unsigned int,
1101 const RequestType &)> &answer_request,
1102 const std::function<
void(
const unsigned int,
const AnswerType &)>
1106 return PEX<RequestType, AnswerType>().run(
1107 targets, create_request, answer_request, process_answer,
comm);
1112 template <
typename RequestType>
1113 std::vector<unsigned int>
1114 pex(
const std::vector<unsigned int> &targets,
1115 const std::function<RequestType(
const unsigned int)> &create_request,
1116 const std::function<
void(
const unsigned int,
const RequestType &)>
1125 using EmptyType = std::tuple<>;
1127 return pex<RequestType, EmptyType>(
1131 [&process_request](
const unsigned int source_rank,
1132 const RequestType &request) -> EmptyType {
1133 process_request(source_rank, request);
1141 [](
const unsigned int ,
1142 const EmptyType & ) {},
1148 template <
typename RequestType,
typename AnswerType>
1149 std::vector<unsigned int>
1151 const std::vector<unsigned int> &targets,
1152 const std::function<RequestType(
const unsigned int)> &create_request,
1153 const std::function<AnswerType(
const unsigned int,
const RequestType &)>
1155 const std::function<
void(
const unsigned int,
const AnswerType &)>
1159 return Serial<RequestType, AnswerType>().run(
1160 targets, create_request, answer_request, process_answer,
comm);
1165 template <
typename RequestType>
1166 std::vector<unsigned int>
1168 const std::vector<unsigned int> &targets,
1169 const std::function<RequestType(
const unsigned int)> &create_request,
1170 const std::function<
void(
const unsigned int,
const RequestType &)>
1179 using EmptyType = std::tuple<>;
1181 return serial<RequestType, EmptyType>(
1185 [&process_request](
const unsigned int source_rank,
1186 const RequestType &request) -> EmptyType {
1187 process_request(source_rank, request);
1195 [](
const unsigned int ,
1196 const EmptyType & ) {},
1202 template <
typename RequestType,
typename AnswerType>
1203 std::vector<unsigned int>
1205 const std::vector<unsigned int> &targets,
1206 const std::function<RequestType(
const unsigned int)> &create_request,
1207 const std::function<AnswerType(
const unsigned int,
const RequestType &)>
1209 const std::function<
void(
const unsigned int,
const AnswerType &)>
1213 return Selector<RequestType, AnswerType>().run(
1214 targets, create_request, answer_request, process_answer,
comm);
1219 template <
typename RequestType>
1220 std::vector<unsigned int>
1222 const std::vector<unsigned int> &targets,
1223 const std::function<RequestType(
const unsigned int)> &create_request,
1224 const std::function<
void(
const unsigned int,
const RequestType &)>
1233 using EmptyType = std::tuple<>;
1235 return selector<RequestType, EmptyType>(
1239 [&process_request](
const unsigned int source_rank,
1240 const RequestType &request) -> EmptyType {
1241 process_request(source_rank, request);
1249 [](
const unsigned int ,
1250 const EmptyType & ) {},
1271 namespace ConsensusAlgorithms
1280 has_unique_elements(
const std::vector<unsigned int> &targets)
1282 std::vector<unsigned int> my_destinations = targets;
1283 std::sort(my_destinations.begin(), my_destinations.end());
1284 return (std::adjacent_find(my_destinations.begin(),
1285 my_destinations.end()) ==
1286 my_destinations.end());
1295 handle_exception(std::exception_ptr &&exception,
const MPI_Comm comm)
1297# ifdef DEAL_II_WITH_MPI
1302 std::rethrow_exception(exception);
1310 <<
"----------------------------------------------------"
1315 <<
" on processing: " << std::endl
1316 << exc.
what() << std::endl
1317 <<
"Aborting!" << std::endl
1318 <<
"----------------------------------------------------"
1322 MPI_Abort(
comm, 255);
1324 catch (std::exception &exc)
1329 <<
"----------------------------------------------------"
1332 <<
"Exception within ConsensusAlgorithm"
1334 <<
" on processing: " << std::endl
1335 << exc.what() << std::endl
1336 <<
"Aborting!" << std::endl
1337 <<
"----------------------------------------------------"
1341 MPI_Abort(
comm, 255);
1348 <<
"----------------------------------------------------"
1351 <<
"Unknown exception within ConsensusAlgorithm!" << std::endl
1352 <<
"Aborting!" << std::endl
1353 <<
"----------------------------------------------------"
1357 MPI_Abort(
comm, 255);
1364 std::rethrow_exception(exception);
1371 template <
typename RequestType,
typename AnswerType>
1374 const RequestType &,
1382 template <
typename RequestType,
typename AnswerType>
1392 template <
typename RequestType,
typename AnswerType>
1402 template <
typename RequestType,
typename AnswerType>
1403 std::vector<unsigned int>
1405 Process<RequestType, AnswerType> &process,
1411 process.compute_targets(),
1413 [&process](
const unsigned int target) {
1414 RequestType request;
1415 process.create_request(target, request);
1419 [&process](
const unsigned int source,
const RequestType &request) {
1421 process.answer_request(source, request, answer);
1425 [&process](
const unsigned int target,
const AnswerType &answer) {
1426 process.read_answer(target, answer);
1433 template <
typename RequestType,
typename AnswerType>
1434 std::vector<unsigned int>
1436 const std::vector<unsigned int> &targets,
1437 const std::function<RequestType(
const unsigned int)> &create_request,
1438 const std::function<AnswerType(
const unsigned int,
const RequestType &)>
1440 const std::function<
void(
const unsigned int,
const AnswerType &)>
1444 Assert(has_unique_elements(targets),
1445 ExcMessage(
"The consensus algorithms expect that each process "
1446 "only sends a single message to another process, "
1447 "but the targets provided include duplicates."));
1449 static CollectiveMutex mutex;
1450 CollectiveMutex::ScopedLock lock(mutex,
comm);
1456 start_communication(targets, create_request,
comm);
1472 while (all_locally_originated_receives_are_completed(process_answer,
1474 maybe_answer_one_request(answer_request,
comm);
1478 signal_finish(
comm);
1483 while (all_remotely_originated_receives_are_completed() ==
false)
1484 maybe_answer_one_request(answer_request,
comm);
1487 clean_up_and_end_communication(
comm);
1491 handle_exception(std::current_exception(),
comm);
1494 return std::vector<unsigned int>(requesting_processes.begin(),
1495 requesting_processes.end());
1500 template <
typename RequestType,
typename AnswerType>
1503 const std::vector<unsigned int> &targets,
1504 const std::function<RequestType(
const unsigned int)> &create_request,
1507# ifdef DEAL_II_WITH_MPI
1509 const auto n_targets = targets.size();
1515 send_requests.resize(n_targets);
1516 send_buffers.resize(n_targets);
1520 for (
unsigned int index = 0;
index < n_targets; ++
index)
1522 const unsigned int rank = targets[
index];
1525 auto &send_buffer = send_buffers[
index];
1528 std::vector<char>());
1531 auto ierr = MPI_Isend(send_buffer.data(),
1537 &send_requests[index]);
1543 n_outstanding_answers = n_targets;
1547 (void)create_request;
1554 template <
typename RequestType,
typename AnswerType>
1558 const std::function<
void(
const unsigned int,
const AnswerType &)>
1562# ifdef DEAL_II_WITH_MPI
1570 if (n_outstanding_answers == 0)
1577 int request_is_pending;
1579 const auto ierr = MPI_Iprobe(
1580 MPI_ANY_SOURCE, tag_deliver,
comm, &request_is_pending, &status);
1586 if (request_is_pending == 0)
1592 const auto target = status.MPI_SOURCE;
1599 MPI_Get_count(&status, MPI_CHAR, &message_size);
1602 std::vector<char> recv_buffer(message_size);
1608 const int ierr = MPI_Recv(recv_buffer.data(),
1619 process_answer(target,
1620 Utilities::unpack<AnswerType>(recv_buffer,
1625 --n_outstanding_answers;
1635 return (n_outstanding_answers == 0);
1640 (void)process_answer;
1649 template <
typename RequestType,
typename AnswerType>
1652 const std::function<AnswerType(
const unsigned int,
const RequestType &)>
1656# ifdef DEAL_II_WITH_MPI
1671 int request_is_pending;
1672 const auto ierr = MPI_Iprobe(
1673 MPI_ANY_SOURCE, tag_request,
comm, &request_is_pending, &status);
1676 if (request_is_pending != 0)
1680 const auto other_rank = status.MPI_SOURCE;
1682 Assert(requesting_processes.find(other_rank) ==
1683 requesting_processes.end(),
1684 ExcMessage(
"Process is requesting a second time!"));
1685 requesting_processes.insert(other_rank);
1689 auto ierr = MPI_Get_count(&status, MPI_CHAR, &number_amount);
1693 std::vector<char> buffer_recv(number_amount);
1694 ierr = MPI_Recv(buffer_recv.data(),
1705 request_buffers.emplace_back(std::make_unique<std::vector<char>>());
1706 auto &request_buffer = *request_buffers.back();
1710 Utilities::unpack<RequestType>(
1711 buffer_recv,
false)),
1715 request_requests.emplace_back(std::make_unique<MPI_Request>());
1716 ierr = MPI_Isend(request_buffer.data(),
1717 request_buffer.size(),
1722 request_requests.back().get());
1726 (void)answer_request;
1733 template <
typename RequestType,
typename AnswerType>
1737# ifdef DEAL_II_WITH_MPI
1738 const auto ierr = MPI_Ibarrier(
comm, &barrier_request);
1747 template <
typename RequestType,
typename AnswerType>
1750 AnswerType>::all_remotely_originated_receives_are_completed()
1752# ifdef DEAL_II_WITH_MPI
1753 int all_ranks_reached_barrier;
1754 const auto ierr = MPI_Test(&barrier_request,
1755 &all_ranks_reached_barrier,
1758 return all_ranks_reached_barrier != 0;
1766 template <
typename RequestType,
typename AnswerType>
1772# ifdef DEAL_II_WITH_MPI
1775 if (send_requests.size() > 0)
1777 const int ierr = MPI_Waitall(send_requests.size(),
1778 send_requests.data(),
1779 MPI_STATUSES_IGNORE);
1783 int ierr = MPI_Wait(&barrier_request, MPI_STATUS_IGNORE);
1786 for (
auto &i : request_requests)
1788 ierr = MPI_Wait(i.get(), MPI_STATUS_IGNORE);
1795 ierr = MPI_Barrier(
comm);
1804 template <
typename RequestType,
typename AnswerType>
1805 std::vector<unsigned int>
1807 const std::vector<unsigned int> &targets,
1808 const std::function<RequestType(
const unsigned int)> &create_request,
1809 const std::function<AnswerType(
const unsigned int,
const RequestType &)>
1811 const std::function<
void(
const unsigned int,
const AnswerType &)>
1815 Assert(has_unique_elements(targets),
1816 ExcMessage(
"The consensus algorithms expect that each process "
1817 "only sends a single message to another process, "
1818 "but the targets provided include duplicates."));
1820 static CollectiveMutex mutex;
1821 CollectiveMutex::ScopedLock lock(mutex,
comm);
1828 const unsigned int n_requests =
1829 start_communication(targets, create_request,
comm);
1832 for (
unsigned int request = 0; request < n_requests; ++request)
1833 answer_one_request(request, answer_request,
comm);
1836 process_incoming_answers(targets.size(), process_answer,
comm);
1839 clean_up_and_end_communication();
1843 handle_exception(std::current_exception(),
comm);
1846 return std::vector<unsigned int>(requesting_processes.begin(),
1847 requesting_processes.end());
1852 template <
typename RequestType,
typename AnswerType>
1855 const std::vector<unsigned int> &targets,
1856 const std::function<RequestType(
const unsigned int)> &create_request,
1859# ifdef DEAL_II_WITH_MPI
1865 const unsigned int n_targets = targets.size();
1868 const unsigned int n_sources =
1872 recv_buffers.resize(n_targets);
1873 send_buffers.resize(n_targets);
1874 send_request_requests.resize(n_targets);
1876 send_answer_requests.resize(n_sources);
1877 requests_buffers.resize(n_sources);
1880 for (
unsigned int i = 0; i < n_targets; ++i)
1882 const unsigned int rank = targets[i];
1886 auto &send_buffer = send_buffers[i];
1891 auto ierr = MPI_Isend(send_buffer.data(),
1897 &send_request_requests[i]);
1904 (void)create_request;
1912 template <
typename RequestType,
typename AnswerType>
1915 const unsigned int index,
1916 const std::function<AnswerType(
const unsigned int,
const RequestType &)>
1920# ifdef DEAL_II_WITH_MPI
1929 int ierr = MPI_Probe(MPI_ANY_SOURCE, tag_request,
comm, &status);
1933 const unsigned int other_rank = status.MPI_SOURCE;
1935 Assert(requesting_processes.find(other_rank) ==
1936 requesting_processes.end(),
1938 "A process is sending a request after a request from "
1939 "the same process has previously already been "
1940 "received. This algorithm does not expect this to happen."));
1941 requesting_processes.insert(other_rank);
1945 ierr = MPI_Get_count(&status, MPI_CHAR, &number_amount);
1948 std::vector<char> buffer_recv(number_amount);
1949 ierr = MPI_Recv(buffer_recv.data(),
1960 auto &request_buffer = requests_buffers[
index];
1964 Utilities::unpack<RequestType>(
1965 buffer_recv,
false)),
1967 std::vector<char>());
1969 ierr = MPI_Isend(request_buffer.data(),
1970 request_buffer.size(),
1975 &send_answer_requests[index]);
1978 (void)answer_request;
1986 template <
typename RequestType,
typename AnswerType>
1989 const unsigned int n_targets,
1990 const std::function<
void(
const unsigned int,
const AnswerType &)>
1994# ifdef DEAL_II_WITH_MPI
2003 for (
unsigned int i = 0; i < n_targets; ++i)
2008 MPI_Probe(MPI_ANY_SOURCE, tag_deliver,
comm, &status);
2012 const auto other_rank = status.MPI_SOURCE;
2015 const int ierr = MPI_Get_count(&status, MPI_CHAR, &message_size);
2018 std::vector<char> recv_buffer(message_size);
2024 const int ierr = MPI_Recv(recv_buffer.data(),
2035 process_answer(other_rank,
2036 Utilities::unpack<AnswerType>(recv_buffer,
false));
2040 (void)process_answer;
2047 template <
typename RequestType,
typename AnswerType>
2051# ifdef DEAL_II_WITH_MPI
2054 if (send_request_requests.size() > 0)
2056 const int ierr = MPI_Waitall(send_request_requests.size(),
2057 send_request_requests.data(),
2058 MPI_STATUSES_IGNORE);
2063 if (send_answer_requests.size() > 0)
2065 const int ierr = MPI_Waitall(send_answer_requests.size(),
2066 send_answer_requests.data(),
2067 MPI_STATUSES_IGNORE);
2075 template <
typename RequestType,
typename AnswerType>
2076 std::vector<unsigned int>
2078 const std::vector<unsigned int> &targets,
2079 const std::function<RequestType(
const unsigned int)> &create_request,
2080 const std::function<AnswerType(
const unsigned int,
const RequestType &)>
2082 const std::function<
void(
const unsigned int,
const AnswerType &)>
2088 ExcMessage(
"You shouldn't use the 'Serial' class on "
2089 "communicators that have more than one process "
2090 "associated with it."));
2093 if (targets.size() != 0)
2095 Assert(targets.size() == 1,
2097 "On a single process, the only valid target "
2098 "is process zero (the process itself), which can only be "
2105 const RequestType request =
2106 (create_request ? create_request(0) : RequestType());
2107 const AnswerType answer =
2108 (answer_request ? answer_request(0, request) : AnswerType());
2111 process_answer(0, answer);
2119 template <
typename RequestType,
typename AnswerType>
2120 std::vector<unsigned int>
2122 const std::vector<unsigned int> &targets,
2123 const std::function<RequestType(
const unsigned int)> &create_request,
2124 const std::function<AnswerType(
const unsigned int,
const RequestType &)>
2126 const std::function<
void(
const unsigned int,
const AnswerType &)>
2139# ifdef DEAL_II_WITH_MPI
2145 consensus_algo.reset(
new NBX<RequestType, AnswerType>());
2149 consensus_algo.reset(
new PEX<RequestType, AnswerType>());
2151 consensus_algo.reset(
new Serial<RequestType, AnswerType>());
2153 return consensus_algo->run(
2154 targets, create_request, answer_request, process_answer,
comm);
const char * get_exc_name() const
virtual const char * what() const noexcept override
virtual ~Interface()=default
std::vector< unsigned int > run(Process< RequestType, AnswerType > &process, const MPI_Comm comm)
virtual std::vector< unsigned int > run(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)=0
void start_communication(const std::vector< unsigned int > &targets, const std::function< RequestType(const unsigned int)> &create_request, const MPI_Comm comm)
void maybe_answer_one_request(const std::function< AnswerType(const unsigned int, const RequestType &)> &answer_request, const MPI_Comm comm)
std::vector< std::unique_ptr< std::vector< char > > > request_buffers
std::set< unsigned int > requesting_processes
MPI_Request barrier_request
virtual std::vector< unsigned int > run(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) override
void clean_up_and_end_communication(const MPI_Comm comm)
bool all_locally_originated_receives_are_completed(const std::function< void(const unsigned int, const AnswerType &)> &process_answer, const MPI_Comm comm)
std::vector< std::unique_ptr< MPI_Request > > request_requests
std::vector< std::vector< char > > send_buffers
void signal_finish(const MPI_Comm comm)
bool all_remotely_originated_receives_are_completed()
unsigned int n_outstanding_answers
std::vector< MPI_Request > send_requests
void clean_up_and_end_communication()
std::vector< MPI_Request > send_answer_requests
std::vector< MPI_Request > send_request_requests
unsigned int start_communication(const std::vector< unsigned int > &targets, const std::function< RequestType(const unsigned int)> &create_request, const MPI_Comm comm)
std::vector< std::vector< char > > requests_buffers
virtual std::vector< unsigned int > run(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) override
std::vector< std::vector< char > > send_buffers
void answer_one_request(const unsigned int index, const std::function< AnswerType(const unsigned int, const RequestType &)> &answer_request, const MPI_Comm comm)
std::set< unsigned int > requesting_processes
std::vector< std::vector< char > > recv_buffers
void process_incoming_answers(const unsigned int n_targets, const std::function< void(const unsigned int, const AnswerType &)> &process_answer, const MPI_Comm comm)
virtual std::vector< unsigned int > compute_targets()=0
virtual ~Process()=default
virtual void answer_request(const unsigned int other_rank, const RequestType &buffer_recv, AnswerType &request_buffer)
virtual void read_answer(const unsigned int other_rank, const AnswerType &recv_buffer)
virtual void create_request(const unsigned int other_rank, RequestType &send_buffer)
virtual ~Selector()=default
virtual std::vector< unsigned int > run(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) override
std::shared_ptr< Interface< RequestType, AnswerType > > consensus_algo
virtual std::vector< unsigned int > run(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) override
#define DEAL_II_NAMESPACE_OPEN
#define DEAL_II_NAMESPACE_CLOSE
#define Assert(cond, exc)
#define AssertDimension(dim1, dim2)
#define AssertThrowMPI(error_code)
#define AssertIndexRange(index, range)
static ::ExceptionBase & ExcMessage(std::string arg1)
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)
std::vector< unsigned int > serial(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)
std::vector< unsigned int > nbx(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)
std::vector< unsigned int > pex(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)
unsigned int n_mpi_processes(const MPI_Comm mpi_communicator)
unsigned int this_mpi_process(const MPI_Comm mpi_communicator)
unsigned int compute_n_point_to_point_communications(const MPI_Comm mpi_comm, const std::vector< unsigned int > &destinations)
size_t pack(const T &object, std::vector< char > &dest_buffer, const bool allow_compression=true)
void run(const Iterator &begin, const std_cxx20::type_identity_t< Iterator > &end, Worker worker, Copier copier, const ScratchData &sample_scratch_data, const CopyData &sample_copy_data, const unsigned int queue_length, const unsigned int chunk_size)
*braid_SplitCommworld & comm