19#ifndef TIMPI_COMMUNICATOR_H
20#define TIMPI_COMMUNICATOR_H
28#include "timpi/timpi_config.h"
44#include <unordered_map>
53#if TIMPI_PROCESSOR_ID_BYTES == 1
55#elif TIMPI_PROCESSOR_ID_BYTES == 2
57#elif TIMPI_PROCESSOR_ID_BYTES == 4
59#elif TIMPI_PROCESSOR_ID_BYTES == 8
256 template <
typename Map,
257 typename std::enable_if<std::is_base_of<DataType, StandardType<typename Map::key_type>>::value &&
258 std::is_base_of<DataType, StandardType<typename Map::mapped_type>>::value,
267 template <
typename Map,
268 typename std::enable_if<!(std::is_base_of<DataType, StandardType<typename Map::key_type>>::value &&
269 std::is_base_of<DataType, StandardType<typename Map::mapped_type>>::value),
277 template <
typename Map,
278 typename std::enable_if<std::is_base_of<DataType, StandardType<typename Map::key_type>>::value &&
279 std::is_base_of<DataType, StandardType<typename Map::mapped_type>>::value,
291 template <
typename Map,
292 typename std::enable_if<!(std::is_base_of<DataType, StandardType<typename Map::key_type>>::value &&
293 std::is_base_of<DataType, StandardType<typename Map::mapped_type>>::value),
304 template <
typename Map,
305 typename std::enable_if<std::is_base_of<DataType, StandardType<typename Map::key_type>>::value &&
306 std::is_base_of<DataType, StandardType<typename Map::mapped_type>>::value,
315 template <
typename Map,
316 typename std::enable_if<!(std::is_base_of<DataType, StandardType<typename Map::key_type>>::value &&
317 std::is_base_of<DataType, StandardType<typename Map::mapped_type>>::value),
323 template <
typename T,
typename A1,
typename A2>
375 template <
typename T>
390 template <
typename T>
399 template <
typename T>
407 template <
typename T>
416 template <
typename T>
419 unsigned int &
min_id)
const;
426 template <
typename T,
typename A1,
typename A2>
428 void minloc(std::vector<T,A1> &
r,
429 std::vector<unsigned int,A2> &
min_id)
const;
435 template <
typename T>
443 template <
typename T>
452 template <
typename T>
455 unsigned int &
max_id)
const;
462 template <
typename T,
typename A1,
typename A2>
464 void maxloc(std::vector<T,A1> &
r,
465 std::vector<unsigned int,A2> &
max_id)
const;
471 template <
typename T>
479 template <
typename T>
487 template <
typename T>
495 template <
typename T>
503 template <
typename T>
511 template <
typename T>
519 template <
typename T>
527 template <
typename T>
535 template <
typename T>
543 template <
typename T>
551 template <
typename T>
559 template <
typename T>
567 template <
typename T>
575 template <
typename T>
583 template <
typename T>
591 template <
typename T>
609 template <
typename T>
622 template <
typename T>
645 template <
typename T>
654 template <
typename T>
663 template <
typename T>
677 template <
typename T>
691 template <
typename T>
703 template <
typename T>
714 template <
typename T>
723 template <
typename T>
737 template <
typename T>
751 template <
typename T>
777 template <
typename T,
typename A,
778 typename std::enable_if<std::is_base_of<DataType, StandardType<T>>::value,
int>::type = 0>
781 std::vector<T,A> &
buf,
793 template <
typename T,
typename A,
794 typename std::enable_if<Has_buffer_type<Packing<T>>::value,
int>::type = 0>
797 std::vector<T,A> &
buf,
815 template <
typename T,
typename A,
typename std::enable_if<std::is_base_of<DataType, StandardType<T>>::value,
int>::type = 0>
818 std::vector<T,A> &
buf,
835 template <
typename T,
typename A,
836 typename std::enable_if<Has_buffer_type<Packing<T>>::value,
int>::type = 0>
839 std::vector<T,A> &
buf,
867 template <
typename Context,
typename OutputIter,
typename T>
894 template <
typename Context,
typename Iter>
922 template <
typename Context,
typename Iter>
940 template <
typename Context,
typename Iter>
958 template <
typename Context,
typename Iter>
965 std::shared_ptr<std::vector<
typename TIMPI::Packing<
typename std::iterator_traits<Iter>::value_type>::buffer_type>> &
buffer,
994 template <
typename Context,
typename OutputIter,
typename T>
1014 template <
typename Context,
typename OutputIter,
typename T>
1036 template <
typename Context,
typename OutputIter,
typename T>
1055 template <
typename T1,
typename T2,
1056 typename std::enable_if<std::is_base_of<DataType, StandardType<T1>>::value &&
1057 std::is_base_of<DataType, StandardType<T2>>::value,
1123 template <
typename T1,
typename T2>
1138 template <
typename T,
typename A>
1141 std::vector<T,A> & recv)
const;
1148 template <
typename T,
typename A>
1151 std::vector<std::basic_string<T>,
A> &
recv_data,
1180 template <
typename T,
typename A,
1181 typename std::enable_if<std::is_base_of<DataType, StandardType<T>>::value,
int>::type = 0>
1183 std::vector<T,A> &
r)
const;
1185 template <
typename T,
typename A,
1186 typename std::enable_if<Has_buffer_type<Packing<T>>::value,
int>::type = 0>
1188 std::vector<T,A> &
r)
const;
1195 template <
typename T,
typename A,
typename std::enable_if<std::is_base_of<DataType, StandardType<T>>::value,
1206 template <
typename T,
typename A,
typename std::enable_if<Has_buffer_type<Packing<T>>::value,
1216 template <
typename T,
typename A>
1218 std::vector<std::basic_string<T>,
A> &
recv_data,
1245 template <
typename T,
typename A,
1246 typename std::enable_if<std::is_base_of<DataType, StandardType<T>>::value,
int>::type = 0>
1257 template <
typename T,
typename A1,
typename A2,
1258 typename std::enable_if<std::is_base_of<DataType, StandardType<T>>::value,
int>::type = 0>
1267 template <
typename T,
typename A1,
typename A2,
1268 typename std::enable_if<Has_buffer_type<Packing<T>>::value,
int>::type = 0>
1297 template <
typename T,
typename A,
1298 typename std::enable_if<Has_buffer_type<Packing<T>>::value,
int>::type = 0>
1305 template <
typename T,
typename A>
1314 template <
typename T,
typename A>
1317 const unsigned int root_id=0)
const;
1325 template <
typename T,
typename A>
1327 std::vector<T,A> & recv,
1328 const unsigned int root_id=0)
const;
1336 template <
typename T,
typename A1,
typename A2>
1338 const std::vector<CountType,A2>
counts,
1339 std::vector<T,A1> & recv,
1340 const unsigned int root_id=0)
const;
1342#ifdef TIMPI_HAVE_MPI
1347 template <
typename T,
typename A1,
typename A2>
1349 const std::vector<int,A2>
counts,
1350 std::vector<T,A1> & recv,
1351 const unsigned int root_id=0)
const;
1360 template <
typename T,
typename A1,
typename A2>
1362 std::vector<T,A1> & recv,
1382 template <
typename Context,
typename Iter,
typename OutputIter>
1405 template <
typename Context,
typename Iter,
typename OutputIter>
1417 template <
typename T,
typename A>
1431 template <
typename T
1432#ifdef TIMPI_HAVE_MPI
1434 typename std::enable_if<std::is_base_of<DataType, StandardType<T>>::value,
int>::type = 0
1440#ifdef TIMPI_HAVE_MPI
1452 template <
typename T,
1453 typename std::enable_if<Has_buffer_type<Packing<T>>::value,
int>::type = 0>
1481 template <
typename Context,
typename OutputContext,
typename Iter,
typename OutputIter>
1487 const unsigned int root_id = 0,
1497#include "timpi/parallel_communicator_specializations"
Encapsulates the MPI_Comm object.
void bitwise_and(T &r) const
Take a local variable and replace it with the bitwise_and of its values on all processors.
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 bitwise_or(const T &r, T &o, Request &req) const
Non-blocking bitwise_or of the local value r into o with the request req.
void scatter(const std::vector< T, A1 > &data, const std::vector< int, A2 > counts, std::vector< T, A1 > &recv, const unsigned int root_id=0) const
vector<int> based scatter, for backwards compatibility
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.
void allgather_packed_range(Context *context, Iter range_begin, const Iter range_end, OutputIter out, std::size_t approx_buffer_size=1000000) const
Take a range of local variables, combine it with ranges from all processors, and write the output to ...
SendMode send_mode() const
Gets the user-requested SendMode.
processor_id_type size() const
void bitwise_or(T &r) const
Take a local variable and replace it with the bitwise_or of its values on all processors.
std::size_t packed_size_of(const std::vector< std::vector< T, A1 >, A2 > &buf, const DataType &type) const
void broadcast_packed_range(const Context *context1, Iter range_begin, const Iter range_end, OutputContext *context2, OutputIter out, const unsigned int root_id=0, std::size_t approx_buffer_size=1000000) const
Blocking-broadcast range-of-pointers to one processor.
void set_union(T &data) const
Take a container of local variables on each processor, and replace it with their union over all proce...
void allgather(const std::vector< T, A1 > &send_data, std::vector< std::vector< T, A1 >, A2 > &recv_data, const bool identical_buffer_sizes=false) const
Take a vector of fixed size local variables and collect similar vectors from all processors.
void maxloc(T &r, unsigned int &max_id) const
Take a local variable and replace it with the maximum of it's values on all processors,...
MessageTag get_unique_tag(int tagvalue=MessageTag::invalid_tag) const
Get a tag that is unique to this Communicator.
void split(int color, int key, Communicator &target) const
void receive_packed_range(const unsigned int dest_processor_id, Context *context, OutputIter out, const T *output_type, const MessageTag &tag=any_tag) const
Blocking-receive range-of-pointers from one processor.
void sum(const T &r, T &o, Request &req) const
Non-blocking sum of the local value r into o with the request req.
void logical_and(const T &r, T &o, Request &req) const
Non-blocking logical_and of the local value r into o with the request req.
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 scatter(const std::vector< T, A1 > &data, const std::vector< CountType, A2 > counts, std::vector< T, A1 > &recv, const unsigned int root_id=0) const
Take a vector of local variables and scatter the ith variable-sized chunk to the ith processor in the...
SendMode
Whether to use default or synchronous sends?
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.
Communicator()
Default Constructor.
void send_receive(const unsigned int dest_processor_id, const T1 &send_data, const DataType &type1, const unsigned int source_processor_id, T2 &recv_data, const DataType &type2, 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...
Communicator(const Communicator &)=delete
void logical_or(const T &r, T &o, Request &req) const
Non-blocking logical_or of the local value r into o with the request req.
void clear()
Free and reset this communicator.
void map_broadcast(Map &data, const unsigned int root_id, const bool identical_sizes) const
Private implementation function called by the map-based broadcast() specializations.
processor_id_type rank() const
void barrier() const
Pause execution until all processors reach a certain point.
void reference_unique_tag(int tagvalue) const
Reference an already-acquired tag, so that we know it will be dereferenced multiple times before we c...
Communicator & operator=(const Communicator &)=delete
Communicator(Communicator &&)=default
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 scatter(const std::vector< std::vector< T, A1 >, A2 > &data, std::vector< T, A1 > &recv, const unsigned int root_id=0, const bool identical_buffer_sizes=false) const
Take a vector of vectors and scatter the ith inner vector to the ith processor in the communicator.
void nonblocking_send_packed_range(const unsigned int dest_processor_id, const Context *context, Iter range_begin, const Iter range_end, Request &req, std::shared_ptr< std::vector< typename TIMPI::Packing< typename std::iterator_traits< Iter >::value_type >::buffer_type > > &buffer, const MessageTag &tag=no_tag) const
Similar to the above Nonblocking send_packed_range with a few important differences:
void gather(const unsigned int root_id, const std::basic_string< T > &send_data, std::vector< std::basic_string< T >, A > &recv_data, const bool identical_buffer_sizes=false) const
The gather overload for string types has an optional identical_buffer_sizes optimization for when all...
void logical_and(T &r) const
Take a local variable and replace it with the logical_and of its values on all processors.
void map_max(Map &data) const
Private implementation function called by the map-based max() specializations.
void alltoall(std::vector< T, A > &r) const
Effectively transposes the input vector across all processors.
timpi_pure bool semiverify(const T *r) const
Check whether a local pointer points to the same value on all processors where it is not null,...
void max(T &r) const
Take a local variable and replace it with the maximum of it's values on all processors.
void bitwise_xor(T &r) const
Take a local variable and replace it with the bitwise_xor of its values on all processors.
void map_sum(Map &data) const
Private implementation function called by the map-based sum() specializations.
void min(const T &r, T &o, Request &req) const
Non-blocking minimum of the local value r into o with the request req.
timpi_pure bool verify(const T &r) const
Check whether a local variable has the same value on all processors, returning true if it does or fal...
void send_mode(const SendMode sm)
Explicitly sets the SendMode type used for send operations.
void product(const T &r, T &o, Request &req) const
Non-blocking product of the local value r into o with the request req.
void allgather(std::vector< std::basic_string< T >, A > &r, const bool identical_buffer_sizes=false) const
AllGather overload for vectors of string types.
void logical_xor(T &r) const
Take a local variable and replace it with the logical_xor of its values on all processors.
void bitwise_xor(const T &r, T &o, Request &req) const
Non-blocking bitwise_xor of the local value r into o with the request req.
void bitwise_and(const T &r, T &o, Request &req) const
Non-blocking bitwise_and of the local value r into o with the request req.
void min(T &r) const
Take a local variable and replace it with the minimum of it's values on all processors.
void product(T &r) const
Take a local variable and replace it with the product of its values on all processors.
communicator _communicator
void duplicate(const Communicator &comm)
void minloc(T &r, unsigned int &min_id) const
Take a local variable and replace it with the minimum of it's values on all processors,...
void sum(T &r) const
Take a local variable and replace it with the sum of it's values on all processors.
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...
void scatter(const std::vector< T, A > &data, std::vector< T, A > &recv, const unsigned int root_id=0) const
Take a vector of local variables and scatter the ith equal-sized chunk to the ith processor in the co...
void dereference_unique_tag(int tagvalue) const
Dereference an already-acquired tag, and see if we can re-release it.
void set_union(T &data, const unsigned int root_id) const
Take a container (set, map, unordered_set, multimap, etc) of local variables on each processor,...
void allgather(std::vector< T, A > &r, const bool identical_buffer_sizes=false) const
Take a vector of fixed size local variables and expand it to include values from all processors.
void nonblocking_receive_packed_range(const unsigned int src_processor_id, Context *context, OutputIter out, const T *output_type, Request &req, Status &stat, std::shared_ptr< std::vector< typename TIMPI::Packing< T >::buffer_type > > &buffer, const MessageTag &tag=any_tag) const
Non-Blocking-receive range-of-pointers from one processor.
void gather_packed_range(const unsigned int root_id, Context *context, Iter range_begin, const Iter range_end, OutputIter out, std::size_t approx_buffer_size=1000000) const
Take a range of local variables, combine it with ranges from all processors, and write the output to ...
void logical_xor(const T &r, T &o, Request &req) const
Non-blocking logical_xor of the local value r into o with the request req.
void scatter(const std::vector< T, A > &data, T &recv, const unsigned int root_id=0) const
Take a vector of local variables and scatter the ith item to the ith processor in the communicator.
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.
SyncType
What algorithm to use for parallel synchronization?
void logical_or(T &r) const
Take a local variable and replace it with the logical_or of its values on all processors.
void broadcast(T &data, const unsigned int root_id=0, const bool identical_sizes=false) const
Take a local value and broadcast it to all processors.
void assign(const communicator &comm)
Utility function for setting our member variables from an MPI communicator.
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_packed_range(const unsigned int dest_processor_id, const Context *context, Iter range_begin, const Iter range_end, const MessageTag &tag=no_tag, std::size_t approx_buffer_size=1000000) const
Blocking-send range-of-pointers to one processor.
void gather(const unsigned int root_id, const T &send_data, std::vector< T, A > &recv) const
Take a vector of length comm.size(), and on processor root_id fill in recv[processor_id] = the value ...
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...
SyncType sync_type() const
Gets the user-requested SyncType.
void split_by_type(int split_type, int key, info i, Communicator &target) const
constexpr processor_id_type size() const
void gather(const unsigned int root_id, std::vector< T, A > &r) const
Take a vector of local variables and expand it on processor root_id to include values from all proces...
const communicator & get() const
std::map< int, unsigned int > used_tag_values
void allgather(const T &send_data, std::vector< T, A > &recv_data) const
Take a vector of length this->size(), and fill in recv[processor_id] = the value of send on that proc...
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.
static const int invalid_tag
Invalid tag, to allow for default construction.
StandardType<T>'s which do not define a way to MPI_Type T should inherit from this class.
Encapsulates the MPI_Request.
Encapsulates the MPI_Status struct.
Communicator(const TIMPI::communicator &comm)
Communicator(const Communicator &)=delete
Communicator & operator=(const Communicator &)=delete
Communicator(Communicator &&)=default
Define data types and (un)serialization functions for use when encoding a potentially-variable-size o...
const MessageTag any_tag
Default message tag ids.
MPI_Info info
Info object used by some MPI-3 methods.
DIE A HORRIBLE DEATH HERE typedef MPI_Comm communicator
Communicator object for talking with subsets of processors.
uint8_t processor_id_type
const unsigned int any_source
Processor id meaning "Accept from any source".
Tnew cast_int(Told oldvar)