libMesh
Public Types | Public Member Functions | Private Member Functions | Private Attributes | List of all members
libMesh::Parallel::Communicator Class Reference

Encapsulates the MPI_Comm object. More...

#include <parallel.h>

Public Types

enum  SendMode { DEFAULT =0, SYNCHRONOUS }
 Whether to use default or synchronous sends? More...
 

Public Member Functions

 Communicator ()
 Default Constructor. More...
 
 Communicator (const communicator &comm)
 
 ~Communicator ()
 
void split (int color, int key, Communicator &target) const
 
void duplicate (const Communicator &comm)
 
void duplicate (const communicator &comm)
 
communicatorget ()
 
const communicatorget () const
 
MessageTag get_unique_tag (int tagvalue) const
 Get a tag that is unique to this Communicator. More...
 
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. More...
 
void dereference_unique_tag (int tagvalue) const
 Dereference an already-acquired tag, and see if we can re-release it. More...
 
void clear ()
 Free and reset this communicator. More...
 
Communicatoroperator= (const communicator &comm)
 
unsigned int rank () const
 
unsigned int size () const
 
void send_mode (const SendMode sm)
 Explicitly sets the SendMode type used for send operations. More...
 
SendMode send_mode () const
 Gets the user-requested SendMode. More...
 
void barrier () const
 Pause execution until all processors reach a certain point. More...
 
template<typename T >
bool verify (const T &r) const
 Verify that a local variable has the same value on all processors. More...
 
template<typename T >
bool semiverify (const T *r) const
 Verify that a local pointer points to the same value on all processors where it is not NULL. More...
 
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. More...
 
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. More...
 
template<typename T >
void minloc (std::vector< T > &r, std::vector< unsigned int > &min_id) const
 Take a vector of local variables and replace each entry with the minimum of it's values on all processors. More...
 
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. More...
 
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. More...
 
template<typename T >
void maxloc (std::vector< T > &r, std::vector< unsigned int > &max_id) const
 Take a vector of local variables and replace each entry with the maximum of it's values on all processors. More...
 
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. More...
 
template<typename T >
void set_union (T &data, const unsigned int root_id) const
 Take a container of local variables on each processor, and collect their union over all processors, replacing the set on processor 0. More...
 
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. More...
 
status probe (const unsigned int src_processor_id, const MessageTag &tag=any_tag) const
 Blocking message probe. More...
 
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. More...
 
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. More...
 
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. More...
 
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. More...
 
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. More...
 
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. More...
 
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. More...
 
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. More...
 
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. More...
 
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) const
 Blocking-send range-of-pointers to one processor. More...
 
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) const
 Nonblocking-send range-of-pointers to one processor. More...
 
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: More...
 
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. More...
 
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. More...
 
template<typename T1 , typename T2 >
void send_receive (const unsigned int dest_processor_id, const T1 &send, const unsigned int source_processor_id, T2 &recv, 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. More...
 
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) const
 Send a range-of-pointers to one processor while simultaneously receiving another range from a (potentially different) processor. More...
 
template<typename T1 , typename T2 >
void send_receive (const unsigned int dest_processor_id, const T1 &send, const DataType &type1, const unsigned int source_processor_id, T2 &recv, 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. More...
 
template<typename T >
void gather (const unsigned int root_id, const T &send, std::vector< T > &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. More...
 
template<typename T >
void gather (const unsigned int root_id, const std::basic_string< T > &send, std::vector< std::basic_string< T >> &recv, const bool identical_buffer_sizes=false) const
 Gather overload for string types. More...
 
template<typename T >
void gather (const unsigned int root_id, std::vector< T > &r) const
 Take a vector of local variables and expand it on processor root_id to include values from all processors. More...
 
template<typename T >
void allgather (const T &send, std::vector< T > &recv) const
 Take a vector of length this->size(), and fill in recv[processor_id] = the value of send on that processor. More...
 
template<typename T >
void allgather (const std::basic_string< T > &send, std::vector< std::basic_string< T >> &recv, const bool identical_buffer_sizes=false) const
 AllGather overload for string types. More...
 
template<typename T >
void allgather (std::vector< T > &r, const bool identical_buffer_sizes=false) const
 Take a vector of local variables and expand it to include values from all processors. More...
 
template<typename T >
void allgather (std::vector< std::basic_string< T >> &r, const bool identical_buffer_sizes=false) const
 AllGather overload for vectors of string types. More...
 
template<typename T >
void scatter (const std::vector< T > &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. More...
 
template<typename T >
void scatter (const std::vector< T > &data, std::vector< T > &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. More...
 
template<typename T >
void scatter (const std::vector< T > &data, const std::vector< int > counts, std::vector< T > &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. More...
 
template<typename T >
void scatter (const std::vector< std::vector< T >> &data, std::vector< T > &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. More...
 
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) 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. More...
 
template<typename Context , typename Iter , typename OutputIter >
void allgather_packed_range (Context *context, Iter range_begin, const Iter range_end, OutputIter out) const
 Take a range of local variables, combine it with ranges from all processors, and write the output to the output iterator. More...
 
template<typename T >
void alltoall (std::vector< T > &r) const
 Effectively transposes the input vector across all processors. More...
 
template<typename T >
void broadcast (T &data, const unsigned int root_id=0) const
 Take a local value and broadcast it to all processors. More...
 
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) const
 Blocking-broadcast range-of-pointers to one processor. More...
 
template<>
bool verify (const bool &r) const
 
template<>
bool semiverify (const bool *r) const
 
template<typename T >
bool semiverify (const std::vector< T > *r) const
 
template<typename T >
void min (std::vector< T > &r) const
 
template<typename T >
void max (std::vector< T > &r) const
 
template<typename T >
void sum (std::vector< T > &r) const
 
template<typename T >
void sum (std::complex< T > &r) const
 
template<typename T >
void sum (std::vector< std::complex< T >> &r) const
 
template<typename T >
void set_union (std::set< T > &data, const unsigned int root_id) const
 
template<typename T >
void set_union (std::set< T > &data) const
 
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 >
void send (const unsigned int dest_processor_id, const std::set< T > &buf, const MessageTag &tag) const
 
template<typename T >
void send (const unsigned int dest_processor_id, const std::set< T > &buf, Request &req, const MessageTag &tag) const
 
template<typename T >
void send (const unsigned int dest_processor_id, const std::set< T > &buf, const DataType &type, const MessageTag &tag) const
 
template<typename T >
void send (const unsigned int dest_processor_id, const std::set< T > &buf, const DataType &type, Request &req, const MessageTag &tag) const
 
template<typename T >
void send (const unsigned int dest_processor_id, const std::vector< T > &buf, const MessageTag &tag) const
 
template<typename T >
void send (const unsigned int dest_processor_id, const std::vector< T > &buf, Request &req, const MessageTag &tag) const
 
template<typename T >
void send (const unsigned int dest_processor_id, const std::vector< T > &buf, const DataType &type, const MessageTag &tag) const
 
template<typename T >
void send (const unsigned int dest_processor_id, const std::vector< T > &buf, const DataType &type, Request &req, const MessageTag &tag) const
 
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 >
Status receive (const unsigned int src_processor_id, std::set< T > &buf, const MessageTag &tag) const
 
template<typename T >
void receive (const unsigned int src_processor_id, std::set< T > &buf, Request &req, const MessageTag &tag) const
 
template<typename T >
Status receive (const unsigned int src_processor_id, std::set< T > &buf, const DataType &type, const MessageTag &tag) const
 
template<typename T >
void receive (const unsigned int src_processor_id, std::set< T > &buf, const DataType &type, Request &req, const MessageTag &tag) const
 
template<typename T >
Status receive (const unsigned int src_processor_id, std::vector< T > &buf, const MessageTag &tag) const
 
template<typename T >
void receive (const unsigned int src_processor_id, std::vector< T > &buf, Request &req, const MessageTag &tag) const
 
template<typename T >
Status receive (const unsigned int src_processor_id, std::vector< T > &buf, const DataType &type, const MessageTag &tag) const
 
template<typename T >
void receive (const unsigned int src_processor_id, std::vector< T > &buf, const DataType &type, Request &req, const MessageTag &tag) const
 
template<typename T1 , typename T2 >
void send_receive (const unsigned int dest_processor_id, const std::vector< T1 > &sendvec, const DataType &type1, const unsigned int source_processor_id, std::vector< T2 > &recv, const DataType &type2, const MessageTag &send_tag, const MessageTag &recv_tag) const
 
template<typename T >
void send_receive (const unsigned int dest_processor_id, const std::vector< T > &sendvec, const unsigned int source_processor_id, std::vector< T > &recv, const MessageTag &send_tag, const MessageTag &recv_tag) const
 
template<typename T1 , typename T2 >
void send_receive (const unsigned int dest_processor_id, const std::vector< T1 > &sendvec, const unsigned int source_processor_id, std::vector< T2 > &recv, const MessageTag &send_tag, const MessageTag &recv_tag) const
 
template<typename T1 , typename T2 >
void send_receive (const unsigned int dest_processor_id, const std::vector< std::vector< T1 >> &sendvec, const unsigned int source_processor_id, std::vector< std::vector< T2 >> &recv, const MessageTag &, const MessageTag &) const
 
template<typename T >
void send_receive (const unsigned int dest_processor_id, const std::vector< std::vector< T >> &sendvec, const unsigned int source_processor_id, std::vector< std::vector< T >> &recv, const MessageTag &, const MessageTag &) const
 
template<>
void broadcast (bool &data, const unsigned int root_id) const
 
template<typename T >
void broadcast (std::basic_string< T > &data, const unsigned int root_id) const
 
template<typename T >
void broadcast (std::vector< T > &data, const unsigned int root_id) const
 
template<typename T >
void broadcast (std::vector< std::basic_string< T >> &data, const unsigned int root_id) const
 
template<typename T >
void broadcast (std::set< T > &data, const unsigned int root_id) const
 
template<typename T >
void gather (const unsigned int libmesh_dbg_var(root_id), const T &send_val, std::vector< T > &recv_val) const
 Gather-to-root on one processor. More...
 
template<typename T >
void gather (const unsigned int libmesh_dbg_var(root_id), const std::basic_string< T > &sendval, std::vector< std::basic_string< T >> &recv, const bool) const
 
template<typename T >
void scatter (const std::vector< T > &data, T &recv, const unsigned int libmesh_dbg_var(root_id)) const
 
template<typename T >
void scatter (const std::vector< T > &data, std::vector< T > &recv, const unsigned int libmesh_dbg_var(root_id)) const
 
template<typename T >
void scatter (const std::vector< T > &data, const std::vector< int > counts, std::vector< T > &recv, const unsigned int libmesh_dbg_var(root_id)) const
 
template<typename T >
void scatter (const std::vector< std::vector< T >> &data, std::vector< T > &recv, const unsigned int libmesh_dbg_var(root_id), const bool) const
 
template<typename T >
void broadcast (T &, const unsigned int libmesh_dbg_var(root_id)) const
 

Private Member Functions

 Communicator (const Communicator &)
 
void assign (const communicator &comm)
 Utility function for setting our member variables from an MPI communicator. More...
 

Private Attributes

communicator _communicator
 
unsigned int _rank
 
unsigned int _size
 
SendMode _send_mode
 
std::map< int, unsigned intused_tag_values
 
bool _I_duped_it
 

Detailed Description

Encapsulates the MPI_Comm object.

Allows the size of the group and this process's position in the group to be determined.

Methods of this object are the preferred way to perform distributed-memory parallel operations.

Definition at line 657 of file parallel.h.

Member Enumeration Documentation

Whether to use default or synchronous sends?

Enumerator
DEFAULT 
SYNCHRONOUS 

Definition at line 731 of file parallel.h.

Constructor & Destructor Documentation

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

Default Constructor.

Definition at line 617 of file parallel_implementation.h.

617  :
618 #ifdef LIBMESH_HAVE_MPI
619  _communicator(MPI_COMM_SELF),
620 #endif
621  _rank(0),
622  _size(1),
624  used_tag_values(),
625  _I_duped_it(false) {}
std::map< int, unsigned int > used_tag_values
Definition: parallel.h:752
libMesh::Parallel::Communicator::Communicator ( const communicator comm)
explicit

Definition at line 627 of file parallel_implementation.h.

References assign().

627  :
628 #ifdef LIBMESH_HAVE_MPI
629  _communicator(MPI_COMM_SELF),
630 #endif
631  _rank(0),
632  _size(1),
634  used_tag_values(),
635  _I_duped_it(false)
636 {
637  this->assign(comm);
638 }
void assign(const communicator &comm)
Utility function for setting our member variables from an MPI communicator.
std::map< int, unsigned int > used_tag_values
Definition: parallel.h:752
libMesh::Parallel::Communicator::~Communicator ( )

Definition at line 640 of file parallel_implementation.h.

References clear().

641 {
642  this->clear();
643 }
void clear()
Free and reset this communicator.
libMesh::Parallel::Communicator::Communicator ( const Communicator )
explicitprivate

Definition at line 708 of file parallel_implementation.h.

708  :
709 #ifdef LIBMESH_HAVE_MPI
710  _communicator(MPI_COMM_NULL),
711 #endif
712  _rank(0),
713  _size(1),
715  used_tag_values(),
716  _I_duped_it(false)
717 {
718  libmesh_not_implemented();
719 }
std::map< int, unsigned int > used_tag_values
Definition: parallel.h:752

Member Function Documentation

template<typename T >
void libMesh::Parallel::Communicator::allgather ( const T &  send,
std::vector< T > &  recv 
) const

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

Definition at line 3155 of file parallel_implementation.h.

References libMesh::libmesh_assert().

Referenced by libMesh::LaplaceMeshSmoother::allgather_graph(), libMesh::Parallel::Sort< KeyType, IdxType >::communicate_bins(), libMesh::Nemesis_IO_Helper::compute_num_global_elem_blocks(), libMesh::DofMap::distribute_dofs(), libMesh::MeshCommunication::find_global_indices(), libMesh::MeshRefinement::flag_elements_by_elem_fraction(), libMesh::MeshRefinement::flag_elements_by_nelem_target(), gather(), libMesh::MeshfreeInterpolation::gather_remote_data(), libMesh::ParmetisPartitioner::initialize(), libMesh::Nemesis_IO::read(), libMesh::DistributedMesh::renumber_dof_objects(), libMesh::DofMap::set_nonlocal_dof_objects(), libMesh::Parallel::Sort< KeyType, IdxType >::sort(), ParallelTest::testAllGather(), ParallelTest::testAllGatherEmptyVectorString(), ParallelTest::testAllGatherHalfEmptyVectorString(), ParallelPointTest::testAllGatherPairPointPoint(), ParallelPointTest::testAllGatherPairRealPoint(), ParallelPointTest::testAllGatherPoint(), and ParallelTest::testAllGatherVectorString().

3157 {
3158  LOG_SCOPE ("allgather()","Parallel");
3159 
3160  libmesh_assert(this->size());
3161  recv.resize(this->size());
3162 
3163  unsigned int comm_size = this->size();
3164  if (comm_size > 1)
3165  {
3166  StandardType<T> send_type(&sendval);
3167 
3168  libmesh_call_mpi
3169  (MPI_Allgather (const_cast<T*>(&sendval), 1, send_type, &recv[0], 1,
3170  send_type, this->get()));
3171  }
3172  else if (comm_size > 0)
3173  recv[0] = sendval;
3174 }
unsigned int size() const
Definition: parallel.h:726
libmesh_assert(j)
template<typename T >
void libMesh::Parallel::Communicator::allgather ( const std::basic_string< T > &  send,
std::vector< std::basic_string< T >> &  recv,
const bool  identical_buffer_sizes = false 
) const

AllGather overload for string types.

Definition at line 3179 of file parallel_implementation.h.

References libMesh::Parallel::allgather(), libMesh::libmesh_assert(), and libmesh_nullptr.

3182 {
3183  LOG_SCOPE ("allgather()","Parallel");
3184 
3185  libmesh_assert(this->size());
3186  recv.assign(this->size(), "");
3187 
3188  // serial case
3189  if (this->size() < 2)
3190  {
3191  recv.resize(1);
3192  recv[0] = sendval;
3193  return;
3194  }
3195 
3196  std::vector<int>
3197  sendlengths (this->size(), 0),
3198  displacements(this->size(), 0);
3199 
3200  const int mysize = static_cast<int>(sendval.size());
3201 
3202  if (identical_buffer_sizes)
3203  sendlengths.assign(this->size(), mysize);
3204  else
3205  // first comm step to determine buffer sizes from all processors
3206  this->allgather(mysize, sendlengths);
3207 
3208  // Find the total size of the final array and
3209  // set up the displacement offsets for each processor
3210  unsigned int globalsize = 0;
3211  for (unsigned int i=0; i != this->size(); ++i)
3212  {
3213  displacements[i] = globalsize;
3214  globalsize += sendlengths[i];
3215  }
3216 
3217  // Check for quick return
3218  if (globalsize == 0)
3219  return;
3220 
3221  // monolithic receive buffer
3222  std::string r(globalsize, 0);
3223 
3224  // and get the data from the remote processors.
3225  libmesh_call_mpi
3226  (MPI_Allgatherv (const_cast<T*>(mysize ? &sendval[0] : libmesh_nullptr),
3227  mysize, StandardType<T>(),
3228  &r[0], &sendlengths[0], &displacements[0],
3229  StandardType<T>(), this->get()));
3230 
3231  // slice receive buffer up
3232  for (unsigned int i=0; i != this->size(); ++i)
3233  recv[i] = r.substr(displacements[i], sendlengths[i]);
3234 }
unsigned int size() const
Definition: parallel.h:726
const class libmesh_nullptr_t libmesh_nullptr
libmesh_assert(j)
void allgather(const T &send, std::vector< T > &recv) const
Take a vector of length this->size(), and fill in recv[processor_id] = the value of send on that proc...
template<typename T >
void libMesh::Parallel::Communicator::allgather ( std::vector< T > &  r,
const bool  identical_buffer_sizes = false 
) const

Take a vector of 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.

Definition at line 3239 of file parallel_implementation.h.

References libMesh::Parallel::allgather(), libMesh::libmesh_assert(), libmesh_nullptr, and libMesh::Parallel::verify().

3241 {
3242  if (this->size() < 2)
3243  return;
3244 
3245  LOG_SCOPE("allgather()", "Parallel");
3246 
3247  if (identical_buffer_sizes)
3248  {
3249  if (r.empty())
3250  return;
3251 
3252  libmesh_assert(this->verify(r.size()));
3253 
3254  std::vector<T> r_src(r.size()*this->size());
3255  r_src.swap(r);
3256  StandardType<T> send_type(&r_src[0]);
3257 
3258  libmesh_call_mpi
3259  (MPI_Allgather (&r_src[0], cast_int<int>(r_src.size()),
3260  send_type, &r[0], cast_int<int>(r_src.size()),
3261  send_type, this->get()));
3262  // libmesh_assert(this->verify(r));
3263  return;
3264  }
3265 
3266  std::vector<int>
3267  sendlengths (this->size(), 0),
3268  displacements(this->size(), 0);
3269 
3270  const int mysize = static_cast<int>(r.size());
3271  this->allgather(mysize, sendlengths);
3272 
3273  // Find the total size of the final array and
3274  // set up the displacement offsets for each processor.
3275  unsigned int globalsize = 0;
3276  for (unsigned int i=0; i != this->size(); ++i)
3277  {
3278  displacements[i] = globalsize;
3279  globalsize += sendlengths[i];
3280  }
3281 
3282  // Check for quick return
3283  if (globalsize == 0)
3284  return;
3285 
3286  // copy the input buffer
3287  std::vector<T> r_src(globalsize);
3288  r_src.swap(r);
3289 
3290  StandardType<T> send_type(&r[0]);
3291 
3292  // and get the data from the remote processors.
3293  // Pass NULL if our vector is empty.
3294  libmesh_call_mpi
3295  (MPI_Allgatherv (r_src.empty() ? libmesh_nullptr : &r_src[0], mysize,
3296  send_type, &r[0], &sendlengths[0],
3297  &displacements[0], send_type, this->get()));
3298 }
bool verify(const T &r) const
Verify that a local variable has the same value on all processors.
unsigned int size() const
Definition: parallel.h:726
const class libmesh_nullptr_t libmesh_nullptr
libmesh_assert(j)
void allgather(const T &send, std::vector< T > &recv) const
Take a vector of length this->size(), and fill in recv[processor_id] = the value of send on that proc...
template<typename T >
void libMesh::Parallel::Communicator::allgather ( std::vector< std::basic_string< T >> &  r,
const bool  identical_buffer_sizes = false 
) const

AllGather overload for vectors of string types.

Definition at line 3303 of file parallel_implementation.h.

References libMesh::Parallel::allgather(), end, libMesh::libmesh_assert(), libmesh_nullptr, and libMesh::Parallel::verify().

3305 {
3306  if (this->size() < 2)
3307  return;
3308 
3309  LOG_SCOPE("allgather()", "Parallel");
3310 
3311  if (identical_buffer_sizes)
3312  {
3313  libmesh_assert(this->verify(r.size()));
3314 
3315  // identical_buffer_sizes doesn't buy us much since we have to
3316  // communicate the lengths of strings within each buffer anyway
3317  if (r.empty())
3318  return;
3319  }
3320 
3321  // Concatenate the input buffer into a send buffer, and keep track
3322  // of input string lengths
3323  std::vector<int> mystrlengths (r.size());
3324  std::vector<T> concat_src;
3325 
3326  int myconcatsize = 0;
3327  for (unsigned int i=0; i != r.size(); ++i)
3328  {
3329  int stringlen = cast_int<int>(r[i].size());
3330  mystrlengths[i] = stringlen;
3331  myconcatsize += stringlen;
3332  }
3333  concat_src.reserve(myconcatsize);
3334  for (unsigned int i=0; i != r.size(); ++i)
3335  concat_src.insert
3336  (concat_src.end(), r[i].begin(), r[i].end());
3337 
3338  // Get the string lengths from all other processors
3339  std::vector<int> strlengths = mystrlengths;
3340  this->allgather(strlengths, identical_buffer_sizes);
3341 
3342  // We now know how many strings we'll be receiving
3343  r.resize(strlengths.size());
3344 
3345  // Get the concatenated data sizes from all other processors
3346  std::vector<int> concat_sizes;
3347  this->allgather(myconcatsize, concat_sizes);
3348 
3349  // Find the total size of the final concatenated array and
3350  // set up the displacement offsets for each processor.
3351  std::vector<int> displacements(this->size(), 0);
3352  unsigned int globalsize = 0;
3353  for (unsigned int i=0; i != this->size(); ++i)
3354  {
3355  displacements[i] = globalsize;
3356  globalsize += concat_sizes[i];
3357  }
3358 
3359  // Check for quick return
3360  if (globalsize == 0)
3361  return;
3362 
3363  // Get the concatenated data from the remote processors.
3364  // Pass NULL if our vector is empty.
3365  std::vector<T> concat(globalsize);
3366 
3367  // We may have concat_src.empty(), but we know concat has at least
3368  // one element we can use as an example for StandardType
3369  StandardType<T> send_type(&concat[0]);
3370 
3371  libmesh_call_mpi
3372  (MPI_Allgatherv (concat_src.empty() ?
3373  libmesh_nullptr : &concat_src[0], myconcatsize,
3374  send_type, &concat[0], &concat_sizes[0],
3375  &displacements[0], send_type, this->get()));
3376 
3377  // Finally, split concatenated data into strings
3378  const T * begin = &concat[0];
3379  for (unsigned int i=0; i != r.size(); ++i)
3380  {
3381  const T * end = begin + strlengths[i];
3382  r[i].assign(begin, end);
3383  begin = end;
3384  }
3385 }
bool verify(const T &r) const
Verify that a local variable has the same value on all processors.
unsigned int size() const
Definition: parallel.h:726
const class libmesh_nullptr_t libmesh_nullptr
IterBase * end
Also have a polymorphic pointer to the end object, this prevents iterating past the end...
libmesh_assert(j)
void allgather(const T &send, std::vector< T > &recv) const
Take a vector of length this->size(), and fill in recv[processor_id] = the value of send on that proc...
template<typename Context , typename Iter , typename OutputIter >
void libMesh::Parallel::Communicator::allgather_packed_range ( Context *  context,
Iter  range_begin,
const Iter  range_end,
OutputIter  out 
) const

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

Definition at line 4228 of file parallel_implementation.h.

References libMesh::Parallel::allgather(), libMesh::libmesh_assert(), libmesh_nullptr, libMesh::Parallel::max(), libMesh::Parallel::pack_range(), and libMesh::Parallel::unpack_range().

Referenced by libMesh::MeshCommunication::gather(), and PackedRangeTest::testNullAllGather().

4232 {
4233  typedef typename std::iterator_traits<Iter>::value_type T;
4234  typedef typename Parallel::Packing<T>::buffer_type buffer_t;
4235 
4236  bool nonempty_range = (range_begin != range_end);
4237  this->max(nonempty_range);
4238 
4239  while (nonempty_range)
4240  {
4241  // We will serialize variable size objects from *range_begin to
4242  // *range_end as a sequence of ints in this buffer
4243  std::vector<buffer_t> buffer;
4244 
4245  range_begin = Parallel::pack_range
4246  (context, range_begin, range_end, buffer);
4247 
4248  this->allgather(buffer, false);
4249 
4250  libmesh_assert(buffer.size());
4251 
4253  (buffer, context, out_iter, (T*)libmesh_nullptr);
4254 
4255  nonempty_range = (range_begin != range_end);
4256  this->max(nonempty_range);
4257  }
4258 }
Iter pack_range(const Context *context, Iter range_begin, const Iter range_end, typename std::vector< buffertype > &buffer, std::size_t approx_buffer_size=1000000)
Encode a range of potentially-variable-size objects to a data array.
void max(T &r) const
Take a local variable and replace it with the maximum of it&#39;s values on all processors.
const class libmesh_nullptr_t libmesh_nullptr
libmesh_assert(j)
void unpack_range(const typename std::vector< buffertype > &buffer, Context *context, OutputIter out, const T *output_type)
Decode a range of potentially-variable-size objects from a data array.
void allgather(const T &send, std::vector< T > &recv) const
Take a vector of length this->size(), and fill in recv[processor_id] = the value of send on that proc...
template<typename T >
void libMesh::Parallel::Communicator::alltoall ( std::vector< T > &  r) const

Effectively transposes the input vector across all processors.

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

Definition at line 3557 of file parallel_implementation.h.

References libMesh::libmesh_assert(), and libMesh::Parallel::verify().

Referenced by libMesh::Nemesis_IO::read(), libMesh::MeshCommunication::redistribute(), scatter(), and libMesh::MeshCommunication::send_coarse_ghosts().

3558 {
3559  if (this->size() < 2 || buf.empty())
3560  return;
3561 
3562  LOG_SCOPE("alltoall()", "Parallel");
3563 
3564  // the per-processor size. this is the same for all
3565  // processors using MPI_Alltoall, could be variable
3566  // using MPI_Alltoallv
3567  const int size_per_proc =
3568  cast_int<int>(buf.size()/this->size());
3569 
3570  libmesh_assert_equal_to (buf.size()%this->size(), 0);
3571 
3572  libmesh_assert(this->verify(size_per_proc));
3573 
3574  std::vector<T> tmp(buf);
3575 
3576  StandardType<T> send_type(&tmp[0]);
3577 
3578  libmesh_call_mpi
3579  (MPI_Alltoall (&tmp[0], size_per_proc, send_type, &buf[0],
3580  size_per_proc, send_type, this->get()));
3581 }
bool verify(const T &r) const
Verify that a local variable has the same value on all processors.
unsigned int size() const
Definition: parallel.h:726
libmesh_assert(j)
void libMesh::Parallel::Communicator::assign ( const communicator comm)
private

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

Definition at line 721 of file parallel_implementation.h.

References _communicator, _rank, _send_mode, _size, and DEFAULT.

Referenced by Communicator(), duplicate(), operator=(), and split().

722 {
723  _communicator = comm;
724 #ifdef LIBMESH_HAVE_MPI
725  if (_communicator != MPI_COMM_NULL)
726  {
727  int i;
728  libmesh_call_mpi
729  (MPI_Comm_size(_communicator, &i));
730 
731  libmesh_assert_greater_equal (i, 0);
732  _size = static_cast<unsigned int>(i);
733 
734  libmesh_call_mpi
735  (MPI_Comm_rank(_communicator, &i));
736 
737  libmesh_assert_greater_equal (i, 0);
738  _rank = static_cast<unsigned int>(i);
739  }
740  else
741  {
742  _rank = 0;
743  _size = 1;
744  }
745 #endif
747 }
void libMesh::Parallel::Communicator::barrier ( ) const

Pause execution until all processors reach a certain point.

Definition at line 1008 of file parallel_implementation.h.

Referenced by libMesh::RBEvaluation::read_in_vectors_from_multiple_files(), ParallelTest::testBarrier(), CheckpointIOTest::testSplitter(), WriteVecAndScalar::testWrite(), libMesh::NameBasedIO::write(), libMesh::XdrIO::write(), libMesh::RBEvaluation::write_out_vectors(), libMesh::TransientRBConstruction::write_riesz_representors_to_files(), and libMesh::RBConstruction::write_riesz_representors_to_files().

1009 {
1010  if (this->size() > 1)
1011  {
1012  LOG_SCOPE("barrier()", "Parallel");
1013  libmesh_call_mpi(MPI_Barrier (this->get()));
1014  }
1015 }
unsigned int size() const
Definition: parallel.h:726
template<typename T >
void libMesh::Parallel::Communicator::broadcast ( T &  data,
const unsigned int  root_id = 0 
) const

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 vector, the user is responsible for resizing it on all processors, except in the case when data is a vector of strings.

Definition at line 3586 of file parallel_implementation.h.

References libMesh::libmesh_assert().

Referenced by libMesh::EquationSystems::_read_impl(), libMesh::MeshCommunication::broadcast(), broadcast(), libMesh::RBEIMConstruction::enrich_RB_space(), libMesh::RBEIMConstruction::evaluate_mesh_function(), libMesh::RBConstructionBase< Base >::generate_training_parameters_random(), libMesh::RBConstructionBase< Base >::get_global_max_error_pair(), main(), libMesh::MetisPartitioner::partition_range(), libMesh::System::point_gradient(), libMesh::System::point_hessian(), libMesh::System::point_value(), libMesh::CheckpointIO::read(), libMesh::XdrIO::read(), libMesh::CheckpointIO::read_header(), libMesh::XdrIO::read_header(), libMesh::XdrIO::read_serialized_bc_names(), libMesh::XdrIO::read_serialized_bcs_helper(), libMesh::XdrIO::read_serialized_connectivity(), libMesh::XdrIO::read_serialized_nodes(), libMesh::XdrIO::read_serialized_nodesets(), libMesh::XdrIO::read_serialized_subdomain_names(), ParallelTest::testBroadcast(), ParallelPointTest::testBroadcastPoint(), ParallelPointTest::testBroadcastVectorValue(), and libMesh::NameBasedIO::write().

3587 {
3588  if (this->size() == 1)
3589  {
3590  libmesh_assert (!this->rank());
3591  libmesh_assert (!root_id);
3592  return;
3593  }
3594 
3595  libmesh_assert_less (root_id, this->size());
3596 
3597  LOG_SCOPE("broadcast()", "Parallel");
3598 
3599  // Spread data to remote processors.
3600  libmesh_call_mpi
3601  (MPI_Bcast (&data, 1, StandardType<T>(&data), root_id,
3602  this->get()));
3603 }
unsigned int size() const
Definition: parallel.h:726
libmesh_assert(j)
unsigned int rank() const
Definition: parallel.h:724
IterBase * data
Ideally this private member data should have protected access.
template<>
void libMesh::Parallel::Communicator::broadcast ( bool &  data,
const unsigned int  root_id 
) const

Definition at line 3607 of file parallel_implementation.h.

References data, and libMesh::libmesh_assert().

3608 {
3609  if (this->size() == 1)
3610  {
3611  libmesh_assert (!this->rank());
3612  libmesh_assert (!root_id);
3613  return;
3614  }
3615 
3616  libmesh_assert_less (root_id, this->size());
3617 
3618  LOG_SCOPE("broadcast()", "Parallel");
3619 
3620  // We don't want to depend on MPI-2 or C++ MPI, so we don't have
3621  // MPI::BOOL available
3622  char char_data = data;
3623 
3624  // Spread data to remote processors.
3625  libmesh_call_mpi
3626  (MPI_Bcast (&char_data, 1, StandardType<char>(&char_data),
3627  root_id, this->get()));
3628 
3629  data = char_data;
3630 }
unsigned int size() const
Definition: parallel.h:726
libmesh_assert(j)
unsigned int rank() const
Definition: parallel.h:724
IterBase * data
Ideally this private member data should have protected access.
template<typename T >
void libMesh::Parallel::Communicator::broadcast ( std::basic_string< T > &  data,
const unsigned int  root_id 
) const

Definition at line 3634 of file parallel_implementation.h.

References libMesh::Parallel::broadcast(), and libMesh::libmesh_assert().

3636 {
3637  if (this->size() == 1)
3638  {
3639  libmesh_assert (!this->rank());
3640  libmesh_assert (!root_id);
3641  return;
3642  }
3643 
3644  libmesh_assert_less (root_id, this->size());
3645 
3646  LOG_SCOPE("broadcast()", "Parallel");
3647 
3648  std::size_t data_size = data.size();
3649  this->broadcast(data_size, root_id);
3650 
3651  std::vector<T> data_c(data_size);
3652 #ifndef NDEBUG
3653  std::string orig(data);
3654 #endif
3655 
3656  if (this->rank() == root_id)
3657  for (std::size_t i=0; i<data.size(); i++)
3658  data_c[i] = data[i];
3659 
3660  this->broadcast (data_c, root_id);
3661 
3662  data.assign(data_c.begin(), data_c.end());
3663 
3664 #ifndef NDEBUG
3665  if (this->rank() == root_id)
3666  libmesh_assert_equal_to (data, orig);
3667 #endif
3668 }
unsigned int size() const
Definition: parallel.h:726
libmesh_assert(j)
void broadcast(T &data, const unsigned int root_id=0) const
Take a local value and broadcast it to all processors.
unsigned int rank() const
Definition: parallel.h:724
IterBase * data
Ideally this private member data should have protected access.
template<typename T >
void libMesh::Parallel::Communicator::broadcast ( std::vector< T > &  data,
const unsigned int  root_id 
) const

Definition at line 3673 of file parallel_implementation.h.

References libMesh::libmesh_assert(), and libmesh_nullptr.

3675 {
3676  if (this->size() == 1)
3677  {
3678  libmesh_assert (!this->rank());
3679  libmesh_assert (!root_id);
3680  return;
3681  }
3682 
3683  libmesh_assert_less (root_id, this->size());
3684 
3685  LOG_SCOPE("broadcast()", "Parallel");
3686 
3687  // and get the data from the remote processors.
3688  // Pass NULL if our vector is empty.
3689  T * data_ptr = data.empty() ? libmesh_nullptr : &data[0];
3690 
3691  libmesh_call_mpi
3692  (MPI_Bcast (data_ptr, cast_int<int>(data.size()),
3693  StandardType<T>(data_ptr), root_id, this->get()));
3694 }
unsigned int size() const
Definition: parallel.h:726
const class libmesh_nullptr_t libmesh_nullptr
libmesh_assert(j)
unsigned int rank() const
Definition: parallel.h:724
IterBase * data
Ideally this private member data should have protected access.
template<typename T >
void libMesh::Parallel::Communicator::broadcast ( std::vector< std::basic_string< T >> &  data,
const unsigned int  root_id 
) const

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

Definition at line 3698 of file parallel_implementation.h.

References libMesh::Parallel::broadcast(), and libMesh::libmesh_assert().

3700 {
3701  if (this->size() == 1)
3702  {
3703  libmesh_assert (!this->rank());
3704  libmesh_assert (!root_id);
3705  return;
3706  }
3707 
3708  libmesh_assert_less (root_id, this->size());
3709 
3710  LOG_SCOPE("broadcast()", "Parallel");
3711 
3712  std::size_t bufsize=0;
3713  if (root_id == this->rank())
3714  {
3715  for (std::size_t i=0; i<data.size(); ++i)
3716  bufsize += data[i].size() + 1; // Add one for the string length word
3717  }
3718  this->broadcast(bufsize, root_id);
3719 
3720  // Here we use unsigned int to store up to 32-bit characters
3721  std::vector<unsigned int> temp; temp.reserve(bufsize);
3722  // Pack the strings
3723  if (root_id == this->rank())
3724  {
3725  for (std::size_t i=0; i<data.size(); ++i)
3726  {
3727  temp.push_back(cast_int<unsigned int>(data[i].size()));
3728  for (std::size_t j=0; j != data[i].size(); ++j)
3733  temp.push_back(data[i][j]);
3734  }
3735  }
3736  else
3737  temp.resize(bufsize);
3738 
3739  // broad cast the packed strings
3740  this->broadcast(temp, root_id);
3741 
3742  // Unpack the strings
3743  if (root_id != this->rank())
3744  {
3745  data.clear();
3746  std::vector<unsigned int>::const_iterator iter = temp.begin();
3747  while (iter != temp.end())
3748  {
3749  std::size_t curr_len = *iter++;
3750  data.push_back(std::string(iter, iter+curr_len));
3751  iter += curr_len;
3752  }
3753  }
3754 }
unsigned int size() const
Definition: parallel.h:726
libmesh_assert(j)
void broadcast(T &data, const unsigned int root_id=0) const
Take a local value and broadcast it to all processors.
unsigned int rank() const
Definition: parallel.h:724
IterBase * data
Ideally this private member data should have protected access.
template<typename T >
void libMesh::Parallel::Communicator::broadcast ( std::set< T > &  data,
const unsigned int  root_id 
) const

Definition at line 3760 of file parallel_implementation.h.

References libMesh::Parallel::broadcast(), broadcast(), and libMesh::libmesh_assert().

3762 {
3763  if (this->size() == 1)
3764  {
3765  libmesh_assert (!this->rank());
3766  libmesh_assert (!root_id);
3767  return;
3768  }
3769 
3770  libmesh_assert_less (root_id, this->size());
3771 
3772  LOG_SCOPE("broadcast()", "Parallel");
3773 
3774  std::vector<T> vecdata;
3775  if (this->rank() == root_id)
3776  vecdata.assign(data.begin(), data.end());
3777 
3778  std::size_t vecsize = vecdata.size();
3779  this->broadcast(vecsize, root_id);
3780  if (this->rank() != root_id)
3781  vecdata.resize(vecsize);
3782 
3783  this->broadcast(vecdata, root_id);
3784  if (this->rank() != root_id)
3785  {
3786  data.clear();
3787  data.insert(vecdata.begin(), vecdata.end());
3788  }
3789 }
unsigned int size() const
Definition: parallel.h:726
libmesh_assert(j)
void broadcast(T &data, const unsigned int root_id=0) const
Take a local value and broadcast it to all processors.
unsigned int rank() const
Definition: parallel.h:724
IterBase * data
Ideally this private member data should have protected access.
template<typename T >
void libMesh::Parallel::Communicator::broadcast ( T &  ,
const unsigned int   libmesh_dbg_varroot_id 
) const

Definition at line 4184 of file parallel_implementation.h.

4186 { libmesh_assert_equal_to(root_id, 0); }
template<typename Context , typename OutputContext , typename Iter , typename OutputIter >
void libMesh::Parallel::Communicator::broadcast_packed_range ( const Context *  context1,
Iter  range_begin,
const Iter  range_end,
OutputContext *  context2,
OutputIter  out,
const unsigned int  root_id = 0 
) const

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 Parallel::pack(const T *, vector<int> & data, const Context *) is used to serialize type T onto the end of a data vector.

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

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

Definition at line 3846 of file parallel_implementation.h.

References libMesh::Parallel::broadcast(), libmesh_nullptr, max(), maxloc(), min(), minloc(), libMesh::Parallel::pack_range(), semiverify(), sum(), libMesh::Parallel::unpack_range(), and verify().

Referenced by libMesh::MeshCommunication::broadcast().

3852 {
3853  typedef typename std::iterator_traits<Iter>::value_type T;
3854  typedef typename Parallel::Packing<T>::buffer_type buffer_t;
3855 
3856  do
3857  {
3858  // We will serialize variable size objects from *range_begin to
3859  // *range_end as a sequence of ints in this buffer
3860  std::vector<buffer_t> buffer;
3861 
3862  if (this->rank() == root_id)
3863  range_begin = Parallel::pack_range
3864  (context1, range_begin, range_end, buffer);
3865 
3866  // this->broadcast(vector) requires the receiving vectors to
3867  // already be the appropriate size
3868  std::size_t buffer_size = buffer.size();
3869  this->broadcast (buffer_size, root_id);
3870 
3871  // We continue until there's nothing left to broadcast
3872  if (!buffer_size)
3873  break;
3874 
3875  buffer.resize(buffer_size);
3876 
3877  // Broadcast the packed data
3878  this->broadcast (buffer, root_id);
3879 
3880  if (this->rank() != root_id)
3882  (buffer, context2, out_iter, (T*)libmesh_nullptr);
3883  } while (true); // break above when we reach buffer_size==0
3884 }
Iter pack_range(const Context *context, Iter range_begin, const Iter range_end, typename std::vector< buffertype > &buffer, std::size_t approx_buffer_size=1000000)
Encode a range of potentially-variable-size objects to a data array.
const class libmesh_nullptr_t libmesh_nullptr
void broadcast(T &data, const unsigned int root_id=0) const
Take a local value and broadcast it to all processors.
unsigned int rank() const
Definition: parallel.h:724
void unpack_range(const typename std::vector< buffertype > &buffer, Context *context, OutputIter out, const T *output_type)
Decode a range of potentially-variable-size objects from a data array.
void libMesh::Parallel::Communicator::clear ( )

Free and reset this communicator.

Definition at line 686 of file parallel_implementation.h.

References _communicator, _I_duped_it, and libMesh::libmesh_assert().

Referenced by operator=(), split(), and ~Communicator().

686  {
687 #ifdef LIBMESH_HAVE_MPI
688  if (_I_duped_it)
689  {
690  libmesh_assert (_communicator != MPI_COMM_NULL);
691  libmesh_call_mpi
692  (MPI_Comm_free(&_communicator));
693 
694  _communicator = MPI_COMM_NULL;
695  }
696  _I_duped_it = false;
697 #endif
698 }
libmesh_assert(j)
void libMesh::Parallel::Communicator::dereference_unique_tag ( int  tagvalue) const

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

Definition at line 1382 of file parallel_implementation.h.

References libMesh::libmesh_assert().

1383 {
1384  // This had better be an already-acquired tag.
1385  libmesh_assert(used_tag_values.count(tagvalue));
1386 
1387  used_tag_values[tagvalue]--;
1388  // If we don't have any more outstanding references, we
1389  // don't even need to keep this tag in our "used" set.
1390  if (!used_tag_values[tagvalue])
1391  used_tag_values.erase(tagvalue);
1392 }
libmesh_assert(j)
std::map< int, unsigned int > used_tag_values
Definition: parallel.h:752
void libMesh::Parallel::Communicator::duplicate ( const Communicator comm)

Definition at line 664 of file parallel_implementation.h.

References _communicator, and send_mode().

Referenced by duplicate().

665 {
666  this->duplicate(comm._communicator);
667  this->send_mode(comm.send_mode());
668 }
void duplicate(const Communicator &comm)
SendMode send_mode() const
Gets the user-requested SendMode.
Definition: parallel.h:766
void libMesh::Parallel::Communicator::duplicate ( const communicator comm)

Definition at line 671 of file parallel_implementation.h.

References _communicator, _I_duped_it, assign(), and duplicate().

672 {
673  if (_communicator != MPI_COMM_NULL)
674  {
675  libmesh_call_mpi
676  (MPI_Comm_dup(comm, &_communicator));
677 
678  _I_duped_it = true;
679  }
680  this->assign(_communicator);
681 }
void assign(const communicator &comm)
Utility function for setting our member variables from an MPI communicator.
template<typename T >
void libMesh::Parallel::Communicator::gather ( const unsigned int  root_id,
const T &  send,
std::vector< T > &  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.

Definition at line 3016 of file parallel_implementation.h.

References libmesh_nullptr.

Referenced by gather(), ParallelTest::testAllGatherString(), ParallelTest::testGather(), ParallelTest::testGatherString(), libMesh::XdrIO::write_serialized_bcs_helper(), libMesh::XdrIO::write_serialized_connectivity(), libMesh::XdrIO::write_serialized_nodes(), and libMesh::XdrIO::write_serialized_nodesets().

3019 {
3020  libmesh_assert_less (root_id, this->size());
3021 
3022  if (this->rank() == root_id)
3023  recv.resize(this->size());
3024 
3025  if (this->size() > 1)
3026  {
3027  LOG_SCOPE("gather()", "Parallel");
3028 
3029  StandardType<T> send_type(&sendval);
3030 
3031  libmesh_call_mpi
3032  (MPI_Gather(const_cast<T*>(&sendval), 1, send_type,
3033  recv.empty() ? libmesh_nullptr : &recv[0], 1, send_type,
3034  root_id, this->get()));
3035  }
3036  else
3037  recv[0] = sendval;
3038 }
unsigned int size() const
Definition: parallel.h:726
const class libmesh_nullptr_t libmesh_nullptr
unsigned int rank() const
Definition: parallel.h:724
template<typename T >
void libMesh::Parallel::Communicator::gather ( const unsigned int  root_id,
const std::basic_string< T > &  send,
std::vector< std::basic_string< T >> &  recv,
const bool  identical_buffer_sizes = false 
) const

Gather overload for string types.

Definition at line 3043 of file parallel_implementation.h.

References libMesh::Parallel::gather(), and libmesh_nullptr.

3047 {
3048  libmesh_assert_less (root_id, this->size());
3049 
3050  if (this->rank() == root_id)
3051  recv.resize(this->size());
3052 
3053  if (this->size() > 1)
3054  {
3055  LOG_SCOPE ("gather()","Parallel");
3056 
3057  std::vector<int>
3058  sendlengths (this->size(), 0),
3059  displacements(this->size(), 0);
3060 
3061  const int mysize = static_cast<int>(sendval.size());
3062 
3063  if (identical_buffer_sizes)
3064  sendlengths.assign(this->size(), mysize);
3065  else
3066  // first comm step to determine buffer sizes from all processors
3067  this->gather(root_id, mysize, sendlengths);
3068 
3069  // Find the total size of the final array and
3070  // set up the displacement offsets for each processor
3071  unsigned int globalsize = 0;
3072  for (unsigned int i=0; i < this->size(); ++i)
3073  {
3074  displacements[i] = globalsize;
3075  globalsize += sendlengths[i];
3076  }
3077 
3078  // monolithic receive buffer
3079  std::string r;
3080  if (this->rank() == root_id)
3081  r.resize(globalsize, 0);
3082 
3083  // and get the data from the remote processors.
3084  libmesh_call_mpi
3085  (MPI_Gatherv (const_cast<T*>(&sendval[0]),
3086  mysize, StandardType<T>(),
3087  this->rank() == root_id ? &r[0] : libmesh_nullptr,
3088  &sendlengths[0], &displacements[0],
3089  StandardType<T>(), root_id, this->get()));
3090 
3091  // slice receive buffer up
3092  if (this->rank() == root_id)
3093  for (unsigned int i=0; i != this->size(); ++i)
3094  recv[i] = r.substr(displacements[i], sendlengths[i]);
3095  }
3096  else
3097  recv[0] = sendval;
3098 }
unsigned int size() const
Definition: parallel.h:726
const class libmesh_nullptr_t libmesh_nullptr
void gather(const unsigned int root_id, const T &send, std::vector< T > &recv) const
Take a vector of length comm.size(), and on processor root_id fill in recv[processor_id] = the value ...
unsigned int rank() const
Definition: parallel.h:724
template<typename T >
void libMesh::Parallel::Communicator::gather ( const unsigned int  root_id,
std::vector< T > &  r 
) const

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.

Definition at line 3103 of file parallel_implementation.h.

References libMesh::Parallel::allgather(), libMesh::libmesh_assert(), and libmesh_nullptr.

3105 {
3106  if (this->size() == 1)
3107  {
3108  libmesh_assert (!this->rank());
3109  libmesh_assert (!root_id);
3110  return;
3111  }
3112 
3113  libmesh_assert_less (root_id, this->size());
3114 
3115  std::vector<int>
3116  sendlengths (this->size(), 0),
3117  displacements(this->size(), 0);
3118 
3119  const int mysize = static_cast<int>(r.size());
3120  this->allgather(mysize, sendlengths);
3121 
3122  LOG_SCOPE("gather()", "Parallel");
3123 
3124  // Find the total size of the final array and
3125  // set up the displacement offsets for each processor.
3126  unsigned int globalsize = 0;
3127  for (unsigned int i=0; i != this->size(); ++i)
3128  {
3129  displacements[i] = globalsize;
3130  globalsize += sendlengths[i];
3131  }
3132 
3133  // Check for quick return
3134  if (globalsize == 0)
3135  return;
3136 
3137  // copy the input buffer
3138  std::vector<T> r_src(r);
3139 
3140  // now resize it to hold the global data
3141  // on the receiving processor
3142  if (root_id == this->rank())
3143  r.resize(globalsize);
3144 
3145  // and get the data from the remote processors
3146  libmesh_call_mpi
3147  (MPI_Gatherv (r_src.empty() ? libmesh_nullptr : &r_src[0], mysize,
3148  StandardType<T>(), r.empty() ? libmesh_nullptr : &r[0],
3149  &sendlengths[0], &displacements[0],
3150  StandardType<T>(), root_id, this->get()));
3151 }
unsigned int size() const
Definition: parallel.h:726
const class libmesh_nullptr_t libmesh_nullptr
libmesh_assert(j)
unsigned int rank() const
Definition: parallel.h:724
void allgather(const T &send, std::vector< T > &recv) const
Take a vector of length this->size(), and fill in recv[processor_id] = the value of send on that proc...
template<typename T >
void libMesh::Parallel::Communicator::gather ( const unsigned int   libmesh_dbg_varroot_id,
const T &  send_val,
std::vector< T > &  recv_val 
) const

Gather-to-root on one processor.

Definition at line 4094 of file parallel_implementation.h.

4097 {
4098  libmesh_assert_equal_to (root_id, 0);
4099  recv_val.resize(1);
4100  recv_val[0] = send_val;
4101 }
template<typename T >
void libMesh::Parallel::Communicator::gather ( const unsigned int   libmesh_dbg_varroot_id,
const std::basic_string< T > &  sendval,
std::vector< std::basic_string< T >> &  recv,
const bool   
) const

Definition at line 4104 of file parallel_implementation.h.

References allgather(), and gather().

4108 {
4109  libmesh_assert_equal_to (root_id, 0);
4110  recv.resize(1);
4111  recv[0] = sendval;
4112 }
template<typename Context , typename Iter , typename OutputIter >
void libMesh::Parallel::Communicator::gather_packed_range ( const unsigned int  root_id,
Context *  context,
Iter  range_begin,
const Iter  range_end,
OutputIter  out 
) 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.

Definition at line 4195 of file parallel_implementation.h.

References libMesh::Parallel::gather(), libmesh_nullptr, libMesh::Parallel::max(), libMesh::Parallel::pack_range(), and libMesh::Parallel::unpack_range().

Referenced by libMesh::MeshCommunication::gather().

4200 {
4201  typedef typename std::iterator_traits<Iter>::value_type T;
4202  typedef typename Parallel::Packing<T>::buffer_type buffer_t;
4203 
4204  bool nonempty_range = (range_begin != range_end);
4205  this->max(nonempty_range);
4206 
4207  while (nonempty_range)
4208  {
4209  // We will serialize variable size objects from *range_begin to
4210  // *range_end as a sequence of ints in this buffer
4211  std::vector<buffer_t> buffer;
4212 
4213  range_begin = Parallel::pack_range
4214  (context, range_begin, range_end, buffer);
4215 
4216  this->gather(root_id, buffer);
4217 
4219  (buffer, context, out_iter, (T*)(libmesh_nullptr));
4220 
4221  nonempty_range = (range_begin != range_end);
4222  this->max(nonempty_range);
4223  }
4224 }
Iter pack_range(const Context *context, Iter range_begin, const Iter range_end, typename std::vector< buffertype > &buffer, std::size_t approx_buffer_size=1000000)
Encode a range of potentially-variable-size objects to a data array.
void max(T &r) const
Take a local variable and replace it with the maximum of it&#39;s values on all processors.
const class libmesh_nullptr_t libmesh_nullptr
void gather(const unsigned int root_id, const T &send, std::vector< T > &recv) const
Take a vector of length comm.size(), and on processor root_id fill in recv[processor_id] = the value ...
void unpack_range(const typename std::vector< buffertype > &buffer, Context *context, OutputIter out, const T *output_type)
Decode a range of potentially-variable-size objects from a data array.
communicator& libMesh::Parallel::Communicator::get ( )
const communicator& libMesh::Parallel::Communicator::get ( ) const

Definition at line 694 of file parallel.h.

References operator=().

694 { return _communicator; }
MessageTag libMesh::Parallel::Communicator::get_unique_tag ( int  tagvalue) const

Get a tag that is unique to this Communicator.

Note
If people are also using magic numbers or copying communicators around then we can't guarantee the tag is unique to this MPI_Comm.

Definition at line 1348 of file parallel_implementation.h.

References libMesh::libmesh_assert(), and libMesh::Parallel::MessageTag::MessageTag().

Referenced by libMesh::BoundaryInfo::build_node_list_from_side_list(), libMesh::MeshCommunication::gather_neighboring_elements(), libMesh::MeshRefinement::make_coarsening_compatible(), libMesh::Nemesis_IO::read(), libMesh::MeshCommunication::redistribute(), libMesh::MeshCommunication::send_coarse_ghosts(), libMesh::MeshRefinement::uniformly_coarsen(), and libMesh::XdrIO::write_serialized_nodes().

1349 {
1350  if (used_tag_values.count(tagvalue))
1351  {
1352  // Get the largest value in the used values, and pick one
1353  // larger
1354  tagvalue = used_tag_values.rbegin()->first+1;
1355  libmesh_assert(!used_tag_values.count(tagvalue));
1356  }
1357  used_tag_values[tagvalue] = 1;
1358 
1359  // #ifndef NDEBUG
1360  // // Make sure everyone called get_unique_tag and make sure
1361  // // everyone got the same value
1362  // int maxval = tagvalue;
1363  // this->max(maxval);
1364  // libmesh_assert_equal_to (tagvalue, maxval);
1365  // #endif
1366 
1367  return MessageTag(tagvalue, this);
1368 }
libmesh_assert(j)
std::map< int, unsigned int > used_tag_values
Definition: parallel.h:752
template<typename T >
void libMesh::Parallel::Communicator::max ( T &  r) const

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

Containers are replaced element-wise.

Definition at line 1776 of file parallel_implementation.h.

Referenced by libMesh::MeshRefinement::_coarsen_elements(), libMesh::MeshRefinement::_refine_elements(), libMesh::UnstructuredMesh::all_second_order(), libMesh::MeshTools::Modification::all_tri(), libMesh::DofMap::attach_matrix(), libMesh::Parallel::Sort< KeyType, IdxType >::binsort(), broadcast_packed_range(), libMesh::MeshTools::Generation::build_extrusion(), libMesh::System::calculate_norm(), libMesh::DofMap::check_dirichlet_bcid_consistency(), libMesh::MeshTools::create_bounding_box(), libMesh::MeshTools::create_nodal_bounding_box(), libMesh::MeshTools::create_processor_bounding_box(), libMesh::MeshTools::create_subdomain_bounding_box(), libMesh::MeshRefinement::eliminate_unrefined_patches(), libMesh::RBEIMConstruction::evaluate_mesh_function(), libMesh::MeshRefinement::flag_elements_by_error_fraction(), libMesh::MeshRefinement::flag_elements_by_nelem_target(), libMesh::DofMap::get_info(), libMesh::LocationMap< T >::init(), libMesh::MeshTools::libmesh_assert_parallel_consistent_procids< Elem >(), libMesh::MeshTools::libmesh_assert_parallel_consistent_procids< Node >(), libMesh::MeshTools::libmesh_assert_topology_consistent_procids< Node >(), libMesh::MeshTools::libmesh_assert_valid_boundary_ids(), libMesh::MeshTools::libmesh_assert_valid_dof_ids(), libMesh::MeshTools::libmesh_assert_valid_neighbors(), libMesh::MeshTools::libmesh_assert_valid_refinement_flags(), libMesh::MeshTools::libmesh_assert_valid_unique_ids(), libMesh::MeshRefinement::limit_level_mismatch_at_edge(), libMesh::MeshRefinement::limit_level_mismatch_at_node(), libMesh::MeshRefinement::limit_overrefined_boundary(), libMesh::MeshRefinement::limit_underrefined_boundary(), max(), libMesh::MeshTools::n_active_levels(), libMesh::MeshTools::n_levels(), libMesh::MeshTools::n_p_levels(), libMesh::DistributedMesh::parallel_max_elem_id(), libMesh::DistributedMesh::parallel_max_node_id(), libMesh::ReplicatedMesh::parallel_max_unique_id(), libMesh::DistributedMesh::parallel_max_unique_id(), libMesh::MeshTools::paranoid_n_levels(), libMesh::Nemesis_IO::read(), libMesh::MeshBase::recalculate_n_partitions(), libMesh::MeshRefinement::refine_and_coarsen_elements(), libMesh::Parallel::sync_dofobject_data_by_xyz(), libMesh::MeshRefinement::test_level_one(), libMesh::MeshRefinement::test_unflagged(), ParallelTest::testInfinityMax(), PointLocatorTest::testLocator(), ParallelTest::testMax(), and BoundaryInfoTest::testMesh().

1777 {
1778  if (this->size() > 1)
1779  {
1780  LOG_SCOPE("max(scalar)", "Parallel");
1781 
1782  T temp;
1783  libmesh_call_mpi
1784  (MPI_Allreduce (&r, &temp, 1, StandardType<T>(&r),
1786  this->get()));
1787  r = temp;
1788  }
1789 }
unsigned int size() const
Definition: parallel.h:726
void max(T &r, const Communicator &comm=Communicator_World)
template<typename T >
void libMesh::Parallel::Communicator::max ( std::vector< T > &  r) const

Definition at line 1811 of file parallel_implementation.h.

References libMesh::libmesh_assert(), max(), libMesh::Parallel::max(), and libMesh::Parallel::verify().

1812 {
1813  if (this->size() > 1 && !r.empty())
1814  {
1815  LOG_SCOPE("max(vector)", "Parallel");
1816 
1817  libmesh_assert(this->verify(r.size()));
1818 
1819  std::vector<T> temp(r);
1820  libmesh_call_mpi
1821  (MPI_Allreduce (&temp[0], &r[0], cast_int<int>(r.size()),
1822  StandardType<T>(&temp[0]),
1824  this->get()));
1825  }
1826 }
bool verify(const T &r) const
Verify that a local variable has the same value on all processors.
unsigned int size() const
Definition: parallel.h:726
libmesh_assert(j)
void max(T &r, const Communicator &comm=Communicator_World)
template<typename T >
void libMesh::Parallel::Communicator::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.

Definition at line 1851 of file parallel_implementation.h.

References libMesh::Parallel::dataplusint_type< int >(), libMesh::Parallel::DataPlusInt< T >::rank, and libMesh::Parallel::DataPlusInt< T >::val.

Referenced by broadcast_packed_range(), libMesh::RBEIMConstruction::enrich_RB_space(), libMesh::RBConstructionBase< Base >::get_global_max_error_pair(), and maxloc().

1853 {
1854  if (this->size() > 1)
1855  {
1856  LOG_SCOPE("maxloc(scalar)", "Parallel");
1857 
1858  DataPlusInt<T> data_in;
1859  data_in.val = r;
1860  data_in.rank = this->rank();
1861  DataPlusInt<T> data_out;
1862  libmesh_call_mpi
1863  (MPI_Allreduce (&data_in, &data_out, 1,
1864  dataplusint_type<T>(),
1865  OpFunction<T>::max_location(),
1866  this->get()));
1867  r = data_out.val;
1868  max_id = data_out.rank;
1869  }
1870  else
1871  max_id = this->rank();
1872 }
unsigned int size() const
Definition: parallel.h:726
unsigned int rank() const
Definition: parallel.h:724
template<typename T >
void libMesh::Parallel::Communicator::maxloc ( std::vector< T > &  r,
std::vector< unsigned int > &  max_id 
) const

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 1900 of file parallel_implementation.h.

References libMesh::libmesh_assert(), maxloc(), and libMesh::Parallel::verify().

1902 {
1903  if (this->size() > 1 && !r.empty())
1904  {
1905  LOG_SCOPE("maxloc(vector)", "Parallel");
1906 
1907  libmesh_assert(this->verify(r.size()));
1908 
1909  std::vector<DataPlusInt<T>> data_in(r.size());
1910  for (std::size_t i=0; i != r.size(); ++i)
1911  {
1912  data_in[i].val = r[i];
1913  data_in[i].rank = this->rank();
1914  }
1915  std::vector<DataPlusInt<T>> data_out(r.size());
1916  libmesh_call_mpi
1917  (MPI_Allreduce (&data_in[0], &data_out[0],
1918  cast_int<int>(r.size()),
1919  dataplusint_type<T>(),
1920  OpFunction<T>::max_location(),
1921  this->get()));
1922  for (std::size_t i=0; i != r.size(); ++i)
1923  {
1924  r[i] = data_out[i].val;
1925  max_id[i] = data_out[i].rank;
1926  }
1927  }
1928  else if (!r.empty())
1929  {
1930  for (std::size_t i=0; i != r.size(); ++i)
1931  max_id[i] = this->rank();
1932  }
1933 }
bool verify(const T &r) const
Verify that a local variable has the same value on all processors.
unsigned int size() const
Definition: parallel.h:726
libmesh_assert(j)
unsigned int rank() const
Definition: parallel.h:724
template<typename T >
void libMesh::Parallel::Communicator::min ( T &  r) const

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

Containers are replaced element-wise.

Definition at line 1584 of file parallel_implementation.h.

Referenced by broadcast_packed_range(), libMesh::MeshTools::create_bounding_box(), libMesh::MeshTools::create_nodal_bounding_box(), libMesh::MeshRefinement::create_parent_error_vector(), libMesh::MeshTools::create_processor_bounding_box(), libMesh::MeshTools::create_subdomain_bounding_box(), libMesh::MeshRefinement::flag_elements_by_error_fraction(), libMesh::LocationMap< T >::init(), libMesh::MeshTools::libmesh_assert_parallel_consistent_procids< Elem >(), libMesh::MeshTools::libmesh_assert_parallel_consistent_procids< Node >(), libMesh::DistributedMesh::libmesh_assert_valid_parallel_object_ids(), libMesh::MeshTools::libmesh_assert_valid_refinement_flags(), libMesh::MeshRefinement::make_coarsening_compatible(), libMesh::MeshRefinement::make_flags_parallel_consistent(), libMesh::MeshRefinement::make_refinement_compatible(), min(), libMesh::System::point_gradient(), libMesh::System::point_hessian(), libMesh::System::point_value(), libMesh::Partitioner::set_parent_processor_ids(), ParallelTest::testInfinityMin(), and ParallelTest::testMin().

1585 {
1586  if (this->size() > 1)
1587  {
1588  LOG_SCOPE("min(scalar)", "Parallel");
1589 
1590  T temp = r;
1591  libmesh_call_mpi
1592  (MPI_Allreduce (&temp, &r, 1, StandardType<T>(&temp),
1594  this->get()));
1595  }
1596 }
unsigned int size() const
Definition: parallel.h:726
void min(T &r, const Communicator &comm=Communicator_World)
template<typename T >
void libMesh::Parallel::Communicator::min ( std::vector< T > &  r) const

Definition at line 1619 of file parallel_implementation.h.

References libMesh::libmesh_assert(), min(), libMesh::Parallel::min(), and libMesh::Parallel::verify().

1620 {
1621  if (this->size() > 1 && !r.empty())
1622  {
1623  LOG_SCOPE("min(vector)", "Parallel");
1624 
1625  libmesh_assert(this->verify(r.size()));
1626 
1627  std::vector<T> temp(r);
1628  libmesh_call_mpi
1629  (MPI_Allreduce (&temp[0], &r[0], cast_int<int>(r.size()),
1630  StandardType<T>(&temp[0]),
1632  this->get()));
1633  }
1634 }
bool verify(const T &r) const
Verify that a local variable has the same value on all processors.
unsigned int size() const
Definition: parallel.h:726
libmesh_assert(j)
void min(T &r, const Communicator &comm=Communicator_World)
template<typename T >
void libMesh::Parallel::Communicator::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.

Definition at line 1659 of file parallel_implementation.h.

References libMesh::Parallel::dataplusint_type< int >(), libMesh::Parallel::DataPlusInt< T >::rank, and libMesh::Parallel::DataPlusInt< T >::val.

Referenced by broadcast_packed_range(), main(), and minloc().

1661 {
1662  if (this->size() > 1)
1663  {
1664  LOG_SCOPE("minloc(scalar)", "Parallel");
1665 
1666  DataPlusInt<T> data_in;
1667  data_in.val = r;
1668  data_in.rank = this->rank();
1669  DataPlusInt<T> data_out;
1670  libmesh_call_mpi
1671  (MPI_Allreduce (&data_in, &data_out, 1, dataplusint_type<T>(),
1672  OpFunction<T>::max_location(), this->get()));
1673  r = data_out.val;
1674  min_id = data_out.rank;
1675  }
1676  else
1677  min_id = this->rank();
1678 }
unsigned int size() const
Definition: parallel.h:726
unsigned int rank() const
Definition: parallel.h:724
template<typename T >
void libMesh::Parallel::Communicator::minloc ( std::vector< T > &  r,
std::vector< unsigned int > &  min_id 
) const

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 1705 of file parallel_implementation.h.

References libMesh::libmesh_assert(), minloc(), and libMesh::Parallel::verify().

1707 {
1708  if (this->size() > 1 && !r.empty())
1709  {
1710  LOG_SCOPE("minloc(vector)", "Parallel");
1711 
1712  libmesh_assert(this->verify(r.size()));
1713 
1714  std::vector<DataPlusInt<T>> data_in(r.size());
1715  for (std::size_t i=0; i != r.size(); ++i)
1716  {
1717  data_in[i].val = r[i];
1718  data_in[i].rank = this->rank();
1719  }
1720  std::vector<DataPlusInt<T>> data_out(r.size());
1721  libmesh_call_mpi
1722  (MPI_Allreduce (&data_in[0], &data_out[0],
1723  cast_int<int>(r.size()),
1724  dataplusint_type<T>(),
1725  OpFunction<T>::min_location(), this->get()));
1726  for (std::size_t i=0; i != r.size(); ++i)
1727  {
1728  r[i] = data_out[i].val;
1729  min_id[i] = data_out[i].rank;
1730  }
1731  }
1732  else if (!r.empty())
1733  {
1734  for (std::size_t i=0; i != r.size(); ++i)
1735  min_id[i] = this->rank();
1736  }
1737 }
bool verify(const T &r) const
Verify that a local variable has the same value on all processors.
unsigned int size() const
Definition: parallel.h:726
libmesh_assert(j)
unsigned int rank() const
Definition: parallel.h:724
template<typename Context , typename OutputIter , typename T >
void libMesh::Parallel::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

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 2795 of file parallel_implementation.h.

References libMesh::Parallel::Request::add_post_wait_work(), libMesh::Parallel::receive(), and libMesh::Parallel::Status::size().

2802 {
2803  libmesh_experimental();
2804 
2805  typedef typename Parallel::Packing<T>::buffer_type buffer_t;
2806 
2807  // Receive serialized variable size objects as a sequence of
2808  // buffer_t.
2809  // Allocate a buffer on the heap so we don't have to free it until
2810  // after the Request::wait()
2811  std::vector<buffer_t> * buffer = new std::vector<buffer_t>(stat.size());
2812  this->receive(src_processor_id, *buffer, req, tag);
2813 
2814  // Make the Request::wait() handle unpacking the buffer
2815  req.add_post_wait_work
2816  (new Parallel::PostWaitUnpackBuffer<std::vector<buffer_t>, Context, OutputIter, T>(*buffer, context, out));
2817 
2818  // Make the Request::wait() then handle deleting the buffer
2819  req.add_post_wait_work
2820  (new Parallel::PostWaitDeleteBuffer<std::vector<buffer_t>>(buffer));
2821 }
OStreamProxy out
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 Context , typename Iter >
void libMesh::Parallel::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

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 2464 of file parallel_implementation.h.

References libMesh::Parallel::Request::add_post_wait_work(), libMesh::Parallel::max(), libMesh::Parallel::pack_range(), and libMesh::Parallel::send().

2470 {
2471  libmesh_experimental();
2472 
2473  // Allocate a buffer on the heap so we don't have to free it until
2474  // after the Request::wait()
2475  typedef typename std::iterator_traits<Iter>::value_type T;
2476  typedef typename Parallel::Packing<T>::buffer_type buffer_t;
2477 
2478  if (range_begin != range_end)
2479  {
2480  std::vector<buffer_t> * buffer = new std::vector<buffer_t>();
2481 
2482  range_begin =
2483  Parallel::pack_range(context,
2484  range_begin,
2485  range_end,
2486  *buffer,
2487  // MPI-2 can only use integers for size
2489 
2490  if (range_begin != range_end)
2491  libmesh_error_msg("Non-blocking packed range sends cannot exceed " << std::numeric_limits<int>::max() << "in size");
2492 
2493  // Make the Request::wait() handle deleting the buffer
2494  req.add_post_wait_work
2495  (new Parallel::PostWaitDeleteBuffer<std::vector<buffer_t>>
2496  (buffer));
2497 
2498  // Non-blocking send of the buffer
2499  this->send(dest_processor_id, *buffer, req, tag);
2500  }
2501 }
Iter pack_range(const Context *context, Iter range_begin, const Iter range_end, typename std::vector< buffertype > &buffer, std::size_t approx_buffer_size=1000000)
Encode a range of potentially-variable-size objects to a data array.
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.
void max(T &r, const Communicator &comm=Communicator_World)
Communicator & libMesh::Parallel::Communicator::operator= ( const communicator comm)

Definition at line 700 of file parallel_implementation.h.

References assign(), and clear().

701 {
702  this->clear();
703  this->assign(comm);
704  return *this;
705 }
void assign(const communicator &comm)
Utility function for setting our member variables from an MPI communicator.
void clear()
Free and reset this communicator.
template<typename T >
Status libMesh::Parallel::Communicator::packed_range_probe ( const unsigned int  src_processor_id,
const MessageTag tag,
bool &  flag 
) const

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 Parallel::any_source
tagThe message tag or Parallel::any_tag
flagOutput. True if a message exists. False otherwise.

Definition at line 2101 of file parallel_implementation.h.

References libMesh::Parallel::Status::get(), and libMesh::Parallel::MessageTag::value().

2104 {
2105  LOG_SCOPE("packed_range_probe()", "Parallel");
2106 
2107  libmesh_experimental();
2108 
2109  Status stat((StandardType<typename Packing<T>::buffer_type>()));
2110 
2111  int int_flag;
2112 
2113  libmesh_call_mpi(MPI_Iprobe(src_processor_id,
2114  tag.value(),
2115  this->get(),
2116  &int_flag,
2117  stat.get()));
2118 
2119  flag = int_flag;
2120 
2121  return stat;
2122 }
status libMesh::Parallel::Communicator::probe ( const unsigned int  src_processor_id,
const MessageTag tag = any_tag 
) const

Blocking message probe.

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

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

Definition at line 2087 of file parallel_implementation.h.

References libMesh::Parallel::MessageTag::value().

Referenced by libMesh::MeshCommunication::gather_neighboring_elements(), and set_union().

2089 {
2090  LOG_SCOPE("probe()", "Parallel");
2091 
2092  status stat;
2093 
2094  libmesh_call_mpi
2095  (MPI_Probe (src_processor_id, tag.value(), this->get(), &stat));
2096 
2097  return stat;
2098 }
MPI_Status status
Status object for querying messages.
Definition: parallel.h:176
unsigned int libMesh::Parallel::Communicator::rank ( ) const

Definition at line 724 of file parallel.h.

Referenced by libMesh::RBConstruction::add_scaled_matrix_and_vector(), libMesh::ExodusII_IO::copy_elemental_solution(), libMesh::MeshTools::correct_node_proc_ids(), libMesh::MeshCommunication::find_global_indices(), libMesh::RBConstructionBase< Base >::generate_training_parameters_deterministic(), libMesh::RBConstructionBase< Base >::generate_training_parameters_random(), NumericVectorTest< DistributedVector< Number > >::Localize(), main(), libMesh::ParallelObject::processor_id(), LinearElasticityWithContact::residual_and_jacobian(), BoundaryMeshTest::sanityCheck(), ParsedFEMFunctionTest::setUp(), libMesh::Parallel::sync_dofobject_data_by_id(), libMesh::Parallel::sync_dofobject_data_by_xyz(), ParallelTest::testAllGather(), ParallelTest::testAllGatherHalfEmptyVectorString(), ParallelPointTest::testAllGatherPairPointPoint(), ParallelPointTest::testAllGatherPairRealPoint(), ParallelPointTest::testAllGatherPoint(), ParallelTest::testAllGatherString(), ParallelTest::testAllGatherVectorString(), ParallelTest::testBroadcast(), ParallelPointTest::testBroadcastPoint(), ParallelPointTest::testBroadcastVectorValue(), PackedRangeTest::testContainerSendReceive(), ParallelTest::testGather(), ParallelTest::testGatherString(), ParsedFEMFunctionTest::testGradients(), ParsedFEMFunctionTest::testHessians(), ParsedFEMFunctionTest::testInlineGetter(), ParsedFEMFunctionTest::testInlineSetter(), ParallelPointTest::testIrecvSend(), ParallelTest::testIrecvSend(), ParallelPointTest::testIsendRecv(), ParallelTest::testIsendRecv(), ParallelTest::testMax(), ParallelTest::testMin(), ParsedFEMFunctionTest::testNormals(), PackedRangeTest::testNullAllGather(), PackedRangeTest::testNullSendReceive(), ParallelTest::testRecvIsendSets(), ParallelTest::testScatter(), ParallelTest::testSemiVerify(), ParallelTest::testSplit(), ParsedFEMFunctionTest::testValues(), libMesh::RBDataSerialization::RBEvaluationSerialization::write_to_file(), libMesh::RBDataSerialization::TransientRBEvaluationSerialization::write_to_file(), libMesh::RBDataSerialization::RBEIMEvaluationSerialization::write_to_file(), libMesh::RBDataSerialization::RBSCMEvaluationSerialization::write_to_file(), and libMesh::Parallel::StandardType< std::complex< T > >::~StandardType().

724 { return _rank; }
template<typename T >
Status libMesh::Parallel::Communicator::receive ( const unsigned int  dest_processor_id,
T &  buf,
const MessageTag tag = any_tag 
) const

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

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

Definition at line 2549 of file parallel_implementation.h.

References libMesh::Parallel::Status::get(), libMesh::Parallel::probe(), and libMesh::Parallel::MessageTag::value().

Referenced by libMesh::BoundaryInfo::build_node_list_from_side_list(), libMesh::MeshTools::correct_node_proc_ids(), libMesh::MeshCommunication::gather_neighboring_elements(), libMesh::SystemSubsetBySubdomain::init(), libMesh::MeshRefinement::make_coarsening_compatible(), libMesh::SparseMatrix< T >::print(), libMesh::Nemesis_IO::read(), send(), ParallelPointTest::testIrecvSend(), ParallelTest::testIrecvSend(), ParallelPointTest::testIsendRecv(), ParallelTest::testIsendRecv(), ParallelTest::testRecvIsendSets(), libMesh::MeshRefinement::uniformly_coarsen(), libMesh::XdrIO::write_serialized_bcs_helper(), libMesh::XdrIO::write_serialized_connectivity(), libMesh::XdrIO::write_serialized_nodes(), libMesh::XdrIO::write_serialized_nodesets(), and libMesh::Parallel::StandardType< std::complex< T > >::~StandardType().

2552 {
2553  LOG_SCOPE("receive()", "Parallel");
2554 
2555  // Get the status of the message, explicitly provide the
2556  // datatype so we can later query the size
2557  Status stat(this->probe(src_processor_id, tag), StandardType<T>(&buf));
2558 
2559  libmesh_call_mpi
2560  (MPI_Recv (&buf, 1, StandardType<T>(&buf), src_processor_id,
2561  tag.value(), this->get(), stat.get()));
2562 
2563  return stat;
2564 }
status probe(const unsigned int src_processor_id, const MessageTag &tag=any_tag) const
Blocking message probe.
template<typename T >
void libMesh::Parallel::Communicator::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.

Definition at line 2569 of file parallel_implementation.h.

References libMesh::Parallel::Request::get(), and libMesh::Parallel::MessageTag::value().

2573 {
2574  LOG_SCOPE("receive()", "Parallel");
2575 
2576  libmesh_call_mpi
2577  (MPI_Irecv (&buf, 1, StandardType<T>(&buf), src_processor_id,
2578  tag.value(), this->get(), req.get()));
2579 }
template<typename T >
Status libMesh::Parallel::Communicator::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.

Definition at line 3997 of file parallel_implementation.h.

4001 { libmesh_not_implemented(); return Status(); }
template<typename T >
void libMesh::Parallel::Communicator::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.

Definition at line 4004 of file parallel_implementation.h.

References distance(), libMesh::Parallel::pack_range(), receive_packed_range(), send_receive(), send_receive_packed_range(), and libMesh::Parallel::unpack_range().

4009 { libmesh_not_implemented(); }
template<typename T >
Status libMesh::Parallel::Communicator::receive ( const unsigned int  src_processor_id,
std::basic_string< T > &  buf,
const MessageTag tag 
) const

Definition at line 2505 of file parallel_implementation.h.

References libMesh::Parallel::receive().

2508 {
2509  std::vector<T> tempbuf; // Officially C++ won't let us get a
2510  // modifiable array from a string
2511 
2512  Status stat = this->receive(src_processor_id, tempbuf, tag);
2513  buf.assign(tempbuf.begin(), tempbuf.end());
2514  return stat;
2515 }
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 libMesh::Parallel::Communicator::receive ( const unsigned int  src_processor_id,
std::basic_string< T > &  buf,
Request req,
const MessageTag tag 
) const

Definition at line 2520 of file parallel_implementation.h.

References libMesh::Parallel::Request::add_post_wait_work(), and libMesh::Parallel::receive().

2524 {
2525  // Officially C++ won't let us get a modifiable array from a
2526  // string, and we can't even put one on the stack for the
2527  // non-blocking case.
2528  std::vector<T> * tempbuf = new std::vector<T>();
2529 
2530  // We can clear the string, but the Request::wait() will need to
2531  // handle copying our temporary buffer to it
2532  buf.clear();
2533 
2534  req.add_post_wait_work
2535  (new Parallel::PostWaitCopyBuffer<std::vector<T>,
2536  std::back_insert_iterator<std::basic_string<T>>>
2537  (tempbuf, std::back_inserter(buf)));
2538 
2539  // Make the Request::wait() then handle deleting the buffer
2540  req.add_post_wait_work
2541  (new Parallel::PostWaitDeleteBuffer<std::vector<T>>(tempbuf));
2542 
2543  this->receive(src_processor_id, tempbuf, req, tag);
2544 }
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 >
Status libMesh::Parallel::Communicator::receive ( const unsigned int  src_processor_id,
std::set< T > &  buf,
const MessageTag tag 
) const

Definition at line 2584 of file parallel_implementation.h.

References libmesh_nullptr, and libMesh::Parallel::receive().

2587 {
2588  return this->receive
2589  (src_processor_id, buf,
2590  StandardType<T>(buf.empty() ? libmesh_nullptr : &(*buf.begin())), tag);
2591 }
const class libmesh_nullptr_t libmesh_nullptr
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 libMesh::Parallel::Communicator::receive ( const unsigned int  src_processor_id,
std::set< T > &  buf,
Request req,
const MessageTag tag 
) const

Definition at line 2601 of file parallel_implementation.h.

References libmesh_nullptr, and libMesh::Parallel::receive().

2605 {
2606  this->receive (src_processor_id, buf,
2607  StandardType<T>(buf.empty() ? libmesh_nullptr : &(*buf.begin())), req, tag);
2608 }
const class libmesh_nullptr_t libmesh_nullptr
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 >
Status libMesh::Parallel::Communicator::receive ( const unsigned int  src_processor_id,
std::set< T > &  buf,
const DataType type,
const MessageTag tag 
) const

Definition at line 2614 of file parallel_implementation.h.

References libMesh::Parallel::receive().

2618 {
2619  LOG_SCOPE("receive()", "Parallel");
2620 
2621  std::vector<T> vecbuf;
2622  Status stat = this->receive(src_processor_id, vecbuf, type, tag);
2623  buf.clear();
2624  buf.insert(vecbuf.begin(), vecbuf.end());
2625 
2626  return stat;
2627 }
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 libMesh::Parallel::Communicator::receive ( const unsigned int  src_processor_id,
std::set< T > &  buf,
const DataType type,
Request req,
const MessageTag tag 
) const

Definition at line 2637 of file parallel_implementation.h.

References libMesh::Parallel::Request::add_post_wait_work(), and libMesh::Parallel::receive().

2642 {
2643  LOG_SCOPE("receive()", "Parallel");
2644 
2645  // Allocate temporary buffer on the heap so it lives until after
2646  // the non-blocking send completes
2647  std::vector<T> * vecbuf = new std::vector<T>();
2648 
2649  // We can clear the set, but the Request::wait() will need to
2650  // handle copying our temporary buffer to it
2651  buf.clear();
2652 
2653  req.add_post_wait_work
2654  (new Parallel::PostWaitCopyBuffer<std::vector<T>,
2655  std::insert_iterator<std::set<T>>>
2656  (*vecbuf, std::inserter(buf,buf.end())));
2657 
2658  // Make the Request::wait() then handle deleting the buffer
2659  req.add_post_wait_work
2660  (new Parallel::PostWaitDeleteBuffer<std::vector<T>>(vecbuf));
2661 
2662  this->receive(src_processor_id, *vecbuf, type, req, tag);
2663 }
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 >
Status libMesh::Parallel::Communicator::receive ( const unsigned int  src_processor_id,
std::vector< T > &  buf,
const MessageTag tag 
) const

Definition at line 2669 of file parallel_implementation.h.

References libmesh_nullptr, and libMesh::Parallel::receive().

2672 {
2673  return this->receive
2674  (src_processor_id, buf,
2675  StandardType<T>(buf.empty() ? libmesh_nullptr : &(*buf.begin())), tag);
2676 }
const class libmesh_nullptr_t libmesh_nullptr
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 libMesh::Parallel::Communicator::receive ( const unsigned int  src_processor_id,
std::vector< T > &  buf,
Request req,
const MessageTag tag 
) const

Definition at line 2681 of file parallel_implementation.h.

References libmesh_nullptr, and libMesh::Parallel::receive().

2685 {
2686  this->receive (src_processor_id, buf,
2687  StandardType<T>(buf.empty() ? libmesh_nullptr : &(*buf.begin())), req, tag);
2688 }
const class libmesh_nullptr_t libmesh_nullptr
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 >
Status libMesh::Parallel::Communicator::receive ( const unsigned int  src_processor_id,
std::vector< T > &  buf,
const DataType type,
const MessageTag tag 
) const

Definition at line 2693 of file parallel_implementation.h.

References libMesh::Parallel::Status::get(), libmesh_nullptr, libMesh::Parallel::probe(), libMesh::Parallel::Status::size(), libMesh::Parallel::Status::source(), and libMesh::Parallel::Status::tag().

2697 {
2698  LOG_SCOPE("receive()", "Parallel");
2699 
2700  // Get the status of the message, explicitly provide the
2701  // datatype so we can later query the size
2702  Status stat(this->probe(src_processor_id, tag), type);
2703 
2704  buf.resize(stat.size());
2705 
2706  // Use stat.source() and stat.tag() in the receive - if
2707  // src_processor_id is or tag is "any" then we want to be sure we
2708  // try to receive the same message we just probed.
2709  libmesh_call_mpi
2710  (MPI_Recv (buf.empty() ? libmesh_nullptr : &buf[0],
2711  cast_int<int>(buf.size()), type, stat.source(),
2712  stat.tag(), this->get(), stat.get()));
2713 
2714  libmesh_assert_equal_to (stat.size(), buf.size());
2715 
2716  return stat;
2717 }
const class libmesh_nullptr_t libmesh_nullptr
status probe(const unsigned int src_processor_id, const MessageTag &tag=any_tag) const
Blocking message probe.
template<typename T >
void libMesh::Parallel::Communicator::receive ( const unsigned int  src_processor_id,
std::vector< T > &  buf,
const DataType type,
Request req,
const MessageTag tag 
) const

Definition at line 2722 of file parallel_implementation.h.

References libMesh::Parallel::Request::get(), libmesh_nullptr, and libMesh::Parallel::MessageTag::value().

2727 {
2728  LOG_SCOPE("receive()", "Parallel");
2729 
2730  libmesh_call_mpi
2731  (MPI_Irecv (buf.empty() ? libmesh_nullptr : &buf[0],
2732  cast_int<int>(buf.size()), type, src_processor_id,
2733  tag.value(), this->get(), req.get()));
2734 }
const class libmesh_nullptr_t libmesh_nullptr
template<typename Context , typename OutputIter , typename T >
void libMesh::Parallel::Communicator::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.

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 libMesh::null_output_iterator allows the receive to be dealt with solely by Parallel::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 Parallel::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 Parallel::packed_size(const T *, vector<int>::const_iterator) is used to advance to the beginning of the next object's data.

Definition at line 2738 of file parallel_implementation.h.

References libMesh::Parallel::MessageTag::MessageTag(), libMesh::Parallel::receive(), libMesh::Parallel::Status::source(), libMesh::Parallel::Status::tag(), and libMesh::Parallel::unpack_range().

Referenced by libMesh::MeshCommunication::gather_neighboring_elements(), receive(), libMesh::MeshCommunication::redistribute(), and libMesh::MeshCommunication::send_coarse_ghosts().

2743 {
2744  typedef typename Parallel::Packing<T>::buffer_type buffer_t;
2745 
2746  // Receive serialized variable size objects as sequences of buffer_t
2747  std::size_t total_buffer_size = 0;
2748  Status stat = this->receive(src_processor_id, total_buffer_size, tag);
2749 
2750  // Use stat.source() and stat.tag() in subsequent receives - if
2751  // src_processor_id is or tag is "any" then we want to be sure we
2752  // try to receive messages all corresponding to the same send.
2753 
2754  std::size_t received_buffer_size = 0;
2755  while (received_buffer_size < total_buffer_size)
2756  {
2757  std::vector<buffer_t> buffer;
2758  this->receive(stat.source(), buffer, MessageTag(stat.tag()));
2759  received_buffer_size += buffer.size();
2761  (buffer, context, out_iter, output_type);
2762  }
2763 }
Status receive(const unsigned int dest_processor_id, T &buf, const MessageTag &tag=any_tag) const
Blocking-receive from one processor with data-defined type.
void unpack_range(const typename std::vector< buffertype > &buffer, Context *context, OutputIter out, const T *output_type)
Decode a range of potentially-variable-size objects from a data array.
void libMesh::Parallel::Communicator::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.

Definition at line 1372 of file parallel_implementation.h.

References libMesh::libmesh_assert().

Referenced by libMesh::Parallel::MessageTag::MessageTag().

1373 {
1374  // This had better be an already-acquired tag.
1375  libmesh_assert(used_tag_values.count(tagvalue));
1376 
1377  used_tag_values[tagvalue]++;
1378 }
libmesh_assert(j)
std::map< int, unsigned int > used_tag_values
Definition: parallel.h:752
template<typename T >
void libMesh::Parallel::Communicator::scatter ( const std::vector< T > &  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.

The result is saved into recv.

Definition at line 3390 of file parallel_implementation.h.

References libMesh::libmesh_assert(), and libmesh_nullptr.

Referenced by ParallelTest::testScatter().

3393 {
3394  libmesh_assert_less (root_id, this->size());
3395 
3396  // Do not allow the root_id to scatter a NULL vector.
3397  // That would leave recv in an indeterminate state.
3398  libmesh_assert (this->rank() != root_id || this->size() == data.size());
3399 
3400  if (this->size() == 1)
3401  {
3402  libmesh_assert (!this->rank());
3403  libmesh_assert (!root_id);
3404  recv = data[0];
3405  return;
3406  }
3407 
3408  LOG_SCOPE("scatter()", "Parallel");
3409 
3410  T * data_ptr = const_cast<T*>(data.empty() ? libmesh_nullptr : &data[0]);
3411 
3412  libmesh_call_mpi
3413  (MPI_Scatter (data_ptr, 1, StandardType<T>(data_ptr),
3414  &recv, 1, StandardType<T>(&recv), root_id, this->get()));
3415 }
unsigned int size() const
Definition: parallel.h:726
const class libmesh_nullptr_t libmesh_nullptr
libmesh_assert(j)
unsigned int rank() const
Definition: parallel.h:724
IterBase * data
Ideally this private member data should have protected access.
template<typename T >
void libMesh::Parallel::Communicator::scatter ( const std::vector< T > &  data,
std::vector< T > &  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.

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.

Definition at line 3420 of file parallel_implementation.h.

References libMesh::Parallel::broadcast(), libMesh::libmesh_assert(), and libmesh_nullptr.

3423 {
3424  libmesh_assert_less (root_id, this->size());
3425 
3426  if (this->size() == 1)
3427  {
3428  libmesh_assert (!this->rank());
3429  libmesh_assert (!root_id);
3430  recv.assign(data.begin(), data.end());
3431  return;
3432  }
3433 
3434  LOG_SCOPE("scatter()", "Parallel");
3435 
3436  int recv_buffer_size;
3437  if (this->rank() == root_id)
3438  {
3439  libmesh_assert(data.size() % this->size() == 0);
3440  recv_buffer_size = data.size() / this->size();
3441  }
3442 
3443  this->broadcast(recv_buffer_size);
3444  recv.resize(recv_buffer_size);
3445 
3446  T * data_ptr = const_cast<T*>(data.empty() ? libmesh_nullptr : &data[0]);
3447  T * recv_ptr = recv.empty() ? libmesh_nullptr : &recv[0];
3448 
3449  libmesh_call_mpi
3450  (MPI_Scatter (data_ptr, recv_buffer_size, StandardType<T>(data_ptr),
3451  recv_ptr, recv_buffer_size, StandardType<T>(recv_ptr), root_id, this->get()));
3452 }
unsigned int size() const
Definition: parallel.h:726
const class libmesh_nullptr_t libmesh_nullptr
libmesh_assert(j)
void broadcast(T &data, const unsigned int root_id=0) const
Take a local value and broadcast it to all processors.
unsigned int rank() const
Definition: parallel.h:724
IterBase * data
Ideally this private member data should have protected access.
template<typename T >
void libMesh::Parallel::Communicator::scatter ( const std::vector< T > &  data,
const std::vector< int counts,
std::vector< T > &  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.

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.

Definition at line 3457 of file parallel_implementation.h.

References libMesh::libmesh_assert(), and libmesh_nullptr.

3461 {
3462  libmesh_assert_less (root_id, this->size());
3463 
3464  if (this->size() == 1)
3465  {
3466  libmesh_assert (!this->rank());
3467  libmesh_assert (!root_id);
3468  libmesh_assert (counts.size() == this->size());
3469  recv.assign(data.begin(), data.begin() + counts[0]);
3470  return;
3471  }
3472 
3473  std::vector<int> displacements(this->size(), 0);
3474  if (root_id == this->rank())
3475  {
3476  libmesh_assert(counts.size() == this->size());
3477 
3478  // Create a displacements vector from the incoming counts vector
3479  unsigned int globalsize = 0;
3480  for (unsigned int i=0; i < this->size(); ++i)
3481  {
3482  displacements[i] = globalsize;
3483  globalsize += counts[i];
3484  }
3485 
3486  libmesh_assert(data.size() == globalsize);
3487  }
3488 
3489  LOG_SCOPE("scatter()", "Parallel");
3490 
3491  // Scatter the buffer sizes to size remote buffers
3492  int recv_buffer_size;
3493  this->scatter(counts, recv_buffer_size, root_id);
3494  recv.resize(recv_buffer_size);
3495 
3496  T * data_ptr = const_cast<T*>(data.empty() ? libmesh_nullptr : &data[0]);
3497  int * count_ptr = const_cast<int*>(counts.empty() ? libmesh_nullptr : &counts[0]);
3498  T * recv_ptr = recv.empty() ? libmesh_nullptr : &recv[0];
3499 
3500  // Scatter the non-uniform chunks
3501  libmesh_call_mpi
3502  (MPI_Scatterv (data_ptr, count_ptr, &displacements[0], StandardType<T>(data_ptr),
3503  recv_ptr, recv_buffer_size, StandardType<T>(recv_ptr), root_id, this->get()));
3504 }
void scatter(const std::vector< T > &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...
unsigned int size() const
Definition: parallel.h:726
const class libmesh_nullptr_t libmesh_nullptr
libmesh_assert(j)
unsigned int rank() const
Definition: parallel.h:724
IterBase * data
Ideally this private member data should have protected access.
template<typename T >
void libMesh::Parallel::Communicator::scatter ( const std::vector< std::vector< T >> &  data,
std::vector< T > &  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.

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

Definition at line 3509 of file parallel_implementation.h.

References end, and libMesh::libmesh_assert().

3513 {
3514  libmesh_assert_less (root_id, this->size());
3515 
3516  if (this->size() == 1)
3517  {
3518  libmesh_assert (!this->rank());
3519  libmesh_assert (!root_id);
3520  libmesh_assert (data.size() == this->size());
3521  recv.assign(data[0].begin(), data[0].end());
3522  return;
3523  }
3524 
3525  std::vector<T> stacked_data;
3526  std::vector<int> counts;
3527 
3528  if (root_id == this->rank())
3529  {
3530  libmesh_assert (data.size() == this->size());
3531 
3532  if (!identical_buffer_sizes)
3533  counts.resize(this->size());
3534 
3535  for (std::size_t i=0; i < data.size(); ++i)
3536  {
3537  if (!identical_buffer_sizes)
3538  counts[i] = data[i].size();
3539 #ifndef NDEBUG
3540  else
3541  // Check that buffer sizes are indeed equal
3542  libmesh_assert(!i || data[i-1].size() == data[i].size());
3543 #endif
3544  std::copy(data[i].begin(), data[i].end(), std::back_inserter(stacked_data));
3545  }
3546  }
3547 
3548  if (identical_buffer_sizes)
3549  this->scatter(stacked_data, recv, root_id);
3550  else
3551  this->scatter(stacked_data, counts, recv, root_id);
3552 }
void scatter(const std::vector< T > &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...
unsigned int size() const
Definition: parallel.h:726
IterBase * end
Also have a polymorphic pointer to the end object, this prevents iterating past the end...
libmesh_assert(j)
unsigned int rank() const
Definition: parallel.h:724
IterBase * data
Ideally this private member data should have protected access.
template<typename T >
void libMesh::Parallel::Communicator::scatter ( const std::vector< T > &  data,
T &  recv,
const unsigned int   libmesh_dbg_varroot_id 
) const

Definition at line 4136 of file parallel_implementation.h.

4139 {
4140  libmesh_assert_equal_to (root_id, 0);
4141  recv = data[0];
4142 }
IterBase * data
Ideally this private member data should have protected access.
template<typename T >
void libMesh::Parallel::Communicator::scatter ( const std::vector< T > &  data,
std::vector< T > &  recv,
const unsigned int   libmesh_dbg_varroot_id 
) const

Definition at line 4146 of file parallel_implementation.h.

4149 {
4150  libmesh_assert_equal_to (root_id, 0);
4151  recv.assign(data.begin(), data.end());
4152 }
IterBase * data
Ideally this private member data should have protected access.
template<typename T >
void libMesh::Parallel::Communicator::scatter ( const std::vector< T > &  data,
const std::vector< int counts,
std::vector< T > &  recv,
const unsigned int   libmesh_dbg_varroot_id 
) const

Definition at line 4156 of file parallel_implementation.h.

4160 {
4161  libmesh_assert_equal_to (root_id, 0);
4162  libmesh_assert_equal_to (counts.size(), 1);
4163  recv.assign(data.begin(), data.begin() + counts[0]);
4164 }
IterBase * data
Ideally this private member data should have protected access.
template<typename T >
void libMesh::Parallel::Communicator::scatter ( const std::vector< std::vector< T >> &  data,
std::vector< T > &  recv,
const unsigned int   libmesh_dbg_varroot_id,
const bool   
) const

Definition at line 4168 of file parallel_implementation.h.

References alltoall(), and end.

4172 {
4173  libmesh_assert_equal_to (root_id, 0);
4174  libmesh_assert_equal_to (data.size(), 1);
4175  recv.assign(data[0].begin(), data[0].end());
4176 }
IterBase * end
Also have a polymorphic pointer to the end object, this prevents iterating past the end...
IterBase * data
Ideally this private member data should have protected access.
template<typename T >
bool libMesh::Parallel::Communicator::semiverify ( const T *  r) const

Verify that a local pointer points to the same value on all processors where it is not NULL.

Containers must have the same value in every entry.

Definition at line 1448 of file parallel_implementation.h.

References libMesh::Parallel::max(), libMesh::Parallel::min(), libMesh::Parallel::Attributes< T >::set_highest(), and libMesh::Parallel::Attributes< T >::set_lowest().

Referenced by broadcast_packed_range(), libMesh::MeshTools::libmesh_assert_valid_boundary_ids(), libMesh::MeshTools::libmesh_assert_valid_neighbors(), libMesh::MeshTools::libmesh_assert_valid_unique_ids(), semiverify(), and ParallelTest::testSemiVerify().

1449 {
1450  if (this->size() > 1 && Attributes<T>::has_min_max == true)
1451  {
1452  T tempmin, tempmax;
1453  if (r)
1454  tempmin = tempmax = *r;
1455  else
1456  {
1457  Attributes<T>::set_highest(tempmin);
1458  Attributes<T>::set_lowest(tempmax);
1459  }
1460  this->min(tempmin);
1461  this->max(tempmax);
1462  bool invalid = r && ((*r != tempmin) ||
1463  (*r != tempmax));
1464  this->max(invalid);
1465  return !invalid;
1466  }
1467 
1468 #ifdef LIBMESH_HAVE_CXX11
1469  static_assert(Attributes<T>::has_min_max,
1470  "Tried to semiverify an unverifiable type");
1471 #endif
1472 
1473  return true;
1474 }
unsigned int size() const
Definition: parallel.h:726
void max(T &r) const
Take a local variable and replace it with the maximum of it&#39;s values on all processors.
void min(T &r) const
Take a local variable and replace it with the minimum of it&#39;s values on all processors.
static void set_lowest(T &)
Definition: parallel.h:450
static void set_highest(T &)
Definition: parallel.h:451
static const bool has_min_max
Definition: parallel.h:449
template<>
bool libMesh::Parallel::Communicator::semiverify ( const bool *  r) const

Definition at line 1479 of file parallel_implementation.h.

References libmesh_nullptr.

1480 {
1481  if (r)
1482  {
1483  const unsigned char rnew = *r;
1484  return this->semiverify(&rnew);
1485  }
1486 
1487  const unsigned char * rptr = libmesh_nullptr;
1488  return this->semiverify(rptr);
1489 }
bool semiverify(const T *r) const
Verify that a local pointer points to the same value on all processors where it is not NULL...
const class libmesh_nullptr_t libmesh_nullptr
template<typename T >
bool libMesh::Parallel::Communicator::semiverify ( const std::vector< T > *  r) const

Definition at line 1494 of file parallel_implementation.h.

References libmesh_nullptr, libMesh::Parallel::max(), libMesh::Parallel::min(), semiverify(), verify(), and libMesh::Parallel::verify().

1495 {
1496  if (this->size() > 1 && Attributes<T>::has_min_max == true)
1497  {
1498  std::size_t rsize = r ? r->size() : 0;
1499  std::size_t * psize = r ? &rsize : libmesh_nullptr;
1500 
1501  if (!this->semiverify(psize))
1502  return false;
1503 
1504  this->max(rsize);
1505 
1506  std::vector<T> tempmin, tempmax;
1507  if (r)
1508  {
1509  tempmin = tempmax = *r;
1510  }
1511  else
1512  {
1513  tempmin.resize(rsize);
1514  tempmax.resize(rsize);
1515  Attributes<std::vector<T>>::set_highest(tempmin);
1516  Attributes<std::vector<T>>::set_lowest(tempmax);
1517  }
1518  this->min(tempmin);
1519  this->max(tempmax);
1520  bool invalid = r && ((*r != tempmin) ||
1521  (*r != tempmax));
1522  this->max(invalid);
1523  return !invalid;
1524  }
1525 
1526 #ifdef LIBMESH_HAVE_CXX11
1527  static_assert(Attributes<T>::has_min_max,
1528  "Tried to semiverify a vector of an unverifiable type");
1529 #endif
1530 
1531  return true;
1532 }
bool semiverify(const T *r) const
Verify that a local pointer points to the same value on all processors where it is not NULL...
unsigned int size() const
Definition: parallel.h:726
void max(T &r) const
Take a local variable and replace it with the maximum of it&#39;s values on all processors.
void min(T &r) const
Take a local variable and replace it with the minimum of it&#39;s values on all processors.
const class libmesh_nullptr_t libmesh_nullptr
static const bool has_min_max
Definition: parallel.h:449
template<typename T >
void libMesh::Parallel::Communicator::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.

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

Definition at line 2172 of file parallel_implementation.h.

References libMesh::Parallel::MessageTag::value().

Referenced by libMesh::BoundaryInfo::build_node_list_from_side_list(), libMesh::MeshTools::correct_node_proc_ids(), libMesh::MeshCommunication::gather_neighboring_elements(), libMesh::SystemSubsetBySubdomain::init(), libMesh::MeshRefinement::make_coarsening_compatible(), libMesh::SparseMatrix< T >::print(), libMesh::Nemesis_IO::read(), set_union(), ParallelPointTest::testIrecvSend(), ParallelTest::testIrecvSend(), ParallelPointTest::testIsendRecv(), ParallelTest::testIsendRecv(), ParallelTest::testRecvIsendSets(), libMesh::MeshRefinement::uniformly_coarsen(), libMesh::XdrIO::write_serialized_bcs_helper(), libMesh::XdrIO::write_serialized_connectivity(), libMesh::XdrIO::write_serialized_nodes(), libMesh::XdrIO::write_serialized_nodesets(), and libMesh::Parallel::StandardType< std::complex< T > >::~StandardType().

2175 {
2176  LOG_SCOPE("send()", "Parallel");
2177 
2178  T * dataptr = const_cast<T*> (&buf);
2179 
2180  libmesh_call_mpi
2181  (((this->send_mode() == SYNCHRONOUS) ?
2182  MPI_Ssend : MPI_Send) (dataptr,
2183  1,
2184  StandardType<T>(dataptr),
2185  dest_processor_id,
2186  tag.value(),
2187  this->get()));
2188 }
SendMode send_mode() const
Gets the user-requested SendMode.
Definition: parallel.h:766
template<typename T >
void libMesh::Parallel::Communicator::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.

Definition at line 2193 of file parallel_implementation.h.

References libMesh::Parallel::Request::get(), and libMesh::Parallel::MessageTag::value().

2197 {
2198  LOG_SCOPE("send()", "Parallel");
2199 
2200  T * dataptr = const_cast<T*>(&buf);
2201 
2202  libmesh_call_mpi
2203  (((this->send_mode() == SYNCHRONOUS) ?
2204  MPI_Issend : MPI_Isend) (dataptr,
2205  1,
2206  StandardType<T>(dataptr),
2207  dest_processor_id,
2208  tag.value(),
2209  this->get(),
2210  req.get()));
2211 }
SendMode send_mode() const
Gets the user-requested SendMode.
Definition: parallel.h:766
template<typename T >
void libMesh::Parallel::Communicator::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.

Definition at line 3949 of file parallel_implementation.h.

3953 { libmesh_not_implemented(); }
template<typename T >
void libMesh::Parallel::Communicator::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.

Definition at line 3956 of file parallel_implementation.h.

References receive(), and send_packed_range().

3961 { libmesh_not_implemented(); }
template<typename T >
void libMesh::Parallel::Communicator::send ( const unsigned int  dest_processor_id,
const std::basic_string< T > &  buf,
const MessageTag tag 
) const

Definition at line 2126 of file parallel_implementation.h.

References libmesh_nullptr, and libMesh::Parallel::MessageTag::value().

2129 {
2130  LOG_SCOPE("send()", "Parallel");
2131 
2132  T * dataptr = buf.empty() ? libmesh_nullptr : const_cast<T *>(buf.data());
2133 
2134  libmesh_call_mpi
2135  (((this->send_mode() == SYNCHRONOUS) ?
2136  MPI_Ssend : MPI_Send) (dataptr,
2137  cast_int<int>(buf.size()),
2138  StandardType<T>(dataptr),
2139  dest_processor_id,
2140  tag.value(),
2141  this->get()));
2142 }
const class libmesh_nullptr_t libmesh_nullptr
SendMode send_mode() const
Gets the user-requested SendMode.
Definition: parallel.h:766
template<typename T >
void libMesh::Parallel::Communicator::send ( const unsigned int  dest_processor_id,
const std::basic_string< T > &  buf,
Request req,
const MessageTag tag 
) const

Definition at line 2147 of file parallel_implementation.h.

References libMesh::Parallel::Request::get(), libmesh_nullptr, and libMesh::Parallel::MessageTag::value().

2151 {
2152  LOG_SCOPE("send()", "Parallel");
2153 
2154  T * dataptr = buf.empty() ? libmesh_nullptr : const_cast<T *>(buf.data());
2155 
2156  std::cerr<<"Sending: "<<buf.size()<<std::endl;
2157 
2158  libmesh_call_mpi
2159  (((this->send_mode() == SYNCHRONOUS) ?
2160  MPI_Issend : MPI_Isend) (dataptr,
2161  cast_int<int>(buf.size()),
2162  StandardType<T>(dataptr),
2163  dest_processor_id,
2164  tag.value(),
2165  this->get(),
2166  req.get()));
2167 }
const class libmesh_nullptr_t libmesh_nullptr
SendMode send_mode() const
Gets the user-requested SendMode.
Definition: parallel.h:766
template<typename T >
void libMesh::Parallel::Communicator::send ( const unsigned int  dest_processor_id,
const std::set< T > &  buf,
const MessageTag tag 
) const

Definition at line 2216 of file parallel_implementation.h.

References libmesh_nullptr, and libMesh::Parallel::send().

2219 {
2220  this->send(dest_processor_id, buf,
2221  StandardType<T>(buf.empty() ? libmesh_nullptr : &(*buf.begin())), tag);
2222 }
const class libmesh_nullptr_t libmesh_nullptr
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 libMesh::Parallel::Communicator::send ( const unsigned int  dest_processor_id,
const std::set< T > &  buf,
Request req,
const MessageTag tag 
) const

Definition at line 2227 of file parallel_implementation.h.

References libmesh_nullptr, and libMesh::Parallel::send().

2231 {
2232  this->send(dest_processor_id, buf,
2233  StandardType<T>(buf.empty() ? libmesh_nullptr : &(*buf.begin())), req, tag);
2234 }
const class libmesh_nullptr_t libmesh_nullptr
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 libMesh::Parallel::Communicator::send ( const unsigned int  dest_processor_id,
const std::set< T > &  buf,
const DataType type,
const MessageTag tag 
) const

Definition at line 2239 of file parallel_implementation.h.

References libMesh::Parallel::send().

2243 {
2244  LOG_SCOPE("send()", "Parallel");
2245 
2246  std::vector<T> vecbuf(buf.begin(), buf.end());
2247  this->send(dest_processor_id, vecbuf, type, tag);
2248 }
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 libMesh::Parallel::Communicator::send ( const unsigned int  dest_processor_id,
const std::set< T > &  buf,
const DataType type,
Request req,
const MessageTag tag 
) const

Definition at line 2253 of file parallel_implementation.h.

References libMesh::Parallel::Request::add_post_wait_work(), and libMesh::Parallel::send().

2258 {
2259  LOG_SCOPE("send()", "Parallel");
2260 
2261  // Allocate temporary buffer on the heap so it lives until after
2262  // the non-blocking send completes
2263  std::vector<T> * vecbuf =
2264  new std::vector<T>(buf.begin(), buf.end());
2265 
2266  // Make the Request::wait() handle deleting the buffer
2267  req.add_post_wait_work
2268  (new Parallel::PostWaitDeleteBuffer<std::vector<T>>(vecbuf));
2269 
2270  this->send(dest_processor_id, *vecbuf, type, req, tag);
2271 }
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 libMesh::Parallel::Communicator::send ( const unsigned int  dest_processor_id,
const std::vector< T > &  buf,
const MessageTag tag 
) const

Definition at line 2276 of file parallel_implementation.h.

References libmesh_nullptr, and libMesh::Parallel::send().

2279 {
2280  this->send(dest_processor_id, buf,
2281  StandardType<T>(buf.empty() ? libmesh_nullptr : &buf.front()), tag);
2282 }
const class libmesh_nullptr_t libmesh_nullptr
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 libMesh::Parallel::Communicator::send ( const unsigned int  dest_processor_id,
const std::vector< T > &  buf,
Request req,
const MessageTag tag 
) const

Definition at line 2287 of file parallel_implementation.h.

References libmesh_nullptr, and libMesh::Parallel::send().

2291 {
2292  this->send(dest_processor_id, buf,
2293  StandardType<T>(buf.empty() ? libmesh_nullptr : &buf.front()), req, tag);
2294 }
const class libmesh_nullptr_t libmesh_nullptr
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 libMesh::Parallel::Communicator::send ( const unsigned int  dest_processor_id,
const std::vector< T > &  buf,
const DataType type,
const MessageTag tag 
) const

Definition at line 2299 of file parallel_implementation.h.

References libmesh_nullptr, and libMesh::Parallel::MessageTag::value().

2303 {
2304  LOG_SCOPE("send()", "Parallel");
2305 
2306  libmesh_call_mpi
2307  (((this->send_mode() == SYNCHRONOUS) ?
2308  MPI_Ssend : MPI_Send) (buf.empty() ? libmesh_nullptr : const_cast<T*>(&buf[0]),
2309  cast_int<int>(buf.size()),
2310  type,
2311  dest_processor_id,
2312  tag.value(),
2313  this->get()));
2314 }
const class libmesh_nullptr_t libmesh_nullptr
SendMode send_mode() const
Gets the user-requested SendMode.
Definition: parallel.h:766
template<typename T >
void libMesh::Parallel::Communicator::send ( const unsigned int  dest_processor_id,
const std::vector< T > &  buf,
const DataType type,
Request req,
const MessageTag tag 
) const

Definition at line 2319 of file parallel_implementation.h.

References libMesh::Parallel::Request::get(), libmesh_nullptr, and libMesh::Parallel::MessageTag::value().

2324 {
2325  LOG_SCOPE("send()", "Parallel");
2326 
2327  libmesh_call_mpi
2328  (((this->send_mode() == SYNCHRONOUS) ?
2329  MPI_Issend : MPI_Isend) (buf.empty() ? libmesh_nullptr : const_cast<T*>(&buf[0]),
2330  cast_int<int>(buf.size()),
2331  type,
2332  dest_processor_id,
2333  tag.value(),
2334  this->get(),
2335  req.get()));
2336 }
const class libmesh_nullptr_t libmesh_nullptr
SendMode send_mode() const
Gets the user-requested SendMode.
Definition: parallel.h:766
void libMesh::Parallel::Communicator::send_mode ( const SendMode  sm)

Explicitly sets the SendMode type used for send operations.

Definition at line 761 of file parallel.h.

Referenced by duplicate(), split(), ParallelPointTest::testIrecvSend(), ParallelTest::testIrecvSend(), ParallelPointTest::testIsendRecv(), and ParallelTest::testIsendRecv().

761 { _send_mode = sm; }
SendMode libMesh::Parallel::Communicator::send_mode ( ) const
template<typename Context , typename Iter >
void libMesh::Parallel::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 
) const

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 Parallel::pack(const T *, vector<int> & data, const Context *) is used to serialize type T onto the end of a data vector.

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

Definition at line 2340 of file parallel_implementation.h.

References distance(), libMesh::Parallel::pack_range(), libMesh::Parallel::packed_range_size(), and libMesh::Parallel::send().

Referenced by libMesh::MeshCommunication::gather_neighboring_elements(), libMesh::MeshCommunication::redistribute(), send(), and libMesh::MeshCommunication::send_coarse_ghosts().

2345 {
2346  // We will serialize variable size objects from *range_begin to
2347  // *range_end as a sequence of plain data (e.g. ints) in this buffer
2348  typedef typename std::iterator_traits<Iter>::value_type T;
2349 
2350  std::size_t total_buffer_size =
2351  Parallel::packed_range_size (context, range_begin, range_end);
2352 
2353  this->send(dest_processor_id, total_buffer_size, tag);
2354 
2355 #ifdef DEBUG
2356  std::size_t used_buffer_size = 0;
2357 #endif
2358 
2359  while (range_begin != range_end)
2360  {
2361  libmesh_assert_greater (std::distance(range_begin, range_end), 0);
2362 
2363  std::vector<typename Parallel::Packing<T>::buffer_type> buffer;
2364 
2365  const Iter next_range_begin = Parallel::pack_range
2366  (context, range_begin, range_end, buffer);
2367 
2368  libmesh_assert_greater (std::distance(range_begin, next_range_begin), 0);
2369 
2370  range_begin = next_range_begin;
2371 
2372 #ifdef DEBUG
2373  used_buffer_size += buffer.size();
2374 #endif
2375 
2376  // Blocking send of the buffer
2377  this->send(dest_processor_id, buffer, tag);
2378  }
2379 
2380 #ifdef DEBUG
2381  libmesh_assert_equal_to(used_buffer_size, total_buffer_size);
2382 #endif
2383 }
Iter pack_range(const Context *context, Iter range_begin, const Iter range_end, typename std::vector< buffertype > &buffer, std::size_t approx_buffer_size=1000000)
Encode a range of potentially-variable-size objects to a data array.
Real distance(const Point &p)
std::size_t packed_range_size(const Context *context, Iter range_begin, const Iter range_end)
Return the total buffer size needed to encode a range of potentially-variable-size objects to a data ...
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 Context , typename Iter >
void libMesh::Parallel::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 
) const

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 Parallel::pack(const T *, vector<int> & data, const Context *) is used to serialize type T onto the end of a data vector.

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

Definition at line 2387 of file parallel_implementation.h.

References libMesh::Parallel::Request::add_post_wait_work(), libMesh::Parallel::Request::add_prior_request(), distance(), libMesh::Parallel::pack_range(), libMesh::Parallel::packed_range_size(), and libMesh::Parallel::send().

2393 {
2394  // Allocate a buffer on the heap so we don't have to free it until
2395  // after the Request::wait()
2396  typedef typename std::iterator_traits<Iter>::value_type T;
2397  typedef typename Parallel::Packing<T>::buffer_type buffer_t;
2398 
2399  std::size_t total_buffer_size =
2400  Parallel::packed_range_size (context, range_begin, range_end);
2401 
2402  // That local variable will be gone soon; we need a send buffer that
2403  // will stick around. I heard you like buffering so I put a buffer
2404  // for your buffer size so you can buffer the size of your buffer.
2405  std::size_t * total_buffer_size_buffer = new std::size_t;
2406  *total_buffer_size_buffer = total_buffer_size;
2407 
2408  // Delete the buffer size's buffer when we're done
2409  Request intermediate_req = request();
2410  intermediate_req.add_post_wait_work
2411  (new Parallel::PostWaitDeleteBuffer<std::size_t>(total_buffer_size_buffer));
2412  this->send(dest_processor_id, *total_buffer_size_buffer, intermediate_req, tag);
2413 
2414  // And don't finish up the full request until we're done with its
2415  // dependencies
2416  req.add_prior_request(intermediate_req);
2417 
2418 #ifdef DEBUG
2419  std::size_t used_buffer_size = 0;
2420 #endif
2421 
2422  while (range_begin != range_end)
2423  {
2424  libmesh_assert_greater (std::distance(range_begin, range_end), 0);
2425 
2426  std::vector<buffer_t> * buffer = new std::vector<buffer_t>();
2427 
2428  const Iter next_range_begin =
2429  Parallel::pack_range(context, range_begin, range_end,
2430  *buffer);
2431 
2432  libmesh_assert_greater (std::distance(range_begin, next_range_begin), 0);
2433 
2434  range_begin = next_range_begin;
2435 
2436 #ifdef DEBUG
2437  used_buffer_size += buffer->size();
2438 #endif
2439 
2440  Request next_intermediate_req;
2441 
2442  Request * my_req = (range_begin == range_end) ? &req : &next_intermediate_req;
2443 
2444  // Make the Request::wait() handle deleting the buffer
2445  my_req->add_post_wait_work
2446  (new Parallel::PostWaitDeleteBuffer<std::vector<buffer_t>>
2447  (buffer));
2448 
2449  // Non-blocking send of the buffer
2450  this->send(dest_processor_id, *buffer, *my_req, tag);
2451 
2452  if (range_begin != range_end)
2453  req.add_prior_request(*my_req);
2454  }
2455 }
Iter pack_range(const Context *context, Iter range_begin, const Iter range_end, typename std::vector< buffertype > &buffer, std::size_t approx_buffer_size=1000000)
Encode a range of potentially-variable-size objects to a data array.
MPI_Request request
Request object for non-blocking I/O.
Definition: parallel.h:171
Real distance(const Point &p)
std::size_t packed_range_size(const Context *context, Iter range_begin, const Iter range_end)
Return the total buffer size needed to encode a range of potentially-variable-size objects to a data ...
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 T1 , typename T2 >
void libMesh::Parallel::Communicator::send_receive ( const unsigned int  dest_processor_id,
const T1 &  send,
const unsigned int  source_processor_id,
T2 &  recv,
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.

Send-receive data from one processor.

Definition at line 2856 of file parallel_implementation.h.

References libMesh::Parallel::MessageTag::value().

Referenced by libMesh::ParmetisPartitioner::assign_partitioning(), libMesh::MeshCommunication::find_global_indices(), libMesh::SparsityPattern::Build::parallel_sync(), receive(), libMesh::DistributedMesh::renumber_dof_objects(), libMesh::Partitioner::set_node_processor_ids(), libMesh::DofMap::set_nonlocal_dof_objects(), libMesh::Parallel::sync_dofobject_data_by_id(), libMesh::Parallel::sync_dofobject_data_by_xyz(), and libMesh::XdrIO::write_serialized_connectivity().

2862 {
2863  LOG_SCOPE("send_receive()", "Parallel");
2864 
2865  if (dest_processor_id == this->rank() &&
2866  source_processor_id == this->rank())
2867  {
2868  recv = sendvec;
2869  return;
2870  }
2871 
2872  // MPI_STATUS_IGNORE is from MPI-2; using it with some versions of
2873  // MPICH may cause a crash:
2874  // https://bugzilla.mcs.anl.gov/globus/show_bug.cgi?id=1798
2875 #if MPI_VERSION > 1
2876  libmesh_call_mpi
2877  (MPI_Sendrecv(const_cast<T1*>(&sendvec), 1, StandardType<T1>(&sendvec),
2878  dest_processor_id, send_tag.value(), &recv, 1,
2879  StandardType<T2>(&recv), source_processor_id,
2880  recv_tag.value(), this->get(), MPI_STATUS_IGNORE));
2881 #else
2882  MPI_Status stat;
2883  libmesh_call_mpi
2884  (MPI_Sendrecv(const_cast<T1*>(&sendvec), 1, StandardType<T1>(&sendvec),
2885  dest_processor_id, send_tag.value(), &recv, 1,
2886  StandardType<T2>(&recv), source_processor_id,
2887  recv_tag.value(), this->get(), &stat));
2888 #endif
2889 }
unsigned int rank() const
Definition: parallel.h:724
template<typename T1 , typename T2 >
void libMesh::Parallel::Communicator::send_receive ( const unsigned int  dest_processor_id,
const T1 &  send,
const DataType type1,
const unsigned int  source_processor_id,
T2 &  recv,
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 T1 , typename T2 >
void libMesh::Parallel::Communicator::send_receive ( const unsigned int  dest_processor_id,
const std::vector< T1 > &  sendvec,
const DataType type1,
const unsigned int  source_processor_id,
std::vector< T2 > &  recv,
const DataType type2,
const MessageTag send_tag,
const MessageTag recv_tag 
) const

Definition at line 2826 of file parallel_implementation.h.

References libMesh::Parallel::receive(), libMesh::Parallel::send(), and libMesh::Parallel::Request::wait().

2834 {
2835  LOG_SCOPE("send_receive()", "Parallel");
2836 
2837  if (dest_processor_id == this->rank() &&
2838  source_processor_id == this->rank())
2839  {
2840  recv = sendvec;
2841  return;
2842  }
2843 
2844  Parallel::Request req;
2845 
2846  this->send (dest_processor_id, sendvec, type1, req, send_tag);
2847 
2848  this->receive (source_processor_id, recv, type2, recv_tag);
2849 
2850  req.wait();
2851 }
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.
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.
unsigned int rank() const
Definition: parallel.h:724
template<typename T >
void libMesh::Parallel::Communicator::send_receive ( const unsigned int  dest_processor_id,
const std::vector< T > &  sendvec,
const unsigned int  source_processor_id,
std::vector< T > &  recv,
const MessageTag send_tag,
const MessageTag recv_tag 
) const

Definition at line 2901 of file parallel_implementation.h.

References libmesh_nullptr, and libMesh::Parallel::send_receive().

2907 {
2908  if (dest_processor_id == this->rank() &&
2909  source_processor_id == this->rank())
2910  {
2911  LOG_SCOPE("send_receive()", "Parallel");
2912  recv = sendvec;
2913  return;
2914  }
2915 
2916  const T* example = sendvec.empty() ?
2917  (recv.empty() ? libmesh_nullptr : &recv[0]) : &sendvec[0];
2918 
2919  // Call the user-defined type version with automatic
2920  // type conversion based on template argument:
2921  this->send_receive (dest_processor_id, sendvec,
2922  StandardType<T>(example),
2923  source_processor_id, recv,
2924  StandardType<T>(example),
2925  send_tag, recv_tag);
2926 }
const class libmesh_nullptr_t libmesh_nullptr
void send_receive(const unsigned int dest_processor_id, const T1 &send, const unsigned int source_processor_id, T2 &recv, const MessageTag &send_tag=no_tag, const MessageTag &recv_tag=any_tag) const
Send data send to one processor while simultaneously receiving other data recv from a (potentially di...
unsigned int rank() const
Definition: parallel.h:724
template<typename T1 , typename T2 >
void libMesh::Parallel::Communicator::send_receive ( const unsigned int  dest_processor_id,
const std::vector< T1 > &  sendvec,
const unsigned int  source_processor_id,
std::vector< T2 > &  recv,
const MessageTag send_tag,
const MessageTag recv_tag 
) const

Definition at line 2932 of file parallel_implementation.h.

References libmesh_nullptr, and libMesh::Parallel::send_receive().

2938 {
2939  // Call the user-defined type version with automatic
2940  // type conversion based on template argument:
2941  this->send_receive (dest_processor_id, sendvec,
2942  StandardType<T1>(sendvec.empty() ? libmesh_nullptr : &sendvec[0]),
2943  source_processor_id, recv,
2944  StandardType<T2>(recv.empty() ? libmesh_nullptr : &recv[0]),
2945  send_tag, recv_tag);
2946 }
const class libmesh_nullptr_t libmesh_nullptr
void send_receive(const unsigned int dest_processor_id, const T1 &send, const unsigned int source_processor_id, T2 &recv, const MessageTag &send_tag=no_tag, const MessageTag &recv_tag=any_tag) const
Send data send to one processor while simultaneously receiving other data recv from a (potentially di...
template<typename T1 , typename T2 >
void libMesh::Parallel::Communicator::send_receive ( const unsigned int  dest_processor_id,
const std::vector< std::vector< T1 >> &  sendvec,
const unsigned int  source_processor_id,
std::vector< std::vector< T2 >> &  recv,
const MessageTag ,
const MessageTag  
) const

Definition at line 2952 of file parallel_implementation.h.

References libMesh::Parallel::any_tag, and libMesh::Parallel::no_tag.

2958 {
2959  // FIXME - why aren't we honoring send_tag and recv_tag here?
2960  send_receive_vec_of_vec
2961  (dest_processor_id, sendvec, source_processor_id, recv,
2962  no_tag, any_tag, *this);
2963 }
const MessageTag no_tag
Definition: parallel.h:282
const MessageTag any_tag
Default message tag ids.
Definition: parallel.h:277
template<typename T >
void libMesh::Parallel::Communicator::send_receive ( const unsigned int  dest_processor_id,
const std::vector< std::vector< T >> &  sendvec,
const unsigned int  source_processor_id,
std::vector< std::vector< T >> &  recv,
const MessageTag ,
const MessageTag  
) const

Definition at line 2970 of file parallel_implementation.h.

References libMesh::Parallel::any_tag, and libMesh::Parallel::no_tag.

2976 {
2977  // FIXME - why aren't we honoring send_tag and recv_tag here?
2978  send_receive_vec_of_vec
2979  (dest_processor_id, sendvec, source_processor_id, recv,
2980  no_tag, any_tag, *this);
2981 }
const MessageTag no_tag
Definition: parallel.h:282
const MessageTag any_tag
Default message tag ids.
Definition: parallel.h:277
template<typename Context1 , typename RangeIter , typename Context2 , typename OutputIter , typename T >
void libMesh::Parallel::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_iter,
const T *  output_type,
const MessageTag send_tag = no_tag,
const MessageTag recv_tag = any_tag 
) const

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

Send-receive range-of-pointers from one 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 Parallel::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 libMesh::null_output_iterator allows the receive to be dealt with solely by Parallel::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 Parallel::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 Parallel::packable_size(const T1*, const Context1*) is used to allow data vectors to reserve memory, and for additional error checking.

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

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

Definition at line 2989 of file parallel_implementation.h.

References libMesh::Parallel::receive_packed_range(), libMesh::Parallel::send_packed_range(), and libMesh::Parallel::Request::wait().

Referenced by receive(), PackedRangeTest::testContainerSendReceive(), and PackedRangeTest::testNullSendReceive().

2999 {
3000  LOG_SCOPE("send_receive()", "Parallel");
3001 
3002  Parallel::Request req;
3003 
3004  this->send_packed_range (dest_processor_id, context1, send_begin, send_end,
3005  req, send_tag);
3006 
3007  this->receive_packed_range (source_processor_id, context2, out_iter,
3008  output_type, recv_tag);
3009 
3010  req.wait();
3011 }
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) const
Blocking-send range-of-pointers to one processor.
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 T >
void libMesh::Parallel::Communicator::set_union ( T &  data,
const unsigned int  root_id 
) const

Take a container of local variables on each processor, and collect their union over all processors, replacing the set on processor 0.

Definition at line 3922 of file parallel_implementation.h.

References probe(), and send().

Referenced by libMesh::BoundaryInfo::_find_id_maps(), libMesh::MeshBase::cache_elem_dims(), libMesh::Nemesis_IO_Helper::compute_num_global_nodesets(), libMesh::Nemesis_IO_Helper::compute_num_global_sidesets(), DMlibMeshSetSystem_libMesh(), set_union(), libMesh::MeshBase::subdomain_ids(), and libMesh::BoundaryInfo::sync().

3923 { libmesh_assert_equal_to(root_id, 0); }
template<typename T >
void libMesh::Parallel::Communicator::set_union ( T &  data) const

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

Definition at line 3919 of file parallel_implementation.h.

3919 {}
template<typename T >
void libMesh::Parallel::Communicator::set_union ( std::set< T > &  data,
const unsigned int  root_id 
) const

Definition at line 2044 of file parallel_implementation.h.

References libMesh::Parallel::gather().

2046 {
2047  std::vector<T> vecdata(data.begin(), data.end());
2048  this->gather(root_id, vecdata);
2049  if (this->rank() == root_id)
2050  data.insert(vecdata.begin(), vecdata.end());
2051 }
void gather(const unsigned int root_id, const T &send, std::vector< T > &recv) const
Take a vector of length comm.size(), and on processor root_id fill in recv[processor_id] = the value ...
unsigned int rank() const
Definition: parallel.h:724
IterBase * data
Ideally this private member data should have protected access.
template<typename T >
void libMesh::Parallel::Communicator::set_union ( std::set< T > &  data) const

Definition at line 2056 of file parallel_implementation.h.

References libMesh::Parallel::allgather(), data, libMesh::Parallel::gather(), and set_union().

2057 {
2058  std::vector<T> vecdata(data.begin(), data.end());
2059  this->allgather(vecdata, false);
2060  data.insert(vecdata.begin(), vecdata.end());
2061 }
IterBase * data
Ideally this private member data should have protected access.
void allgather(const T &send, std::vector< T > &recv) const
Take a vector of length this->size(), and fill in recv[processor_id] = the value of send on that proc...
unsigned int libMesh::Parallel::Communicator::size ( ) const
void libMesh::Parallel::Communicator::split ( int  color,
int  key,
Communicator target 
) const

Definition at line 646 of file parallel_implementation.h.

References _I_duped_it, assign(), clear(), and send_mode().

Referenced by ParallelTest::testSplit().

647 {
648  target.clear();
649  MPI_Comm newcomm;
650  libmesh_call_mpi
651  (MPI_Comm_split(this->get(), color, key, &newcomm));
652 
653  target.assign(newcomm);
654  target._I_duped_it = true;
655  target.send_mode(this->send_mode());
656 }
SendMode send_mode() const
Gets the user-requested SendMode.
Definition: parallel.h:766
template<typename T >
void libMesh::Parallel::Communicator::sum ( T &  r) const

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

Containers are replaced element-wise.

Definition at line 1973 of file parallel_implementation.h.

Referenced by libMesh::Parallel::BinSorter< KeyType, IdxType >::binsort(), broadcast_packed_range(), libMesh::Parallel::Histogram< KeyType, IdxType >::build_histogram(), libMesh::System::calculate_norm(), libMesh::Parallel::Sort< KeyType, IdxType >::communicate_bins(), libMesh::RBConstruction::compute_max_error_bound(), libMesh::Nemesis_IO_Helper::compute_num_global_elem_blocks(), libMesh::Nemesis_IO_Helper::compute_num_global_nodesets(), libMesh::Nemesis_IO_Helper::compute_num_global_sidesets(), libMesh::MeshRefinement::create_parent_error_vector(), libMesh::RBEIMConstruction::evaluate_mesh_function(), libMesh::CondensedEigenSystem::get_eigenpair(), libMesh::DofMap::get_info(), integrate_function(), main(), libMesh::DistributedMesh::n_active_elem(), libMesh::BoundaryInfo::n_boundary_conds(), libMesh::BoundaryInfo::n_edge_conds(), libMesh::CondensedEigenSystem::n_global_non_condensed_dofs(), libMesh::BoundaryInfo::n_nodeset_conds(), libMesh::BoundaryInfo::n_shellface_conds(), libMesh::DistributedMesh::parallel_n_elem(), libMesh::DistributedMesh::parallel_n_nodes(), libMesh::DifferentiableQoI::parallel_op(), libMesh::Nemesis_IO::read(), libMesh::ErrorEstimator::reduce_error(), libMesh::Parallel::Sort< KeyType, IdxType >::sort(), libMesh::MeshTools::total_weight(), and libMesh::XdrIO::write_serialized_connectivity().

1974 {
1975  if (this->size() > 1)
1976  {
1977  LOG_SCOPE("sum()", "Parallel");
1978 
1979  T temp = r;
1980  libmesh_call_mpi
1981  (MPI_Allreduce (&temp, &r, 1, StandardType<T>(&temp),
1983  this->get()));
1984  }
1985 }
unsigned int size() const
Definition: parallel.h:726
void sum(T &r, const Communicator &comm=Communicator_World)
template<typename T >
void libMesh::Parallel::Communicator::sum ( std::vector< T > &  r) const

Definition at line 1989 of file parallel_implementation.h.

References libMesh::libmesh_assert(), libMesh::Parallel::sum(), and libMesh::Parallel::verify().

1990 {
1991  if (this->size() > 1 && !r.empty())
1992  {
1993  LOG_SCOPE("sum()", "Parallel");
1994 
1995  libmesh_assert(this->verify(r.size()));
1996 
1997  std::vector<T> temp(r);
1998  libmesh_call_mpi
1999  (MPI_Allreduce (&temp[0], &r[0], cast_int<int>(r.size()),
2000  StandardType<T>(&temp[0]),
2002  this->get()));
2003  }
2004 }
bool verify(const T &r) const
Verify that a local variable has the same value on all processors.
unsigned int size() const
Definition: parallel.h:726
void sum(T &r, const Communicator &comm=Communicator_World)
libmesh_assert(j)
template<typename T >
void libMesh::Parallel::Communicator::sum ( std::complex< T > &  r) const

Definition at line 2010 of file parallel_implementation.h.

2011 {
2012  if (this->size() > 1)
2013  {
2014  LOG_SCOPE("sum()", "Parallel");
2015 
2016  std::complex<T> temp(r);
2017  libmesh_call_mpi
2018  (MPI_Allreduce (&temp, &r, 2, StandardType<T>(),
2020  this->get()));
2021  }
2022 }
unsigned int size() const
Definition: parallel.h:726
void sum(T &r, const Communicator &comm=Communicator_World)
template<typename T >
void libMesh::Parallel::Communicator::sum ( std::vector< std::complex< T >> &  r) const

Definition at line 2026 of file parallel_implementation.h.

References libMesh::libmesh_assert(), libmesh_nullptr, libMesh::Parallel::sum(), and libMesh::Parallel::verify().

2027 {
2028  if (this->size() > 1 && !r.empty())
2029  {
2030  LOG_SCOPE("sum()", "Parallel");
2031 
2032  libmesh_assert(this->verify(r.size()));
2033 
2034  std::vector<std::complex<T>> temp(r);
2035  libmesh_call_mpi
2036  (MPI_Allreduce (&temp[0], &r[0], cast_int<int>(r.size() * 2),
2037  StandardType<T>(libmesh_nullptr),
2038  OpFunction<T>::sum(), this->get()));
2039  }
2040 }
bool verify(const T &r) const
Verify that a local variable has the same value on all processors.
unsigned int size() const
Definition: parallel.h:726
const class libmesh_nullptr_t libmesh_nullptr
void sum(T &r, const Communicator &comm=Communicator_World)
libmesh_assert(j)
template<typename T >
bool libMesh::Parallel::Communicator::verify ( const T &  r) const

Verify that a local variable has the same value on all processors.

Containers must have the same value in every entry.

Definition at line 1415 of file parallel_implementation.h.

References libMesh::Parallel::max(), and libMesh::Parallel::min().

Referenced by libMesh::MeshCommunication::broadcast(), broadcast_packed_range(), libMesh::DofMap::check_dirichlet_bcid_consistency(), libMesh::MeshTools::create_processor_bounding_box(), libMesh::MeshTools::create_subdomain_bounding_box(), libMesh::MeshCommunication::delete_remote_elements(), libMesh::MeshCommunication::gather(), and semiverify().

1416 {
1417  if (this->size() > 1 && Attributes<T>::has_min_max == true)
1418  {
1419  T tempmin = r, tempmax = r;
1420  this->min(tempmin);
1421  this->max(tempmax);
1422  bool verified = (r == tempmin) &&
1423  (r == tempmax);
1424  this->min(verified);
1425  return verified;
1426  }
1427 
1428 #ifdef LIBMESH_HAVE_CXX11
1429  static_assert(Attributes<T>::has_min_max,
1430  "Tried to verify an unverifiable type");
1431 #endif
1432 
1433  return true;
1434 }
unsigned int size() const
Definition: parallel.h:726
void max(T &r) const
Take a local variable and replace it with the maximum of it&#39;s values on all processors.
void min(T &r) const
Take a local variable and replace it with the minimum of it&#39;s values on all processors.
static const bool has_min_max
Definition: parallel.h:449
template<>
bool libMesh::Parallel::Communicator::verify ( const bool &  r) const

Definition at line 1439 of file parallel_implementation.h.

References libMesh::Parallel::verify().

1440 {
1441  const unsigned char rnew = r;
1442  return this->verify(rnew);
1443 }
bool verify(const T &r) const
Verify that a local variable has the same value on all processors.

Member Data Documentation

communicator libMesh::Parallel::Communicator::_communicator
private

Definition at line 746 of file parallel.h.

Referenced by assign(), clear(), duplicate(), and libMesh::ParallelObject::operator=().

bool libMesh::Parallel::Communicator::_I_duped_it
private

Definition at line 753 of file parallel.h.

Referenced by clear(), duplicate(), and split().

unsigned int libMesh::Parallel::Communicator::_rank
private

Definition at line 747 of file parallel.h.

Referenced by assign().

SendMode libMesh::Parallel::Communicator::_send_mode
private

Definition at line 748 of file parallel.h.

Referenced by assign().

unsigned int libMesh::Parallel::Communicator::_size
private

Definition at line 747 of file parallel.h.

Referenced by assign().

std::map<int, unsigned int> libMesh::Parallel::Communicator::used_tag_values
mutableprivate

Definition at line 752 of file parallel.h.


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