20#ifndef TIMPI_PARALLEL_SYNC_H
21#define TIMPI_PARALLEL_SYNC_H
69template <
typename MapToVectors,
70 typename ActionFunctor,
73 typename std::remove_reference<MapToVectors>::type::mapped_type::value_type
74 >::type>::type>>::value,
int>::type = 0>
77 const ActionFunctor & act_on_data);
89template <
typename MapToVectors,
90 typename ActionFunctor,
93 typename std::remove_reference<MapToVectors>::type::mapped_type::value_type
94 >::type>::type>>::value,
int>::type = 0>
97 const ActionFunctor & act_on_data);
136template <
typename datum,
137 typename MapToVectors,
138 typename GatherFunctor,
139 typename ActionFunctor>
141 const MapToVectors & queries,
142 GatherFunctor & gather_data,
143 const ActionFunctor & act_on_data,
144 const datum * example);
177template <
typename MapToVectors,
178 typename ActionFunctor,
181 MapToVectors && data,
183 const ActionFunctor & act_on_data);
193template <
typename datum,
195 typename MapToVectors,
196 typename GatherFunctor,
197 typename ActionFunctor>
199 const MapToVectors & queries,
200 GatherFunctor & gather_data,
201 ActionFunctor & act_on_data,
202 const std::vector<datum,A> * example);
223 comm.
max(someone_found_empty_send);
224 std::stringstream err_msg;
226 err_msg <<
" [" << comm.
rank() <<
"] sent an empty to [" <<
227 empty_target_pid <<
"]";
228 timpi_assert_msg(!someone_found_empty_send,
229 "Some rank(s) sent empty data!" + err_msg.str());
233template <
typename MapToContainers,
234 typename SendFunctor,
235 typename PossiblyReceiveFunctor,
236 typename ActionFunctor>
239 MapToContainers && data,
240 const SendFunctor & send_functor,
241 const PossiblyReceiveFunctor & possibly_receive_functor,
242 const ActionFunctor & act_on_data)
244 typedef typename std::remove_reference<MapToContainers>::type::value_type::second_type
248 timpi_parallel_only(comm);
258 const auto old_send_mode = comm.
send_mode();
265 std::list<Request> send_requests;
279 for (
auto & datapair : data)
284 auto & datum = datapair.second;
289 empty_target_pid = dest_pid;
295 if (dest_pid == comm.
rank())
296 act_on_data(dest_pid, std::move(datum));
299 send_requests.emplace_back();
300 send_functor(dest_pid, datum, send_requests.back(), tag);
309 bool started_barrier =
false;
324 std::list<IncomingInfo> incoming;
325 incoming.emplace_back();
329 auto possibly_receive = [&incoming, &tag, &possibly_receive_functor]() {
330 auto & next_incoming = incoming.back();
331 timpi_assert_equal_to(next_incoming.src_pid,
any_source);
332 if (possibly_receive_functor(next_incoming.src_pid,
334 next_incoming.request, tag))
336 timpi_assert(next_incoming.src_pid !=
any_source);
340 incoming.emplace_back();
353 timpi_assert(incoming.size() > 0);
364 ](IncomingInfo &
info)
369 timpi_assert_equal_to(is_invalid_entry, &
info == &incoming.back());
371 if (is_invalid_entry)
375 if (
info.request.test())
381 act_on_data(
info.src_pid, std::move(
info.data));
392 send_requests.remove_if
416 if (send_requests.empty() && !started_barrier)
418 started_barrier =
true;
424 if (incoming.size() == 1)
428 if (barrier_request.
test())
434 timpi_assert(!possibly_receive());
437 const_cast<Communicator &
>(comm).send_mode(old_send_mode);
445template <
typename MapToContainers,
446 typename SendFunctor,
447 typename ReceiveFunctor,
448 typename ActionFunctor>
451 MapToContainers && data,
452 const SendFunctor & send_functor,
453 const ReceiveFunctor & receive_functor,
454 const ActionFunctor & act_on_data)
456 typedef typename std::remove_reference<MapToContainers>::type::value_type::second_type
460 timpi_parallel_only(comm);
479 std::vector<std::size_t> will_send_to(num_procs, 0);
480 for (
auto & datapair : data)
488 if (datapair.second.empty())
491 empty_target_pid = dest_pid;
496 will_send_to[dest_pid]++;
504 auto & will_receive_from = will_send_to;
508 n_receives += will_receive_from[proc_id];
515 std::list<Request> requests;
518 for (
auto & datapair : data)
521 auto & datum = datapair.second;
527 if (destid == comm.
rank())
529 act_on_data(destid, std::move(datum));
534 requests.emplace_back();
535 send_functor(destid, datum, requests.back(), tag);
574 typedef typename std::remove_reference<MapToContainers>::type::value_type::second_type
664 typedef typename std::remove_reference<MapToContainers>::type::mapped_type
container_type;
665 typedef typename container_type::value_type
nonref_type;
666 typename std::remove_const<nonref_type>::type *
output_type =
nullptr;
752 typename std::enable_if< std::is_base_of<DataType, StandardType<
753 typename InnermostType<
typename std::remove_const<
754 typename std::remove_reference<MapToVectors>::type::mapped_type::value_type
755 >::type>::type>>::value,
int>::type>
760 typedef typename std::remove_reference<MapToVectors>::type::mapped_type
container_type;
761 typedef typename container_type::value_type
nonref_type;
850 typename std::enable_if<Has_buffer_type<Packing<
851 typename InnermostType<
typename std::remove_const<
852 typename std::remove_reference<MapToVectors>::type::mapped_type::value_type
853 >::type>::type>>::value,
int>::type>
863template <
typename datum,
873 typedef typename MapToVectors::mapped_type
query_type;
875 std::multimap<processor_id_type, std::vector<datum> >
956template <
typename datum,
965 const std::vector<datum,A> *)
967 typedef typename MapToVectors::mapped_type
query_type;
970 std::vector<std::vector<std::vector<datum,A>>>
response_data;
982 std::vector<std::vector<datum,A>>
response;
1013 for (std::size_t
i = 0,
Encapsulates the MPI_Comm object.
void max(const T &r, T &o, Request &req) const
Non-blocking maximum of the local value r into o with the request req.
bool possibly_receive_packed_range(unsigned int &src_processor_id, Context *context, OutputIter out, const T *output_type, Request &req, const MessageTag &tag) const
Nonblocking packed range receive from one processor with user-defined type.
void nonblocking_receive_packed_range(const unsigned int src_processor_id, Context *context, OutputIter out, const T *output_type, Request &req, Status &stat, const MessageTag &tag=any_tag) const
Non-Blocking-receive range-of-pointers from one processor.
processor_id_type size() const
MessageTag get_unique_tag(int tagvalue=MessageTag::invalid_tag) const
Get a tag that is unique to this Communicator.
Status packed_range_probe(const unsigned int src_processor_id, const MessageTag &tag, bool &flag) const
Non-Blocking message probe for a packed range message.
void nonblocking_send_packed_range(const unsigned int dest_processor_id, const Context *context, Iter range_begin, const Iter range_end, Request &req, const MessageTag &tag=no_tag) const
Similar to the above Nonblocking send_packed_range with a few important differences:
status probe(const unsigned int src_processor_id, const MessageTag &tag=any_tag) const
Blocking message probe.
processor_id_type rank() const
Status receive(const unsigned int dest_processor_id, T &buf, const MessageTag &tag=any_tag) const
Blocking-receive from one processor with data-defined type.
void alltoall(std::vector< T, A > &r) const
Effectively transposes the input vector across all processors.
void send_mode(const SendMode sm)
Explicitly sets the SendMode type used for send operations.
void send_receive(const unsigned int dest_processor_id, const T1 &send_data, const unsigned int source_processor_id, T2 &recv_data, const MessageTag &send_tag=no_tag, const MessageTag &recv_tag=any_tag) const
Send data send to one processor while simultaneously receiving other data recv from a (potentially di...
bool possibly_receive(unsigned int &src_processor_id, std::vector< T, A > &buf, Request &req, const MessageTag &tag) const
Nonblocking-receive from one processor with user-defined type.
void sync_type(const SyncType st)
Explicitly sets the SyncType used for sync operations.
void nonblocking_barrier(Request &req) const
Start a barrier that doesn't block.
void send_receive_packed_range(const unsigned int dest_processor_id, const Context1 *context1, RangeIter send_begin, const RangeIter send_end, const unsigned int source_processor_id, Context2 *context2, OutputIter out, const T *output_type, const MessageTag &send_tag=no_tag, const MessageTag &recv_tag=any_tag, std::size_t approx_buffer_size=1000000) const
Send a range-of-pointers to one processor while simultaneously receiving another range from a (potent...
void send(const unsigned int dest_processor_id, const T &buf, const MessageTag &tag=no_tag) const
Blocking-send to one processor with data-defined type.
Encapsulates the MPI_Datatype.
Encapsulates the MPI tag integers.
Encapsulates the MPI_Request.
Templated class to provide the appropriate MPI datatype for use with built-in C types or simple C++ c...
Encapsulates the MPI_Status struct.
Define data types and (un)serialization functions for use when encoding a potentially-variable-size o...
void empty_send_assertion(const Communicator &comm, processor_id_type empty_target_pid)
void push_parallel_nbx_helper(const Communicator &comm, MapToContainers &&data, const SendFunctor &send_functor, const PossiblyReceiveFunctor &possibly_receive_functor, const ActionFunctor &act_on_data)
void push_parallel_alltoall_helper(const Communicator &comm, MapToContainers &&data, const SendFunctor &send_functor, const ReceiveFunctor &receive_functor, const ActionFunctor &act_on_data)
void push_parallel_roundrobin_helper(const Communicator &comm, MapToContainers &&data, const SendReceiveFunctor &sendreceive_functor, const ActionFunctor &act_on_data)
StandardType< T > build_standard_type(const T *example=nullptr)
void pull_parallel_vector_data(const Communicator &comm, const MapToVectors &queries, GatherFunctor &gather_data, const ActionFunctor &act_on_data, const datum *example)
Send query vectors, receive and answer them with vectors of data, then act on those answers.
MPI_Info info
Info object used by some MPI-3 methods.
Status wait(Request &r)
Wait for a non-blocking send or receive to finish.
MPI_Request request
Request object for non-blocking I/O.
uint8_t processor_id_type
void push_parallel_vector_data(const Communicator &comm, MapToVectors &&data, const ActionFunctor &act_on_data)
Send and receive and act on vectors of data.
const unsigned int any_source
Processor id meaning "Accept from any source".
Tnew cast_int(Told oldvar)
void push_parallel_packed_range(const Communicator &comm, MapToVectors &&data, Context *context, const ActionFunctor &act_on_data)
Send and receive and act on vectors of data.