15#ifndef dealii_mpi_consensus_algorithm_h
16#define dealii_mpi_consensus_algorithm_h
21#include <deal.II/base/mpi.templates.h>
132 namespace ConsensusAlgorithms
163 template <
typename RequestType,
typename AnswerType>
179 virtual std::vector<unsigned int>
208 const RequestType &buffer_recv,
209 AnswerType &request_buffer);
220 const AnswerType &recv_buffer);
238 template <
typename RequestType,
typename AnswerType>
266 DEAL_II_DEPRECATED_EARLY
267 std::vector<unsigned int>
293 virtual std::vector<unsigned int>
295 const std::vector<unsigned int> &targets,
296 const std::function<RequestType(
const unsigned int)> &create_request,
297 const std::function<AnswerType(
const unsigned int,
298 const RequestType &)> &answer_request,
299 const std::function<
void(
const unsigned int,
const AnswerType &)>
318 template <
typename RequestType,
typename AnswerType>
338 virtual std::vector<unsigned int>
340 const std::vector<unsigned int> &targets,
341 const std::function<RequestType(
const unsigned int)> &create_request,
342 const std::function<AnswerType(
const unsigned int,
343 const RequestType &)> &answer_request,
344 const std::function<
void(
const unsigned int,
const AnswerType &)>
349#ifdef DEAL_II_WITH_MPI
395 const std::function<
void(
const unsigned int,
const AnswerType &)>
421 const std::function<AnswerType(
const unsigned int,
422 const RequestType &)> &answer_request,
431 const std::vector<unsigned int> &targets,
432 const std::function<RequestType(
const unsigned int)> &create_request,
488 template <
typename RequestType,
typename AnswerType>
489 std::vector<unsigned int>
490 nbx(
const std::vector<unsigned int> &targets,
491 const std::function<RequestType(
const unsigned int)> &create_request,
492 const std::function<AnswerType(
const unsigned int,
493 const RequestType &)> &answer_request,
494 const std::function<
void(
const unsigned int,
const AnswerType &)>
535 template <
typename RequestType>
536 std::vector<unsigned int>
537 nbx(
const std::vector<unsigned int> &targets,
538 const std::function<RequestType(
const unsigned int)> &create_request,
539 const std::function<
void(
const unsigned int,
const RequestType &)>
568 template <
typename RequestType,
typename AnswerType>
588 virtual std::vector<unsigned int>
590 const std::vector<unsigned int> &targets,
591 const std::function<RequestType(
const unsigned int)> &create_request,
592 const std::function<AnswerType(
const unsigned int,
593 const RequestType &)> &answer_request,
594 const std::function<
void(
const unsigned int,
const AnswerType &)>
599#ifdef DEAL_II_WITH_MPI
636 const std::vector<unsigned int> &targets,
637 const std::function<RequestType(
const unsigned int)> &create_request,
646 const unsigned int index,
647 const std::function<AnswerType(
const unsigned int,
648 const RequestType &)> &answer_request,
657 const unsigned int n_targets,
658 const std::function<
void(
const unsigned int,
const AnswerType &)>
728 template <
typename RequestType,
typename AnswerType>
729 std::vector<unsigned int>
730 pex(
const std::vector<unsigned int> &targets,
731 const std::function<RequestType(
const unsigned int)> &create_request,
732 const std::function<AnswerType(
const unsigned int,
733 const RequestType &)> &answer_request,
734 const std::function<
void(
const unsigned int,
const AnswerType &)>
775 template <
typename RequestType>
776 std::vector<unsigned int>
777 pex(
const std::vector<unsigned int> &targets,
778 const std::function<RequestType(
const unsigned int)> &create_request,
779 const std::function<
void(
const unsigned int,
const RequestType &)>
788 template <
typename RequestType,
typename AnswerType>
803 virtual std::vector<unsigned int>
805 const std::vector<unsigned int> &targets,
806 const std::function<RequestType(
const unsigned int)> &create_request,
807 const std::function<AnswerType(
const unsigned int,
808 const RequestType &)> &answer_request,
809 const std::function<
void(
const unsigned int,
const AnswerType &)>
848 template <
typename RequestType,
typename AnswerType>
849 std::vector<unsigned int>
851 const std::vector<unsigned int> &targets,
852 const std::function<RequestType(
const unsigned int)> &create_request,
853 const std::function<AnswerType(
const unsigned int,
const RequestType &)>
855 const std::function<
void(
const unsigned int,
const AnswerType &)>
888 template <
typename RequestType>
889 std::vector<unsigned int>
891 const std::vector<unsigned int> &targets,
892 const std::function<RequestType(
const unsigned int)> &create_request,
893 const std::function<
void(
const unsigned int,
const RequestType &)>
911 template <
typename RequestType,
typename AnswerType>
933 virtual std::vector<unsigned int>
935 const std::vector<unsigned int> &targets,
936 const std::function<RequestType(
const unsigned int)> &create_request,
937 const std::function<AnswerType(
const unsigned int,
938 const RequestType &)> &answer_request,
939 const std::function<
void(
const unsigned int,
const AnswerType &)>
994 template <
typename RequestType,
typename AnswerType>
995 std::vector<unsigned int>
997 const std::vector<unsigned int> &targets,
998 const std::function<RequestType(
const unsigned int)> &create_request,
999 const std::function<AnswerType(
const unsigned int,
const RequestType &)>
1001 const std::function<
void(
const unsigned int,
const AnswerType &)>
1042 template <
typename RequestType>
1043 std::vector<unsigned int>
1045 const std::vector<unsigned int> &targets,
1046 const std::function<RequestType(
const unsigned int)> &create_request,
1047 const std::function<
void(
const unsigned int,
const RequestType &)>
1056 template <
typename RequestType,
typename AnswerType>
1057 std::vector<unsigned int>
1058 nbx(
const std::vector<unsigned int> &targets,
1059 const std::function<RequestType(
const unsigned int)> &create_request,
1060 const std::function<AnswerType(
const unsigned int,
1061 const RequestType &)> &answer_request,
1062 const std::function<
void(
const unsigned int,
const AnswerType &)>
1067 targets, create_request, answer_request, process_answer,
comm);
1072 template <
typename RequestType>
1073 std::vector<unsigned int>
1074 nbx(
const std::vector<unsigned int> &targets,
1075 const std::function<RequestType(
const unsigned int)> &create_request,
1076 const std::function<
void(
const unsigned int,
const RequestType &)>
1085 using EmptyType = std::tuple<>;
1087 return nbx<RequestType, EmptyType>(
1091 [&process_request](
const unsigned int source_rank,
1092 const RequestType &request) -> EmptyType {
1093 process_request(source_rank, request);
1101 [](
const unsigned int ,
1102 const EmptyType & ) {},
1108 template <
typename RequestType,
typename AnswerType>
1109 std::vector<unsigned int>
1110 pex(
const std::vector<unsigned int> &targets,
1111 const std::function<RequestType(
const unsigned int)> &create_request,
1112 const std::function<AnswerType(
const unsigned int,
1113 const RequestType &)> &answer_request,
1114 const std::function<
void(
const unsigned int,
const AnswerType &)>
1118 return PEX<RequestType, AnswerType>().run(
1119 targets, create_request, answer_request, process_answer,
comm);
1124 template <
typename RequestType>
1125 std::vector<unsigned int>
1126 pex(
const std::vector<unsigned int> &targets,
1127 const std::function<RequestType(
const unsigned int)> &create_request,
1128 const std::function<
void(
const unsigned int,
const RequestType &)>
1137 using EmptyType = std::tuple<>;
1139 return pex<RequestType, EmptyType>(
1143 [&process_request](
const unsigned int source_rank,
1144 const RequestType &request) -> EmptyType {
1145 process_request(source_rank, request);
1153 [](
const unsigned int ,
1154 const EmptyType & ) {},
1160 template <
typename RequestType,
typename AnswerType>
1161 std::vector<unsigned int>
1163 const std::vector<unsigned int> &targets,
1164 const std::function<RequestType(
const unsigned int)> &create_request,
1165 const std::function<AnswerType(
const unsigned int,
const RequestType &)>
1167 const std::function<
void(
const unsigned int,
const AnswerType &)>
1171 return Serial<RequestType, AnswerType>().run(
1172 targets, create_request, answer_request, process_answer,
comm);
1177 template <
typename RequestType>
1178 std::vector<unsigned int>
1180 const std::vector<unsigned int> &targets,
1181 const std::function<RequestType(
const unsigned int)> &create_request,
1182 const std::function<
void(
const unsigned int,
const RequestType &)>
1191 using EmptyType = std::tuple<>;
1193 return serial<RequestType, EmptyType>(
1197 [&process_request](
const unsigned int source_rank,
1198 const RequestType &request) -> EmptyType {
1199 process_request(source_rank, request);
1207 [](
const unsigned int ,
1208 const EmptyType & ) {},
1214 template <
typename RequestType,
typename AnswerType>
1215 std::vector<unsigned int>
1217 const std::vector<unsigned int> &targets,
1218 const std::function<RequestType(
const unsigned int)> &create_request,
1219 const std::function<AnswerType(
const unsigned int,
const RequestType &)>
1221 const std::function<
void(
const unsigned int,
const AnswerType &)>
1225 return Selector<RequestType, AnswerType>().run(
1226 targets, create_request, answer_request, process_answer,
comm);
1231 template <
typename RequestType>
1232 std::vector<unsigned int>
1234 const std::vector<unsigned int> &targets,
1235 const std::function<RequestType(
const unsigned int)> &create_request,
1236 const std::function<
void(
const unsigned int,
const RequestType &)>
1245 using EmptyType = std::tuple<>;
1247 return selector<RequestType, EmptyType>(
1251 [&process_request](
const unsigned int source_rank,
1252 const RequestType &request) -> EmptyType {
1253 process_request(source_rank, request);
1261 [](
const unsigned int ,
1262 const EmptyType & ) {},
1283 namespace ConsensusAlgorithms
1292 has_unique_elements(
const std::vector<unsigned int> &targets)
1294 std::vector<unsigned int> my_destinations = targets;
1295 std::sort(my_destinations.begin(), my_destinations.end());
1296 return (std::adjacent_find(my_destinations.begin(),
1297 my_destinations.end()) ==
1298 my_destinations.end());
1307 handle_exception(std::exception_ptr &&exception,
const MPI_Comm comm)
1309# ifdef DEAL_II_WITH_MPI
1314 std::rethrow_exception(exception);
1322 <<
"----------------------------------------------------"
1327 <<
" on processing: " << std::endl
1328 << exc.
what() << std::endl
1329 <<
"Aborting!" << std::endl
1330 <<
"----------------------------------------------------"
1334 MPI_Abort(
comm, 255);
1336 catch (std::exception &exc)
1341 <<
"----------------------------------------------------"
1344 <<
"Exception within ConsensusAlgorithm"
1346 <<
" on processing: " << std::endl
1347 << exc.what() << std::endl
1348 <<
"Aborting!" << std::endl
1349 <<
"----------------------------------------------------"
1353 MPI_Abort(
comm, 255);
1360 <<
"----------------------------------------------------"
1363 <<
"Unknown exception within ConsensusAlgorithm!" << std::endl
1364 <<
"Aborting!" << std::endl
1365 <<
"----------------------------------------------------"
1369 MPI_Abort(
comm, 255);
1376 std::rethrow_exception(exception);
1383 template <
typename RequestType,
typename AnswerType>
1386 const RequestType &,
1394 template <
typename RequestType,
typename AnswerType>
1404 template <
typename RequestType,
typename AnswerType>
1414 template <
typename RequestType,
typename AnswerType>
1415 std::vector<unsigned int>
1417 Process<RequestType, AnswerType> &process,
1423 process.compute_targets(),
1425 [&process](
const unsigned int target) {
1426 RequestType request;
1427 process.create_request(target, request);
1431 [&process](
const unsigned int source,
const RequestType &request) {
1433 process.answer_request(source, request, answer);
1437 [&process](
const unsigned int target,
const AnswerType &answer) {
1438 process.read_answer(target, answer);
1445 template <
typename RequestType,
typename AnswerType>
1446 std::vector<unsigned int>
1448 const std::vector<unsigned int> &targets,
1449 const std::function<RequestType(
const unsigned int)> &create_request,
1450 const std::function<AnswerType(
const unsigned int,
const RequestType &)>
1452 const std::function<
void(
const unsigned int,
const AnswerType &)>
1456 Assert(internal::has_unique_elements(targets),
1457 ExcMessage(
"The consensus algorithms expect that each process "
1458 "only sends a single message to another process, "
1459 "but the targets provided include duplicates."));
1461 static CollectiveMutex mutex;
1462 CollectiveMutex::ScopedLock lock(mutex,
comm);
1468 start_communication(targets, create_request,
comm);
1484 while (all_locally_originated_receives_are_completed(process_answer,
1486 maybe_answer_one_request(answer_request,
comm);
1490 signal_finish(
comm);
1495 while (all_remotely_originated_receives_are_completed() ==
false)
1496 maybe_answer_one_request(answer_request,
comm);
1499 clean_up_and_end_communication(
comm);
1503 internal::handle_exception(std::current_exception(),
comm);
1506 return std::vector<unsigned int>(requesting_processes.begin(),
1507 requesting_processes.end());
1512 template <
typename RequestType,
typename AnswerType>
1515 const std::vector<unsigned int> &targets,
1516 const std::function<RequestType(
const unsigned int)> &create_request,
1519# ifdef DEAL_II_WITH_MPI
1521 const auto n_targets = targets.size();
1527 send_requests.resize(n_targets);
1528 send_buffers.resize(n_targets);
1532 for (
unsigned int index = 0;
index < n_targets; ++
index)
1534 const unsigned int rank = targets[
index];
1537 auto &send_buffer = send_buffers[
index];
1540 std::vector<char>());
1543 auto ierr = MPI_Isend(send_buffer.data(),
1549 &send_requests[index]);
1555 n_outstanding_answers = n_targets;
1559 (void)create_request;
1566 template <
typename RequestType,
typename AnswerType>
1570 const std::function<
void(
const unsigned int,
const AnswerType &)>
1574# ifdef DEAL_II_WITH_MPI
1582 if (n_outstanding_answers == 0)
1589 int request_is_pending;
1591 const auto ierr = MPI_Iprobe(
1592 MPI_ANY_SOURCE, tag_deliver,
comm, &request_is_pending, &status);
1598 if (request_is_pending == 0)
1604 const auto target = status.MPI_SOURCE;
1611 MPI_Get_count(&status, MPI_CHAR, &message_size);
1614 std::vector<char> recv_buffer(message_size);
1620 const int ierr = MPI_Recv(recv_buffer.data(),
1631 process_answer(target,
1632 Utilities::unpack<AnswerType>(recv_buffer,
1637 --n_outstanding_answers;
1647 return (n_outstanding_answers == 0);
1652 (void)process_answer;
1661 template <
typename RequestType,
typename AnswerType>
1664 const std::function<AnswerType(
const unsigned int,
const RequestType &)>
1668# ifdef DEAL_II_WITH_MPI
1683 int request_is_pending;
1684 const auto ierr = MPI_Iprobe(
1685 MPI_ANY_SOURCE, tag_request,
comm, &request_is_pending, &status);
1688 if (request_is_pending != 0)
1692 const auto other_rank = status.MPI_SOURCE;
1694 Assert(requesting_processes.find(other_rank) ==
1695 requesting_processes.end(),
1696 ExcMessage(
"Process is requesting a second time!"));
1697 requesting_processes.insert(other_rank);
1701 auto ierr = MPI_Get_count(&status, MPI_CHAR, &number_amount);
1705 std::vector<char> buffer_recv(number_amount);
1706 ierr = MPI_Recv(buffer_recv.data(),
1717 request_buffers.emplace_back(std::make_unique<std::vector<char>>());
1718 auto &request_buffer = *request_buffers.back();
1722 Utilities::unpack<RequestType>(
1723 buffer_recv,
false)),
1727 request_requests.emplace_back(std::make_unique<MPI_Request>());
1728 ierr = MPI_Isend(request_buffer.data(),
1729 request_buffer.size(),
1734 request_requests.back().get());
1738 (void)answer_request;
1745 template <
typename RequestType,
typename AnswerType>
1749# ifdef DEAL_II_WITH_MPI
1750 const auto ierr = MPI_Ibarrier(
comm, &barrier_request);
1759 template <
typename RequestType,
typename AnswerType>
1762 AnswerType>::all_remotely_originated_receives_are_completed()
1764# ifdef DEAL_II_WITH_MPI
1765 int all_ranks_reached_barrier;
1766 const auto ierr = MPI_Test(&barrier_request,
1767 &all_ranks_reached_barrier,
1770 return all_ranks_reached_barrier != 0;
1778 template <
typename RequestType,
typename AnswerType>
1784# ifdef DEAL_II_WITH_MPI
1787 if (send_requests.size() > 0)
1789 const int ierr = MPI_Waitall(send_requests.size(),
1790 send_requests.data(),
1791 MPI_STATUSES_IGNORE);
1795 int ierr = MPI_Wait(&barrier_request, MPI_STATUS_IGNORE);
1798 for (
auto &i : request_requests)
1800 ierr = MPI_Wait(i.get(), MPI_STATUS_IGNORE);
1808 ierr = MPI_Barrier(
comm);
1817 template <
typename RequestType,
typename AnswerType>
1818 std::vector<unsigned int>
1820 const std::vector<unsigned int> &targets,
1821 const std::function<RequestType(
const unsigned int)> &create_request,
1822 const std::function<AnswerType(
const unsigned int,
const RequestType &)>
1824 const std::function<
void(
const unsigned int,
const AnswerType &)>
1828 Assert(internal::has_unique_elements(targets),
1829 ExcMessage(
"The consensus algorithms expect that each process "
1830 "only sends a single message to another process, "
1831 "but the targets provided include duplicates."));
1833 static CollectiveMutex mutex;
1834 CollectiveMutex::ScopedLock lock(mutex,
comm);
1841 const unsigned int n_requests =
1842 start_communication(targets, create_request,
comm);
1845 for (
unsigned int request = 0; request < n_requests; ++request)
1846 answer_one_request(request, answer_request,
comm);
1849 process_incoming_answers(targets.size(), process_answer,
comm);
1852 clean_up_and_end_communication();
1856 internal::handle_exception(std::current_exception(),
comm);
1859 return std::vector<unsigned int>(requesting_processes.begin(),
1860 requesting_processes.end());
1865 template <
typename RequestType,
typename AnswerType>
1868 const std::vector<unsigned int> &targets,
1869 const std::function<RequestType(
const unsigned int)> &create_request,
1872# ifdef DEAL_II_WITH_MPI
1878 const unsigned int n_targets = targets.size();
1881 const unsigned int n_sources =
1885 recv_buffers.resize(n_targets);
1886 send_buffers.resize(n_targets);
1887 send_request_requests.resize(n_targets);
1889 send_answer_requests.resize(n_sources);
1890 requests_buffers.resize(n_sources);
1893 for (
unsigned int i = 0; i < n_targets; ++i)
1895 const unsigned int rank = targets[i];
1899 auto &send_buffer = send_buffers[i];
1904 auto ierr = MPI_Isend(send_buffer.data(),
1910 &send_request_requests[i]);
1917 (void)create_request;
1925 template <
typename RequestType,
typename AnswerType>
1928 const unsigned int index,
1929 const std::function<AnswerType(
const unsigned int,
const RequestType &)>
1933# ifdef DEAL_II_WITH_MPI
1942 int ierr = MPI_Probe(MPI_ANY_SOURCE, tag_request,
comm, &status);
1946 const unsigned int other_rank = status.MPI_SOURCE;
1948 Assert(requesting_processes.find(other_rank) ==
1949 requesting_processes.end(),
1951 "A process is sending a request after a request from "
1952 "the same process has previously already been "
1953 "received. This algorithm does not expect this to happen."));
1954 requesting_processes.insert(other_rank);
1958 ierr = MPI_Get_count(&status, MPI_CHAR, &number_amount);
1961 std::vector<char> buffer_recv(number_amount);
1962 ierr = MPI_Recv(buffer_recv.data(),
1973 auto &request_buffer = requests_buffers[
index];
1977 Utilities::unpack<RequestType>(
1978 buffer_recv,
false)),
1980 std::vector<char>());
1982 ierr = MPI_Isend(request_buffer.data(),
1983 request_buffer.size(),
1988 &send_answer_requests[index]);
1991 (void)answer_request;
1999 template <
typename RequestType,
typename AnswerType>
2002 const unsigned int n_targets,
2003 const std::function<
void(
const unsigned int,
const AnswerType &)>
2007# ifdef DEAL_II_WITH_MPI
2016 for (
unsigned int i = 0; i < n_targets; ++i)
2021 MPI_Probe(MPI_ANY_SOURCE, tag_deliver,
comm, &status);
2025 const auto other_rank = status.MPI_SOURCE;
2028 const int ierr = MPI_Get_count(&status, MPI_CHAR, &message_size);
2031 std::vector<char> recv_buffer(message_size);
2037 const int ierr = MPI_Recv(recv_buffer.data(),
2048 process_answer(other_rank,
2049 Utilities::unpack<AnswerType>(recv_buffer,
false));
2053 (void)process_answer;
2060 template <
typename RequestType,
typename AnswerType>
2064# ifdef DEAL_II_WITH_MPI
2067 if (send_request_requests.size() > 0)
2069 const int ierr = MPI_Waitall(send_request_requests.size(),
2070 send_request_requests.data(),
2071 MPI_STATUSES_IGNORE);
2076 if (send_answer_requests.size() > 0)
2078 const int ierr = MPI_Waitall(send_answer_requests.size(),
2079 send_answer_requests.data(),
2080 MPI_STATUSES_IGNORE);
2088 template <
typename RequestType,
typename AnswerType>
2089 std::vector<unsigned int>
2091 const std::vector<unsigned int> &targets,
2092 const std::function<RequestType(
const unsigned int)> &create_request,
2093 const std::function<AnswerType(
const unsigned int,
const RequestType &)>
2095 const std::function<
void(
const unsigned int,
const AnswerType &)>
2101 ExcMessage(
"You shouldn't use the 'Serial' class on "
2102 "communicators that have more than one process "
2103 "associated with it."));
2106 if (targets.size() != 0)
2108 Assert(targets.size() == 1,
2110 "On a single process, the only valid target "
2111 "is process zero (the process itself), which can only be "
2118 const RequestType request =
2119 (create_request ? create_request(0) : RequestType());
2120 const AnswerType answer =
2121 (answer_request ? answer_request(0, request) : AnswerType());
2124 process_answer(0, answer);
2132 template <
typename RequestType,
typename AnswerType>
2133 std::vector<unsigned int>
2135 const std::vector<unsigned int> &targets,
2136 const std::function<RequestType(
const unsigned int)> &create_request,
2137 const std::function<AnswerType(
const unsigned int,
const RequestType &)>
2139 const std::function<
void(
const unsigned int,
const AnswerType &)>
2152# ifdef DEAL_II_WITH_MPI
2158 consensus_algo.reset(
new NBX<RequestType, AnswerType>());
2162 consensus_algo.reset(
new PEX<RequestType, AnswerType>());
2164 consensus_algo.reset(
new Serial<RequestType, AnswerType>());
2166 return consensus_algo->run(
2167 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
constexpr bool running_in_debug_mode()
#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)
const unsigned int n_procs
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)
std::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)