TIMPI
Loading...
Searching...
No Matches
Public Types | Public Member Functions | Private Member Functions | Private Attributes | List of all members
libMesh::Parallel::Communicator Class Reference

#include <communicator.h>

Inheritance diagram for libMesh::Parallel::Communicator:
[legend]

Public Types

enum  SendMode { DEFAULT =0 , SYNCHRONOUS }
 Whether to use default or synchronous sends? More...
 
enum  SyncType { NBX , ALLTOALL_COUNTS , SENDRECEIVE }
 What algorithm to use for parallel synchronization? More...
 

Public Member Functions

 Communicator ()=default
 
 Communicator (const TIMPI::communicator &comm)
 
 Communicator (const Communicator &)=delete
 
Communicatoroperator= (const Communicator &)=delete
 
 Communicator (Communicator &&)=default
 
Communicatoroperator= (Communicator &&)=default
 
 ~Communicator ()=default
 
void split (int color, int key, Communicator &target) const
 
void split_by_type (int split_type, int key, info i, Communicator &target) const
 
void duplicate (const Communicator &comm)
 
void duplicate (const communicator &comm)
 
communicator & get ()
 
const communicator & get () const
 
MessageTag get_unique_tag (int tagvalue=MessageTag::invalid_tag) const
 Get a tag that is unique to this Communicator.
 
void reference_unique_tag (int tagvalue) const
 Reference an already-acquired tag, so that we know it will be dereferenced multiple times before we can re-release it.
 
void dereference_unique_tag (int tagvalue) const
 Dereference an already-acquired tag, and see if we can re-release it.
 
void clear ()
 Free and reset this communicator.
 
processor_id_type rank () const
 
processor_id_type size () const
 
constexpr processor_id_type size () const
 
void send_mode (const SendMode sm)
 Explicitly sets the SendMode type used for send operations.
 
SendMode send_mode () const
 Gets the user-requested SendMode.
 
void sync_type (const SyncType st)
 Explicitly sets the SyncType used for sync operations.
 
void sync_type (const std::string &st)
 Sets the sync type used for sync operations via a string.
 
SyncType sync_type () const
 Gets the user-requested SyncType.
 
void barrier () const
 Pause execution until all processors reach a certain point.
 
void nonblocking_barrier (Request &req) const
 Start a barrier that doesn't block.
 
template<typename T >
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 false if not.
 
template<typename T >
bool verify (const T &r) const
 
template<typename T >
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, returning true if it does or false if not.
 
template<typename T >
bool semiverify (const T *r) const
 
template<typename T >
void min (const T &r, T &o, Request &req) const
 Non-blocking minimum of the local value r into o with the request req.
 
template<typename T >
void min (T &r) const
 Take a local variable and replace it with the minimum of it's values on all processors.
 
template<typename A >
void min (std::vector< bool, A > &r) const
 
template<typename T >
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, returning the minimum rank of a processor which originally held the minimum value.
 
template<typename T , typename A1 , typename A2 >
void minloc (std::vector< T, A1 > &r, std::vector< unsigned int, A2 > &min_id) const
 Take a vector of local variables and replace each entry with the minimum of it's values on all processors.
 
template<typename A1 , typename A2 >
void minloc (std::vector< bool, A1 > &r, std::vector< unsigned int, A2 > &min_id) const
 
template<typename T >
void max (const T &r, T &o, Request &req) const
 Non-blocking maximum of the local value r into o with the request req.
 
template<typename T >
void max (T &r) const
 Take a local variable and replace it with the maximum of it's values on all processors.
 
template<typename A >
void max (std::vector< bool, A > &r) const
 
template<typename T >
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, returning the minimum rank of a processor which originally held the maximum value.
 
template<typename T , typename A1 , typename A2 >
void maxloc (std::vector< T, A1 > &r, std::vector< unsigned int, A2 > &max_id) const
 Take a vector of local variables and replace each entry with the maximum of it's values on all processors.
 
template<typename A1 , typename A2 >
void maxloc (std::vector< bool, A1 > &r, std::vector< unsigned int, A2 > &max_id) const
 
template<typename T >
void product (T &r) const
 Take a local variable and replace it with the product of its values on all processors.
 
template<typename T >
void product (const T &r, T &o, Request &req) const
 Non-blocking product of the local value r into o with the request req.
 
template<typename T >
void logical_and (T &r) const
 Take a local variable and replace it with the logical_and of its values on all processors.
 
template<typename T >
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.
 
template<typename T >
void bitwise_and (T &r) const
 Take a local variable and replace it with the bitwise_and of its values on all processors.
 
template<typename T >
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.
 
template<typename T >
void logical_or (T &r) const
 Take a local variable and replace it with the logical_or of its values on all processors.
 
template<typename T >
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.
 
template<typename T >
void bitwise_or (T &r) const
 Take a local variable and replace it with the bitwise_or of its values on all processors.
 
template<typename T >
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.
 
template<typename T >
void logical_xor (T &r) const
 Take a local variable and replace it with the logical_xor of its values on all processors.
 
template<typename T >
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.
 
template<typename T >
void bitwise_xor (T &r) const
 Take a local variable and replace it with the bitwise_xor of its values on all processors.
 
template<typename T >
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.
 
template<typename T >
void sum (T &r) const
 Take a local variable and replace it with the sum of it's values on all processors.
 
template<typename T >
void sum (const T &r, T &o, Request &req) const
 Non-blocking sum of the local value r into o with the request req.
 
template<typename T >
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, and collect their union over all processors, replacing the original on the processor with rank root_id.
 
template<typename T >
void set_union (T &data) const
 Take a container of local variables on each processor, and replace it with their union over all processors, replacing the original on all processors.
 
status probe (const unsigned int src_processor_id, const MessageTag &tag=any_tag) const
 Blocking message probe.
 
template<typename T >
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.
 
template<typename T >
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.
 
template<typename T >
void send (const unsigned int dest_processor_id, const T &buf, Request &req, const MessageTag &tag=no_tag) const
 Nonblocking-send to one processor with data-defined type.
 
template<typename T >
void send (const unsigned int dest_processor_id, const T &buf, const DataType &type, const MessageTag &tag=no_tag) const
 Blocking-send to one processor with user-defined type.
 
template<typename T >
void send (const unsigned int dest_processor_id, const T &buf, const DataType &type, Request &req, const MessageTag &tag=no_tag) const
 Nonblocking-send to one processor with user-defined type.
 
template<typename T >
void send (const unsigned int dest_processor_id, const T &buf, const NotADataType &type, Request &req, const MessageTag &tag=no_tag) const
 Nonblocking-send to one processor with user-defined packable type.
 
template<typename T >
void send (const unsigned int dest_processor_id, const std::basic_string< T > &buf, const MessageTag &tag) const
 
template<typename T >
void send (const unsigned int dest_processor_id, const std::basic_string< T > &buf, Request &req, const MessageTag &tag) const
 
template<typename T >
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.
 
template<typename T >
void receive (const unsigned int dest_processor_id, T &buf, Request &req, const MessageTag &tag=any_tag) const
 Nonblocking-receive from one processor with data-defined type.
 
template<typename T >
Status receive (const unsigned int dest_processor_id, T &buf, const DataType &type, const MessageTag &tag=any_tag) const
 Blocking-receive from one processor with user-defined type.
 
template<typename T >
void receive (const unsigned int dest_processor_id, T &buf, const DataType &type, Request &req, const MessageTag &tag=any_tag) const
 Nonblocking-receive from one processor with user-defined type.
 
template<typename T >
Status receive (const unsigned int src_processor_id, std::basic_string< T > &buf, const MessageTag &tag) const
 
template<typename T >
void receive (const unsigned int src_processor_id, std::basic_string< T > &buf, Request &req, const MessageTag &tag) const
 
template<typename T , typename A , typename std::enable_if< std::is_base_of< DataType, StandardType< T > >::value, int >::type = 0>
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.
 
template<typename T , typename A , typename std::enable_if< Has_buffer_type< Packing< T > >::value, int >::type = 0>
bool possibly_receive (unsigned int &src_processor_id, std::vector< T, A > &buf, Request &req, const MessageTag &tag) const
 dispatches to possibly_receive_packed_range
 
template<typename T , typename A , typename std::enable_if< std::is_base_of< DataType, StandardType< T > >::value, int >::type = 0>
bool possibly_receive (unsigned int &src_processor_id, std::vector< T, A > &buf, const DataType &type, Request &req, const MessageTag &tag) const
 Nonblocking-receive from one processor with user-defined type.
 
template<typename T , typename A , typename std::enable_if< Has_buffer_type< Packing< T > >::value, int >::type = 0>
bool possibly_receive (unsigned int &src_processor_id, std::vector< T, A > &buf, const NotADataType &type, Request &req, const MessageTag &tag) const
 Nonblocking-receive from one processor with user-defined type.
 
template<typename T , typename A1 , typename A2 >
bool possibly_receive (unsigned int &src_processor_id, std::vector< std::vector< T, A1 >, A2 > &buf, const DataType &type, Request &req, const MessageTag &tag) const
 
template<typename Context , typename OutputIter , typename T >
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.
 
template<typename Context , typename Iter >
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.
 
template<typename Context , typename Iter >
void 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, std::size_t approx_buffer_size=1000000) const
 Nonblocking-send range-of-pointers to one processor.
 
template<typename Context , typename Iter >
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:
 
template<typename Context , typename Iter >
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:
 
template<typename Context , typename Iter >
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 Packing< typename std::iterator_traits< Iter >::value_type >::buffer_type > > &buffer, const MessageTag &tag) const
 
template<typename Context , typename OutputIter , typename T >
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.
 
template<typename Context , typename OutputIter , typename T >
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.
 
template<typename Context , typename OutputIter , typename T >
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.
 
template<typename Context , typename OutputIter , typename T >
void nonblocking_receive_packed_range (const unsigned int src_processor_id, Context *context, OutputIter out, const T *, Request &req, Status &stat, std::shared_ptr< std::vector< typename Packing< T >::buffer_type > > &buffer, const MessageTag &tag) const
 
template<typename T1 , typename T2 , typename std::enable_if< std::is_base_of< DataType, StandardType< T1 > >::value &&std::is_base_of< DataType, StandardType< T2 > >::value, int >::type = 0>
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 different) processor.
 
template<typename T1 , typename T2 >
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 different) processor, using a user-specified MPI Dataype.
 
template<typename T , typename A , typename std::enable_if< Has_buffer_type< Packing< T > >::value, int >::type >
void send_receive (const unsigned int dest_processor_id, const std::vector< T, A > &send_data, const unsigned int source_processor_id, std::vector< T, A > &recv_data, const MessageTag &send_tag, const MessageTag &recv_tag) const
 
template<typename T , typename A1 , typename A2 >
void send_receive (const unsigned int dest_processor_id, const std::vector< std::vector< T, A1 >, A2 > &sendvec, const unsigned int source_processor_id, std::vector< std::vector< T, A1 >, A2 > &recv, const MessageTag &send_tag, const MessageTag &recv_tag) const
 
template<typename T1 , typename T2 , typename std::enable_if< std::is_base_of< DataType, StandardType< T1 > >::value &&std::is_base_of< DataType, StandardType< T2 > >::value, int >::type >
void send_receive (const unsigned int timpi_dbg_var(send_tgt), const T1 &send_val, const unsigned int timpi_dbg_var(recv_source), T2 &recv_val, const MessageTag &, const MessageTag &) const
 Send-receive data from one processor.
 
template<typename T , typename A , typename std::enable_if< std::is_base_of< DataType, StandardType< T > >::value, int >::type >
void send_receive (const unsigned int timpi_dbg_var(dest_processor_id), const std::vector< T, A > &send, const unsigned int timpi_dbg_var(source_processor_id), std::vector< T, A > &recv, const MessageTag &, const MessageTag &) const
 
template<typename T , typename A1 , typename A2 >
void send_receive (const unsigned int timpi_dbg_var(dest_processor_id), const std::vector< std::vector< T, A1 >, A2 > &send, const unsigned int timpi_dbg_var(source_processor_id), std::vector< std::vector< T, A1 >, A2 > &recv, const MessageTag &, const MessageTag &) const
 
template<typename Context1 , typename RangeIter , typename Context2 , typename OutputIter , typename T >
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 (potentially different) processor.
 
template<typename Context1 , typename RangeIter , typename Context2 , typename OutputIter , typename T >
void send_receive_packed_range (const unsigned int timpi_dbg_var(dest_processor_id), const Context1 *context1, RangeIter send_begin, const RangeIter send_end, const unsigned int timpi_dbg_var(source_processor_id), Context2 *context2, OutputIter out_iter, const T *output_type, const MessageTag &, const MessageTag &, std::size_t) const
 Send-receive range-of-pointers from one processor.
 
template<typename T , typename A >
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 of send on processor processor_id.
 
template<typename T , typename A >
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 strings are the same length.
 
template<typename T , typename A , typename std::enable_if< std::is_base_of< DataType, StandardType< T > >::value, int >::type = 0>
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 processors.
 
template<typename T , typename A , typename std::enable_if< Has_buffer_type< Packing< T > >::value, int >::type = 0>
void gather (const unsigned int root_id, std::vector< T, A > &r) const
 
template<typename T , typename A , typename std::enable_if< std::is_base_of< DataType, StandardType< T > >::value, int >::type = 0>
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 processor.
 
template<typename T , typename A , typename std::enable_if< Has_buffer_type< Packing< T > >::value, int >::type = 0>
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 processor.
 
template<typename T , typename A >
void allgather (const std::basic_string< T > &send_data, std::vector< std::basic_string< T >, A > &recv_data, const bool identical_buffer_sizes=false) const
 The allgather overload for string types has an optional identical_buffer_sizes optimization for when all strings are the same length.
 
template<typename T , typename A , typename std::enable_if< std::is_base_of< DataType, StandardType< T > >::value, int >::type = 0>
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.
 
template<typename T , typename A1 , typename A2 , typename std::enable_if< std::is_base_of< DataType, StandardType< T > >::value, int >::type = 0>
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.
 
template<typename T , typename A1 , typename A2 , typename std::enable_if< Has_buffer_type< Packing< T > >::value, int >::type = 0>
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 dynamic-size local variables and collect similar vectors from all processors.
 
template<typename T , typename A , typename std::enable_if< Has_buffer_type< Packing< T > >::value, int >::type = 0>
void allgather (std::vector< T, A > &r, const bool identical_buffer_sizes=false) const
 Take a vector of possibly dynamically sized local variables and expand it to include values from all processors.
 
template<typename T , typename A >
void allgather (std::vector< std::basic_string< T >, A > &r, const bool identical_buffer_sizes=false) const
 AllGather overload for vectors of string types.
 
template<typename T , typename A >
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.
 
template<typename T , typename A >
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 communicator.
 
template<typename T , typename A1 , typename A2 >
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 communicator.
 
template<typename T , typename A1 , typename A2 >
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
 
template<typename T , typename A1 , typename A2 >
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.
 
template<typename Context , typename Iter , typename OutputIter >
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 the output iterator on rank root.
 
template<typename Context , typename Iter , typename OutputIter >
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 the output iterator.
 
template<typename T , typename A >
void alltoall (std::vector< T, A > &r) const
 Effectively transposes the input vector across all processors.
 
template<typename T #ifdef TIMPI_HAVE_MPI, typename std::enable_if< std::is_base_of< DataType, StandardType< T > >::value, int >::type = 0 #endif>
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.
 
template<typename T , typename std::enable_if< Has_buffer_type< Packing< T > >::value, int >::type = 0>
void broadcast (T &data, const unsigned int root_id=0, const bool identical_sizes=false) const
 Take a possibly dynamically-sized local value and broadcast it to all processors.
 
template<typename T >
void broadcast (std::basic_string< T > &data, const unsigned int root_id, const bool identical_sizes) const
 
template<typename T , typename A >
void broadcast (std::vector< std::basic_string< T >, A > &data, const unsigned int root_id, const bool identical_sizes) const
 
template<typename Context , typename OutputContext , typename Iter , typename OutputIter >
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.
 

Private Member Functions

void assign (const communicator &comm)
 Utility function for setting our member variables from an MPI communicator.
 
template<typename Map , typename std::enable_if< std::is_base_of< DataType, StandardType< typename Map::key_type > >::value &&std::is_base_of< DataType, StandardType< typename Map::mapped_type > >::value, int >::type = 0>
void map_sum (Map &data) const
 Private implementation function called by the map-based sum() specializations.
 
template<typename Map , typename std::enable_if<!(std::is_base_of< DataType, StandardType< typename Map::key_type > >::value &&std::is_base_of< DataType, StandardType< typename Map::mapped_type > >::value), int >::type = 0>
void map_sum (Map &data) const
 Private implementation function called by the map-based sum() specializations.
 
template<typename Map , typename std::enable_if< std::is_base_of< DataType, StandardType< typename Map::key_type > >::value &&std::is_base_of< DataType, StandardType< typename Map::mapped_type > >::value, int >::type = 0>
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.
 
template<typename Map , typename std::enable_if<!(std::is_base_of< DataType, StandardType< typename Map::key_type > >::value &&std::is_base_of< DataType, StandardType< typename Map::mapped_type > >::value), int >::type = 0>
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.
 
template<typename Map , typename std::enable_if< std::is_base_of< DataType, StandardType< typename Map::key_type > >::value &&std::is_base_of< DataType, StandardType< typename Map::mapped_type > >::value, int >::type = 0>
void map_max (Map &data) const
 Private implementation function called by the map-based max() specializations.
 
template<typename Map , typename std::enable_if<!(std::is_base_of< DataType, StandardType< typename Map::key_type > >::value &&std::is_base_of< DataType, StandardType< typename Map::mapped_type > >::value), int >::type = 0>
void map_max (Map &data) const
 Private implementation function called by the map-based max() specializations.
 
template<typename T , typename A1 , typename A2 >
std::size_t packed_size_of (const std::vector< std::vector< T, A1 >, A2 > &buf, const DataType &type) const
 

Private Attributes

communicator _communicator
 
processor_id_type _rank
 
processor_id_type _size
 
SendMode _send_mode
 
SyncType _sync_type
 
std::map< int, unsigned int > used_tag_values
 
int _next_tag
 
int _max_tag
 
bool _I_duped_it
 

Detailed Description

Definition at line 1508 of file communicator.h.

Member Enumeration Documentation

◆ SendMode

Whether to use default or synchronous sends?

Enumerator
DEFAULT 
SYNCHRONOUS 

Definition at line 220 of file communicator.h.

◆ SyncType

What algorithm to use for parallel synchronization?

Enumerator
NBX 
ALLTOALL_COUNTS 
SENDRECEIVE 

Definition at line 225 of file communicator.h.

Constructor & Destructor Documentation

◆ Communicator() [1/4]

libMesh::Parallel::Communicator::Communicator ( )
default

◆ Communicator() [2/4]

libMesh::Parallel::Communicator::Communicator ( const TIMPI::communicator comm)
inlineexplicit

Definition at line 1511 of file communicator.h.

1511: TIMPI::Communicator(comm) {}
Encapsulates the MPI_Comm object.

◆ Communicator() [3/4]

libMesh::Parallel::Communicator::Communicator ( const Communicator )
delete

◆ Communicator() [4/4]

libMesh::Parallel::Communicator::Communicator ( Communicator &&  )
default

◆ ~Communicator()

libMesh::Parallel::Communicator::~Communicator ( )
default

Member Function Documentation

◆ allgather() [1/8]

template<typename T , typename A >
void TIMPI::Communicator::allgather ( const std::basic_string< T > &  send_data,
std::vector< std::basic_string< T >, A > &  recv_data,
const bool  identical_buffer_sizes = false 
) const
inlineinherited

The allgather overload for string types has an optional identical_buffer_sizes optimization for when all strings are the same length.

Definition at line 1629 of file parallel_implementation.h.

1632{
1633 TIMPI_LOG_SCOPE ("allgather()","Parallel");
1634
1635 timpi_assert(this->size());
1636 recv.assign(this->size(), "");
1637
1638 // serial case
1639 if (this->size() < 2)
1640 {
1641 recv.resize(1);
1642 recv[0] = sendval;
1643 return;
1644 }
1645
1646 std::vector<CountType>
1647 sendlengths (this->size(), 0);
1648 std::vector<DispType>
1649 displacements(this->size(), 0);
1650
1652
1654 sendlengths.assign(this->size(), mysize);
1655 else
1656 // first comm step to determine buffer sizes from all processors
1657 this->allgather(mysize, sendlengths);
1658
1659 // Find the total size of the final array and
1660 // set up the displacement offsets for each processor
1662 for (unsigned int i=0; i != this->size(); ++i)
1663 {
1665 globalsize += sendlengths[i];
1666 }
1667
1668 // Check for quick return
1669 if (globalsize == 0)
1670 return;
1671
1672 // monolithic receive buffer
1673 std::basic_string<T> r(globalsize, 0);
1674
1675 // and get the data from the remote processors.
1677 (TIMPI_ALLGATHERV(const_cast<T*>(mysize ? sendval.data() : nullptr),
1678 mysize, StandardType<T>(),
1680 StandardType<T>(), this->get()));
1681
1682 // slice receive buffer up
1683 for (unsigned int i=0; i != this->size(); ++i)
1684 recv[i] = r.substr(displacements[i], sendlengths[i]);
1685}
processor_id_type size() const
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...
communicator & get()
MPI_Count CountType
Definition status.h:47
Tnew cast_int(Told oldvar)

References TIMPI::Communicator::allgather(), TIMPI::cast_int(), TIMPI::Communicator::get(), and TIMPI::Communicator::size().

◆ allgather() [2/8]

template<typename T , typename A1 , typename A2 , typename std::enable_if< std::is_base_of< DataType, StandardType< T > >::value, int >::type = 0>
void TIMPI::Communicator::allgather ( const std::vector< T, A1 > &  send_data,
std::vector< std::vector< T, A1 >, A2 > &  recv_data,
const bool  identical_buffer_sizes = false 
) const
inlineinherited

Take a vector of fixed size local variables and collect similar vectors from all processors.

By default, each processor is allowed to have its own unique input buffer length. If it is known that all processors have the same input sizes additional communication can be avoided.

◆ allgather() [3/8]

template<typename T , typename A1 , typename A2 , typename std::enable_if< Has_buffer_type< Packing< T > >::value, int >::type = 0>
void TIMPI::Communicator::allgather ( const std::vector< T, A1 > &  send_data,
std::vector< std::vector< T, A1 >, A2 > &  recv_data,
const bool  identical_buffer_sizes = false 
) const
inlineinherited

Take a vector of dynamic-size local variables and collect similar vectors from all processors.

◆ allgather() [4/8]

template<typename T , typename A , typename std::enable_if< std::is_base_of< DataType, StandardType< T > >::value, int >::type = 0>
void TIMPI::Communicator::allgather ( const T &  send_data,
std::vector< T, A > &  recv_data 
) const
inlineinherited

◆ allgather() [5/8]

template<typename T , typename A , typename std::enable_if< Has_buffer_type< Packing< T > >::value, int >::type = 0>
void TIMPI::Communicator::allgather ( const T &  send_data,
std::vector< T, A > &  recv_data 
) const
inlineinherited

Take a vector of length this->size(), and fill in recv[processor_id] = the value of send on that processor.

This overload works on potentially dynamically sized types, and dispatches to allgather_packed_range

◆ allgather() [6/8]

template<typename T , typename A >
void TIMPI::Communicator::allgather ( std::vector< std::basic_string< T >, A > &  r,
const bool  identical_buffer_sizes = false 
) const
inlineinherited

AllGather overload for vectors of string types.

◆ allgather() [7/8]

template<typename T , typename A , typename std::enable_if< std::is_base_of< DataType, StandardType< T > >::value, int >::type = 0>
void TIMPI::Communicator::allgather ( std::vector< T, A > &  r,
const bool  identical_buffer_sizes = false 
) const
inlineinherited

Take a vector of fixed size local variables and expand it to include values from all processors.

By default, each processor is allowed to have its own unique input buffer length. If it is known that all processors have the same input sizes additional communication can be avoided.

Specifically, this function transforms this:

* Processor 0: [ ... N_0 ]
* Processor 1: [ ....... N_1 ]
* ...
* Processor M: [ .. N_M]
* 

into this:

* [ [ ... N_0 ] [ ....... N_1 ] ... [ .. N_M] ]
* 

on each processor. This function is collective and therefore must be called by all processors in the Communicator.

◆ allgather() [8/8]

template<typename T , typename A , typename std::enable_if< Has_buffer_type< Packing< T > >::value, int >::type = 0>
void TIMPI::Communicator::allgather ( std::vector< T, A > &  r,
const bool  identical_buffer_sizes = false 
) const
inlineinherited

Take a vector of possibly dynamically sized local variables and expand it to include values from all processors.

By default, each processor is allowed to have its own unique input buffer length. If it is known that all processors have the same input sizes additional communication can be avoided.

Specifically, this function transforms this:

* Processor 0: [ ... N_0 ]
* Processor 1: [ ....... N_1 ]
* ...
* Processor M: [ .. N_M]
* 

into this:

* [ [ ... N_0 ] [ ....... N_1 ] ... [ .. N_M] ]
* 

on each processor. This function is collective and therefore must be called by all processors in the Communicator.

◆ allgather_packed_range()

template<typename Context , typename Iter , typename OutputIter >
void TIMPI::Communicator::allgather_packed_range ( Context context,
Iter  range_begin,
const Iter  range_end,
OutputIter  out,
std::size_t  approx_buffer_size = 1000000 
) const
inlineinherited

Take a range of local variables, combine it with ranges from all processors, and write the output to the output iterator.

The approximate maximum size (in entries; number of bytes will likely be 4x or 8x larger) to use in a single data vector buffer to send can be specified for performance or memory usage reasons; if the range cannot be packed into a single buffer of this size then multiple buffers and messages will be used.

Note that the received data vector sizes will be the sum of the sent vector sizes; a smaller-than-default size may be useful for users on many processors, in cases where all-to-one communication cannot be avoided entirely.

Referenced by testGettableStringAllGather(), testNestingAllGather(), testNullAllGather(), and testTupleStringAllGather().

◆ alltoall()

template<typename T , typename A >
void TIMPI::Communicator::alltoall ( std::vector< T, A > &  r) const
inlineinherited

Effectively transposes the input vector across all processors.

The jth entry on processor i is replaced with the ith entry from processor j.

Referenced by TIMPI::detail::push_parallel_alltoall_helper().

◆ assign()

void TIMPI::Communicator::assign ( const communicator comm)
privateinherited

Utility function for setting our member variables from an MPI communicator.

Definition at line 185 of file communicator.C.

186{
187 _communicator = comm;
188#ifdef TIMPI_HAVE_MPI
190 {
191 int i;
194
197
200
203
204 int * maxTag;
205 int flag = false;
208 _max_tag = *maxTag;
209 }
210 else
211 {
212 _rank = 0;
213 _size = 1;
214 _max_tag = std::numeric_limits<int>::max();
215 }
216 _next_tag = _max_tag / 2;
217#endif
218}
processor_id_type _size
processor_id_type _rank
communicator _communicator

References TIMPI::Communicator::_communicator, TIMPI::Communicator::_max_tag, TIMPI::Communicator::_next_tag, TIMPI::Communicator::_rank, TIMPI::Communicator::_size, and TIMPI::cast_int().

Referenced by TIMPI::Communicator::Communicator(), TIMPI::Communicator::duplicate(), and TIMPI::Communicator::operator=().

◆ barrier()

void TIMPI::Communicator::barrier ( ) const
inherited

Pause execution until all processors reach a certain point.

Definition at line 225 of file communicator.C.

226{
227 if (this->size() > 1)
228 {
229 TIMPI_LOG_SCOPE("barrier()", "Communicator");
230 timpi_call_mpi(MPI_Barrier (this->get()));
231 }
232}

References TIMPI::cast_int(), TIMPI::Communicator::get(), and TIMPI::Communicator::size().

Referenced by testBarrier(), and TIMPI::TIMPIInit::~TIMPIInit().

◆ bitwise_and() [1/2]

template<typename T >
void TIMPI::Communicator::bitwise_and ( const T &  r,
T &  o,
Request req 
) const
inlineinherited

Non-blocking bitwise_and of the local value r into o with the request req.

◆ bitwise_and() [2/2]

template<typename T >
void TIMPI::Communicator::bitwise_and ( T &  r) const
inlineinherited

Take a local variable and replace it with the bitwise_and of its values on all processors.

Containers are replaced element-wise.

◆ bitwise_or() [1/2]

template<typename T >
void TIMPI::Communicator::bitwise_or ( const T &  r,
T &  o,
Request req 
) const
inlineinherited

Non-blocking bitwise_or of the local value r into o with the request req.

◆ bitwise_or() [2/2]

template<typename T >
void TIMPI::Communicator::bitwise_or ( T &  r) const
inlineinherited

Take a local variable and replace it with the bitwise_or of its values on all processors.

Containers are replaced element-wise.

◆ bitwise_xor() [1/2]

template<typename T >
void TIMPI::Communicator::bitwise_xor ( const T &  r,
T &  o,
Request req 
) const
inlineinherited

Non-blocking bitwise_xor of the local value r into o with the request req.

◆ bitwise_xor() [2/2]

template<typename T >
void TIMPI::Communicator::bitwise_xor ( T &  r) const
inlineinherited

Take a local variable and replace it with the bitwise_xor of its values on all processors.

Containers are replaced element-wise.

◆ broadcast() [1/4]

template<typename T >
void TIMPI::Communicator::broadcast ( std::basic_string< T > &  data,
const unsigned int  root_id,
const bool  identical_sizes 
) const
inlineinherited

Definition at line 1720 of file parallel_implementation.h.

1723{
1724 if (this->size() == 1)
1725 {
1726 timpi_assert (!this->rank());
1728 return;
1729 }
1730
1731 timpi_assert_less (root_id, this->size());
1733
1734 TIMPI_LOG_SCOPE("broadcast()", "Parallel");
1735
1736 std::size_t data_size = data.size();
1737
1738 if (identical_sizes)
1739 timpi_assert(this->verify(data_size));
1740 else
1741 this->broadcast(data_size, root_id);
1742
1743 std::vector<T> data_c(data_size);
1744#ifndef NDEBUG
1745 std::basic_string<T> orig(data);
1746#endif
1747
1748 if (this->rank() == root_id)
1749 for (std::size_t i=0; i<data.size(); i++)
1750 data_c[i] = data[i];
1751
1753
1754 data.assign(data_c.begin(), data_c.end());
1755
1756#ifndef NDEBUG
1757 if (this->rank() == root_id)
1759#endif
1760}
processor_id_type rank() const
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 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.
static const bool is_fixed_type
Definition data_type.h:130

References TIMPI::Communicator::broadcast(), TIMPI::cast_int(), TIMPI::Communicator::rank(), TIMPI::Communicator::size(), and TIMPI::Communicator::verify().

◆ broadcast() [2/4]

template<typename T , typename A >
void TIMPI::Communicator::broadcast ( std::vector< std::basic_string< T >, A > &  data,
const unsigned int  root_id,
const bool  identical_sizes 
) const
inlineinherited

The strings will be packed in one long array with the size of each string preceding the actual characters

Definition at line 1764 of file parallel_implementation.h.

1767{
1768 if (this->size() == 1)
1769 {
1770 timpi_assert (!this->rank());
1772 return;
1773 }
1774
1775 timpi_assert_less (root_id, this->size());
1777
1778 TIMPI_LOG_SCOPE("broadcast()", "Parallel");
1779
1780 std::size_t bufsize=0;
1781 if (root_id == this->rank() || identical_sizes)
1782 {
1783 for (std::size_t i=0; i<data.size(); ++i)
1784 bufsize += data[i].size() + 1; // Add one for the string length word
1785 }
1786
1787 if (identical_sizes)
1788 timpi_assert(this->verify(bufsize));
1789 else
1790 this->broadcast(bufsize, root_id);
1791
1792 // Here we use unsigned int to store up to 32-bit characters
1793 std::vector<unsigned int> temp; temp.reserve(bufsize);
1794 // Pack the strings
1795 if (root_id == this->rank())
1796 {
1797 for (std::size_t i=0; i<data.size(); ++i)
1798 {
1799 temp.push_back(cast_int<unsigned int>(data[i].size()));
1800 for (std::size_t j=0; j != data[i].size(); ++j)
1805 temp.push_back(data[i][j]);
1806 }
1807 }
1808 else
1809 temp.resize(bufsize);
1810
1811 // broad cast the packed strings
1812 this->broadcast(temp, root_id, true);
1813
1814 // Unpack the strings
1815 if (root_id != this->rank())
1816 {
1817 data.clear();
1818 typename std::vector<unsigned int>::const_iterator iter = temp.begin();
1819 while (iter != temp.end())
1820 {
1821 std::size_t curr_len = *iter++;
1822 data.push_back(std::basic_string<T>(iter, iter+curr_len));
1823 iter += curr_len;
1824 }
1825 }
1826}

References TIMPI::Communicator::broadcast(), TIMPI::cast_int(), TIMPI::Communicator::rank(), TIMPI::Communicator::size(), and TIMPI::Communicator::verify().

◆ broadcast() [3/4]

template<typename T #ifdef TIMPI_HAVE_MPI, typename std::enable_if< std::is_base_of< DataType, StandardType< T > >::value, int >::type = 0 #endif>
void TIMPI::Communicator::broadcast ( T &  data,
const unsigned int  root_id = 0,
const bool  identical_sizes = false 
) const
inlineinherited

Take a local value and broadcast it to all processors.

Optionally takes the root_id processor, which specifies the processor initiating the broadcast.

If data is a container, it will be resized on target processors. When using pre-sized target containers, specify identical_sizes=true on all processors for an optimization.

Fixed variant

Referenced by TIMPI::Communicator::broadcast(), TIMPI::Communicator::broadcast(), testBroadcast(), testBroadcastArrayType(), testBroadcastNestedType(), testBroadcastString(), testContainerBroadcast(), and testVectorOfContainersBroadcast().

◆ broadcast() [4/4]

template<typename T , typename std::enable_if< Has_buffer_type< Packing< T > >::value, int >::type = 0>
void TIMPI::Communicator::broadcast ( T &  data,
const unsigned int  root_id = 0,
const bool  identical_sizes = false 
) const
inlineinherited

Take a possibly dynamically-sized local value and broadcast it to all processors.

Optionally takes the root_id processor, which specifies the processor initiating the broadcast.

If data is a container, it will be resized on target processors. When using pre-sized target containers, specify identical_sizes=true on all processors for an optimization.

Dynamic variant

◆ broadcast_packed_range()

template<typename Context , typename OutputContext , typename Iter , typename OutputIter >
void TIMPI::Communicator::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
inlineinherited

Blocking-broadcast range-of-pointers to one processor.

This function does not send the raw pointers, but rather constructs new objects at the other end whose contents match the objects pointed to by the sender.

void TIMPI::pack(const T *, vector<int> & data, const Context *) is used to serialize type T onto the end of a data vector.

unsigned int TIMPI::packable_size(const T *, const Context *) is used to allow data vectors to reserve memory, and for additional error checking

unsigned int TIMPI::packed_size(const T *, vector<int>::const_iterator) is used to advance to the beginning of the next object's data.

The approximate maximum size (in entries; number of bytes will likely be 4x or 8x larger) to use in a single data vector buffer can be specified for performance or memory usage reasons; if the range cannot be packed into a single buffer of this size then multiple buffers and messages will be used.

◆ clear()

void TIMPI::Communicator::clear ( )
inherited

Free and reset this communicator.

Definition at line 162 of file communicator.C.

162 {
163#ifdef TIMPI_HAVE_MPI
164 if (_I_duped_it)
165 {
169
171 }
172 _I_duped_it = false;
173#endif
174}

References TIMPI::Communicator::_communicator, TIMPI::Communicator::_I_duped_it, and TIMPI::cast_int().

Referenced by TIMPI::Communicator::operator=(), and TIMPI::Communicator::~Communicator().

◆ dereference_unique_tag()

void TIMPI::Communicator::dereference_unique_tag ( int  tagvalue) const
inherited

Dereference an already-acquired tag, and see if we can re-release it.

Definition at line 46 of file communicator.C.

47{
48 // This had better be an already-acquired tag.
50
52 // If we don't have any more outstanding references, we
53 // don't even need to keep this tag in our "used" set.
56}
std::map< int, unsigned int > used_tag_values

References TIMPI::cast_int(), and TIMPI::Communicator::used_tag_values.

Referenced by TIMPI::MessageTag::operator=(), TIMPI::MessageTag::operator=(), and TIMPI::MessageTag::~MessageTag().

◆ duplicate() [1/2]

void TIMPI::Communicator::duplicate ( const Communicator comm)
inherited

Definition at line 137 of file communicator.C.

138{
139 this->duplicate(comm._communicator);
140 this->send_mode(comm.send_mode());
141 this->sync_type(comm.sync_type());
142}
SendMode send_mode() const
Gets the user-requested SendMode.
void duplicate(const Communicator &comm)
SyncType sync_type() const
Gets the user-requested SyncType.

References TIMPI::Communicator::_communicator, TIMPI::Communicator::duplicate(), TIMPI::Communicator::send_mode(), TIMPI::Communicator::send_mode(), TIMPI::Communicator::sync_type(), and TIMPI::Communicator::sync_type().

Referenced by TIMPI::Communicator::duplicate(), testGetUniqueTagAuto(), and testStringSyncType().

◆ duplicate() [2/2]

void TIMPI::Communicator::duplicate ( const communicator comm)
inherited

Definition at line 146 of file communicator.C.

147{
149 {
151 (MPI_Comm_dup(comm, &_communicator));
152
153 _I_duped_it = true;
154 }
155 this->assign(_communicator);
156}
void assign(const communicator &comm)
Utility function for setting our member variables from an MPI communicator.

References TIMPI::Communicator::_communicator, TIMPI::Communicator::_I_duped_it, TIMPI::Communicator::assign(), and TIMPI::cast_int().

◆ gather() [1/4]

template<typename T , typename A >
void TIMPI::Communicator::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
inlineinherited

The gather overload for string types has an optional identical_buffer_sizes optimization for when all strings are the same length.

◆ gather() [2/4]

template<typename T , typename A >
void TIMPI::Communicator::gather ( const unsigned int  root_id,
const T &  send_data,
std::vector< T, A > &  recv 
) const
inlineinherited

Take a vector of length comm.size(), and on processor root_id fill in recv[processor_id] = the value of send on processor processor_id.

Referenced by testGather(), testGatherString(), and testGatherString2().

◆ gather() [3/4]

template<typename T , typename A , typename std::enable_if< std::is_base_of< DataType, StandardType< T > >::value, int >::type = 0>
void TIMPI::Communicator::gather ( const unsigned int  root_id,
std::vector< T, A > &  r 
) const
inlineinherited

Take a vector of local variables and expand it on processor root_id to include values from all processors.

This handles the case where the lengths of the vectors may vary. Specifically, this function transforms this:

* Processor 0: [ ... N_0 ]
* Processor 1: [ ....... N_1 ]
* ...
* Processor M: [ .. N_M]
* 

into this:

* [ [ ... N_0 ] [ ....... N_1 ] ... [ .. N_M] ]
* 

on processor root_id. This function is collective and therefore must be called by all processors in the Communicator.

If the type T is a standard (fixed-size) type then we use a standard MPI_Gatherv; if it is a packable variable-size type then we dispatch to gather_packed_range.

◆ gather() [4/4]

template<typename T , typename A , typename std::enable_if< Has_buffer_type< Packing< T > >::value, int >::type = 0>
void TIMPI::Communicator::gather ( const unsigned int  root_id,
std::vector< T, A > &  r 
) const
inlineinherited

◆ gather_packed_range()

template<typename Context , typename Iter , typename OutputIter >
void TIMPI::Communicator::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
inlineinherited

Take a range of local variables, combine it with ranges from all processors, and write the output to the output iterator on rank root.

The approximate maximum size (in entries; number of bytes will likely be 4x or 8x larger) to use in a single data vector buffer to send can be specified for performance or memory usage reasons; if the range cannot be packed into a single buffer of this size then multiple buffers and messages will be used.

Note that the received data vector sizes will be the sum of the sent vector sizes; a smaller-than-default size may be useful for users on many processors, in cases where all-to-one communication cannot be avoided entirely.

◆ get() [1/2]

communicator & TIMPI::Communicator::get ( )
inlineinherited

◆ get() [2/2]

const communicator & TIMPI::Communicator::get ( ) const
inlineinherited

Definition at line 169 of file communicator.h.

169{ return _communicator; }

References TIMPI::Communicator::_communicator.

◆ get_unique_tag()

MessageTag TIMPI::Communicator::get_unique_tag ( int  tagvalue = MessageTag::invalid_tag) const
inherited

Get a tag that is unique to this Communicator.

A requested tag value may be provided. If no request is made then an automatic unique tag value will be generated; such usage of get_unique_tag() must be done on every processor in a consistent order.

Note
If people are also using magic numbers or copying raw communicators around then we can't guarantee the tag is unique to this MPI_Comm.
Leaving tagvalue unspecified is recommended in most cases. Manually selecting tag values is dangerous, as tag values may be freed and reselected earlier than expected in asynchronous communication algorithms.

Definition at line 251 of file communicator.C.

252{
254 {
255#ifndef NDEBUG
256 // Automatic tag values have to be requested in sync
257 int maxval = _next_tag;
258 this->max(maxval);
260#endif
262 }
263
264 if (used_tag_values.count(tagvalue))
265 {
266 // Get the largest value in the used values, and pick one
267 // larger
268 tagvalue = used_tag_values.rbegin()->first+1;
270 }
271 if (tagvalue >= _next_tag)
273
274 if (_next_tag >= _max_tag)
276
278
279 return MessageTag(tagvalue, this);
280}
void max(const T &r, T &o, Request &req) const
Non-blocking maximum of the local value r into o with the request req.
static const int invalid_tag
Invalid tag, to allow for default construction.
Definition message_tag.h:53

References TIMPI::Communicator::_max_tag, TIMPI::Communicator::_next_tag, TIMPI::cast_int(), TIMPI::MessageTag::invalid_tag, TIMPI::Communicator::max(), and TIMPI::Communicator::used_tag_values.

Referenced by TIMPI::pull_parallel_vector_data(), TIMPI::detail::push_parallel_alltoall_helper(), TIMPI::detail::push_parallel_nbx_helper(), TIMPI::detail::push_parallel_roundrobin_helper(), testGetUniqueTagManual(), and testGetUniqueTagOverlap().

◆ logical_and() [1/2]

template<typename T >
void TIMPI::Communicator::logical_and ( const T &  r,
T &  o,
Request req 
) const
inlineinherited

Non-blocking logical_and of the local value r into o with the request req.

◆ logical_and() [2/2]

template<typename T >
void TIMPI::Communicator::logical_and ( T &  r) const
inlineinherited

Take a local variable and replace it with the logical_and of its values on all processors.

Containers are replaced element-wise.

◆ logical_or() [1/2]

template<typename T >
void TIMPI::Communicator::logical_or ( const T &  r,
T &  o,
Request req 
) const
inlineinherited

Non-blocking logical_or of the local value r into o with the request req.

◆ logical_or() [2/2]

template<typename T >
void TIMPI::Communicator::logical_or ( T &  r) const
inlineinherited

Take a local variable and replace it with the logical_or of its values on all processors.

Containers are replaced element-wise.

◆ logical_xor() [1/2]

template<typename T >
void TIMPI::Communicator::logical_xor ( const T &  r,
T &  o,
Request req 
) const
inlineinherited

Non-blocking logical_xor of the local value r into o with the request req.

◆ logical_xor() [2/2]

template<typename T >
void TIMPI::Communicator::logical_xor ( T &  r) const
inlineinherited

Take a local variable and replace it with the logical_xor of its values on all processors.

Containers are replaced element-wise.

◆ map_broadcast() [1/2]

template<typename Map , typename std::enable_if< std::is_base_of< DataType, StandardType< typename Map::key_type > >::value &&std::is_base_of< DataType, StandardType< typename Map::mapped_type > >::value, int >::type = 0>
void TIMPI::Communicator::map_broadcast ( Map data,
const unsigned int  root_id,
const bool  identical_sizes 
) const
privateinherited

Private implementation function called by the map-based broadcast() specializations.

This is_fixed_type variant saves a communication by broadcasting pairs

◆ map_broadcast() [2/2]

template<typename Map , typename std::enable_if<!(std::is_base_of< DataType, StandardType< typename Map::key_type > >::value &&std::is_base_of< DataType, StandardType< typename Map::mapped_type > >::value), int >::type = 0>
void TIMPI::Communicator::map_broadcast ( Map data,
const unsigned int  root_id,
const bool  identical_sizes 
) const
privateinherited

Private implementation function called by the map-based broadcast() specializations.

This !is_fixed_type variant makes two broadcasts, which is slower but gives more control over reach broadcast (e.g. we may need to specialize for either key_type or mapped_type)

◆ map_max() [1/2]

template<typename Map , typename std::enable_if<!(std::is_base_of< DataType, StandardType< typename Map::key_type > >::value &&std::is_base_of< DataType, StandardType< typename Map::mapped_type > >::value), int >::type >
void TIMPI::Communicator::map_max ( Map data) const
privateinherited

Private implementation function called by the map-based max() specializations.

This is_fixed_type variant saves a communication by broadcasting pairs

Definition at line 2329 of file parallel_implementation.h.

2330{
2331 if (this->size() > 1)
2332 {
2333 TIMPI_LOG_SCOPE("max(map)", "Parallel");
2334
2335 // Since the input map may have different keys on different
2336 // processors, we first gather all the keys and values, then for
2337 // each key we choose the max value over all procs. We
2338 // initialize the max with the first value we encounter rather
2339 // than some "global" minimum, since the latter is difficult to
2340 // do generically.
2341 std::vector<std::pair<typename Map::key_type, typename Map::mapped_type>>
2342 vecdata(data.begin(), data.end());
2343
2344 this->allgather(vecdata, /*identical_buffer_sizes=*/false);
2345
2346 data.clear();
2347
2348 for (const auto & pr : vecdata)
2349 {
2350 // Attempt to insert this value. If it works, then the value didn't
2351 // already exist and we can go on. If it fails, compute the std::max
2352 // between the current and existing values.
2353 auto result = data.insert(pr);
2354
2355 bool inserted = result.second;
2356
2357 if (!inserted)
2358 {
2359 auto it = result.first;
2360 it->second = std::max(it->second, pr.second);
2361 }
2362 }
2363 }
2364}

References TIMPI::Communicator::allgather(), TIMPI::cast_int(), and TIMPI::Communicator::size().

◆ map_max() [2/2]

template<typename Map , typename std::enable_if<!(std::is_base_of< DataType, StandardType< typename Map::key_type > >::value &&std::is_base_of< DataType, StandardType< typename Map::mapped_type > >::value), int >::type = 0>
void TIMPI::Communicator::map_max ( Map data) const
privateinherited

Private implementation function called by the map-based max() specializations.

This !is_fixed_type variant calls allgather twice: once for the keys and once for the values.

◆ map_sum() [1/2]

template<typename Map , typename std::enable_if< std::is_base_of< DataType, StandardType< typename Map::key_type > >::value &&std::is_base_of< DataType, StandardType< typename Map::mapped_type > >::value, int >::type = 0>
void TIMPI::Communicator::map_sum ( Map data) const
privateinherited

Private implementation function called by the map-based sum() specializations.

This is_fixed_type variant saves a communication by broadcasting pairs

◆ map_sum() [2/2]

template<typename Map , typename std::enable_if<!(std::is_base_of< DataType, StandardType< typename Map::key_type > >::value &&std::is_base_of< DataType, StandardType< typename Map::mapped_type > >::value), int >::type = 0>
void TIMPI::Communicator::map_sum ( Map data) const
privateinherited

Private implementation function called by the map-based sum() specializations.

This !is_fixed_type variant calls allgather twice: once for the keys and once for the values.

◆ max() [1/3]

template<typename T >
void TIMPI::Communicator::max ( const T &  r,
T &  o,
Request req 
) const
inlineinherited

◆ max() [2/3]

template<typename A >
void TIMPI::Communicator::max ( std::vector< bool, A > &  r) const
inlineinherited

Definition at line 2303 of file parallel_implementation.h.

2304{
2305 if (this->size() > 1 && !r.empty())
2306 {
2307 TIMPI_LOG_SCOPE("max(vector<bool>)", "Parallel");
2308
2309 timpi_assert(this->verify(r.size()));
2310
2311 std::vector<unsigned int> ruint;
2313 std::vector<unsigned int> temp(ruint.size());
2315 (TIMPI_ALLREDUCE (ruint.data(), temp.data(),
2316 cast_int<CountType>(ruint.size()),
2318 this->get()));
2320 }
2321}

References TIMPI::cast_int(), TIMPI::Communicator::size(), and TIMPI::Communicator::verify().

◆ max() [3/3]

template<typename T >
void TIMPI::Communicator::max ( T &  r) const
inlineinherited

Take a local variable and replace it with the maximum of it's values on all processors.

Containers are replaced element-wise.

◆ maxloc() [1/3]

template<typename A1 , typename A2 >
void TIMPI::Communicator::maxloc ( std::vector< bool, A1 > &  r,
std::vector< unsigned int, A2 > &  max_id 
) const
inlineinherited

Definition at line 2504 of file parallel_implementation.h.

2506{
2507 if (this->size() > 1 && !r.empty())
2508 {
2509 TIMPI_LOG_SCOPE("maxloc(vector<bool>)", "Parallel");
2510
2511 timpi_assert(this->verify(r.size()));
2512
2513 std::vector<DataPlusInt<int>> data_in(r.size());
2514 for (std::size_t i=0; i != r.size(); ++i)
2515 {
2516 data_in[i].val = r[i];
2517 data_in[i].rank = this->rank();
2518 }
2519 std::vector<DataPlusInt<int>> data_out(r.size());
2521 (TIMPI_ALLREDUCE(data_in.data(), data_out.data(),
2522 cast_int<CountType>(r.size()),
2524 OpFunction<int>::max_location(),
2525 this->get()));
2526 for (std::size_t i=0; i != r.size(); ++i)
2527 {
2528 r[i] = data_out[i].val;
2529 max_id[i] = data_out[i].rank;
2530 }
2531 }
2532 else if (!r.empty())
2533 {
2534 for (std::size_t i=0; i != r.size(); ++i)
2535 max_id[i] = this->rank();
2536 }
2537}

References TIMPI::cast_int(), TIMPI::Communicator::rank(), TIMPI::Communicator::size(), and TIMPI::Communicator::verify().

◆ maxloc() [2/3]

template<typename T , typename A1 , typename A2 >
void TIMPI::Communicator::maxloc ( std::vector< T, A1 > &  r,
std::vector< unsigned int, A2 > &  max_id 
) const
inlineinherited

Take a vector of local variables and replace each entry with the maximum of it's values on all processors.

Set each min_id entry to the minimum rank where a corresponding maximum was found.

Definition at line 2466 of file parallel_implementation.h.

2468{
2469 if (this->size() > 1 && !r.empty())
2470 {
2471 TIMPI_LOG_SCOPE("maxloc(vector)", "Parallel");
2472
2473 timpi_assert(this->verify(r.size()));
2474
2475 std::vector<DataPlusInt<T>> data_in(r.size());
2476 for (std::size_t i=0; i != r.size(); ++i)
2477 {
2478 data_in[i].val = r[i];
2479 data_in[i].rank = this->rank();
2480 }
2481 std::vector<DataPlusInt<T>> data_out(r.size());
2482
2484 (TIMPI_ALLREDUCE(data_in.data(), data_out.data(),
2485 cast_int<CountType>(r.size()),
2487 OpFunction<T>::max_location(),
2488 this->get()));
2489 for (std::size_t i=0; i != r.size(); ++i)
2490 {
2491 r[i] = data_out[i].val;
2492 max_id[i] = data_out[i].rank;
2493 }
2494 }
2495 else if (!r.empty())
2496 {
2497 for (std::size_t i=0; i != r.size(); ++i)
2498 max_id[i] = this->rank();
2499 }
2500}

References TIMPI::cast_int(), TIMPI::Communicator::rank(), TIMPI::Communicator::size(), and TIMPI::Communicator::verify().

◆ maxloc() [3/3]

template<typename T >
void TIMPI::Communicator::maxloc ( T &  r,
unsigned int max_id 
) const
inlineinherited

Take a local variable and replace it with the maximum of it's values on all processors, returning the minimum rank of a processor which originally held the maximum value.

Definition at line 2441 of file parallel_implementation.h.

2443{
2444 if (this->size() > 1)
2445 {
2446 TIMPI_LOG_SCOPE("maxloc(scalar)", "Parallel");
2447
2449 ignore(data_in); // unused ifndef TIMPI_HAVE_MPI
2450 data_in.val = r;
2451 data_in.rank = this->rank();
2452
2454 (TIMPI_ALLREDUCE (MPI_IN_PLACE, &data_in, 1,
2456 OpFunction<T>::max_location(), this->get()));
2457 r = data_in.val;
2458 max_id = data_in.rank;
2459 }
2460 else
2461 max_id = this->rank();
2462}
void ignore(const Args &...)

References TIMPI::cast_int(), TIMPI::Communicator::get(), TIMPI::ignore(), TIMPI::Communicator::rank(), and TIMPI::Communicator::size().

Referenced by testMaxloc(), testMaxlocBool(), testMaxlocDouble(), and testMaxlocPair().

◆ min() [1/3]

template<typename T >
void TIMPI::Communicator::min ( const T &  r,
T &  o,
Request req 
) const
inlineinherited

◆ min() [2/3]

template<typename A >
void TIMPI::Communicator::min ( std::vector< bool, A > &  r) const
inlineinherited

Definition at line 2182 of file parallel_implementation.h.

2183{
2184 if (this->size() > 1 && !r.empty())
2185 {
2186 TIMPI_LOG_SCOPE("min(vector<bool>)", "Parallel");
2187
2188 timpi_assert(this->verify(r.size()));
2189
2190 std::vector<unsigned int> ruint;
2192 std::vector<unsigned int> temp(ruint.size());
2195 (ruint.data(), temp.data(),
2196 cast_int<CountType>(ruint.size()),
2199 }
2200}

References TIMPI::cast_int(), TIMPI::Communicator::size(), and TIMPI::Communicator::verify().

◆ min() [3/3]

template<typename T >
void TIMPI::Communicator::min ( T &  r) const
inlineinherited

Take a local variable and replace it with the minimum of it's values on all processors.

Containers are replaced element-wise.

◆ minloc() [1/3]

template<typename A1 , typename A2 >
void TIMPI::Communicator::minloc ( std::vector< bool, A1 > &  r,
std::vector< unsigned int, A2 > &  min_id 
) const
inlineinherited

Definition at line 2266 of file parallel_implementation.h.

2268{
2269 if (this->size() > 1 && !r.empty())
2270 {
2271 TIMPI_LOG_SCOPE("minloc(vector<bool>)", "Parallel");
2272
2273 timpi_assert(this->verify(r.size()));
2274
2275 std::vector<DataPlusInt<int>> data_in(r.size());
2276 for (std::size_t i=0; i != r.size(); ++i)
2277 {
2278 data_in[i].val = r[i];
2279 data_in[i].rank = this->rank();
2280 }
2281 std::vector<DataPlusInt<int>> data_out(r.size());
2284 (data_in.data(), data_out.data(),
2286 OpFunction<int>::min_location(), this->get()));
2287 for (std::size_t i=0; i != r.size(); ++i)
2288 {
2289 r[i] = data_out[i].val;
2290 min_id[i] = data_out[i].rank;
2291 }
2292 }
2293 else if (!r.empty())
2294 {
2295 for (std::size_t i=0; i != r.size(); ++i)
2296 min_id[i] = this->rank();
2297 }
2298}

References TIMPI::cast_int(), TIMPI::Communicator::rank(), TIMPI::Communicator::size(), and TIMPI::Communicator::verify().

◆ minloc() [2/3]

template<typename T , typename A1 , typename A2 >
void TIMPI::Communicator::minloc ( std::vector< T, A1 > &  r,
std::vector< unsigned int, A2 > &  min_id 
) const
inlineinherited

Take a vector of local variables and replace each entry with the minimum of it's values on all processors.

Set each min_id entry to the minimum rank where a corresponding minimum was found.

Definition at line 2229 of file parallel_implementation.h.

2231{
2232 if (this->size() > 1 && !r.empty())
2233 {
2234 TIMPI_LOG_SCOPE("minloc(vector)", "Parallel");
2235
2236 timpi_assert(this->verify(r.size()));
2237
2238 std::vector<DataPlusInt<T>> data_in(r.size());
2239 for (std::size_t i=0; i != r.size(); ++i)
2240 {
2241 data_in[i].val = r[i];
2242 data_in[i].rank = this->rank();
2243 }
2244 std::vector<DataPlusInt<T>> data_out(r.size());
2245
2247 (TIMPI_ALLREDUCE (data_in.data(), data_out.data(),
2248 cast_int<CountType>(r.size()),
2250 OpFunction<T>::min_location(), this->get()));
2251 for (std::size_t i=0; i != r.size(); ++i)
2252 {
2253 r[i] = data_out[i].val;
2254 min_id[i] = data_out[i].rank;
2255 }
2256 }
2257 else if (!r.empty())
2258 {
2259 for (std::size_t i=0; i != r.size(); ++i)
2260 min_id[i] = this->rank();
2261 }
2262}

References TIMPI::cast_int(), TIMPI::Communicator::rank(), TIMPI::Communicator::size(), and TIMPI::Communicator::verify().

◆ minloc() [3/3]

template<typename T >
void TIMPI::Communicator::minloc ( T &  r,
unsigned int min_id 
) const
inlineinherited

Take a local variable and replace it with the minimum of it's values on all processors, returning the minimum rank of a processor which originally held the minimum value.

Definition at line 2204 of file parallel_implementation.h.

2206{
2207 if (this->size() > 1)
2208 {
2209 TIMPI_LOG_SCOPE("minloc(scalar)", "Parallel");
2210
2212 ignore(data_in); // unused ifndef TIMPI_HAVE_MPI
2213 data_in.val = r;
2214 data_in.rank = this->rank();
2215
2217 (TIMPI_ALLREDUCE (MPI_IN_PLACE, &data_in, 1,
2219 OpFunction<T>::min_location(), this->get()));
2220 r = data_in.val;
2221 min_id = data_in.rank;
2222 }
2223 else
2224 min_id = this->rank();
2225}

References TIMPI::cast_int(), TIMPI::Communicator::get(), TIMPI::ignore(), TIMPI::Communicator::rank(), and TIMPI::Communicator::size().

Referenced by testMinloc(), testMinlocBool(), testMinlocDouble(), and testMinlocPair().

◆ nonblocking_barrier()

void TIMPI::Communicator::nonblocking_barrier ( Request req) const
inherited

Start a barrier that doesn't block.

Definition at line 238 of file communicator.C.

239{
240 if (this->size() > 1)
241 {
242 TIMPI_LOG_SCOPE("nonblocking_barrier()", "Communicator");
243 timpi_call_mpi(MPI_Ibarrier (this->get(), req.get()));
244 }
245}

References TIMPI::cast_int(), TIMPI::Communicator::get(), TIMPI::Request::get(), and TIMPI::Communicator::size().

Referenced by TIMPI::detail::push_parallel_nbx_helper().

◆ nonblocking_receive_packed_range() [1/3]

template<typename Context , typename OutputIter , typename T >
void TIMPI::Communicator::nonblocking_receive_packed_range ( const unsigned int  src_processor_id,
Context context,
OutputIter  out,
const T *  ,
Request req,
Status stat,
std::shared_ptr< std::vector< typename Packing< T >::buffer_type > > &  buffer,
const MessageTag tag 
) const
inlineinherited

Definition at line 1937 of file parallel_implementation.h.

1945{
1946 // If they didn't pass in a buffer - let's make one
1947 if (buffer == nullptr)
1948 buffer = std::make_shared<std::vector<typename Packing<T>::buffer_type>>();
1949 else
1950 buffer->clear();
1951
1952 // Receive serialized variable size objects as a sequence of
1953 // buffer_t.
1954 // Allocate a buffer on the heap so we don't have to free it until
1955 // after the Request::wait()
1956 buffer->resize(stat.size());
1957 this->receive(src_processor_id, *buffer, req, tag);
1958
1959 // Make the Request::wait() handle unpacking the buffer
1960 req.add_post_wait_work
1961 (new PostWaitUnpackBuffer<std::vector<typename Packing<T>::buffer_type>, Context, OutputIter, T>(*buffer, context, out));
1962
1963 // Make it dereference the shared pointer (possibly freeing the buffer)
1964 req.add_post_wait_work
1965 (new PostWaitDereferenceSharedPtr<std::vector<typename Packing<T>::buffer_type>>(buffer));
1966}
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.

References TIMPI::cast_int(), and TIMPI::Communicator::receive().

◆ nonblocking_receive_packed_range() [2/3]

template<typename Context , typename OutputIter , typename T >
void TIMPI::Communicator::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
inlineinherited

Non-Blocking-receive range-of-pointers from one processor.

This is meant to receive messages from nonblocking_send_packed_range

Similar in design to the above receive_packed_range. However, this version requires a Request and a Status.

The Status must be a positively tested Status for a message of this type (i.e. a message does exist). It should most likely be generated by Communicator::packed_range_probe.

Definition at line 1290 of file parallel_implementation.h.

1297{
1298 typedef typename Packing<T>::buffer_type buffer_t;
1299
1300 // Receive serialized variable size objects as a sequence of
1301 // buffer_t.
1302 // Allocate a buffer on the heap so we don't have to free it until
1303 // after the Request::wait()
1304 std::vector<buffer_t> * buffer = new std::vector<buffer_t>(stat.size());
1305 this->receive(src_processor_id, *buffer, req, tag);
1306
1307 // Make the Request::wait() handle unpacking the buffer
1308 req.add_post_wait_work
1309 (new PostWaitUnpackBuffer<std::vector<buffer_t>, Context, OutputIter, T>(*buffer, context, out));
1310
1311 // Make the Request::wait() then handle deleting the buffer
1312 req.add_post_wait_work
1313 (new PostWaitDeleteBuffer<std::vector<buffer_t>>(buffer));
1314
1315 // The MessageTag should stay registered for the Request lifetime
1316 req.add_post_wait_work
1317 (new PostWaitDereferenceTag(tag));
1318}

References TIMPI::cast_int(), and TIMPI::Communicator::receive().

Referenced by TIMPI::push_parallel_packed_range().

◆ nonblocking_receive_packed_range() [3/3]

template<typename Context , typename OutputIter , typename T >
void TIMPI::Communicator::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
inlineinherited

Non-Blocking-receive range-of-pointers from one processor.

This is meant to receive messages from nonblocking_send_packed_range

Similar in design to the above receive_packed_range. However, this version requires a Request and a Status.

The Status must be a positively tested Status for a message of this type (i.e. a message does exist). It should most likely be generated by Communicator::packed_range_probe.

◆ nonblocking_send_packed_range() [1/3]

template<typename Context , typename Iter >
void TIMPI::Communicator::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
inlineinherited

Similar to the above Nonblocking send_packed_range with a few important differences:

  1. The total size of the packed buffer MUST be less than std::numeric_limits<int>::max()
  2. Only one message is generated
  3. On the receiving end the message should be tested for using Communicator::packed_range_probe()
  4. The message must be received by Communicator::nonblocking_receive_packed_range()

Definition at line 777 of file parallel_implementation.h.

783{
784 // Allocate a buffer on the heap so we don't have to free it until
785 // after the Request::wait()
786 typedef typename std::iterator_traits<Iter>::value_type T;
787 typedef typename Packing<T>::buffer_type buffer_t;
788
789 if (range_begin != range_end)
790 {
791 std::vector<buffer_t> * buffer = new std::vector<buffer_t>();
792
796 range_end,
797 *buffer,
798 // MPI-2/3 can only use signed integers for size,
799 // and with this API we need to fit a non-blocking
800 // send into one buffer
801 std::numeric_limits<CountType>::max());
802
803 if (range_begin != range_end)
804 timpi_error_msg("Non-blocking packed range sends cannot exceed " << std::numeric_limits<CountType>::max() << "in size");
805
806 // Make the Request::wait() handle deleting the buffer
807 req.add_post_wait_work
808 (new PostWaitDeleteBuffer<std::vector<buffer_t>>
809 (buffer));
810
811 // Non-blocking send of the buffer
812 this->send(dest_processor_id, *buffer, req, tag);
813 }
814}
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.
Iter pack_range(const Context *context, Iter range_begin, const Iter range_end, std::vector< buffertype > &buffer, std::size_t approx_buffer_size)
Helper function for range packing.
Definition packing.h:1044

References TIMPI::cast_int(), TIMPI::pack_range(), and TIMPI::Communicator::send().

Referenced by TIMPI::push_parallel_packed_range().

◆ nonblocking_send_packed_range() [2/3]

template<typename Context , typename Iter >
void TIMPI::Communicator::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 Packing< typename std::iterator_traits< Iter >::value_type >::buffer_type > > &  buffer,
const MessageTag tag 
) const
inlineinherited

Definition at line 1584 of file parallel_implementation.h.

1591{
1592 // Allocate a buffer on the heap so we don't have to free it until
1593 // after the Request::wait()
1594 typedef typename std::iterator_traits<Iter>::value_type T;
1595 typedef typename Packing<T>::buffer_type buffer_t;
1596
1597 if (range_begin != range_end)
1598 {
1599 if (buffer == nullptr)
1600 buffer = std::make_shared<std::vector<buffer_t>>();
1601 else
1602 buffer->clear();
1603
1604 range_begin =
1607 range_end,
1608 *buffer,
1609 // MPI-2/3 can only use signed integers for size,
1610 // and with this API we need to fit a non-blocking
1611 // send into one buffer
1612 std::numeric_limits<CountType>::max());
1613
1614 if (range_begin != range_end)
1615 timpi_error_msg("Non-blocking packed range sends cannot exceed " << std::numeric_limits<CountType>::max() << "in size");
1616
1617 // Make it dereference the shared pointer (possibly freeing the buffer)
1618 req.add_post_wait_work
1619 (new PostWaitDereferenceSharedPtr<std::vector<buffer_t>>(buffer));
1620
1621 // Non-blocking send of the buffer
1622 this->send(dest_processor_id, *buffer, req, tag);
1623 }
1624}

References TIMPI::cast_int(), TIMPI::pack_range(), and TIMPI::Communicator::send().

◆ nonblocking_send_packed_range() [3/3]

template<typename Context , typename Iter >
void TIMPI::Communicator::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
inlineinherited

Similar to the above Nonblocking send_packed_range with a few important differences:

  1. The total size of the packed buffer MUST be less than std::numeric_limits<int>::max()
  2. Only one message is generated
  3. On the receiving end the message should be tested for using Communicator::packed_range_probe()
  4. The message must be received by Communicator::nonblocking_receive_packed_range()

◆ operator=() [1/2]

Communicator & libMesh::Parallel::Communicator::operator= ( Communicator &&  )
default

◆ operator=() [2/2]

Communicator & libMesh::Parallel::Communicator::operator= ( const Communicator )
delete

◆ packed_range_probe()

template<typename T >
Status TIMPI::Communicator::packed_range_probe ( const unsigned int  src_processor_id,
const MessageTag tag,
bool flag 
) const
inlineinherited

Non-Blocking message probe for a packed range message.

Allows information about a message to be examined before the message is actually received.

Template type must match the object type that will be in the packed range

Parameters
src_processor_idThe processor the message is expected from or TIMPI::any_source
tagThe message tag or TIMPI::any_tag
flagOutput. True if a message exists. False otherwise.

Referenced by TIMPI::push_parallel_packed_range().

◆ packed_size_of()

template<typename T , typename A1 , typename A2 >
std::size_t TIMPI::Communicator::packed_size_of ( const std::vector< std::vector< T, A1 >, A2 > &  buf,
const DataType type 
) const
privateinherited

Definition at line 266 of file parallel_implementation.h.

268{
269 // Figure out how many bytes we need to pack all the data
270 //
271 // Start with the outer buffer size
273
275 (TIMPI_PACK_SIZE (1, TIMPI_COUNT_TYPE, this->get(), &packedsize));
276
277 std::size_t sendsize = packedsize;
278
279 const std::size_t n_vecs = buf.size();
280
281 for (std::size_t i = 0; i != n_vecs; ++i)
282 {
283 // The size of the ith inner buffer
285 (TIMPI_PACK_SIZE (1, TIMPI_COUNT_TYPE, this->get(), &packedsize));
286
288
289 // The data for each inner buffer
292 type, this->get(), &packedsize));
293
295 }
296
297 timpi_assert (sendsize /* should at least be 1! */);
298 return sendsize;
299}

References TIMPI::cast_int(), TIMPI::Communicator::get(), and TIMPI::Communicator::size().

◆ possibly_receive() [1/5]

template<typename T , typename A1 , typename A2 >
bool TIMPI::Communicator::possibly_receive ( unsigned int src_processor_id,
std::vector< std::vector< T, A1 >, A2 > &  buf,
const DataType type,
Request req,
const MessageTag tag 
) const
inlineinherited

Definition at line 2031 of file parallel_implementation.h.

2036{
2037 TIMPI_LOG_SCOPE("possibly_receive()", "Parallel");
2038
2039 Status stat(type);
2040
2041 int int_flag = 0;
2042
2045
2047 tag.value(),
2048 this->get(),
2049 &int_flag,
2050 stat.get()));
2051
2052 if (int_flag)
2053 {
2054 src_processor_id = stat.source();
2055
2056 std::vector<char> * recvbuf =
2057 new std::vector<char>(stat.size(StandardType<char>()));
2058
2059 this->receive(src_processor_id, *recvbuf, MPI_PACKED, req, tag);
2060
2061 // When we wait on the receive, we'll unpack the temporary buffer
2062 req.add_post_wait_work
2063 (new PostWaitUnpackNestedBuffer<std::vector<std::vector<T,A1>,A2>>
2064 (*recvbuf, buf, type, *this));
2065
2066 // And then we'll free the temporary buffer
2067 req.add_post_wait_work
2068 (new PostWaitDeleteBuffer<std::vector<char>>(recvbuf));
2069
2070 // The MessageTag should stay registered for the Request lifetime
2071 req.add_post_wait_work
2072 (new PostWaitDereferenceTag(tag));
2073 }
2074
2075 return int_flag;
2076}
const unsigned int any_source
Processor id meaning "Accept from any source".

References TIMPI::any_source, TIMPI::cast_int(), TIMPI::Communicator::receive(), TIMPI::Communicator::size(), and TIMPI::MessageTag::value().

◆ possibly_receive() [2/5]

template<typename T , typename A , typename std::enable_if< std::is_base_of< DataType, StandardType< T > >::value, int >::type >
bool TIMPI::Communicator::possibly_receive ( unsigned int src_processor_id,
std::vector< T, A > &  buf,
const DataType type,
Request req,
const MessageTag tag 
) const
inlineinherited

Nonblocking-receive from one processor with user-defined type.

As above, but with manually-specified data type.

Parameters
src_processor_idThe pid to receive from or "any". will be set to the actual src being received from
bufThe buffer to receive into
typeThe intrinsic datatype to receive
reqThe request to use
tagThe tag to use

Definition at line 1971 of file parallel_implementation.h.

1976{
1977 TIMPI_LOG_SCOPE("possibly_receive()", "Parallel");
1978
1979 Status stat(type);
1980
1981 int int_flag = 0;
1982
1985
1987 tag.value(),
1988 this->get(),
1989 &int_flag,
1990 stat.get()));
1991
1992 if (int_flag)
1993 {
1994 buf.resize(stat.size());
1995
1996 src_processor_id = stat.source();
1997
1999 (TIMPI_IRECV(buf.data(), cast_int<CountType>(buf.size()), type,
2000 src_processor_id, tag.value(), this->get(),
2001 req.get()));
2002
2003 // The MessageTag should stay registered for the Request lifetime
2004 req.add_post_wait_work
2005 (new PostWaitDereferenceTag(tag));
2006 }
2007
2008 return int_flag;
2009}

References TIMPI::any_source, TIMPI::cast_int(), TIMPI::Communicator::size(), and TIMPI::MessageTag::value().

◆ possibly_receive() [3/5]

template<typename T , typename A , typename std::enable_if< Has_buffer_type< Packing< T > >::value, int >::type >
bool TIMPI::Communicator::possibly_receive ( unsigned int src_processor_id,
std::vector< T, A > &  buf,
const NotADataType type,
Request req,
const MessageTag tag 
) const
inlineinherited

Nonblocking-receive from one processor with user-defined type.

Dispatches to possibly_receive_packed_range

Parameters
src_processor_idThe pid to receive from or "any". will be set to the actual src being received from
bufThe buffer to receive into
typeThe packable type to receive
reqThe request to use
tagThe tag to use

Definition at line 2012 of file parallel_implementation.h.

2017{
2018 TIMPI_LOG_SCOPE("possibly_receive()", "Parallel");
2019
2021 (void *)(nullptr),
2022 std::inserter(buf, buf.end()),
2023 (T *)(nullptr),
2024 req,
2025 tag);
2026}
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.

References TIMPI::cast_int(), and TIMPI::Communicator::possibly_receive_packed_range().

◆ possibly_receive() [4/5]

template<typename T , typename A , typename std::enable_if< std::is_base_of< DataType, StandardType< T > >::value, int >::type = 0>
bool TIMPI::Communicator::possibly_receive ( unsigned int src_processor_id,
std::vector< T, A > &  buf,
Request req,
const MessageTag tag 
) const
inlineinherited

Nonblocking-receive from one processor with user-defined type.

Checks to see if a message can be received from the src_processor_id . If so, it starts a non-blocking receive using the passed in request and returns true

Otherwise - if there is no message to receive it returns false

Note: The buf does NOT need to be properly sized before this call this will resize the buffer automatically

Parameters
src_processor_idThe pid to receive from or "any". will be set to the actual src being received from
bufThe buffer to receive into
reqThe request to use
tagThe tag to use

Referenced by TIMPI::push_parallel_vector_data().

◆ possibly_receive() [5/5]

template<typename T , typename A , typename std::enable_if< Has_buffer_type< Packing< T > >::value, int >::type = 0>
bool TIMPI::Communicator::possibly_receive ( unsigned int src_processor_id,
std::vector< T, A > &  buf,
Request req,
const MessageTag tag 
) const
inlineinherited

dispatches to possibly_receive_packed_range

Parameters
src_processor_idThe pid to receive from or "any". will be set to the actual src being received from
bufThe buffer to receive into
reqThe request to use
tagThe tag to use

◆ possibly_receive_packed_range()

template<typename Context , typename OutputIter , typename T >
bool TIMPI::Communicator::possibly_receive_packed_range ( unsigned int src_processor_id,
Context context,
OutputIter  out,
const T *  output_type,
Request req,
const MessageTag tag 
) const
inherited

Nonblocking packed range receive from one processor with user-defined type.

Checks to see if a message can be received from the src_processor_id . If so, it starts a nonblocking packed range receive using the passed in request and returns true

Otherwise - if there is no message to receive it returns false

void Parallel::unpack(const T *, OutputIter data, const Context *) is used to unserialize type T

Parameters
src_processor_idThe pid to receive from or "any". will be set to the actual src being receieved from
contextContext pointer that will be passed into the unpack functions
outThe output iterator
output_typeThe intrinsic datatype to receive
reqThe request to use
tagThe tag to use

Referenced by TIMPI::Communicator::possibly_receive(), and TIMPI::push_parallel_packed_range().

◆ probe()

status TIMPI::Communicator::probe ( const unsigned int  src_processor_id,
const MessageTag tag = any_tag 
) const
inherited

Blocking message probe.

Allows information about a message to be examined before the message is actually received.

Definition at line 283 of file communicator.C.

285{
286 TIMPI_LOG_SCOPE("probe()", "Communicator");
287
288#ifndef TIMPI_HAVE_MPI
291#endif
292
293 status stat;
294
297
299 (MPI_Probe (int(src_processor_id), tag.value(), this->get(), &stat));
300
301 return stat;
302}
MPI_Status status
Status object for querying messages.
Definition status.h:44

References TIMPI::any_source, TIMPI::cast_int(), TIMPI::ignore(), TIMPI::Communicator::size(), and TIMPI::MessageTag::value().

Referenced by TIMPI::pull_parallel_vector_data(), TIMPI::detail::push_parallel_alltoall_helper(), and TIMPI::Communicator::receive().

◆ product() [1/2]

template<typename T >
void TIMPI::Communicator::product ( const T &  r,
T &  o,
Request req 
) const
inlineinherited

Non-blocking product of the local value r into o with the request req.

◆ product() [2/2]

template<typename T >
void TIMPI::Communicator::product ( T &  r) const
inlineinherited

Take a local variable and replace it with the product of its values on all processors.

Containers are replaced element-wise.

◆ rank()

processor_id_type TIMPI::Communicator::rank ( ) const
inlineinherited

Definition at line 208 of file communicator.h.

208{ return _rank; }

References TIMPI::Communicator::_rank.

Referenced by TIMPI::Communicator::broadcast(), TIMPI::Communicator::broadcast(), TIMPI::detail::empty_send_assertion(), fill_data(), fill_data(), fill_scalar_data(), fill_scalar_data(), fill_vector_data(), fill_vector_data(), TIMPI::Communicator::maxloc(), TIMPI::Communicator::maxloc(), TIMPI::Communicator::maxloc(), TIMPI::Communicator::minloc(), TIMPI::Communicator::minloc(), TIMPI::Communicator::minloc(), TIMPI::pull_parallel_vector_data(), TIMPI::detail::push_parallel_alltoall_helper(), TIMPI::detail::push_parallel_nbx_helper(), TIMPI::detail::push_parallel_roundrobin_helper(), TIMPI::Communicator::send_receive(), TIMPI::Communicator::send_receive_packed_range(), testAllGather(), testAllGatherHalfEmptyVectorString(), testAllGatherString(), testAllGatherVectorString(), testAllGatherVectorVector(), testAllGatherVectorVectorInPlace(), testAllGatherVectorVectorPacked(), testArrayContainerAllGather(), testBigUnion(), testBroadcast(), testBroadcastArrayType(), testBroadcastNestedType(), testBroadcastString(), testContainerAllGather(), testContainerBroadcast(), testContainerSendReceive(), testEmptyEntry(), testGather(), testGatherString(), testGatherString2(), testGettableStringAllGather(), testIrecvSend(), testIsendRecv(), testLargeSetUnion(), testMapContainerAllGather(), testMapMap(), testMapMax(), testMapSet(), testMax(), testMaxloc(), testMaxlocBool(), testMaxlocDouble(), testMaxlocPair(), testMaxVecBool(), testMin(), testMinLarge(), testMinloc(), testMinlocBool(), testMinlocDouble(), testMinlocPair(), testMinVecBool(), testMPIULongMin(), testNestingAllGather(), testNonblockingMax(), testNonblockingMin(), testNonblockingString(), testNonblockingSum(), testNonblockingTest(), testNonblockingWaitany(), testNonFixedTypeMapMax(), testNonFixedTypeSum(), testNullAllGather(), testNullSendReceive(), testPackedSetUnion(), testPairContainerAllGather(), testPush(), testPushImpl(), testPushMove(), testPushMultimapImpl(), testPushMultimapVecVecImpl(), testPushPackedImpl(), testPushPackedImplMove(), testPushPackedNestedImpl(), testPushVecVecImpl(), testRecvIsendSets(), testRecvIsendVecVecs(), testScatter(), testSemiVerifyInf(), testSemiVerifyString(), testSemiVerifyType(), testSemiVerifyVector(), testSendRecvVecVecs(), testSplit(), testSplitByType(), testSum(), testSumOpFunction(), testTupleContainerAllGather(), testTupleStringAllGather(), testUnion(), testVectorOfContainersAllGather(), and testVectorOfContainersBroadcast().

◆ receive() [1/6]

template<typename T >
Status TIMPI::Communicator::receive ( const unsigned int  dest_processor_id,
T &  buf,
const DataType type,
const MessageTag tag = any_tag 
) const
inlineinherited

Blocking-receive from one processor with user-defined type.

If T is a container, container-of-containers, etc., then type should be the DataType of the underlying fixed-size entries in the container(s).

Definition at line 155 of file serial_implementation.h.

159{ timpi_not_implemented(); return Status(); }

References TIMPI::cast_int().

◆ receive() [2/6]

template<typename T >
void TIMPI::Communicator::receive ( const unsigned int  dest_processor_id,
T &  buf,
const DataType type,
Request req,
const MessageTag tag = any_tag 
) const
inlineinherited

Nonblocking-receive from one processor with user-defined type.

If T is a container, container-of-containers, etc., then type should be the DataType of the underlying fixed-size entries in the container(s).

Definition at line 162 of file serial_implementation.h.

References TIMPI::cast_int().

◆ receive() [3/6]

template<typename T >
Status TIMPI::Communicator::receive ( const unsigned int  dest_processor_id,
T &  buf,
const MessageTag tag = any_tag 
) const
inlineinherited

Blocking-receive from one processor with data-defined type.

We do not currently support receives on one processor without MPI.

Definition at line 862 of file parallel_implementation.h.

865{
866 TIMPI_LOG_SCOPE("receive()", "Parallel");
867
868 // Get the status of the message, explicitly provide the
869 // datatype so we can later query the size
870 Status stat(this->probe(src_processor_id, tag), StandardType<T>(&buf));
871
874
877 tag.value(), this->get(), stat.get()));
878
879 return stat;
880}
status probe(const unsigned int src_processor_id, const MessageTag &tag=any_tag) const
Blocking message probe.

References TIMPI::any_source, TIMPI::cast_int(), TIMPI::Communicator::probe(), TIMPI::Communicator::size(), and TIMPI::MessageTag::value().

Referenced by TIMPI::Communicator::nonblocking_receive_packed_range(), TIMPI::Communicator::nonblocking_receive_packed_range(), TIMPI::Communicator::possibly_receive(), TIMPI::pull_parallel_vector_data(), TIMPI::push_parallel_vector_data(), TIMPI::Communicator::receive(), TIMPI::Communicator::receive(), TIMPI::Communicator::receive_packed_range(), testIrecvSend(), testIsendRecv(), testNonblockingString(), testRecvIsendSets(), testRecvIsendVecVecs(), and testSendRecvVecVecs().

◆ receive() [4/6]

template<typename T >
void TIMPI::Communicator::receive ( const unsigned int  dest_processor_id,
T &  buf,
Request req,
const MessageTag tag = any_tag 
) const
inlineinherited

Nonblocking-receive from one processor with data-defined type.

Definition at line 885 of file parallel_implementation.h.

889{
890 TIMPI_LOG_SCOPE("receive()", "Parallel");
891
894
897 tag.value(), this->get(), req.get()));
898
899 // The MessageTag should stay registered for the Request lifetime
900 req.add_post_wait_work
901 (new PostWaitDereferenceTag(tag));
902}

References TIMPI::any_source, TIMPI::cast_int(), TIMPI::Communicator::size(), and TIMPI::MessageTag::value().

◆ receive() [5/6]

template<typename T >
Status TIMPI::Communicator::receive ( const unsigned int  src_processor_id,
std::basic_string< T > &  buf,
const MessageTag tag 
) const
inlineinherited

Definition at line 818 of file parallel_implementation.h.

821{
822 std::vector<T> tempbuf; // Officially C++ won't let us get a
823 // modifiable array from a string
824
825 Status stat = this->receive(src_processor_id, tempbuf, tag);
826 buf.assign(tempbuf.begin(), tempbuf.end());
827 return stat;
828}

References TIMPI::cast_int(), and TIMPI::Communicator::receive().

◆ receive() [6/6]

template<typename T >
void TIMPI::Communicator::receive ( const unsigned int  src_processor_id,
std::basic_string< T > &  buf,
Request req,
const MessageTag tag 
) const
inlineinherited

Definition at line 833 of file parallel_implementation.h.

837{
838 // Officially C++ won't let us get a modifiable array from a
839 // string, and we can't even put one on the stack for the
840 // non-blocking case.
841 std::vector<T> * tempbuf = new std::vector<T>(buf.size());
842
843 // We can clear the string, but the Request::wait() will need to
844 // handle copying our temporary buffer to it
845 buf.clear();
846
847 req.add_post_wait_work
848 (new PostWaitCopyBuffer<std::vector<T>,
849 std::back_insert_iterator<std::basic_string<T>>>
850 (*tempbuf, std::back_inserter(buf)));
851
852 // Make the Request::wait() then handle deleting the buffer
853 req.add_post_wait_work
854 (new PostWaitDeleteBuffer<std::vector<T>>(tempbuf));
855
856 this->receive(src_processor_id, *tempbuf, req, tag);
857}

References TIMPI::cast_int(), and TIMPI::Communicator::receive().

◆ receive_packed_range()

template<typename Context , typename OutputIter , typename T >
void TIMPI::Communicator::receive_packed_range ( const unsigned int  dest_processor_id,
Context context,
OutputIter  out,
const T *  output_type,
const MessageTag tag = any_tag 
) const
inlineinherited

Blocking-receive range-of-pointers from one processor.

This function does not receive raw pointers, but rather constructs new objects whose contents match the objects pointed to by the sender.

The objects will be of type T = iterator_traits<OutputIter>::value_type.

Using std::back_inserter as the output iterator allows receive to fill any container type. Using some null_output_iterator allows the receive to be dealt with solely by TIMPI::unpack(), for objects whose unpack() is written so as to not leak memory when used in this fashion.

A future version of this method should be created to preallocate memory when receiving vectors...

void TIMPI::unpack(vector<int>::iterator in, T ** out, Context *) is used to unserialize type T, typically into a new heap-allocated object whose pointer is returned as *out.

unsigned int TIMPI::packed_size(const T *, vector<int>::const_iterator) is used to advance to the beginning of the next object's data.

Definition at line 1226 of file parallel_implementation.h.

1231{
1232 typedef typename Packing<T>::buffer_type buffer_t;
1233
1234 // Receive serialized variable size objects as sequences of buffer_t
1235 std::size_t total_buffer_size = 0;
1236 Status stat = this->receive(src_processor_id, total_buffer_size, tag);
1237
1238 // Use stat.source() and stat.tag() in subsequent receives - if
1239 // src_processor_id is or tag is "any" then we want to be sure we
1240 // try to receive messages all corresponding to the same send.
1241
1242 std::size_t received_buffer_size = 0;
1243
1244 // OutputIter might not have operator= implemented; for maximum
1245 // compatibility we'll rely on its copy constructor.
1246 std::unique_ptr<OutputIter> next_out_iter =
1247 std::make_unique<OutputIter>(out_iter);
1248
1250 {
1251 std::vector<buffer_t> buffer;
1252 this->receive(stat.source(), buffer, MessageTag(stat.tag()));
1253 received_buffer_size += buffer.size();
1256 next_out_iter = std::make_unique<OutputIter>(return_out_iter);
1257 }
1258}
OutputIter unpack_range(const std::vector< buffertype > &buffer, Context *context, OutputIter out_iter, const T *)
Helper function for range unpacking.
Definition packing.h:1103

References TIMPI::cast_int(), TIMPI::Communicator::receive(), TIMPI::Status::source(), and TIMPI::unpack_range().

Referenced by TIMPI::Communicator::send_receive_packed_range().

◆ reference_unique_tag()

void TIMPI::Communicator::reference_unique_tag ( int  tagvalue) const
inherited

Reference an already-acquired tag, so that we know it will be dereferenced multiple times before we can re-release it.

Definition at line 37 of file communicator.C.

38{
39 // This had better be an already-acquired tag.
41
43}

References TIMPI::cast_int(), and TIMPI::Communicator::used_tag_values.

Referenced by TIMPI::MessageTag::MessageTag(), and TIMPI::MessageTag::operator=().

◆ scatter() [1/5]

template<typename T , typename A1 , typename A2 >
void TIMPI::Communicator::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
inlineinherited

Take a vector of vectors and scatter the ith inner vector to the ith processor in the communicator.

The result is saved into recv buffer. The recv buffer does not have to be sized prior to this operation.

◆ scatter() [2/5]

template<typename T , typename A >
void TIMPI::Communicator::scatter ( const std::vector< T, A > &  data,
std::vector< T, A > &  recv,
const unsigned int  root_id = 0 
) const
inlineinherited

Take a vector of local variables and scatter the ith equal-sized chunk to the ith processor in the communicator.

The data size must be a multiple of the communicator size. The result is saved into recv buffer. The recv buffer does not have to be sized prior to this operation.

◆ scatter() [3/5]

template<typename T , typename A >
void TIMPI::Communicator::scatter ( const std::vector< T, A > &  data,
T &  recv,
const unsigned int  root_id = 0 
) const
inlineinherited

Take a vector of local variables and scatter the ith item to the ith processor in the communicator.

The result is saved into recv.

Referenced by testScatter().

◆ scatter() [4/5]

template<typename T , typename A1 , typename A2 >
void TIMPI::Communicator::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
inlineinherited

Take a vector of local variables and scatter the ith variable-sized chunk to the ith processor in the communicator.

The counts vector should contain the number of items for each processor. The result is saved into recv buffer. The recv buffer does not have to be sized prior to this operation.

◆ scatter() [5/5]

template<typename T , typename A1 , typename A2 >
void TIMPI::Communicator::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
inlineinherited

vector<int> based scatter, for backwards compatibility

◆ semiverify() [1/2]

template<typename T >
timpi_pure bool TIMPI::Communicator::semiverify ( const T *  r) const
inlineinherited

Check whether a local pointer points to the same value on all processors where it is not null, returning true if it does or false if not.

Useful in assertions and possibly in user error checking.

Containers must have the same value in every entry on all processors where the pointer is not null for this function to return true.

Referenced by testSemiVerifyInf(), testSemiVerifyString(), testSemiVerifyType(), and testSemiVerifyVector().

◆ semiverify() [2/2]

template<typename T >
bool TIMPI::Communicator::semiverify ( const T *  r) const
inlineinherited

Definition at line 2112 of file parallel_implementation.h.

2113{
2114 if (this->size() > 1 && Attributes<T>::has_min_max == true)
2115 {
2116 T tempmin, tempmax;
2117 if (r)
2118 tempmin = tempmax = *r;
2119 else
2120 {
2121 Attributes<T>::set_highest(tempmin);
2122 Attributes<T>::set_lowest(tempmax);
2123 }
2124 this->min(tempmin);
2125 this->max(tempmax);
2126 bool invalid = r && ((*r != tempmin) ||
2127 (*r != tempmax));
2128 this->max(invalid);
2129 return !invalid;
2130 }
2131
2132 static_assert(Attributes<T>::has_min_max,
2133 "Tried to semiverify an unverifiable type");
2134
2135 return true;
2136}
void min(const T &r, T &o, Request &req) const
Non-blocking minimum of the local value r into o with the request req.
static const bool has_min_max
Definition attributes.h:48

References TIMPI::cast_int(), TIMPI::Communicator::max(), TIMPI::Communicator::min(), and TIMPI::Communicator::size().

◆ send() [1/7]

template<typename T >
void TIMPI::Communicator::send ( const unsigned int  dest_processor_id,
const std::basic_string< T > &  buf,
const MessageTag tag 
) const
inlineinherited

Definition at line 303 of file parallel_implementation.h.

306{
307 TIMPI_LOG_SCOPE("send()", "Parallel");
308
309 T * dataptr = buf.empty() ? nullptr : const_cast<T *>(buf.data());
310
312
314 (((this->send_mode() == SYNCHRONOUS) ?
316 (dataptr, cast_int<CountType>(buf.size()),
317 StandardType<T>(dataptr), dest_processor_id, tag.value(),
318 this->get()));
319}

References TIMPI::cast_int(), TIMPI::Communicator::get(), TIMPI::Communicator::send_mode(), TIMPI::Communicator::size(), TIMPI::Communicator::SYNCHRONOUS, and TIMPI::MessageTag::value().

◆ send() [2/7]

template<typename T >
void TIMPI::Communicator::send ( const unsigned int  dest_processor_id,
const std::basic_string< T > &  buf,
Request req,
const MessageTag tag 
) const
inlineinherited

Definition at line 324 of file parallel_implementation.h.

328{
329 TIMPI_LOG_SCOPE("send()", "Parallel");
330
331 T * dataptr = buf.empty() ? nullptr : const_cast<T *>(buf.data());
332
334
336 (((this->send_mode() == SYNCHRONOUS) ?
338 (dataptr, cast_int<CountType>(buf.size()),
339 StandardType<T>(dataptr), dest_processor_id, tag.value(),
340 this->get(), req.get()));
341
342 // The MessageTag should stay registered for the Request lifetime
343 req.add_post_wait_work
344 (new PostWaitDereferenceTag(tag));
345}

References TIMPI::cast_int(), TIMPI::Communicator::get(), TIMPI::Request::get(), TIMPI::Communicator::send_mode(), TIMPI::Communicator::size(), TIMPI::Communicator::SYNCHRONOUS, and TIMPI::MessageTag::value().

◆ send() [3/7]

template<typename T >
void TIMPI::Communicator::send ( const unsigned int  dest_processor_id,
const T &  buf,
const DataType type,
const MessageTag tag = no_tag 
) const
inlineinherited

Blocking-send to one processor with user-defined type.

If T is a container, container-of-containers, etc., then type should be the DataType of the underlying fixed-size entries in the container(s).

Definition at line 78 of file serial_implementation.h.

References TIMPI::cast_int().

◆ send() [4/7]

template<typename T >
void TIMPI::Communicator::send ( const unsigned int  dest_processor_id,
const T &  buf,
const DataType type,
Request req,
const MessageTag tag = no_tag 
) const
inlineinherited

Nonblocking-send to one processor with user-defined type.

If T is a container, container-of-containers, etc., then type should be the DataType of the underlying fixed-size entries in the container(s).

Definition at line 85 of file serial_implementation.h.

References TIMPI::cast_int().

◆ send() [5/7]

template<typename T >
void TIMPI::Communicator::send ( const unsigned int  dest_processor_id,
const T &  buf,
const MessageTag tag = no_tag 
) const
inlineinherited

◆ send() [6/7]

template<typename T >
void TIMPI::Communicator::send ( const unsigned int  dest_processor_id,
const T &  buf,
const NotADataType type,
Request req,
const MessageTag tag = no_tag 
) const
inlineinherited

Nonblocking-send to one processor with user-defined packable type.

Packing<T> must be defined for T

Definition at line 93 of file serial_implementation.h.

References TIMPI::cast_int().

◆ send() [7/7]

template<typename T >
void TIMPI::Communicator::send ( const unsigned int  dest_processor_id,
const T &  buf,
Request req,
const MessageTag tag = no_tag 
) const
inlineinherited

Nonblocking-send to one processor with data-defined type.

Definition at line 370 of file parallel_implementation.h.

374{
375 TIMPI_LOG_SCOPE("send()", "Parallel");
376
377 T * dataptr = const_cast<T*>(&buf);
378
380
382 (((this->send_mode() == SYNCHRONOUS) ?
384 (dataptr, 1, StandardType<T>(dataptr), dest_processor_id,
385 tag.value(), this->get(), req.get()));
386
387 // The MessageTag should stay registered for the Request lifetime
388 req.add_post_wait_work
389 (new PostWaitDereferenceTag(tag));
390}

References TIMPI::cast_int(), TIMPI::Communicator::get(), TIMPI::Request::get(), TIMPI::Communicator::send_mode(), TIMPI::Communicator::size(), TIMPI::Communicator::SYNCHRONOUS, and TIMPI::MessageTag::value().

◆ send_mode() [1/2]

SendMode TIMPI::Communicator::send_mode ( ) const
inlineinherited

◆ send_mode() [2/2]

void TIMPI::Communicator::send_mode ( const SendMode  sm)
inlineinherited

Explicitly sets the SendMode type used for send operations.

Definition at line 333 of file communicator.h.

333{ _send_mode = sm; }

References TIMPI::Communicator::_send_mode, and TIMPI::cast_int().

Referenced by TIMPI::Communicator::duplicate(), TIMPI::detail::push_parallel_nbx_helper(), testIrecvSend(), and testIsendRecv().

◆ send_packed_range() [1/2]

template<typename Context , typename Iter >
void TIMPI::Communicator::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
inlineinherited

Blocking-send range-of-pointers to one processor.

This function does not send the raw pointers, but rather constructs new objects at the other end whose contents match the objects pointed to by the sender.

void TIMPI::pack(const T *, vector<int> & data, const Context *) is used to serialize type T onto the end of a data vector.

unsigned int TIMPI::packable_size(const T *, const Context *) is used to allow data vectors to reserve memory, and for additional error checking

The approximate maximum size (in entries; number of bytes will likely be 4x or 8x larger) to use in a single data vector buffer can be specified for performance or memory usage reasons; if the range cannot be packed into a single buffer of this size then multiple buffers and messages will be used.

Definition at line 648 of file parallel_implementation.h.

654{
655 // We will serialize variable size objects from *range_begin to
656 // *range_end as a sequence of plain data (e.g. ints) in this buffer
657 typedef typename std::iterator_traits<Iter>::value_type T;
658
659 std::size_t total_buffer_size =
661
662 this->send(dest_processor_id, total_buffer_size, tag);
663
664#ifdef DEBUG
665 std::size_t used_buffer_size = 0;
666#endif
667
668 while (range_begin != range_end)
669 {
670 timpi_assert_greater (std::distance(range_begin, range_end), 0);
671
672 std::vector<typename Packing<T>::buffer_type> buffer;
673
676
678
680
681#ifdef DEBUG
682 used_buffer_size += buffer.size();
683#endif
684
685 // Blocking send of the buffer
686 this->send(dest_processor_id, buffer, tag);
687 }
688
689#ifdef DEBUG
691#endif
692}
std::size_t packed_range_size(const Context *context, Iter range_begin, const Iter range_end)
Helper function for range packing.
Definition packing.h:1023

References TIMPI::cast_int(), TIMPI::pack_range(), TIMPI::packed_range_size(), and TIMPI::Communicator::send().

Referenced by TIMPI::Communicator::send_receive_packed_range().

◆ send_packed_range() [2/2]

template<typename Context , typename Iter >
void TIMPI::Communicator::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,
std::size_t  approx_buffer_size = 1000000 
) const
inlineinherited

Nonblocking-send range-of-pointers to one processor.

This function does not send the raw pointers, but rather constructs new objects at the other end whose contents match the objects pointed to by the sender.

void TIMPI::pack(const T *, vector<int> & data, const Context *) is used to serialize type T onto the end of a data vector.

unsigned int TIMPI::packable_size(const T *, const Context *) is used to allow data vectors to reserve memory, and for additional error checking

The approximate maximum size (in entries; number of bytes will likely be 4x or 8x larger) to use in a single data vector buffer can be specified for performance or memory usage reasons; if the range cannot be packed into a single buffer of this size then multiple buffers and messages will be used.

Definition at line 696 of file parallel_implementation.h.

703{
704 // Allocate a buffer on the heap so we don't have to free it until
705 // after the Request::wait()
706 typedef typename std::iterator_traits<Iter>::value_type T;
707 typedef typename Packing<T>::buffer_type buffer_t;
708
709 std::size_t total_buffer_size =
711
712 // That local variable will be gone soon; we need a send buffer that
713 // will stick around. I heard you like buffering so I put a buffer
714 // for your buffer size so you can buffer the size of your buffer.
715 std::size_t * total_buffer_size_buffer = new std::size_t;
717
718 // Delete the buffer size's buffer when we're done
719 Request intermediate_req = request();
720 intermediate_req.add_post_wait_work
722 this->send(dest_processor_id, *total_buffer_size_buffer, intermediate_req, tag);
723
724 // And don't finish up the full request until we're done with its
725 // dependencies
726 req.add_prior_request(intermediate_req);
727
728#ifdef DEBUG
729 std::size_t used_buffer_size = 0;
730#endif
731
732 while (range_begin != range_end)
733 {
734 timpi_assert_greater (std::distance(range_begin, range_end), 0);
735
736 std::vector<buffer_t> * buffer = new std::vector<buffer_t>();
737
740
742
744
745#ifdef DEBUG
746 used_buffer_size += buffer->size();
747#endif
748
749 Request next_intermediate_req;
750
752
753 // Make the Request::wait() handle deleting the buffer
754 my_req->add_post_wait_work
755 (new PostWaitDeleteBuffer<std::vector<buffer_t>>
756 (buffer));
757
758 // Non-blocking send of the buffer
759 this->send(dest_processor_id, *buffer, *my_req, tag);
760
761 if (range_begin != range_end)
762 req.add_prior_request(*my_req);
763 }
764
765#ifdef DEBUG
767#endif
768}
MPI_Request request
Request object for non-blocking I/O.
Definition request.h:49

References TIMPI::cast_int(), TIMPI::pack_range(), TIMPI::packed_range_size(), and TIMPI::Communicator::send().

◆ send_receive() [1/7]

template<typename T , typename A1 , typename A2 >
void TIMPI::Communicator::send_receive ( const unsigned int  dest_processor_id,
const std::vector< std::vector< T, A1 >, A2 > &  sendvec,
const unsigned int  source_processor_id,
std::vector< std::vector< T, A1 >, A2 > &  recv,
const MessageTag send_tag,
const MessageTag recv_tag 
) const
inlineinherited

Definition at line 1509 of file parallel_implementation.h.

References TIMPI::cast_int().

◆ send_receive() [2/7]

template<typename T , typename A , typename std::enable_if< std::is_base_of< DataType, StandardType< T > >::value, int >::type >
void TIMPI::Communicator::send_receive ( const unsigned int  dest_processor_id,
const std::vector< T, A > &  send_data,
const unsigned int  source_processor_id,
std::vector< T, A > &  recv_data,
const MessageTag send_tag,
const MessageTag recv_tag 
) const
inlineinherited

Definition at line 1376 of file parallel_implementation.h.

1382{
1383 this->send_receive_packed_range(dest_processor_id, (void *)(nullptr),
1384 send_data.begin(), send_data.end(),
1385 source_processor_id, (void *)(nullptr),
1386 std::back_inserter(recv_data),
1387 (const T *)(nullptr),
1389}
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...

References TIMPI::cast_int(), and TIMPI::Communicator::send_receive_packed_range().

◆ send_receive() [3/7]

template<typename T1 , typename T2 >
void TIMPI::Communicator::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
inlineinherited

Send data send to one processor while simultaneously receiving other data recv from a (potentially different) processor, using a user-specified MPI Dataype.

◆ send_receive() [4/7]

template<typename T1 , typename T2 , typename std::enable_if< std::is_base_of< DataType, StandardType< T1 > >::value &&std::is_base_of< DataType, StandardType< T2 > >::value, int >::type >
void TIMPI::Communicator::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
inlineinherited

Send data send to one processor while simultaneously receiving other data recv from a (potentially different) processor.

This overload is defined for fixed-size data; other overloads exist for many other categories.

Definition at line 1397 of file parallel_implementation.h.

1403{
1404 TIMPI_LOG_SCOPE("send_receive()", "Parallel");
1405
1406 if (dest_processor_id == this->rank() &&
1407 source_processor_id == this->rank())
1408 {
1409 recv = sendvec;
1410 return;
1411 }
1412
1416
1417 // MPI_STATUS_IGNORE is from MPI-2; using it with some versions of
1418 // MPICH may cause a crash:
1419 // https://bugzilla.mcs.anl.gov/globus/show_bug.cgi?id=1798
1421 (TIMPI_SENDRECV(const_cast<T1*>(&sendvec), 1, StandardType<T1>(&sendvec),
1422 dest_processor_id, send_tag.value(), &recv, 1,
1424 recv_tag.value(), this->get(), MPI_STATUS_IGNORE));
1425}

References TIMPI::any_source, TIMPI::cast_int(), TIMPI::Communicator::rank(), and TIMPI::Communicator::size().

Referenced by TIMPI::push_parallel_vector_data().

◆ send_receive() [5/7]

template<typename T , typename A1 , typename A2 >
void TIMPI::Communicator::send_receive ( const unsigned int   timpi_dbg_vardest_processor_id,
const std::vector< std::vector< T, A1 >, A2 > &  send,
const unsigned int   timpi_dbg_varsource_processor_id,
std::vector< std::vector< T, A1 >, A2 > &  recv,
const MessageTag ,
const MessageTag  
) const
inlineinherited

◆ send_receive() [6/7]

template<typename T , typename A , typename std::enable_if< Has_buffer_type< Packing< T > >::value, int >::type >
void TIMPI::Communicator::send_receive ( const unsigned int   timpi_dbg_vardest_processor_id,
const std::vector< T, A > &  send,
const unsigned int   timpi_dbg_varsource_processor_id,
std::vector< T, A > &  recv,
const MessageTag ,
const MessageTag  
) const
inlineinherited

◆ send_receive() [7/7]

template<typename T1 , typename T2 , typename std::enable_if< std::is_base_of< DataType, StandardType< T1 > >::value &&std::is_base_of< DataType, StandardType< T2 > >::value, int >::type >
void TIMPI::Communicator::send_receive ( const unsigned int   timpi_dbg_varsend_tgt,
const T1 send_val,
const unsigned int   timpi_dbg_varrecv_source,
T2 recv_val,
const MessageTag ,
const MessageTag  
) const
inlineinherited

Send-receive data from one processor.

Definition at line 189 of file serial_implementation.h.

References TIMPI::cast_int().

◆ send_receive_packed_range() [1/2]

template<typename Context1 , typename RangeIter , typename Context2 , typename OutputIter , typename T >
void TIMPI::Communicator::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
inlineinherited

Send a range-of-pointers to one processor while simultaneously receiving another range from a (potentially different) processor.

This function does not send or receive raw pointers, but rather constructs new objects at each receiver whose contents match the objects pointed to by the sender.

The objects being sent will be of type T1 = iterator_traits<RangeIter>::value_type, and the objects being received will be of type T2 = iterator_traits<OutputIter>::value_type

void TIMPI::pack(const T1*, vector<int> & data, const Context1*) is used to serialize type T1 onto the end of a data vector.

Using std::back_inserter as the output iterator allows send_receive to fill any container type. Using some null_output_iterator allows the receive to be dealt with solely by TIMPI::unpack(), for objects whose unpack() is written so as to not leak memory when used in this fashion.

A future version of this method should be created to preallocate memory when receiving vectors...

void TIMPI::unpack(vector<int>::iterator in, T2** out, Context *) is used to unserialize type T2, typically into a new heap-allocated object whose pointer is returned as *out.

unsigned int TIMPI::packable_size(const T1*, const Context1*) is used to allow data vectors to reserve memory, and for additional error checking.

unsigned int TIMPI::packed_size(const T2*, vector<int>::const_iterator) is used to advance to the beginning of the next object's data.

Definition at line 1527 of file parallel_implementation.h.

1538{
1539 TIMPI_LOG_SCOPE("send_receive()", "Parallel");
1540
1542 ((dest_processor_id == this->rank()),
1543 (source_processor_id == this->rank()));
1544
1545 if (dest_processor_id == this->rank() &&
1546 source_processor_id == this->rank())
1547 {
1548 // We need to pack and unpack, even if we don't need to
1549 // communicate the buffer, just in case user Packing
1550 // specializations have side effects
1551
1552 // OutputIter might not have operator= implemented; for maximum
1553 // compatibility we'll rely on its copy constructor.
1554 std::unique_ptr<OutputIter> next_out_iter =
1555 std::make_unique<OutputIter>(out_iter);
1556
1557 typedef typename Packing<T>::buffer_type buffer_t;
1558 while (send_begin != send_end)
1559 {
1560 std::vector<buffer_t> buffer;
1565 next_out_iter = std::make_unique<OutputIter>(return_out_iter);
1566 }
1567 return;
1568 }
1569
1570 Request req;
1571
1574
1577
1578 req.wait();
1579}
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 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.

References TIMPI::cast_int(), TIMPI::pack_range(), TIMPI::Communicator::rank(), TIMPI::Communicator::receive_packed_range(), TIMPI::Communicator::send_packed_range(), and TIMPI::unpack_range().

Referenced by TIMPI::push_parallel_packed_range(), TIMPI::Communicator::send_receive(), testContainerSendReceive(), and testNullSendReceive().

◆ send_receive_packed_range() [2/2]

template<typename Context1 , typename RangeIter , typename Context2 , typename OutputIter , typename T >
void TIMPI::Communicator::send_receive_packed_range ( const unsigned int   timpi_dbg_vardest_processor_id,
const Context1 context1,
RangeIter  send_begin,
const RangeIter  send_end,
const unsigned int   timpi_dbg_varsource_processor_id,
Context2 context2,
OutputIter  out_iter,
const T *  output_type,
const MessageTag ,
const MessageTag ,
std::size_t   
) const
inlineinherited

Send-receive range-of-pointers from one processor.

If you call this without MPI you might be making a mistake, but we'll support it.

Definition at line 321 of file serial_implementation.h.

333{
334 // This makes no sense on one processor unless we're deliberately
335 // sending to ourself.
338
339 // On one processor, we just need to pack the range and then unpack
340 // it again.
341 typedef typename std::iterator_traits<RangeIter>::value_type T1;
342 typedef typename Packing<T1>::buffer_type buffer_t;
343
344 // OutputIter might not have operator= implemented; for maximum
345 // compatibility we'll rely on its copy constructor.
346 std::unique_ptr<OutputIter> next_out_iter =
347 std::make_unique<OutputIter>(out_iter);
348
349 while (send_begin != send_end)
350 {
351 timpi_assert_greater (std::distance(send_begin, send_end), 0);
352
353 // We will serialize variable size objects from *range_begin to
354 // *range_end as a sequence of ints in this buffer
355 std::vector<buffer_t> buffer;
356
359
361
363
366 next_out_iter = std::make_unique<OutputIter>(return_out_iter);
367 }
368}

References TIMPI::cast_int(), TIMPI::pack_range(), and TIMPI::unpack_range().

◆ set_union() [1/2]

template<typename T >
void TIMPI::Communicator::set_union ( T &  data) const
inlineinherited

Take a container of local variables on each processor, and replace it with their union over all processors, replacing the original on all processors.

If the data is a multiset or multimap or unordered_multimap, and entries exist on different processors with the same key, these entries are duplicated in the gathered container.

◆ set_union() [2/2]

template<typename T >
void TIMPI::Communicator::set_union ( T &  data,
const unsigned int  root_id 
) const
inlineinherited

Take a container (set, map, unordered_set, multimap, etc) of local variables on each processor, and collect their union over all processors, replacing the original on the processor with rank root_id.

If the data is a map or unordered_map and entries exist on different processors with the same key and different values, then the value with the lowest processor id takes precedence.

If the data is a multiset or multimap or unordered_multimap, and entries exist on different processors with the same key, these entries are duplicated in the gathered container.

Referenced by testBigUnion(), testLargeSetUnion(), testMapMap(), testMapSet(), testPackedSetUnion(), and testUnion().

◆ size() [1/2]

processor_id_type TIMPI::Communicator::size ( ) const
inlineinherited

Definition at line 211 of file communicator.h.

211{ return _size; }

References TIMPI::Communicator::_size.

Referenced by TIMPI::Communicator::allgather(), TIMPI::Communicator::barrier(), TIMPI::Communicator::broadcast(), TIMPI::Communicator::broadcast(), TIMPI::Communicator::map_max(), TIMPI::Communicator::max(), TIMPI::Communicator::maxloc(), TIMPI::Communicator::maxloc(), TIMPI::Communicator::maxloc(), TIMPI::Communicator::min(), TIMPI::Communicator::minloc(), TIMPI::Communicator::minloc(), TIMPI::Communicator::minloc(), TIMPI::Communicator::nonblocking_barrier(), TIMPI::Communicator::packed_size_of(), TIMPI::Communicator::possibly_receive(), TIMPI::Communicator::possibly_receive(), TIMPI::Communicator::probe(), TIMPI::pull_parallel_vector_data(), TIMPI::detail::push_parallel_alltoall_helper(), TIMPI::detail::push_parallel_nbx_helper(), TIMPI::detail::push_parallel_roundrobin_helper(), TIMPI::Communicator::receive(), TIMPI::Communicator::receive(), TIMPI::Communicator::semiverify(), TIMPI::Communicator::send(), TIMPI::Communicator::send(), TIMPI::Communicator::send(), TIMPI::Communicator::send(), TIMPI::Communicator::send_receive(), testAllGatherString(), testAllGatherVectorVectorInPlace(), testArrayContainerAllGather(), testBigUnion(), testContainerAllGather(), testContainerSendReceive(), testEmptyEntry(), testGettableStringAllGather(), testIrecvSend(), testIsendRecv(), testLargeSetUnion(), testMapContainerAllGather(), testMapMax(), testMax(), testMaxloc(), testMaxlocBool(), testMaxlocDouble(), testMaxlocPair(), testMaxVecBool(), testMinloc(), testMinlocBool(), testMinlocDouble(), testMinlocPair(), testMinVecBool(), testNestingAllGather(), testNonblockingMax(), testNonblockingString(), testNonblockingSum(), testNonFixedTypeMapMax(), testNonFixedTypeSum(), testNullSendReceive(), testPackedSetUnion(), testPairContainerAllGather(), testPull(), testPullImpl(), testPullOversized(), testPullPacked(), testPullVecVec(), testPullVecVecImpl(), testPullVecVecOversized(), testPush(), testPushImpl(), testPushMove(), testPushMultimap(), testPushMultimapImpl(), testPushMultimapOversized(), testPushMultimapVecVec(), testPushMultimapVecVecImpl(), testPushMultimapVecVecOversized(), testPushOversized(), testPushPacked(), testPushPackedImpl(), testPushPackedImplMove(), testPushPackedMove(), testPushPackedMoveOversized(), testPushPackedNestedImpl(), testPushPackedOversized(), testPushVecVec(), testPushVecVecImpl(), testPushVecVecOversized(), testRecvIsendSets(), testRecvIsendVecVecs(), testScatter(), testSendRecvVecVecs(), testSplit(), testSplitByType(), testSum(), testSumOpFunction(), testTupleContainerAllGather(), testTupleStringAllGather(), testUnion(), testVectorOfContainersAllGather(), testVectorOfContainersBroadcast(), and TIMPI::Communicator::verify().

◆ size() [2/2]

constexpr processor_id_type TIMPI::Communicator::size ( ) const
inlineconstexprinherited

Definition at line 214 of file communicator.h.

214{ return 1; }

◆ split()

void TIMPI::Communicator::split ( int  color,
int  key,
Communicator target 
) const
inherited

Definition at line 97 of file communicator.C.

98{
99 target.clear();
102 (MPI_Comm_split(this->get(), color, key, &newcomm));
103
104 target.assign(newcomm);
105 target._I_duped_it = (color != MPI_UNDEFINED);
106 target.send_mode(this->send_mode());
107 target.sync_type(this->sync_type());
108}

References TIMPI::cast_int(), TIMPI::Communicator::get(), TIMPI::Communicator::send_mode(), TIMPI::Communicator::sync_type(), and TIMPI::Communicator::sync_type().

Referenced by testSplit().

◆ split_by_type()

void TIMPI::Communicator::split_by_type ( int  split_type,
int  key,
info  i,
Communicator target 
) const
inherited

Definition at line 111 of file communicator.C.

112{
113 target.clear();
116 (MPI_Comm_split_type(this->get(), split_type, key, i, &newcomm));
117
118 target.assign(newcomm);
119 target._I_duped_it = (split_type != MPI_UNDEFINED);
120 target.send_mode(this->send_mode());
121 target.sync_type(this->sync_type());
122}

References TIMPI::cast_int(), TIMPI::Communicator::get(), TIMPI::Communicator::send_mode(), TIMPI::Communicator::sync_type(), and TIMPI::Communicator::sync_type().

Referenced by testSplitByType().

◆ sum() [1/2]

template<typename T >
void TIMPI::Communicator::sum ( const T &  r,
T &  o,
Request req 
) const
inlineinherited

Non-blocking sum of the local value r into o with the request req.

◆ sum() [2/2]

template<typename T >
void TIMPI::Communicator::sum ( T &  r) const
inlineinherited

Take a local variable and replace it with the sum of it's values on all processors.

Containers are replaced element-wise.

Referenced by testNonblockingSum(), testNonFixedTypeSum(), testSum(), and testSumOpFunction().

◆ sync_type() [1/3]

SyncType TIMPI::Communicator::sync_type ( ) const
inlineinherited

◆ sync_type() [2/3]

void TIMPI::Communicator::sync_type ( const std::string &  st)
inherited

Sets the sync type used for sync operations via a string.

Useful for changing the sync type via a CLI arg or parameter.

Definition at line 455 of file communicator.C.

456{
457 SyncType type = NBX;
458 if (st == "sendreceive")
459 type = SENDRECEIVE;
460 else if (st == "alltoall")
461 type = ALLTOALL_COUNTS;
462 else if (st != "nbx")
463 timpi_error_msg("Unrecognized TIMPI sync type " << st);
464 this->sync_type(type);
465}
SyncType
What algorithm to use for parallel synchronization?

References TIMPI::Communicator::ALLTOALL_COUNTS, TIMPI::cast_int(), TIMPI::Communicator::NBX, TIMPI::Communicator::SENDRECEIVE, and TIMPI::Communicator::sync_type().

◆ sync_type() [3/3]

void TIMPI::Communicator::sync_type ( const SyncType  st)
inlineinherited

◆ verify() [1/2]

template<typename T >
timpi_pure bool TIMPI::Communicator::verify ( const T &  r) const
inlineinherited

Check whether a local variable has the same value on all processors, returning true if it does or false if not.

Useful in assertions and possibly in user error checking.

Containers must have the same value in every entry for this function to return true.

Referenced by TIMPI::Communicator::broadcast(), TIMPI::Communicator::broadcast(), TIMPI::Communicator::max(), TIMPI::Communicator::maxloc(), TIMPI::Communicator::maxloc(), TIMPI::Communicator::min(), TIMPI::Communicator::minloc(), and TIMPI::Communicator::minloc().

◆ verify() [2/2]

template<typename T >
bool TIMPI::Communicator::verify ( const T &  r) const
inlineinherited

Definition at line 2092 of file parallel_implementation.h.

2093{
2094 if (this->size() > 1 && Attributes<T>::has_min_max == true)
2095 {
2096 T tempmin = r, tempmax = r;
2097 this->min(tempmin);
2098 this->max(tempmax);
2099 bool verified = (r == tempmin) &&
2100 (r == tempmax);
2101 this->min(verified);
2102 return verified;
2103 }
2104
2105 static_assert(Attributes<T>::has_min_max,
2106 "Tried to verify an unverifiable type");
2107
2108 return true;
2109}

References TIMPI::cast_int(), TIMPI::Communicator::max(), TIMPI::Communicator::min(), and TIMPI::Communicator::size().

Member Data Documentation

◆ _communicator

communicator TIMPI::Communicator::_communicator
privateinherited

◆ _I_duped_it

bool TIMPI::Communicator::_I_duped_it
privateinherited

Definition at line 249 of file communicator.h.

Referenced by TIMPI::Communicator::clear(), and TIMPI::Communicator::duplicate().

◆ _max_tag

int TIMPI::Communicator::_max_tag
privateinherited

◆ _next_tag

int TIMPI::Communicator::_next_tag
mutableprivateinherited

◆ _rank

processor_id_type TIMPI::Communicator::_rank
privateinherited

Definition at line 237 of file communicator.h.

Referenced by TIMPI::Communicator::assign(), and TIMPI::Communicator::rank().

◆ _send_mode

SendMode TIMPI::Communicator::_send_mode
privateinherited

◆ _size

processor_id_type TIMPI::Communicator::_size
privateinherited

Definition at line 237 of file communicator.h.

Referenced by TIMPI::Communicator::assign(), and TIMPI::Communicator::size().

◆ _sync_type

SyncType TIMPI::Communicator::_sync_type
privateinherited

◆ used_tag_values

std::map<int, unsigned int> TIMPI::Communicator::used_tag_values
mutableprivateinherited

The documentation for this class was generated from the following file: