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
160 template <
typename RequestType,
typename AnswerType>
176 virtual std::vector<unsigned int>
205 const RequestType &buffer_recv,
206 AnswerType &request_buffer);
217 const AnswerType &recv_buffer);
235 template <
typename RequestType,
typename AnswerType>
263 DEAL_II_DEPRECATED_EARLY
264 std::vector<unsigned int>
290 virtual std::vector<unsigned int>
292 const std::vector<unsigned int> &targets,
293 const std::function<RequestType(
const unsigned int)> &create_request,
294 const std::function<AnswerType(
const unsigned int,
295 const RequestType &)> &answer_request,
296 const std::function<
void(
const unsigned int,
const AnswerType &)>
315 template <
typename RequestType,
typename AnswerType>
335 virtual std::vector<unsigned int>
337 const std::vector<unsigned int> &targets,
338 const std::function<RequestType(
const unsigned int)> &create_request,
339 const std::function<AnswerType(
const unsigned int,
340 const RequestType &)> &answer_request,
341 const std::function<
void(
const unsigned int,
const AnswerType &)>
346#ifdef DEAL_II_WITH_MPI
392 const std::function<
void(
const unsigned int,
const AnswerType &)>
418 const std::function<AnswerType(
const unsigned int,
419 const RequestType &)> &answer_request,
428 const std::vector<unsigned int> &targets,
429 const std::function<RequestType(
const unsigned int)> &create_request,
485 template <
typename RequestType,
typename AnswerType>
486 std::vector<unsigned int>
487 nbx(
const std::vector<unsigned int> &targets,
488 const std::function<RequestType(
const unsigned int)> &create_request,
489 const std::function<AnswerType(
const unsigned int,
490 const RequestType &)> &answer_request,
491 const std::function<
void(
const unsigned int,
const AnswerType &)>
532 template <
typename RequestType>
533 std::vector<unsigned int>
534 nbx(
const std::vector<unsigned int> &targets,
535 const std::function<RequestType(
const unsigned int)> &create_request,
536 const std::function<
void(
const unsigned int,
const RequestType &)>
565 template <
typename RequestType,
typename AnswerType>
585 virtual std::vector<unsigned int>
587 const std::vector<unsigned int> &targets,
588 const std::function<RequestType(
const unsigned int)> &create_request,
589 const std::function<AnswerType(
const unsigned int,
590 const RequestType &)> &answer_request,
591 const std::function<
void(
const unsigned int,
const AnswerType &)>
596#ifdef DEAL_II_WITH_MPI
633 const std::vector<unsigned int> &targets,
634 const std::function<RequestType(
const unsigned int)> &create_request,
643 const unsigned int index,
644 const std::function<AnswerType(
const unsigned int,
645 const RequestType &)> &answer_request,
654 const unsigned int n_targets,
655 const std::function<
void(
const unsigned int,
const AnswerType &)>
725 template <
typename RequestType,
typename AnswerType>
726 std::vector<unsigned int>
727 pex(
const std::vector<unsigned int> &targets,
728 const std::function<RequestType(
const unsigned int)> &create_request,
729 const std::function<AnswerType(
const unsigned int,
730 const RequestType &)> &answer_request,
731 const std::function<
void(
const unsigned int,
const AnswerType &)>
772 template <
typename RequestType>
773 std::vector<unsigned int>
774 pex(
const std::vector<unsigned int> &targets,
775 const std::function<RequestType(
const unsigned int)> &create_request,
776 const std::function<
void(
const unsigned int,
const RequestType &)>
785 template <
typename RequestType,
typename AnswerType>
800 virtual std::vector<unsigned int>
802 const std::vector<unsigned int> &targets,
803 const std::function<RequestType(
const unsigned int)> &create_request,
804 const std::function<AnswerType(
const unsigned int,
805 const RequestType &)> &answer_request,
806 const std::function<
void(
const unsigned int,
const AnswerType &)>
845 template <
typename RequestType,
typename AnswerType>
846 std::vector<unsigned int>
848 const std::vector<unsigned int> &targets,
849 const std::function<RequestType(
const unsigned int)> &create_request,
850 const std::function<AnswerType(
const unsigned int,
const RequestType &)>
852 const std::function<
void(
const unsigned int,
const AnswerType &)>
885 template <
typename RequestType>
886 std::vector<unsigned int>
888 const std::vector<unsigned int> &targets,
889 const std::function<RequestType(
const unsigned int)> &create_request,
890 const std::function<
void(
const unsigned int,
const RequestType &)>
908 template <
typename RequestType,
typename AnswerType>
930 virtual std::vector<unsigned int>
932 const std::vector<unsigned int> &targets,
933 const std::function<RequestType(
const unsigned int)> &create_request,
934 const std::function<AnswerType(
const unsigned int,
935 const RequestType &)> &answer_request,
936 const std::function<
void(
const unsigned int,
const AnswerType &)>
991 template <
typename RequestType,
typename AnswerType>
992 std::vector<unsigned int>
994 const std::vector<unsigned int> &targets,
995 const std::function<RequestType(
const unsigned int)> &create_request,
996 const std::function<AnswerType(
const unsigned int,
const RequestType &)>
998 const std::function<
void(
const unsigned int,
const AnswerType &)>
1039 template <
typename RequestType>
1040 std::vector<unsigned int>
1042 const std::vector<unsigned int> &targets,
1043 const std::function<RequestType(
const unsigned int)> &create_request,
1044 const std::function<
void(
const unsigned int,
const RequestType &)>
1053 template <
typename RequestType,
typename AnswerType>
1054 std::vector<unsigned int>
1055 nbx(
const std::vector<unsigned int> &targets,
1056 const std::function<RequestType(
const unsigned int)> &create_request,
1057 const std::function<AnswerType(
const unsigned int,
1058 const RequestType &)> &answer_request,
1059 const std::function<
void(
const unsigned int,
const AnswerType &)>
1064 targets, create_request, answer_request, process_answer,
comm);
1069 template <
typename RequestType>
1070 std::vector<unsigned int>
1071 nbx(
const std::vector<unsigned int> &targets,
1072 const std::function<RequestType(
const unsigned int)> &create_request,
1073 const std::function<
void(
const unsigned int,
const RequestType &)>
1082 using EmptyType = std::tuple<>;
1084 return nbx<RequestType, EmptyType>(
1088 [&process_request](
const unsigned int source_rank,
1089 const RequestType &request) -> EmptyType {
1090 process_request(source_rank, request);
1098 [](
const unsigned int ,
1099 const EmptyType & ) {},
1105 template <
typename RequestType,
typename AnswerType>
1106 std::vector<unsigned int>
1107 pex(
const std::vector<unsigned int> &targets,
1108 const std::function<RequestType(
const unsigned int)> &create_request,
1109 const std::function<AnswerType(
const unsigned int,
1110 const RequestType &)> &answer_request,
1111 const std::function<
void(
const unsigned int,
const AnswerType &)>
1115 return PEX<RequestType, AnswerType>().run(
1116 targets, create_request, answer_request, process_answer,
comm);
1121 template <
typename RequestType>
1122 std::vector<unsigned int>
1123 pex(
const std::vector<unsigned int> &targets,
1124 const std::function<RequestType(
const unsigned int)> &create_request,
1125 const std::function<
void(
const unsigned int,
const RequestType &)>
1134 using EmptyType = std::tuple<>;
1136 return pex<RequestType, EmptyType>(
1140 [&process_request](
const unsigned int source_rank,
1141 const RequestType &request) -> EmptyType {
1142 process_request(source_rank, request);
1150 [](
const unsigned int ,
1151 const EmptyType & ) {},
1157 template <
typename RequestType,
typename AnswerType>
1158 std::vector<unsigned int>
1160 const std::vector<unsigned int> &targets,
1161 const std::function<RequestType(
const unsigned int)> &create_request,
1162 const std::function<AnswerType(
const unsigned int,
const RequestType &)>
1164 const std::function<
void(
const unsigned int,
const AnswerType &)>
1168 return Serial<RequestType, AnswerType>().run(
1169 targets, create_request, answer_request, process_answer,
comm);
1174 template <
typename RequestType>
1175 std::vector<unsigned int>
1177 const std::vector<unsigned int> &targets,
1178 const std::function<RequestType(
const unsigned int)> &create_request,
1179 const std::function<
void(
const unsigned int,
const RequestType &)>
1188 using EmptyType = std::tuple<>;
1190 return serial<RequestType, EmptyType>(
1194 [&process_request](
const unsigned int source_rank,
1195 const RequestType &request) -> EmptyType {
1196 process_request(source_rank, request);
1204 [](
const unsigned int ,
1205 const EmptyType & ) {},
1211 template <
typename RequestType,
typename AnswerType>
1212 std::vector<unsigned int>
1214 const std::vector<unsigned int> &targets,
1215 const std::function<RequestType(
const unsigned int)> &create_request,
1216 const std::function<AnswerType(
const unsigned int,
const RequestType &)>
1218 const std::function<
void(
const unsigned int,
const AnswerType &)>
1222 return Selector<RequestType, AnswerType>().run(
1223 targets, create_request, answer_request, process_answer,
comm);
1228 template <
typename RequestType>
1229 std::vector<unsigned int>
1231 const std::vector<unsigned int> &targets,
1232 const std::function<RequestType(
const unsigned int)> &create_request,
1233 const std::function<
void(
const unsigned int,
const RequestType &)>
1242 using EmptyType = std::tuple<>;
1244 return selector<RequestType, EmptyType>(
1248 [&process_request](
const unsigned int source_rank,
1249 const RequestType &request) -> EmptyType {
1250 process_request(source_rank, request);
1258 [](
const unsigned int ,
1259 const EmptyType & ) {},
1280 namespace ConsensusAlgorithms
1289 has_unique_elements(
const std::vector<unsigned int> &targets)
1291 std::vector<unsigned int> my_destinations = targets;
1292 std::sort(my_destinations.begin(), my_destinations.end());
1293 return (std::adjacent_find(my_destinations.begin(),
1294 my_destinations.end()) ==
1295 my_destinations.end());
1304 handle_exception(std::exception_ptr &&exception,
const MPI_Comm comm)
1306# ifdef DEAL_II_WITH_MPI
1311 std::rethrow_exception(exception);
1319 <<
"----------------------------------------------------"
1324 <<
" on processing: " << std::endl
1325 << exc.
what() << std::endl
1326 <<
"Aborting!" << std::endl
1327 <<
"----------------------------------------------------"
1331 MPI_Abort(
comm, 255);
1333 catch (std::exception &exc)
1338 <<
"----------------------------------------------------"
1341 <<
"Exception within ConsensusAlgorithm"
1343 <<
" on processing: " << std::endl
1344 << exc.what() << std::endl
1345 <<
"Aborting!" << std::endl
1346 <<
"----------------------------------------------------"
1350 MPI_Abort(
comm, 255);
1357 <<
"----------------------------------------------------"
1360 <<
"Unknown exception within ConsensusAlgorithm!" << std::endl
1361 <<
"Aborting!" << std::endl
1362 <<
"----------------------------------------------------"
1366 MPI_Abort(
comm, 255);
1373 std::rethrow_exception(exception);
1380 template <
typename RequestType,
typename AnswerType>
1383 const RequestType &,
1391 template <
typename RequestType,
typename AnswerType>
1401 template <
typename RequestType,
typename AnswerType>
1411 template <
typename RequestType,
typename AnswerType>
1412 std::vector<unsigned int>
1414 Process<RequestType, AnswerType> &process,
1420 process.compute_targets(),
1422 [&process](
const unsigned int target) {
1423 RequestType request;
1424 process.create_request(target, request);
1428 [&process](
const unsigned int source,
const RequestType &request) {
1430 process.answer_request(source, request, answer);
1434 [&process](
const unsigned int target,
const AnswerType &answer) {
1435 process.read_answer(target, answer);
1442 template <
typename RequestType,
typename AnswerType>
1443 std::vector<unsigned int>
1445 const std::vector<unsigned int> &targets,
1446 const std::function<RequestType(
const unsigned int)> &create_request,
1447 const std::function<AnswerType(
const unsigned int,
const RequestType &)>
1449 const std::function<
void(
const unsigned int,
const AnswerType &)>
1453 Assert(has_unique_elements(targets),
1454 ExcMessage(
"The consensus algorithms expect that each process "
1455 "only sends a single message to another process, "
1456 "but the targets provided include duplicates."));
1458 static CollectiveMutex mutex;
1459 CollectiveMutex::ScopedLock lock(mutex,
comm);
1465 start_communication(targets, create_request,
comm);
1481 while (all_locally_originated_receives_are_completed(process_answer,
1483 maybe_answer_one_request(answer_request,
comm);
1487 signal_finish(
comm);
1492 while (all_remotely_originated_receives_are_completed() ==
false)
1493 maybe_answer_one_request(answer_request,
comm);
1496 clean_up_and_end_communication(
comm);
1500 handle_exception(std::current_exception(),
comm);
1503 return std::vector<unsigned int>(requesting_processes.begin(),
1504 requesting_processes.end());
1509 template <
typename RequestType,
typename AnswerType>
1512 const std::vector<unsigned int> &targets,
1513 const std::function<RequestType(
const unsigned int)> &create_request,
1516# ifdef DEAL_II_WITH_MPI
1518 const auto n_targets = targets.size();
1524 send_requests.resize(n_targets);
1525 send_buffers.resize(n_targets);
1529 for (
unsigned int index = 0;
index < n_targets; ++
index)
1531 const unsigned int rank = targets[
index];
1534 auto &send_buffer = send_buffers[
index];
1537 std::vector<char>());
1540 auto ierr = MPI_Isend(send_buffer.data(),
1546 &send_requests[index]);
1552 n_outstanding_answers = n_targets;
1556 (void)create_request;
1563 template <
typename RequestType,
typename AnswerType>
1567 const std::function<
void(
const unsigned int,
const AnswerType &)>
1571# ifdef DEAL_II_WITH_MPI
1579 if (n_outstanding_answers == 0)
1586 int request_is_pending;
1588 const auto ierr = MPI_Iprobe(
1589 MPI_ANY_SOURCE, tag_deliver,
comm, &request_is_pending, &status);
1595 if (request_is_pending == 0)
1601 const auto target = status.MPI_SOURCE;
1608 MPI_Get_count(&status, MPI_CHAR, &message_size);
1611 std::vector<char> recv_buffer(message_size);
1617 const int ierr = MPI_Recv(recv_buffer.data(),
1628 process_answer(target,
1629 Utilities::unpack<AnswerType>(recv_buffer,
1634 --n_outstanding_answers;
1644 return (n_outstanding_answers == 0);
1649 (void)process_answer;
1658 template <
typename RequestType,
typename AnswerType>
1661 const std::function<AnswerType(
const unsigned int,
const RequestType &)>
1665# ifdef DEAL_II_WITH_MPI
1680 int request_is_pending;
1681 const auto ierr = MPI_Iprobe(
1682 MPI_ANY_SOURCE, tag_request,
comm, &request_is_pending, &status);
1685 if (request_is_pending != 0)
1689 const auto other_rank = status.MPI_SOURCE;
1691 Assert(requesting_processes.find(other_rank) ==
1692 requesting_processes.end(),
1693 ExcMessage(
"Process is requesting a second time!"));
1694 requesting_processes.insert(other_rank);
1698 auto ierr = MPI_Get_count(&status, MPI_CHAR, &number_amount);
1702 std::vector<char> buffer_recv(number_amount);
1703 ierr = MPI_Recv(buffer_recv.data(),
1714 request_buffers.emplace_back(std::make_unique<std::vector<char>>());
1715 auto &request_buffer = *request_buffers.back();
1719 Utilities::unpack<RequestType>(
1720 buffer_recv,
false)),
1724 request_requests.emplace_back(std::make_unique<MPI_Request>());
1725 ierr = MPI_Isend(request_buffer.data(),
1726 request_buffer.size(),
1731 request_requests.back().get());
1735 (void)answer_request;
1742 template <
typename RequestType,
typename AnswerType>
1746# ifdef DEAL_II_WITH_MPI
1747 const auto ierr = MPI_Ibarrier(
comm, &barrier_request);
1756 template <
typename RequestType,
typename AnswerType>
1759 AnswerType>::all_remotely_originated_receives_are_completed()
1761# ifdef DEAL_II_WITH_MPI
1762 int all_ranks_reached_barrier;
1763 const auto ierr = MPI_Test(&barrier_request,
1764 &all_ranks_reached_barrier,
1767 return all_ranks_reached_barrier != 0;
1775 template <
typename RequestType,
typename AnswerType>
1781# ifdef DEAL_II_WITH_MPI
1784 if (send_requests.size() > 0)
1786 const int ierr = MPI_Waitall(send_requests.size(),
1787 send_requests.data(),
1788 MPI_STATUSES_IGNORE);
1792 int ierr = MPI_Wait(&barrier_request, MPI_STATUS_IGNORE);
1795 for (
auto &i : request_requests)
1797 ierr = MPI_Wait(i.get(), MPI_STATUS_IGNORE);
1804 ierr = MPI_Barrier(
comm);
1813 template <
typename RequestType,
typename AnswerType>
1814 std::vector<unsigned int>
1816 const std::vector<unsigned int> &targets,
1817 const std::function<RequestType(
const unsigned int)> &create_request,
1818 const std::function<AnswerType(
const unsigned int,
const RequestType &)>
1820 const std::function<
void(
const unsigned int,
const AnswerType &)>
1824 Assert(has_unique_elements(targets),
1825 ExcMessage(
"The consensus algorithms expect that each process "
1826 "only sends a single message to another process, "
1827 "but the targets provided include duplicates."));
1829 static CollectiveMutex mutex;
1830 CollectiveMutex::ScopedLock lock(mutex,
comm);
1837 const unsigned int n_requests =
1838 start_communication(targets, create_request,
comm);
1841 for (
unsigned int request = 0; request < n_requests; ++request)
1842 answer_one_request(request, answer_request,
comm);
1845 process_incoming_answers(targets.size(), process_answer,
comm);
1848 clean_up_and_end_communication();
1852 handle_exception(std::current_exception(),
comm);
1855 return std::vector<unsigned int>(requesting_processes.begin(),
1856 requesting_processes.end());
1861 template <
typename RequestType,
typename AnswerType>
1864 const std::vector<unsigned int> &targets,
1865 const std::function<RequestType(
const unsigned int)> &create_request,
1868# ifdef DEAL_II_WITH_MPI
1874 const unsigned int n_targets = targets.size();
1877 const unsigned int n_sources =
1881 recv_buffers.resize(n_targets);
1882 send_buffers.resize(n_targets);
1883 send_request_requests.resize(n_targets);
1885 send_answer_requests.resize(n_sources);
1886 requests_buffers.resize(n_sources);
1889 for (
unsigned int i = 0; i < n_targets; ++i)
1891 const unsigned int rank = targets[i];
1895 auto &send_buffer = send_buffers[i];
1900 auto ierr = MPI_Isend(send_buffer.data(),
1906 &send_request_requests[i]);
1913 (void)create_request;
1921 template <
typename RequestType,
typename AnswerType>
1924 const unsigned int index,
1925 const std::function<AnswerType(
const unsigned int,
const RequestType &)>
1929# ifdef DEAL_II_WITH_MPI
1938 int ierr = MPI_Probe(MPI_ANY_SOURCE, tag_request,
comm, &status);
1942 const unsigned int other_rank = status.MPI_SOURCE;
1944 Assert(requesting_processes.find(other_rank) ==
1945 requesting_processes.end(),
1947 "A process is sending a request after a request from "
1948 "the same process has previously already been "
1949 "received. This algorithm does not expect this to happen."));
1950 requesting_processes.insert(other_rank);
1954 ierr = MPI_Get_count(&status, MPI_CHAR, &number_amount);
1957 std::vector<char> buffer_recv(number_amount);
1958 ierr = MPI_Recv(buffer_recv.data(),
1969 auto &request_buffer = requests_buffers[
index];
1973 Utilities::unpack<RequestType>(
1974 buffer_recv,
false)),
1976 std::vector<char>());
1978 ierr = MPI_Isend(request_buffer.data(),
1979 request_buffer.size(),
1984 &send_answer_requests[index]);
1987 (void)answer_request;
1995 template <
typename RequestType,
typename AnswerType>
1998 const unsigned int n_targets,
1999 const std::function<
void(
const unsigned int,
const AnswerType &)>
2003# ifdef DEAL_II_WITH_MPI
2012 for (
unsigned int i = 0; i < n_targets; ++i)
2017 MPI_Probe(MPI_ANY_SOURCE, tag_deliver,
comm, &status);
2021 const auto other_rank = status.MPI_SOURCE;
2024 const int ierr = MPI_Get_count(&status, MPI_CHAR, &message_size);
2027 std::vector<char> recv_buffer(message_size);
2033 const int ierr = MPI_Recv(recv_buffer.data(),
2044 process_answer(other_rank,
2045 Utilities::unpack<AnswerType>(recv_buffer,
false));
2049 (void)process_answer;
2056 template <
typename RequestType,
typename AnswerType>
2060# ifdef DEAL_II_WITH_MPI
2063 if (send_request_requests.size() > 0)
2065 const int ierr = MPI_Waitall(send_request_requests.size(),
2066 send_request_requests.data(),
2067 MPI_STATUSES_IGNORE);
2072 if (send_answer_requests.size() > 0)
2074 const int ierr = MPI_Waitall(send_answer_requests.size(),
2075 send_answer_requests.data(),
2076 MPI_STATUSES_IGNORE);
2084 template <
typename RequestType,
typename AnswerType>
2085 std::vector<unsigned int>
2087 const std::vector<unsigned int> &targets,
2088 const std::function<RequestType(
const unsigned int)> &create_request,
2089 const std::function<AnswerType(
const unsigned int,
const RequestType &)>
2091 const std::function<
void(
const unsigned int,
const AnswerType &)>
2097 ExcMessage(
"You shouldn't use the 'Serial' class on "
2098 "communicators that have more than one process "
2099 "associated with it."));
2102 if (targets.size() != 0)
2104 Assert(targets.size() == 1,
2106 "On a single process, the only valid target "
2107 "is process zero (the process itself), which can only be "
2114 const RequestType request =
2115 (create_request ? create_request(0) : RequestType());
2116 const AnswerType answer =
2117 (answer_request ? answer_request(0, request) : AnswerType());
2120 process_answer(0, answer);
2128 template <
typename RequestType,
typename AnswerType>
2129 std::vector<unsigned int>
2131 const std::vector<unsigned int> &targets,
2132 const std::function<RequestType(
const unsigned int)> &create_request,
2133 const std::function<AnswerType(
const unsigned int,
const RequestType &)>
2135 const std::function<
void(
const unsigned int,
const AnswerType &)>
2148# ifdef DEAL_II_WITH_MPI
2154 consensus_algo.reset(
new NBX<RequestType, AnswerType>());
2158 consensus_algo.reset(
new PEX<RequestType, AnswerType>());
2160 consensus_algo.reset(
new Serial<RequestType, AnswerType>());
2162 return consensus_algo->run(
2163 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)
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)
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)