13#ifndef dealii_mpi_consensus_algorithm_h
14#define dealii_mpi_consensus_algorithm_h
19#include <deal.II/base/mpi.templates.h>
161 template <
typename RequestType,
typename AnswerType>
177 virtual std::vector<unsigned int>
206 const RequestType &buffer_recv,
207 AnswerType &request_buffer);
218 const AnswerType &recv_buffer);
236 template <
typename RequestType,
typename AnswerType>
266 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>
333 std::vector<unsigned int>
342 virtual std::vector<unsigned int>
344 const std::vector<unsigned int> &targets,
345 const std::function<RequestType(
const unsigned int)> &create_request,
346 const std::function<AnswerType(
const unsigned int,
347 const RequestType &)> &answer_request,
348 const std::function<
void(
const unsigned int,
const AnswerType &)>
353#ifdef DEAL_II_WITH_MPI
399 const std::function<
void(
const unsigned int,
const AnswerType &)>
425 const std::function<AnswerType(
const unsigned int,
426 const RequestType &)> &answer_request,
435 const std::vector<unsigned int> &targets,
436 const std::function<RequestType(
const unsigned int)> &create_request,
492 template <
typename RequestType,
typename AnswerType>
493 std::vector<unsigned int>
494 nbx(
const std::vector<unsigned int> &targets,
495 const std::function<RequestType(
const unsigned int)> &create_request,
496 const std::function<AnswerType(
const unsigned int,
497 const RequestType &)> &answer_request,
498 const std::function<
void(
const unsigned int,
const AnswerType &)>
539 template <
typename RequestType>
540 std::vector<unsigned int>
541 nbx(
const std::vector<unsigned int> &targets,
542 const std::function<RequestType(
const unsigned int)> &create_request,
543 const std::function<
void(
const unsigned int,
const RequestType &)>
572 template <
typename RequestType,
typename AnswerType>
587 std::vector<unsigned int>
596 virtual std::vector<unsigned int>
598 const std::vector<unsigned int> &targets,
599 const std::function<RequestType(
const unsigned int)> &create_request,
600 const std::function<AnswerType(
const unsigned int,
601 const RequestType &)> &answer_request,
602 const std::function<
void(
const unsigned int,
const AnswerType &)>
607#ifdef DEAL_II_WITH_MPI
644 const std::vector<unsigned int> &targets,
645 const std::function<RequestType(
const unsigned int)> &create_request,
654 const unsigned int index,
655 const std::function<AnswerType(
const unsigned int,
656 const RequestType &)> &answer_request,
665 const unsigned int n_targets,
666 const std::function<
void(
const unsigned int,
const AnswerType &)>
736 template <
typename RequestType,
typename AnswerType>
737 std::vector<unsigned int>
738 pex(
const std::vector<unsigned int> &targets,
739 const std::function<RequestType(
const unsigned int)> &create_request,
740 const std::function<AnswerType(
const unsigned int,
741 const RequestType &)> &answer_request,
742 const std::function<
void(
const unsigned int,
const AnswerType &)>
783 template <
typename RequestType>
784 std::vector<unsigned int>
785 pex(
const std::vector<unsigned int> &targets,
786 const std::function<RequestType(
const unsigned int)> &create_request,
787 const std::function<
void(
const unsigned int,
const RequestType &)>
796 template <
typename RequestType,
typename AnswerType>
806 std::vector<unsigned int>
815 virtual std::vector<unsigned int>
817 const std::vector<unsigned int> &targets,
818 const std::function<RequestType(
const unsigned int)> &create_request,
819 const std::function<AnswerType(
const unsigned int,
820 const RequestType &)> &answer_request,
821 const std::function<
void(
const unsigned int,
const AnswerType &)>
860 template <
typename RequestType,
typename AnswerType>
861 std::vector<unsigned int>
863 const std::vector<unsigned int> &targets,
864 const std::function<RequestType(
const unsigned int)> &create_request,
865 const std::function<AnswerType(
const unsigned int,
const RequestType &)>
867 const std::function<
void(
const unsigned int,
const AnswerType &)>
900 template <
typename RequestType>
901 std::vector<unsigned int>
903 const std::vector<unsigned int> &targets,
904 const std::function<RequestType(
const unsigned int)> &create_request,
905 const std::function<
void(
const unsigned int,
const RequestType &)>
923 template <
typename RequestType,
typename AnswerType>
938 std::vector<unsigned int>
949 virtual std::vector<unsigned int>
951 const std::vector<unsigned int> &targets,
952 const std::function<RequestType(
const unsigned int)> &create_request,
953 const std::function<AnswerType(
const unsigned int,
954 const RequestType &)> &answer_request,
955 const std::function<
void(
const unsigned int,
const AnswerType &)>
1010 template <
typename RequestType,
typename AnswerType>
1011 std::vector<unsigned int>
1013 const std::vector<unsigned int> &targets,
1014 const std::function<RequestType(
const unsigned int)> &create_request,
1015 const std::function<AnswerType(
const unsigned int,
const RequestType &)>
1017 const std::function<
void(
const unsigned int,
const AnswerType &)>
1058 template <
typename RequestType>
1059 std::vector<unsigned int>
1061 const std::vector<unsigned int> &targets,
1062 const std::function<RequestType(
const unsigned int)> &create_request,
1063 const std::function<
void(
const unsigned int,
const RequestType &)>
1072 template <
typename RequestType,
typename AnswerType>
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<AnswerType(
const unsigned int,
1077 const RequestType &)> &answer_request,
1078 const std::function<
void(
const unsigned int,
const AnswerType &)>
1083 targets, create_request, answer_request, process_answer,
comm);
1088 template <
typename RequestType>
1089 std::vector<unsigned int>
1090 nbx(
const std::vector<unsigned int> &targets,
1091 const std::function<RequestType(
const unsigned int)> &create_request,
1092 const std::function<
void(
const unsigned int,
const RequestType &)>
1101 using EmptyType = std::tuple<>;
1107 [&process_request](
const unsigned int source_rank,
1108 const RequestType &request) -> EmptyType {
1109 process_request(source_rank, request);
1117 [](
const unsigned int ,
1118 const EmptyType & ) {},
1124 template <
typename RequestType,
typename AnswerType>
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<AnswerType(
const unsigned int,
1129 const RequestType &)> &answer_request,
1130 const std::function<
void(
const unsigned int,
const AnswerType &)>
1132 const MPI_Comm
comm)
1135 targets, create_request, answer_request, process_answer,
comm);
1140 template <
typename RequestType>
1141 std::vector<unsigned int>
1142 pex(
const std::vector<unsigned int> &targets,
1143 const std::function<RequestType(
const unsigned int)> &create_request,
1144 const std::function<
void(
const unsigned int,
const RequestType &)>
1146 const MPI_Comm
comm)
1153 using EmptyType = std::tuple<>;
1159 [&process_request](
const unsigned int source_rank,
1160 const RequestType &request) -> EmptyType {
1161 process_request(source_rank, request);
1169 [](
const unsigned int ,
1170 const EmptyType & ) {},
1176 template <
typename RequestType,
typename AnswerType>
1177 std::vector<unsigned int>
1179 const std::vector<unsigned int> &targets,
1180 const std::function<RequestType(
const unsigned int)> &create_request,
1181 const std::function<AnswerType(
const unsigned int,
const RequestType &)>
1183 const std::function<
void(
const unsigned int,
const AnswerType &)>
1185 const MPI_Comm
comm)
1188 targets, create_request, answer_request, process_answer,
comm);
1193 template <
typename RequestType>
1194 std::vector<unsigned int>
1196 const std::vector<unsigned int> &targets,
1197 const std::function<RequestType(
const unsigned int)> &create_request,
1198 const std::function<
void(
const unsigned int,
const RequestType &)>
1200 const MPI_Comm
comm)
1207 using EmptyType = std::tuple<>;
1213 [&process_request](
const unsigned int source_rank,
1214 const RequestType &request) -> EmptyType {
1215 process_request(source_rank, request);
1223 [](
const unsigned int ,
1224 const EmptyType & ) {},
1230 template <
typename RequestType,
typename AnswerType>
1231 std::vector<unsigned int>
1233 const std::vector<unsigned int> &targets,
1234 const std::function<RequestType(
const unsigned int)> &create_request,
1235 const std::function<AnswerType(
const unsigned int,
const RequestType &)>
1237 const std::function<
void(
const unsigned int,
const AnswerType &)>
1239 const MPI_Comm
comm)
1242 targets, create_request, answer_request, process_answer,
comm);
1247 template <
typename RequestType>
1248 std::vector<unsigned int>
1250 const std::vector<unsigned int> &targets,
1251 const std::function<RequestType(
const unsigned int)> &create_request,
1252 const std::function<
void(
const unsigned int,
const RequestType &)>
1254 const MPI_Comm
comm)
1261 using EmptyType = std::tuple<>;
1267 [&process_request](
const unsigned int source_rank,
1268 const RequestType &request) -> EmptyType {
1269 process_request(source_rank, request);
1277 [](
const unsigned int ,
1278 const EmptyType & ) {},
1308 has_unique_elements(
const std::vector<unsigned int> &targets)
1310 std::vector<unsigned int> my_destinations = targets;
1311 std::sort(my_destinations.begin(), my_destinations.end());
1312 return (std::adjacent_find(my_destinations.begin(),
1313 my_destinations.end()) ==
1314 my_destinations.end());
1323 handle_exception(std::exception_ptr &&exception,
const MPI_Comm
comm)
1325# ifdef DEAL_II_WITH_MPI
1330 std::rethrow_exception(exception);
1332 catch (ExceptionBase &exc)
1338 <<
"----------------------------------------------------"
1343 <<
" on processing: " << std::endl
1344 << exc.
what() << std::endl
1345 <<
"Aborting!" << std::endl
1346 <<
"----------------------------------------------------"
1350 MPI_Abort(
comm, 255);
1352 catch (std::exception &exc)
1357 <<
"----------------------------------------------------"
1360 <<
"Exception within ConsensusAlgorithm"
1362 <<
" on processing: " << std::endl
1363 << exc.what() << std::endl
1364 <<
"Aborting!" << std::endl
1365 <<
"----------------------------------------------------"
1369 MPI_Abort(
comm, 255);
1376 <<
"----------------------------------------------------"
1379 <<
"Unknown exception within ConsensusAlgorithm!" << std::endl
1380 <<
"Aborting!" << std::endl
1381 <<
"----------------------------------------------------"
1385 MPI_Abort(
comm, 255);
1392 std::rethrow_exception(exception);
1399 template <
typename RequestType,
typename AnswerType>
1402 const RequestType &,
1410 template <
typename RequestType,
typename AnswerType>
1420 template <
typename RequestType,
typename AnswerType>
1430 template <
typename RequestType,
typename AnswerType>
1431 std::vector<unsigned int>
1434 const MPI_Comm
comm)
1439 process.compute_targets(),
1441 [&process](
const unsigned int target) {
1442 RequestType request;
1443 process.create_request(target, request);
1447 [&process](
const unsigned int source,
const RequestType &request) {
1449 process.answer_request(source, request, answer);
1453 [&process](
const unsigned int target,
const AnswerType &answer) {
1454 process.read_answer(target, answer);
1461 template <
typename RequestType,
typename AnswerType>
1462 std::vector<unsigned int>
1464 const std::vector<unsigned int> &targets,
1465 const std::function<RequestType(
const unsigned int)> &create_request,
1466 const std::function<AnswerType(
const unsigned int,
const RequestType &)>
1468 const std::function<
void(
const unsigned int,
const AnswerType &)>
1470 const MPI_Comm
comm)
1472 Assert(internal::has_unique_elements(targets),
1473 ExcMessage(
"The consensus algorithms expect that each process "
1474 "only sends a single message to another process, "
1475 "but the targets provided include duplicates."));
1477 static CollectiveMutex mutex;
1478 CollectiveMutex::ScopedLock lock(mutex,
comm);
1484 start_communication(targets, create_request,
comm);
1500 while (all_locally_originated_receives_are_completed(process_answer,
1502 maybe_answer_one_request(answer_request,
comm);
1506 signal_finish(
comm);
1511 while (all_remotely_originated_receives_are_completed() ==
false)
1512 maybe_answer_one_request(answer_request,
comm);
1515 clean_up_and_end_communication(
comm);
1519 internal::handle_exception(std::current_exception(),
comm);
1522 return std::vector<unsigned int>(requesting_processes.begin(),
1523 requesting_processes.end());
1528 template <
typename RequestType,
typename AnswerType>
1531 const std::vector<unsigned int> &targets,
1532 const std::function<RequestType(
const unsigned int)> &create_request,
1533 const MPI_Comm
comm)
1535# ifdef DEAL_II_WITH_MPI
1537 const auto n_targets = targets.size();
1539 const int tag_request = Utilities::MPI::internal::Tags::
1540 consensus_algorithm_nbx_answer_request;
1543 send_requests.resize(n_targets);
1544 send_buffers.resize(n_targets);
1548 for (
unsigned int index = 0;
index < n_targets; ++
index)
1550 const unsigned int rank = targets[
index];
1553 auto &send_buffer = send_buffers[
index];
1556 std::vector<char>());
1559 auto ierr = MPI_Isend(send_buffer.data(),
1565 &send_requests[index]);
1571 n_outstanding_answers = n_targets;
1575 (void)create_request;
1582 template <
typename RequestType,
typename AnswerType>
1586 const std::function<
void(
const unsigned int,
const AnswerType &)>
1588 const MPI_Comm
comm)
1590# ifdef DEAL_II_WITH_MPI
1598 if (n_outstanding_answers == 0)
1602 const int tag_deliver = Utilities::MPI::internal::Tags::
1603 consensus_algorithm_nbx_process_deliver;
1605 int request_is_pending;
1607 const auto ierr = MPI_Iprobe(
1608 MPI_ANY_SOURCE, tag_deliver,
comm, &request_is_pending, &status);
1614 if (request_is_pending == 0)
1620 const auto target = status.MPI_SOURCE;
1627 MPI_Get_count(&status, MPI_CHAR, &message_size);
1630 std::vector<char> recv_buffer(message_size);
1633 const int tag_deliver = Utilities::MPI::internal::Tags::
1634 consensus_algorithm_nbx_process_deliver;
1636 const int ierr = MPI_Recv(recv_buffer.data(),
1647 process_answer(target,
1653 --n_outstanding_answers;
1663 return (n_outstanding_answers == 0);
1668 (void)process_answer;
1677 template <
typename RequestType,
typename AnswerType>
1680 const std::function<AnswerType(
const unsigned int,
const RequestType &)>
1682 const MPI_Comm
comm)
1684# ifdef DEAL_II_WITH_MPI
1686 const int tag_request = Utilities::MPI::internal::Tags::
1687 consensus_algorithm_nbx_answer_request;
1688 const int tag_deliver = Utilities::MPI::internal::Tags::
1689 consensus_algorithm_nbx_process_deliver;
1699 int request_is_pending;
1700 const auto ierr = MPI_Iprobe(
1701 MPI_ANY_SOURCE, tag_request,
comm, &request_is_pending, &status);
1704 if (request_is_pending != 0)
1708 const auto other_rank = status.MPI_SOURCE;
1710 Assert(requesting_processes.find(other_rank) ==
1711 requesting_processes.end(),
1712 ExcMessage(
"Process is requesting a second time!"));
1713 requesting_processes.insert(other_rank);
1717 auto ierr = MPI_Get_count(&status, MPI_CHAR, &number_amount);
1721 std::vector<char> buffer_recv(number_amount);
1722 ierr = MPI_Recv(buffer_recv.data(),
1733 request_buffers.emplace_back(std::make_unique<std::vector<char>>());
1734 auto &request_buffer = *request_buffers.back();
1739 buffer_recv,
false)),
1743 request_requests.emplace_back(std::make_unique<MPI_Request>());
1744 ierr = MPI_Isend(request_buffer.data(),
1745 request_buffer.size(),
1750 request_requests.back().get());
1754 (void)answer_request;
1761 template <
typename RequestType,
typename AnswerType>
1765# ifdef DEAL_II_WITH_MPI
1766 const auto ierr = MPI_Ibarrier(
comm, &barrier_request);
1775 template <
typename RequestType,
typename AnswerType>
1778 AnswerType>::all_remotely_originated_receives_are_completed()
1780# ifdef DEAL_II_WITH_MPI
1781 int all_ranks_reached_barrier;
1782 const auto ierr = MPI_Test(&barrier_request,
1783 &all_ranks_reached_barrier,
1786 return all_ranks_reached_barrier != 0;
1794 template <
typename RequestType,
typename AnswerType>
1797 const MPI_Comm
comm)
1800# ifdef DEAL_II_WITH_MPI
1803 if (send_requests.size() > 0)
1805 const int ierr = MPI_Waitall(send_requests.size(),
1806 send_requests.data(),
1807 MPI_STATUSES_IGNORE);
1811 int ierr = MPI_Wait(&barrier_request, MPI_STATUS_IGNORE);
1814 for (
auto &i : request_requests)
1816 ierr = MPI_Wait(i.get(), MPI_STATUS_IGNORE);
1824 ierr = MPI_Barrier(
comm);
1833 template <
typename RequestType,
typename AnswerType>
1834 std::vector<unsigned int>
1836 const std::vector<unsigned int> &targets,
1837 const std::function<RequestType(
const unsigned int)> &create_request,
1838 const std::function<AnswerType(
const unsigned int,
const RequestType &)>
1840 const std::function<
void(
const unsigned int,
const AnswerType &)>
1842 const MPI_Comm
comm)
1844 Assert(internal::has_unique_elements(targets),
1845 ExcMessage(
"The consensus algorithms expect that each process "
1846 "only sends a single message to another process, "
1847 "but the targets provided include duplicates."));
1849 static CollectiveMutex mutex;
1850 CollectiveMutex::ScopedLock lock(mutex,
comm);
1857 const unsigned int n_requests =
1858 start_communication(targets, create_request,
comm);
1861 for (
unsigned int request = 0; request < n_requests; ++request)
1862 answer_one_request(request, answer_request,
comm);
1865 process_incoming_answers(targets.size(), process_answer,
comm);
1868 clean_up_and_end_communication();
1872 internal::handle_exception(std::current_exception(),
comm);
1875 return std::vector<unsigned int>(requesting_processes.begin(),
1876 requesting_processes.end());
1881 template <
typename RequestType,
typename AnswerType>
1884 const std::vector<unsigned int> &targets,
1885 const std::function<RequestType(
const unsigned int)> &create_request,
1886 const MPI_Comm
comm)
1888# ifdef DEAL_II_WITH_MPI
1889 const int tag_request = Utilities::MPI::internal::Tags::
1890 consensus_algorithm_pex_answer_request;
1894 const unsigned int n_targets = targets.size();
1897 const unsigned int n_sources =
1901 recv_buffers.resize(n_targets);
1902 send_buffers.resize(n_targets);
1903 send_request_requests.resize(n_targets);
1905 send_answer_requests.resize(n_sources);
1906 requests_buffers.resize(n_sources);
1909 for (
unsigned int i = 0; i < n_targets; ++i)
1911 const unsigned int rank = targets[i];
1915 auto &send_buffer = send_buffers[i];
1920 auto ierr = MPI_Isend(send_buffer.data(),
1926 &send_request_requests[i]);
1933 (void)create_request;
1941 template <
typename RequestType,
typename AnswerType>
1944 const unsigned int index,
1945 const std::function<AnswerType(
const unsigned int,
const RequestType &)>
1947 const MPI_Comm
comm)
1949# ifdef DEAL_II_WITH_MPI
1950 const int tag_request = Utilities::MPI::internal::Tags::
1951 consensus_algorithm_pex_answer_request;
1952 const int tag_deliver = Utilities::MPI::internal::Tags::
1953 consensus_algorithm_pex_process_deliver;
1958 int ierr = MPI_Probe(MPI_ANY_SOURCE, tag_request,
comm, &status);
1962 const unsigned int other_rank = status.MPI_SOURCE;
1964 Assert(requesting_processes.find(other_rank) ==
1965 requesting_processes.end(),
1967 "A process is sending a request after a request from "
1968 "the same process has previously already been "
1969 "received. This algorithm does not expect this to happen."));
1970 requesting_processes.insert(other_rank);
1974 ierr = MPI_Get_count(&status, MPI_CHAR, &number_amount);
1977 std::vector<char> buffer_recv(number_amount);
1978 ierr = MPI_Recv(buffer_recv.data(),
1989 auto &request_buffer = requests_buffers[
index];
1994 buffer_recv,
false)),
1996 std::vector<char>());
1998 ierr = MPI_Isend(request_buffer.data(),
1999 request_buffer.size(),
2004 &send_answer_requests[index]);
2007 (void)answer_request;
2015 template <
typename RequestType,
typename AnswerType>
2018 const unsigned int n_targets,
2019 const std::function<
void(
const unsigned int,
const AnswerType &)>
2021 const MPI_Comm
comm)
2023# ifdef DEAL_II_WITH_MPI
2024 const int tag_deliver = Utilities::MPI::internal::Tags::
2025 consensus_algorithm_pex_process_deliver;
2032 for (
unsigned int i = 0; i < n_targets; ++i)
2037 MPI_Probe(MPI_ANY_SOURCE, tag_deliver,
comm, &status);
2041 const auto other_rank = status.MPI_SOURCE;
2044 const int ierr = MPI_Get_count(&status, MPI_CHAR, &message_size);
2047 std::vector<char> recv_buffer(message_size);
2053 const int ierr = MPI_Recv(recv_buffer.data(),
2064 process_answer(other_rank,
2069 (void)process_answer;
2076 template <
typename RequestType,
typename AnswerType>
2080# ifdef DEAL_II_WITH_MPI
2083 if (send_request_requests.size() > 0)
2085 const int ierr = MPI_Waitall(send_request_requests.size(),
2086 send_request_requests.data(),
2087 MPI_STATUSES_IGNORE);
2092 if (send_answer_requests.size() > 0)
2094 const int ierr = MPI_Waitall(send_answer_requests.size(),
2095 send_answer_requests.data(),
2096 MPI_STATUSES_IGNORE);
2104 template <
typename RequestType,
typename AnswerType>
2105 std::vector<unsigned int>
2107 const std::vector<unsigned int> &targets,
2108 const std::function<RequestType(
const unsigned int)> &create_request,
2109 const std::function<AnswerType(
const unsigned int,
const RequestType &)>
2111 const std::function<
void(
const unsigned int,
const AnswerType &)>
2113 const MPI_Comm
comm)
2116 ExcMessage(
"You shouldn't use the 'Serial' class on "
2117 "communicators that have more than one process "
2118 "associated with it."));
2121 if (targets.size() != 0)
2123 Assert(targets.size() == 1,
2125 "On a single process, the only valid target "
2126 "is process zero (the process itself), which can only be "
2133 const RequestType request =
2134 (create_request ? create_request(0) : RequestType());
2135 const AnswerType answer =
2136 (answer_request ? answer_request(0, request) : AnswerType());
2139 process_answer(0, answer);
2147 template <
typename RequestType,
typename AnswerType>
2148 std::vector<unsigned int>
2150 const std::vector<unsigned int> &targets,
2151 const std::function<RequestType(
const unsigned int)> &create_request,
2152 const std::function<AnswerType(
const unsigned int,
const RequestType &)>
2154 const std::function<
void(
const unsigned int,
const AnswerType &)>
2156 const MPI_Comm
comm)
2167# ifdef DEAL_II_WITH_MPI
2181 return consensus_algo->run(
2182 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::vector< unsigned int > run(Process< RequestType, AnswerType > &process, const MPI_Comm comm)
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::vector< unsigned int > run(Process< RequestType, AnswerType > &process, 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::vector< unsigned int > run(Process< RequestType, AnswerType > &process, const MPI_Comm comm)
std::shared_ptr< Interface< RequestType, AnswerType > > consensus_algo
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) override
#define DEAL_II_DEPRECATED
#define DEAL_II_NAMESPACE_OPEN
#define DEAL_II_DISABLE_EXTRA_DIAGNOSTICS
constexpr bool running_in_debug_mode()
#define DEAL_II_NAMESPACE_CLOSE
#define DEAL_II_ENABLE_EXTRA_DIAGNOSTICS
#define Assert(cond, exc)
#define AssertDimension(dim1, dim2)
#define AssertThrowMPI(error_code)
#define AssertIndexRange(index, range)
static ::ExceptionBase & ExcMessage(std::string arg1)
* * if(update_pressure &update_flags) * compute_pressure(constitutive_request
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)
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