15#ifndef dealii_mpi_consensus_algorithm_h
16#define dealii_mpi_consensus_algorithm_h
21#include <deal.II/base/mpi.templates.h>
129 namespace ConsensusAlgorithms
155 template <
typename RequestType,
typename AnswerType>
171 virtual std::vector<unsigned int>
200 const RequestType &buffer_recv,
201 AnswerType &request_buffer);
212 const AnswerType &recv_buffer);
230 template <
typename RequestType,
typename AnswerType>
253 std::vector<unsigned int>
279 virtual std::vector<unsigned int>
281 const std::vector<unsigned int> &targets,
282 const std::function<RequestType(
const unsigned int)> &create_request,
283 const std::function<AnswerType(
const unsigned int,
284 const RequestType &)> &answer_request,
285 const std::function<
void(
const unsigned int,
const AnswerType &)>
304 template <
typename RequestType,
typename AnswerType>
324 virtual std::vector<unsigned int>
326 const std::vector<unsigned int> &targets,
327 const std::function<RequestType(
const unsigned int)> &create_request,
328 const std::function<AnswerType(
const unsigned int,
329 const RequestType &)> &answer_request,
330 const std::function<
void(
const unsigned int,
const AnswerType &)>
335#ifdef DEAL_II_WITH_MPI
381 const std::function<
void(
const unsigned int,
const AnswerType &)>
407 const std::function<AnswerType(
const unsigned int,
408 const RequestType &)> &answer_request,
417 const std::vector<unsigned int> &targets,
418 const std::function<RequestType(
const unsigned int)> &create_request,
474 template <
typename RequestType,
typename AnswerType>
475 std::vector<unsigned int>
476 nbx(
const std::vector<unsigned int> &targets,
477 const std::function<RequestType(
const unsigned int)> &create_request,
478 const std::function<AnswerType(
const unsigned int,
479 const RequestType &)> &answer_request,
480 const std::function<
void(
const unsigned int,
const AnswerType &)>
521 template <
typename RequestType>
522 std::vector<unsigned int>
523 nbx(
const std::vector<unsigned int> &targets,
524 const std::function<RequestType(
const unsigned int)> &create_request,
525 const std::function<
void(
const unsigned int,
const RequestType &)>
554 template <
typename RequestType,
typename AnswerType>
574 virtual std::vector<unsigned int>
576 const std::vector<unsigned int> &targets,
577 const std::function<RequestType(
const unsigned int)> &create_request,
578 const std::function<AnswerType(
const unsigned int,
579 const RequestType &)> &answer_request,
580 const std::function<
void(
const unsigned int,
const AnswerType &)>
585#ifdef DEAL_II_WITH_MPI
622 const std::vector<unsigned int> &targets,
623 const std::function<RequestType(
const unsigned int)> &create_request,
632 const unsigned int index,
633 const std::function<AnswerType(
const unsigned int,
634 const RequestType &)> &answer_request,
643 const unsigned int n_targets,
644 const std::function<
void(
const unsigned int,
const AnswerType &)>
714 template <
typename RequestType,
typename AnswerType>
715 std::vector<unsigned int>
716 pex(
const std::vector<unsigned int> &targets,
717 const std::function<RequestType(
const unsigned int)> &create_request,
718 const std::function<AnswerType(
const unsigned int,
719 const RequestType &)> &answer_request,
720 const std::function<
void(
const unsigned int,
const AnswerType &)>
761 template <
typename RequestType>
762 std::vector<unsigned int>
763 pex(
const std::vector<unsigned int> &targets,
764 const std::function<RequestType(
const unsigned int)> &create_request,
765 const std::function<
void(
const unsigned int,
const RequestType &)>
774 template <
typename RequestType,
typename AnswerType>
789 virtual std::vector<unsigned int>
791 const std::vector<unsigned int> &targets,
792 const std::function<RequestType(
const unsigned int)> &create_request,
793 const std::function<AnswerType(
const unsigned int,
794 const RequestType &)> &answer_request,
795 const std::function<
void(
const unsigned int,
const AnswerType &)>
834 template <
typename RequestType,
typename AnswerType>
835 std::vector<unsigned int>
837 const std::vector<unsigned int> &targets,
838 const std::function<RequestType(
const unsigned int)> &create_request,
839 const std::function<AnswerType(
const unsigned int,
const RequestType &)>
841 const std::function<
void(
const unsigned int,
const AnswerType &)>
874 template <
typename RequestType>
875 std::vector<unsigned int>
877 const std::vector<unsigned int> &targets,
878 const std::function<RequestType(
const unsigned int)> &create_request,
879 const std::function<
void(
const unsigned int,
const RequestType &)>
897 template <
typename RequestType,
typename AnswerType>
919 virtual std::vector<unsigned int>
921 const std::vector<unsigned int> &targets,
922 const std::function<RequestType(
const unsigned int)> &create_request,
923 const std::function<AnswerType(
const unsigned int,
924 const RequestType &)> &answer_request,
925 const std::function<
void(
const unsigned int,
const AnswerType &)>
980 template <
typename RequestType,
typename AnswerType>
981 std::vector<unsigned int>
983 const std::vector<unsigned int> &targets,
984 const std::function<RequestType(
const unsigned int)> &create_request,
985 const std::function<AnswerType(
const unsigned int,
const RequestType &)>
987 const std::function<
void(
const unsigned int,
const AnswerType &)>
1028 template <
typename RequestType>
1029 std::vector<unsigned int>
1031 const std::vector<unsigned int> &targets,
1032 const std::function<RequestType(
const unsigned int)> &create_request,
1033 const std::function<
void(
const unsigned int,
const RequestType &)>
1042 template <
typename RequestType,
typename AnswerType>
1043 std::vector<unsigned int>
1044 nbx(
const std::vector<unsigned int> &targets,
1045 const std::function<RequestType(
const unsigned int)> &create_request,
1046 const std::function<AnswerType(
const unsigned int,
1047 const RequestType &)> &answer_request,
1048 const std::function<
void(
const unsigned int,
const AnswerType &)>
1053 targets, create_request, answer_request, process_answer,
comm);
1058 template <
typename RequestType>
1059 std::vector<unsigned int>
1060 nbx(
const std::vector<unsigned int> &targets,
1061 const std::function<RequestType(
const unsigned int)> &create_request,
1062 const std::function<
void(
const unsigned int,
const RequestType &)>
1071 using EmptyType = std::tuple<>;
1077 [&process_request](
const unsigned int source_rank,
1078 const RequestType &request) -> EmptyType {
1079 process_request(source_rank, request);
1087 [](
const unsigned int ,
1088 const EmptyType & ) {},
1094 template <
typename RequestType,
typename AnswerType>
1095 std::vector<unsigned int>
1096 pex(
const std::vector<unsigned int> &targets,
1097 const std::function<RequestType(
const unsigned int)> &create_request,
1098 const std::function<AnswerType(
const unsigned int,
1099 const RequestType &)> &answer_request,
1100 const std::function<
void(
const unsigned int,
const AnswerType &)>
1104 return PEX<RequestType, AnswerType>().run(
1105 targets, create_request, answer_request, process_answer,
comm);
1110 template <
typename RequestType>
1111 std::vector<unsigned int>
1112 pex(
const std::vector<unsigned int> &targets,
1113 const std::function<RequestType(
const unsigned int)> &create_request,
1114 const std::function<
void(
const unsigned int,
const RequestType &)>
1123 using EmptyType = std::tuple<>;
1129 [&process_request](
const unsigned int source_rank,
1130 const RequestType &request) -> EmptyType {
1131 process_request(source_rank, request);
1139 [](
const unsigned int ,
1140 const EmptyType & ) {},
1146 template <
typename RequestType,
typename AnswerType>
1147 std::vector<unsigned int>
1149 const std::vector<unsigned int> &targets,
1150 const std::function<RequestType(
const unsigned int)> &create_request,
1151 const std::function<AnswerType(
const unsigned int,
const RequestType &)>
1153 const std::function<
void(
const unsigned int,
const AnswerType &)>
1157 return Serial<RequestType, AnswerType>().run(
1158 targets, create_request, answer_request, process_answer,
comm);
1163 template <
typename RequestType>
1164 std::vector<unsigned int>
1166 const std::vector<unsigned int> &targets,
1167 const std::function<RequestType(
const unsigned int)> &create_request,
1168 const std::function<
void(
const unsigned int,
const RequestType &)>
1177 using EmptyType = std::tuple<>;
1183 [&process_request](
const unsigned int source_rank,
1184 const RequestType &request) -> EmptyType {
1185 process_request(source_rank, request);
1193 [](
const unsigned int ,
1194 const EmptyType & ) {},
1200 template <
typename RequestType,
typename AnswerType>
1201 std::vector<unsigned int>
1203 const std::vector<unsigned int> &targets,
1204 const std::function<RequestType(
const unsigned int)> &create_request,
1205 const std::function<AnswerType(
const unsigned int,
const RequestType &)>
1207 const std::function<
void(
const unsigned int,
const AnswerType &)>
1211 return Selector<RequestType, AnswerType>().run(
1212 targets, create_request, answer_request, process_answer,
comm);
1217 template <
typename RequestType>
1218 std::vector<unsigned int>
1220 const std::vector<unsigned int> &targets,
1221 const std::function<RequestType(
const unsigned int)> &create_request,
1222 const std::function<
void(
const unsigned int,
const RequestType &)>
1231 using EmptyType = std::tuple<>;
1237 [&process_request](
const unsigned int source_rank,
1238 const RequestType &request) -> EmptyType {
1239 process_request(source_rank, request);
1247 [](
const unsigned int ,
1248 const EmptyType & ) {},
1269 namespace ConsensusAlgorithms
1278 has_unique_elements(
const std::vector<unsigned int> &targets)
1280 std::vector<unsigned int> my_destinations = targets;
1281 std::sort(my_destinations.begin(), my_destinations.end());
1282 return (std::adjacent_find(my_destinations.begin(),
1283 my_destinations.end()) ==
1284 my_destinations.end());
1293 handle_exception(std::exception_ptr &&exception,
const MPI_Comm comm)
1295# ifdef DEAL_II_WITH_MPI
1300 std::rethrow_exception(exception);
1308 <<
"----------------------------------------------------"
1313 <<
" on processing: " << std::endl
1314 << exc.
what() << std::endl
1315 <<
"Aborting!" << std::endl
1316 <<
"----------------------------------------------------"
1320 MPI_Abort(
comm, 255);
1322 catch (std::exception &exc)
1327 <<
"----------------------------------------------------"
1330 <<
"Exception within ConsensusAlgorithm"
1332 <<
" on processing: " << std::endl
1333 << exc.what() << std::endl
1334 <<
"Aborting!" << std::endl
1335 <<
"----------------------------------------------------"
1339 MPI_Abort(
comm, 255);
1346 <<
"----------------------------------------------------"
1349 <<
"Unknown exception within ConsensusAlgorithm!" << std::endl
1350 <<
"Aborting!" << std::endl
1351 <<
"----------------------------------------------------"
1355 MPI_Abort(
comm, 255);
1362 std::rethrow_exception(exception);
1369 template <
typename RequestType,
typename AnswerType>
1372 const RequestType &,
1380 template <
typename RequestType,
typename AnswerType>
1390 template <
typename RequestType,
typename AnswerType>
1400 template <
typename RequestType,
typename AnswerType>
1401 std::vector<unsigned int>
1403 Process<RequestType, AnswerType> &process,
1409 process.compute_targets(),
1411 [&process](
const unsigned int target) {
1412 RequestType request;
1413 process.create_request(target, request);
1417 [&process](
const unsigned int source,
const RequestType &request) {
1419 process.answer_request(source, request, answer);
1423 [&process](
const unsigned int target,
const AnswerType &answer) {
1424 process.read_answer(target, answer);
1431 template <
typename RequestType,
typename AnswerType>
1432 std::vector<unsigned int>
1434 const std::vector<unsigned int> &targets,
1435 const std::function<RequestType(
const unsigned int)> &create_request,
1436 const std::function<AnswerType(
const unsigned int,
const RequestType &)>
1438 const std::function<
void(
const unsigned int,
const AnswerType &)>
1442 Assert(has_unique_elements(targets),
1443 ExcMessage(
"The consensus algorithms expect that each process "
1444 "only sends a single message to another process, "
1445 "but the targets provided include duplicates."));
1447 static CollectiveMutex mutex;
1448 CollectiveMutex::ScopedLock lock(mutex,
comm);
1454 start_communication(targets, create_request,
comm);
1470 while (all_locally_originated_receives_are_completed(process_answer,
1472 maybe_answer_one_request(answer_request,
comm);
1476 signal_finish(
comm);
1481 while (all_remotely_originated_receives_are_completed() ==
false)
1482 maybe_answer_one_request(answer_request,
comm);
1485 clean_up_and_end_communication(
comm);
1489 handle_exception(std::current_exception(),
comm);
1492 return std::vector<unsigned int>(requesting_processes.begin(),
1493 requesting_processes.end());
1498 template <
typename RequestType,
typename AnswerType>
1501 const std::vector<unsigned int> &targets,
1502 const std::function<RequestType(
const unsigned int)> &create_request,
1505# ifdef DEAL_II_WITH_MPI
1507 const auto n_targets = targets.size();
1513 send_requests.resize(n_targets);
1514 send_buffers.resize(n_targets);
1518 for (
unsigned int index = 0;
index < n_targets; ++
index)
1520 const unsigned int rank = targets[
index];
1523 auto &send_buffer = send_buffers[
index];
1526 std::vector<char>());
1529 auto ierr = MPI_Isend(send_buffer.data(),
1535 &send_requests[index]);
1541 n_outstanding_answers = n_targets;
1545 (void)create_request;
1552 template <
typename RequestType,
typename AnswerType>
1556 const std::function<
void(
const unsigned int,
const AnswerType &)>
1560# ifdef DEAL_II_WITH_MPI
1568 if (n_outstanding_answers == 0)
1575 int request_is_pending;
1577 const auto ierr = MPI_Iprobe(
1578 MPI_ANY_SOURCE, tag_deliver,
comm, &request_is_pending, &status);
1584 if (request_is_pending == 0)
1590 const auto target = status.MPI_SOURCE;
1597 MPI_Get_count(&status, MPI_CHAR, &message_size);
1600 std::vector<char> recv_buffer(message_size);
1606 const int ierr = MPI_Recv(recv_buffer.data(),
1617 process_answer(target,
1623 --n_outstanding_answers;
1633 return (n_outstanding_answers == 0);
1638 (void)process_answer;
1647 template <
typename RequestType,
typename AnswerType>
1650 const std::function<AnswerType(
const unsigned int,
const RequestType &)>
1654# ifdef DEAL_II_WITH_MPI
1669 int request_is_pending;
1670 const auto ierr = MPI_Iprobe(
1671 MPI_ANY_SOURCE, tag_request,
comm, &request_is_pending, &status);
1674 if (request_is_pending != 0)
1678 const auto other_rank = status.MPI_SOURCE;
1680 Assert(requesting_processes.find(other_rank) ==
1681 requesting_processes.end(),
1682 ExcMessage(
"Process is requesting a second time!"));
1683 requesting_processes.insert(other_rank);
1687 auto ierr = MPI_Get_count(&status, MPI_CHAR, &number_amount);
1691 std::vector<char> buffer_recv(number_amount);
1692 ierr = MPI_Recv(buffer_recv.data(),
1703 request_buffers.emplace_back(std::make_unique<std::vector<char>>());
1704 auto &request_buffer = *request_buffers.back();
1709 buffer_recv,
false)),
1713 request_requests.emplace_back(std::make_unique<MPI_Request>());
1714 ierr = MPI_Isend(request_buffer.data(),
1715 request_buffer.size(),
1720 request_requests.back().get());
1724 (void)answer_request;
1731 template <
typename RequestType,
typename AnswerType>
1735# ifdef DEAL_II_WITH_MPI
1736 const auto ierr = MPI_Ibarrier(
comm, &barrier_request);
1745 template <
typename RequestType,
typename AnswerType>
1748 AnswerType>::all_remotely_originated_receives_are_completed()
1750# ifdef DEAL_II_WITH_MPI
1751 int all_ranks_reached_barrier;
1752 const auto ierr = MPI_Test(&barrier_request,
1753 &all_ranks_reached_barrier,
1756 return all_ranks_reached_barrier != 0;
1764 template <
typename RequestType,
typename AnswerType>
1770# ifdef DEAL_II_WITH_MPI
1773 if (send_requests.size() > 0)
1775 const int ierr = MPI_Waitall(send_requests.size(),
1776 send_requests.data(),
1777 MPI_STATUSES_IGNORE);
1781 int ierr = MPI_Wait(&barrier_request, MPI_STATUS_IGNORE);
1784 for (
auto &i : request_requests)
1786 ierr = MPI_Wait(i.get(), MPI_STATUS_IGNORE);
1793 ierr = MPI_Barrier(
comm);
1802 template <
typename RequestType,
typename AnswerType>
1803 std::vector<unsigned int>
1805 const std::vector<unsigned int> &targets,
1806 const std::function<RequestType(
const unsigned int)> &create_request,
1807 const std::function<AnswerType(
const unsigned int,
const RequestType &)>
1809 const std::function<
void(
const unsigned int,
const AnswerType &)>
1813 Assert(has_unique_elements(targets),
1814 ExcMessage(
"The consensus algorithms expect that each process "
1815 "only sends a single message to another process, "
1816 "but the targets provided include duplicates."));
1818 static CollectiveMutex mutex;
1819 CollectiveMutex::ScopedLock lock(mutex,
comm);
1826 const unsigned int n_requests =
1827 start_communication(targets, create_request,
comm);
1830 for (
unsigned int request = 0; request < n_requests; ++request)
1831 answer_one_request(request, answer_request,
comm);
1834 process_incoming_answers(targets.size(), process_answer,
comm);
1837 clean_up_and_end_communication();
1841 handle_exception(std::current_exception(),
comm);
1844 return std::vector<unsigned int>(requesting_processes.begin(),
1845 requesting_processes.end());
1850 template <
typename RequestType,
typename AnswerType>
1853 const std::vector<unsigned int> &targets,
1854 const std::function<RequestType(
const unsigned int)> &create_request,
1857# ifdef DEAL_II_WITH_MPI
1863 const unsigned int n_targets = targets.size();
1866 const unsigned int n_sources =
1870 recv_buffers.resize(n_targets);
1871 send_buffers.resize(n_targets);
1872 send_request_requests.resize(n_targets);
1874 send_answer_requests.resize(n_sources);
1875 requests_buffers.resize(n_sources);
1878 for (
unsigned int i = 0; i < n_targets; ++i)
1880 const unsigned int rank = targets[i];
1884 auto &send_buffer = send_buffers[i];
1889 auto ierr = MPI_Isend(send_buffer.data(),
1895 &send_request_requests[i]);
1902 (void)create_request;
1910 template <
typename RequestType,
typename AnswerType>
1913 const unsigned int index,
1914 const std::function<AnswerType(
const unsigned int,
const RequestType &)>
1918# ifdef DEAL_II_WITH_MPI
1927 int ierr = MPI_Probe(MPI_ANY_SOURCE, tag_request,
comm, &status);
1931 const unsigned int other_rank = status.MPI_SOURCE;
1933 Assert(requesting_processes.find(other_rank) ==
1934 requesting_processes.end(),
1936 "A process is sending a request after a request from "
1937 "the same process has previously already been "
1938 "received. This algorithm does not expect this to happen."));
1939 requesting_processes.insert(other_rank);
1943 ierr = MPI_Get_count(&status, MPI_CHAR, &number_amount);
1946 std::vector<char> buffer_recv(number_amount);
1947 ierr = MPI_Recv(buffer_recv.data(),
1958 auto &request_buffer = requests_buffers[
index];
1963 buffer_recv,
false)),
1965 std::vector<char>());
1967 ierr = MPI_Isend(request_buffer.data(),
1968 request_buffer.size(),
1973 &send_answer_requests[index]);
1976 (void)answer_request;
1984 template <
typename RequestType,
typename AnswerType>
1987 const unsigned int n_targets,
1988 const std::function<
void(
const unsigned int,
const AnswerType &)>
1992# ifdef DEAL_II_WITH_MPI
2001 for (
unsigned int i = 0; i < n_targets; ++i)
2006 MPI_Probe(MPI_ANY_SOURCE, tag_deliver,
comm, &status);
2010 const auto other_rank = status.MPI_SOURCE;
2013 const int ierr = MPI_Get_count(&status, MPI_CHAR, &message_size);
2016 std::vector<char> recv_buffer(message_size);
2022 const int ierr = MPI_Recv(recv_buffer.data(),
2033 process_answer(other_rank,
2038 (void)process_answer;
2045 template <
typename RequestType,
typename AnswerType>
2049# ifdef DEAL_II_WITH_MPI
2052 if (send_request_requests.size() > 0)
2054 const int ierr = MPI_Waitall(send_request_requests.size(),
2055 send_request_requests.data(),
2056 MPI_STATUSES_IGNORE);
2061 if (send_answer_requests.size() > 0)
2063 const int ierr = MPI_Waitall(send_answer_requests.size(),
2064 send_answer_requests.data(),
2065 MPI_STATUSES_IGNORE);
2073 template <
typename RequestType,
typename AnswerType>
2074 std::vector<unsigned int>
2076 const std::vector<unsigned int> &targets,
2077 const std::function<RequestType(
const unsigned int)> &create_request,
2078 const std::function<AnswerType(
const unsigned int,
const RequestType &)>
2080 const std::function<
void(
const unsigned int,
const AnswerType &)>
2086 ExcMessage(
"You shouldn't use the 'Serial' class on "
2087 "communicators that have more than one process "
2088 "associated with it."));
2091 if (targets.size() != 0)
2093 Assert(targets.size() == 1,
2095 "On a single process, the only valid target "
2096 "is process zero (the process itself), which can only be "
2103 const RequestType request =
2104 (create_request ? create_request(0) : RequestType());
2105 const AnswerType answer =
2106 (answer_request ? answer_request(0, request) : AnswerType());
2109 process_answer(0, answer);
2117 template <
typename RequestType,
typename AnswerType>
2118 std::vector<unsigned int>
2120 const std::vector<unsigned int> &targets,
2121 const std::function<RequestType(
const unsigned int)> &create_request,
2122 const std::function<AnswerType(
const unsigned int,
const RequestType &)>
2124 const std::function<
void(
const unsigned int,
const AnswerType &)>
2137# ifdef DEAL_II_WITH_MPI
2143 consensus_algo.reset(
new NBX<RequestType, AnswerType>());
2147 consensus_algo.reset(
new PEX<RequestType, AnswerType>());
2149 consensus_algo.reset(
new Serial<RequestType, AnswerType>());
2151 return consensus_algo->run(
2152 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)
T unpack(const std::vector< char > &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