libMesh::Parallel::Communicator Class Reference

#include <parallel.h>

Public Types

enum  SendMode { DEFAULT =0, SYNCHRONOUS }
 

Public Member Functions

 Communicator ()
 
 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
 
void reference_unique_tag (int tagvalue) const
 
void dereference_unique_tag (int tagvalue) const
 
void clear ()
 
Communicatoroperator= (const communicator &comm)
 
unsigned int rank () const
 
unsigned int size () const
 
void send_mode (const SendMode sm)
 
SendMode send_mode () const
 
void barrier () const
 
template<typename T >
bool verify (const T &r) const
 
template<typename T >
bool semiverify (const T *r) const
 
template<typename T >
void min (T &r) const
 
template<typename T >
void minloc (T &r, unsigned int &min_id) const
 
template<typename T >
void minloc (std::vector< T > &r, std::vector< unsigned int > &min_id) const
 
template<typename T >
void max (T &r) const
 
template<typename T >
void maxloc (T &r, unsigned int &max_id) const
 
template<typename T >
void maxloc (std::vector< T > &r, std::vector< unsigned int > &max_id) const
 
template<typename T >
void sum (T &r) const
 
template<typename T >
void set_union (T &data, const unsigned int root_id) const
 
template<typename T >
void set_union (T &data) const
 
status probe (const unsigned int src_processor_id, const MessageTag &tag=any_tag) const
 
template<typename T >
Status packed_range_probe (const unsigned int src_processor_id, const MessageTag &tag, bool &flag) const
 
template<typename T >
void send (const unsigned int dest_processor_id, const T &buf, const MessageTag &tag=no_tag) const
 
template<typename T >
void send (const unsigned int dest_processor_id, const T &buf, Request &req, const MessageTag &tag=no_tag) const
 
template<typename T >
void send (const unsigned int dest_processor_id, const T &buf, const DataType &type, const MessageTag &tag=no_tag) const
 
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
 
template<typename T >
Status receive (const unsigned int dest_processor_id, T &buf, const MessageTag &tag=any_tag) const
 
template<typename T >
void receive (const unsigned int dest_processor_id, T &buf, Request &req, const MessageTag &tag=any_tag) const
 
template<typename T >
Status receive (const unsigned int dest_processor_id, T &buf, const DataType &type, const MessageTag &tag=any_tag) const
 
template<typename T >
void receive (const unsigned int dest_processor_id, T &buf, const DataType &type, Request &req, const MessageTag &tag=any_tag) const
 
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
 
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
 
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
 
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
 
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
 
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
 
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
 
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
 
template<typename T >
void gather (const unsigned int root_id, const T &send, std::vector< T > &recv) const
 
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
 
template<typename T >
void gather (const unsigned int root_id, std::vector< T > &r) const
 
template<typename T >
void allgather (const T &send, std::vector< T > &recv) const
 
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
 
template<typename T >
void allgather (std::vector< T > &r, const bool identical_buffer_sizes=false) const
 
template<typename T >
void allgather (std::vector< std::basic_string< T > > &r, const bool identical_buffer_sizes=false) const
 
template<typename T >
void scatter (const std::vector< T > &data, T &recv, const unsigned int root_id=0) const
 
template<typename T >
void scatter (const std::vector< T > &data, std::vector< T > &recv, const unsigned int root_id=0) const
 
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
 
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
 
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
 
template<typename Context , typename Iter , typename OutputIter >
void allgather_packed_range (Context *context, Iter range_begin, const Iter range_end, OutputIter out) const
 
template<typename T >
void alltoall (std::vector< T > &r) const
 
template<typename T >
void broadcast (T &data, const unsigned int root_id=0) const
 
template<typename Context , typename OutputContext , typename Iter , typename OutputIter >
void broadcast_packed_range (const Context *context1, Iter range_begin, const Iter range_end, OutputContext *context2, OutputIter out, const unsigned int root_id=0) const
 
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
 
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)
 

Private Attributes

communicator _communicator
 
unsigned int _rank
 
unsigned int _size
 
SendMode _send_mode
 
std::map< int, unsigned int > used_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 653 of file parallel.h.

Member Enumeration Documentation

Whether to use default or synchronous sends?

Enumerator
DEFAULT 
SYNCHRONOUS 

Definition at line 727 of file parallel.h.

Constructor & Destructor Documentation

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

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:748
libMesh::Parallel::Communicator::Communicator ( const communicator comm)
inlineexplicit

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)
std::map< int, unsigned int > used_tag_values
Definition: parallel.h:748
libMesh::Parallel::Communicator::~Communicator ( )
inline

Definition at line 640 of file parallel_implementation.h.

References clear().

641 {
642  this->clear();
643 }
libMesh::Parallel::Communicator::Communicator ( const Communicator )
inlineexplicitprivate

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:748

Member Function Documentation

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

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

Definition at line 3157 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::ParmetisPartitioner::initialize(), libMesh::Nemesis_IO::read(), libMesh::DistributedMesh::renumber_dof_objects(), libMesh::DofMap::set_nonlocal_dof_objects(), and libMesh::Parallel::Sort< KeyType, IdxType >::sort().

3159 {
3160  LOG_SCOPE ("allgather()","Parallel");
3161 
3162  libmesh_assert(this->size());
3163  recv.resize(this->size());
3164 
3165  unsigned int comm_size = this->size();
3166  if (comm_size > 1)
3167  {
3168  StandardType<T> send_type(&sendval);
3169 
3170  libmesh_call_mpi
3171  (MPI_Allgather (const_cast<T*>(&sendval), 1, send_type, &recv[0], 1,
3172  send_type, this->get()));
3173  }
3174  else if (comm_size > 0)
3175  recv[0] = sendval;
3176 }
unsigned int size() const
Definition: parallel.h:722
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
inline

AllGather overload for string types

Definition at line 3181 of file parallel_implementation.h.

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

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

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

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

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

AllGather overload for vectors of string types

Definition at line 3305 of file parallel_implementation.h.

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

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

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

Definition at line 4230 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().

4234 {
4235  typedef typename std::iterator_traits<Iter>::value_type T;
4236  typedef typename Parallel::Packing<T>::buffer_type buffer_t;
4237 
4238  bool nonempty_range = (range_begin != range_end);
4239  this->max(nonempty_range);
4240 
4241  while (nonempty_range)
4242  {
4243  // We will serialize variable size objects from *range_begin to
4244  // *range_end as a sequence of ints in this buffer
4245  std::vector<buffer_t> buffer;
4246 
4247  range_begin = Parallel::pack_range
4248  (context, range_begin, range_end, buffer);
4249 
4250  this->allgather(buffer, false);
4251 
4252  libmesh_assert(buffer.size());
4253 
4255  (buffer, context, out_iter, (T*)libmesh_nullptr);
4256 
4257  nonempty_range = (range_begin != range_end);
4258  this->max(nonempty_range);
4259  }
4260 }
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)
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)
void allgather(const T &send, std::vector< T > &recv) const
template<typename T >
void libMesh::Parallel::Communicator::alltoall ( std::vector< T > &  r) const
inline

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 3559 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().

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

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
inline

Pause execution until all processors reach a certain point.

Definition at line 1008 of file parallel_implementation.h.

Referenced by libMesh::NameBasedIO::write(), and libMesh::XdrIO::write().

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:722
template<typename T >
void libMesh::Parallel::Communicator::broadcast ( T &  data,
const unsigned int  root_id = 0 
) const
inline

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

References libMesh::libmesh_assert().

Referenced by libMesh::EquationSystems::_read_impl(), libMesh::MeshCommunication::broadcast(), broadcast(), 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_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(), and libMesh::NameBasedIO::write().

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

Definition at line 3609 of file parallel_implementation.h.

References data, and libMesh::libmesh_assert().

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

Definition at line 3636 of file parallel_implementation.h.

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

3638 {
3639  if (this->size() == 1)
3640  {
3641  libmesh_assert (!this->rank());
3642  libmesh_assert (!root_id);
3643  return;
3644  }
3645 
3646  libmesh_assert_less (root_id, this->size());
3647 
3648  LOG_SCOPE("broadcast()", "Parallel");
3649 
3650  std::size_t data_size = data.size();
3651  this->broadcast(data_size, root_id);
3652 
3653  std::vector<T> data_c(data_size);
3654 #ifndef NDEBUG
3655  std::string orig(data);
3656 #endif
3657 
3658  if (this->rank() == root_id)
3659  for (std::size_t i=0; i<data.size(); i++)
3660  data_c[i] = data[i];
3661 
3662  this->broadcast (data_c, root_id);
3663 
3664  data.assign(data_c.begin(), data_c.end());
3665 
3666 #ifndef NDEBUG
3667  if (this->rank() == root_id)
3668  libmesh_assert_equal_to (data, orig);
3669 #endif
3670 }
unsigned int size() const
Definition: parallel.h:722
libmesh_assert(j)
void broadcast(T &data, const unsigned int root_id=0) const
unsigned int rank() const
Definition: parallel.h:720
IterBase * data
template<typename T >
void libMesh::Parallel::Communicator::broadcast ( std::vector< T > &  data,
const unsigned int  root_id 
) const
inline

Definition at line 3675 of file parallel_implementation.h.

References libMesh::libmesh_assert(), and libmesh_nullptr.

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

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

Definition at line 3700 of file parallel_implementation.h.

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

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

Definition at line 3762 of file parallel_implementation.h.

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

3764 {
3765  if (this->size() == 1)
3766  {
3767  libmesh_assert (!this->rank());
3768  libmesh_assert (!root_id);
3769  return;
3770  }
3771 
3772  libmesh_assert_less (root_id, this->size());
3773 
3774  LOG_SCOPE("broadcast()", "Parallel");
3775 
3776  std::vector<T> vecdata;
3777  if (this->rank() == root_id)
3778  vecdata.assign(data.begin(), data.end());
3779 
3780  std::size_t vecsize = vecdata.size();
3781  this->broadcast(vecsize, root_id);
3782  if (this->rank() != root_id)
3783  vecdata.resize(vecsize);
3784 
3785  this->broadcast(vecdata, root_id);
3786  if (this->rank() != root_id)
3787  {
3788  data.clear();
3789  data.insert(vecdata.begin(), vecdata.end());
3790  }
3791 }
unsigned int size() const
Definition: parallel.h:722
libmesh_assert(j)
void broadcast(T &data, const unsigned int root_id=0) const
unsigned int rank() const
Definition: parallel.h:720
IterBase * data
template<typename T >
void libMesh::Parallel::Communicator::broadcast ( T &  ,
const unsigned int   libmesh_dbg_varroot_id 
) const
inline

Definition at line 4186 of file parallel_implementation.h.

4188 { 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
inline

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 3848 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().

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

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 libMesh::LibMeshInit::LibMeshInit(), 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
inline

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:748
void libMesh::Parallel::Communicator::duplicate ( const Communicator comm)
inline

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
Definition: parallel.h:762
void libMesh::Parallel::Communicator::duplicate ( const communicator comm)
inline

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)
template<typename T >
void libMesh::Parallel::Communicator::gather ( const unsigned int  root_id,
const T &  send,
std::vector< T > &  recv 
) const
inline

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

References libmesh_nullptr.

Referenced by gather(), libMesh::XdrIO::write_serialized_bcs_helper(), libMesh::XdrIO::write_serialized_connectivity(), libMesh::XdrIO::write_serialized_nodes(), and libMesh::XdrIO::write_serialized_nodesets().

3021 {
3022  libmesh_assert_less (root_id, this->size());
3023 
3024  if (this->rank() == root_id)
3025  recv.resize(this->size());
3026 
3027  if (this->size() > 1)
3028  {
3029  LOG_SCOPE("gather()", "Parallel");
3030 
3031  StandardType<T> send_type(&sendval);
3032 
3033  libmesh_call_mpi
3034  (MPI_Gather(const_cast<T*>(&sendval), 1, send_type,
3035  recv.empty() ? libmesh_nullptr : &recv[0], 1, send_type,
3036  root_id, this->get()));
3037  }
3038  else
3039  recv[0] = sendval;
3040 }
unsigned int size() const
Definition: parallel.h:722
const class libmesh_nullptr_t libmesh_nullptr
unsigned int rank() const
Definition: parallel.h:720
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
inline

Gather overload for string types

Definition at line 3045 of file parallel_implementation.h.

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

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

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

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

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

Gather-to-root on one processor.

Definition at line 4096 of file parallel_implementation.h.

4099 {
4100  libmesh_assert_equal_to (root_id, 0);
4101  recv_val.resize(1);
4102  recv_val[0] = send_val;
4103 }
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
inline

Definition at line 4106 of file parallel_implementation.h.

References allgather(), and gather().

4110 {
4111  libmesh_assert_equal_to (root_id, 0);
4112  recv.resize(1);
4113  recv[0] = sendval;
4114 }
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
inline

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 4197 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().

4202 {
4203  typedef typename std::iterator_traits<Iter>::value_type T;
4204  typedef typename Parallel::Packing<T>::buffer_type buffer_t;
4205 
4206  bool nonempty_range = (range_begin != range_end);
4207  this->max(nonempty_range);
4208 
4209  while (nonempty_range)
4210  {
4211  // We will serialize variable size objects from *range_begin to
4212  // *range_end as a sequence of ints in this buffer
4213  std::vector<buffer_t> buffer;
4214 
4215  range_begin = Parallel::pack_range
4216  (context, range_begin, range_end, buffer);
4217 
4218  this->gather(root_id, buffer);
4219 
4221  (buffer, context, out_iter, (T*)(libmesh_nullptr));
4222 
4223  nonempty_range = (range_begin != range_end);
4224  this->max(nonempty_range);
4225  }
4226 }
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)
const class libmesh_nullptr_t libmesh_nullptr
void gather(const unsigned int root_id, const T &send, std::vector< T > &recv) const
void unpack_range(const typename std::vector< buffertype > &buffer, Context *context, OutputIter out, const T *output_type)
const communicator& libMesh::Parallel::Communicator::get ( ) const
inline

Definition at line 690 of file parallel.h.

References operator=().

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

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:748
template<typename T >
void libMesh::Parallel::Communicator::max ( T &  r) const
inline

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::EpetraVector< T >::close(), 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::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(), libMesh::DistributedVector< T >::max(), 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::Parallel::sync_dofobject_data_by_xyz(), libMesh::MeshRefinement::test_level_one(), and libMesh::MeshRefinement::test_unflagged().

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:722
void max(T &r, const Communicator &comm=Communicator_World)
template<typename T >
void libMesh::Parallel::Communicator::max ( std::vector< T > &  r) const
inline

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 }
unsigned int size() const
Definition: parallel.h:722
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
inline

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(), 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:722
unsigned int rank() const
Definition: parallel.h:720
template<typename T >
void libMesh::Parallel::Communicator::maxloc ( std::vector< T > &  r,
std::vector< unsigned int > &  max_id 
) const
inline

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 }
unsigned int size() const
Definition: parallel.h:722
libmesh_assert(j)
unsigned int rank() const
Definition: parallel.h:720
template<typename T >
void libMesh::Parallel::Communicator::min ( T &  r) const
inline

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(), libMesh::DistributedVector< T >::min(), min(), libMesh::System::point_gradient(), libMesh::System::point_hessian(), libMesh::System::point_value(), and libMesh::Partitioner::set_parent_processor_ids().

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:722
void min(T &r, const Communicator &comm=Communicator_World)
template<typename T >
void libMesh::Parallel::Communicator::min ( std::vector< T > &  r) const
inline

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 }
unsigned int size() const
Definition: parallel.h:722
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
inline

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(), 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:722
unsigned int rank() const
Definition: parallel.h:720
template<typename T >
void libMesh::Parallel::Communicator::minloc ( std::vector< T > &  r,
std::vector< unsigned int > &  min_id 
) const
inline

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 }
unsigned int size() const
Definition: parallel.h:722
libmesh_assert(j)
unsigned int rank() const
Definition: parallel.h:720
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
inline

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

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

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

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

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

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

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)
template<typename T >
Status libMesh::Parallel::Communicator::packed_range_probe ( const unsigned int  src_processor_id,
const MessageTag tag,
bool &  flag 
) const
inline

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  START_LOG("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  STOP_LOG("packed_range_probe()", "Parallel");
2122 
2123  return stat;
2124 }
status libMesh::Parallel::Communicator::probe ( const unsigned int  src_processor_id,
const MessageTag tag = any_tag 
) const
inline

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

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

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
Definition: parallel.h:172
template<typename T >
Status libMesh::Parallel::Communicator::receive ( const unsigned int  dest_processor_id,
T &  buf,
const MessageTag tag = any_tag 
) const
inline

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

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

Definition at line 2551 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(), 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().

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

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

Definition at line 2571 of file parallel_implementation.h.

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

2575 {
2576  LOG_SCOPE("receive()", "Parallel");
2577 
2578  libmesh_call_mpi
2579  (MPI_Irecv (&buf, 1, StandardType<T>(&buf), src_processor_id,
2580  tag.value(), this->get(), req.get()));
2581 }
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
inline

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

Definition at line 3999 of file parallel_implementation.h.

4003 { 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
inline

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

Definition at line 4006 of file parallel_implementation.h.

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

4011 { 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
inline

Definition at line 2507 of file parallel_implementation.h.

References libMesh::Parallel::receive().

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

Definition at line 2522 of file parallel_implementation.h.

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

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

Definition at line 2586 of file parallel_implementation.h.

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

2589 {
2590  return this->receive
2591  (src_processor_id, buf,
2592  StandardType<T>(buf.empty() ? libmesh_nullptr : &(*buf.begin())), tag);
2593 }
const class libmesh_nullptr_t libmesh_nullptr
Status receive(const unsigned int dest_processor_id, T &buf, const MessageTag &tag=any_tag) const
template<typename T >
void libMesh::Parallel::Communicator::receive ( const unsigned int  src_processor_id,
std::set< T > &  buf,
Request req,
const MessageTag tag 
) const
inline

Definition at line 2603 of file parallel_implementation.h.

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

2607 {
2608  this->receive (src_processor_id, buf,
2609  StandardType<T>(buf.empty() ? libmesh_nullptr : &(*buf.begin())), req, tag);
2610 }
const class libmesh_nullptr_t libmesh_nullptr
Status receive(const unsigned int dest_processor_id, T &buf, const MessageTag &tag=any_tag) const
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
inline

Definition at line 2616 of file parallel_implementation.h.

References libMesh::Parallel::receive().

2620 {
2621  LOG_SCOPE("receive()", "Parallel");
2622 
2623  std::vector<T> vecbuf;
2624  Status stat = this->receive(src_processor_id, vecbuf, type, tag);
2625  buf.clear();
2626  buf.insert(vecbuf.begin(), vecbuf.end());
2627 
2628  return stat;
2629 }
Status receive(const unsigned int dest_processor_id, T &buf, const MessageTag &tag=any_tag) const
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
inline

Definition at line 2639 of file parallel_implementation.h.

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

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

Definition at line 2671 of file parallel_implementation.h.

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

2674 {
2675  return this->receive
2676  (src_processor_id, buf,
2677  StandardType<T>(buf.empty() ? libmesh_nullptr : &(*buf.begin())), tag);
2678 }
const class libmesh_nullptr_t libmesh_nullptr
Status receive(const unsigned int dest_processor_id, T &buf, const MessageTag &tag=any_tag) const
template<typename T >
void libMesh::Parallel::Communicator::receive ( const unsigned int  src_processor_id,
std::vector< T > &  buf,
Request req,
const MessageTag tag 
) const
inline

Definition at line 2683 of file parallel_implementation.h.

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

2687 {
2688  this->receive (src_processor_id, buf,
2689  StandardType<T>(buf.empty() ? libmesh_nullptr : &(*buf.begin())), req, tag);
2690 }
const class libmesh_nullptr_t libmesh_nullptr
Status receive(const unsigned int dest_processor_id, T &buf, const MessageTag &tag=any_tag) const
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
inline

Definition at line 2695 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().

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

Definition at line 2724 of file parallel_implementation.h.

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

2729 {
2730  LOG_SCOPE("receive()", "Parallel");
2731 
2732  libmesh_call_mpi
2733  (MPI_Irecv (buf.empty() ? libmesh_nullptr : &buf[0],
2734  cast_int<int>(buf.size()), type, src_processor_id,
2735  tag.value(), this->get(), req.get()));
2736 }
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
inline

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 2740 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().

2745 {
2746  typedef typename Parallel::Packing<T>::buffer_type buffer_t;
2747 
2748  // Receive serialized variable size objects as sequences of buffer_t
2749  std::size_t total_buffer_size = 0;
2750  Status stat = this->receive(src_processor_id, total_buffer_size, tag);
2751 
2752  // Use stat.source() and stat.tag() in subsequent receives - if
2753  // src_processor_id is or tag is "any" then we want to be sure we
2754  // try to receive messages all corresponding to the same send.
2755 
2756  std::size_t received_buffer_size = 0;
2757  while (received_buffer_size < total_buffer_size)
2758  {
2759  std::vector<buffer_t> buffer;
2760  this->receive(stat.source(), buffer, MessageTag(stat.tag()));
2761  received_buffer_size += buffer.size();
2763  (buffer, context, out_iter, output_type);
2764  }
2765 }
Status receive(const unsigned int dest_processor_id, T &buf, const MessageTag &tag=any_tag) const
void unpack_range(const typename std::vector< buffertype > &buffer, Context *context, OutputIter out, const T *output_type)
void libMesh::Parallel::Communicator::reference_unique_tag ( int  tagvalue) const
inline

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:748
template<typename T >
void libMesh::Parallel::Communicator::scatter ( const std::vector< T > &  data,
T &  recv,
const unsigned int  root_id = 0 
) const
inline

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

References libMesh::libmesh_assert(), and libmesh_nullptr.

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

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

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

3425 {
3426  libmesh_assert_less (root_id, this->size());
3427 
3428  if (this->size() == 1)
3429  {
3430  libmesh_assert (!this->rank());
3431  libmesh_assert (!root_id);
3432  recv.assign(data.begin(), data.end());
3433  return;
3434  }
3435 
3436  LOG_SCOPE("scatter()", "Parallel");
3437 
3438  int recv_buffer_size;
3439  if (this->rank() == root_id)
3440  {
3441  libmesh_assert(data.size() % this->size() == 0);
3442  recv_buffer_size = data.size() / this->size();
3443  }
3444 
3445  this->broadcast(recv_buffer_size);
3446  recv.resize(recv_buffer_size);
3447 
3448  T * data_ptr = const_cast<T*>(data.empty() ? libmesh_nullptr : &data[0]);
3449  T * recv_ptr = recv.empty() ? libmesh_nullptr : &recv[0];
3450 
3451  libmesh_call_mpi
3452  (MPI_Scatter (data_ptr, recv_buffer_size, StandardType<T>(data_ptr),
3453  recv_ptr, recv_buffer_size, StandardType<T>(recv_ptr), root_id, this->get()));
3454 }
unsigned int size() const
Definition: parallel.h:722
const class libmesh_nullptr_t libmesh_nullptr
libmesh_assert(j)
void broadcast(T &data, const unsigned int root_id=0) const
unsigned int rank() const
Definition: parallel.h:720
IterBase * data
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
inline

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

References libMesh::libmesh_assert(), and libmesh_nullptr.

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

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

References end, and libMesh::libmesh_assert().

3515 {
3516  libmesh_assert_less (root_id, this->size());
3517 
3518  if (this->size() == 1)
3519  {
3520  libmesh_assert (!this->rank());
3521  libmesh_assert (!root_id);
3522  libmesh_assert (data.size() == this->size());
3523  recv.assign(data[0].begin(), data[0].end());
3524  return;
3525  }
3526 
3527  std::vector<T> stacked_data;
3528  std::vector<int> counts;
3529 
3530  if (root_id == this->rank())
3531  {
3532  libmesh_assert (data.size() == this->size());
3533 
3534  if (!identical_buffer_sizes)
3535  counts.resize(this->size());
3536 
3537  for (std::size_t i=0; i < data.size(); ++i)
3538  {
3539  if (!identical_buffer_sizes)
3540  counts[i] = data[i].size();
3541 #ifndef NDEBUG
3542  else
3543  // Check that buffer sizes are indeed equal
3544  libmesh_assert(!i || data[i-1].size() == data[i].size());
3545 #endif
3546  std::copy(data[i].begin(), data[i].end(), std::back_inserter(stacked_data));
3547  }
3548  }
3549 
3550  if (identical_buffer_sizes)
3551  this->scatter(stacked_data, recv, root_id);
3552  else
3553  this->scatter(stacked_data, counts, recv, root_id);
3554 }
void scatter(const std::vector< T > &data, T &recv, const unsigned int root_id=0) const
unsigned int size() const
Definition: parallel.h:722
IterBase * end
libmesh_assert(j)
unsigned int rank() const
Definition: parallel.h:720
IterBase * data
template<typename T >
void libMesh::Parallel::Communicator::scatter ( const std::vector< T > &  data,
T &  recv,
const unsigned int   libmesh_dbg_varroot_id 
) const
inline

Definition at line 4138 of file parallel_implementation.h.

4141 {
4142  libmesh_assert_equal_to (root_id, 0);
4143  recv = data[0];
4144 }
IterBase * data
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
inline

Definition at line 4148 of file parallel_implementation.h.

4151 {
4152  libmesh_assert_equal_to (root_id, 0);
4153  recv.assign(data.begin(), data.end());
4154 }
IterBase * data
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
inline

Definition at line 4158 of file parallel_implementation.h.

4162 {
4163  libmesh_assert_equal_to (root_id, 0);
4164  libmesh_assert_equal_to (counts.size(), 1);
4165  recv.assign(data.begin(), data.begin() + counts[0]);
4166 }
IterBase * data
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
inline

Definition at line 4170 of file parallel_implementation.h.

References alltoall(), and end.

4174 {
4175  libmesh_assert_equal_to (root_id, 0);
4176  libmesh_assert_equal_to (data.size(), 1);
4177  recv.assign(data[0].begin(), data[0].end());
4178 }
IterBase * end
IterBase * data
template<typename T >
bool libMesh::Parallel::Communicator::semiverify ( const T *  r) const
inline

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(), and semiverify().

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:722
static void set_lowest(T &)
Definition: parallel.h:446
static void set_highest(T &)
Definition: parallel.h:447
static const bool has_min_max
Definition: parallel.h:445
template<>
bool libMesh::Parallel::Communicator::semiverify ( const bool *  r) const
inline

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 }
const class libmesh_nullptr_t libmesh_nullptr
template<typename T >
bool libMesh::Parallel::Communicator::semiverify ( const std::vector< T > *  r) const
inline

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 }
unsigned int size() const
Definition: parallel.h:722
const class libmesh_nullptr_t libmesh_nullptr
static const bool has_min_max
Definition: parallel.h:445
template<typename T >
void libMesh::Parallel::Communicator::send ( const unsigned int  dest_processor_id,
const T &  buf,
const MessageTag tag = no_tag 
) const
inline

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

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

Definition at line 2174 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(), 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().

2177 {
2178  LOG_SCOPE("send()", "Parallel");
2179 
2180  T * dataptr = const_cast<T*> (&buf);
2181 
2182  libmesh_call_mpi
2183  (((this->send_mode() == SYNCHRONOUS) ?
2184  MPI_Ssend : MPI_Send) (dataptr,
2185  1,
2186  StandardType<T>(dataptr),
2187  dest_processor_id,
2188  tag.value(),
2189  this->get()));
2190 }
SendMode send_mode() const
Definition: parallel.h:762
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
inline

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

Definition at line 2195 of file parallel_implementation.h.

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

2199 {
2200  LOG_SCOPE("send()", "Parallel");
2201 
2202  T * dataptr = const_cast<T*>(&buf);
2203 
2204  libmesh_call_mpi
2205  (((this->send_mode() == SYNCHRONOUS) ?
2206  MPI_Issend : MPI_Isend) (dataptr,
2207  1,
2208  StandardType<T>(dataptr),
2209  dest_processor_id,
2210  tag.value(),
2211  this->get(),
2212  req.get()));
2213 }
SendMode send_mode() const
Definition: parallel.h:762
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
inline

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

Definition at line 3951 of file parallel_implementation.h.

3955 { 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
inline

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

Definition at line 3958 of file parallel_implementation.h.

References receive(), and send_packed_range().

3963 { 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
inline

Definition at line 2128 of file parallel_implementation.h.

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

2131 {
2132  LOG_SCOPE("send()", "Parallel");
2133 
2134  T * dataptr = buf.empty() ? libmesh_nullptr : const_cast<T *>(buf.data());
2135 
2136  libmesh_call_mpi
2137  (((this->send_mode() == SYNCHRONOUS) ?
2138  MPI_Ssend : MPI_Send) (dataptr,
2139  cast_int<int>(buf.size()),
2140  StandardType<T>(dataptr),
2141  dest_processor_id,
2142  tag.value(),
2143  this->get()));
2144 }
const class libmesh_nullptr_t libmesh_nullptr
SendMode send_mode() const
Definition: parallel.h:762
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
inline

Definition at line 2149 of file parallel_implementation.h.

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

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

Definition at line 2218 of file parallel_implementation.h.

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

2221 {
2222  this->send(dest_processor_id, buf,
2223  StandardType<T>(buf.empty() ? libmesh_nullptr : &(*buf.begin())), tag);
2224 }
const class libmesh_nullptr_t libmesh_nullptr
void send(const unsigned int dest_processor_id, const T &buf, const MessageTag &tag=no_tag) const
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
inline

Definition at line 2229 of file parallel_implementation.h.

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

2233 {
2234  this->send(dest_processor_id, buf,
2235  StandardType<T>(buf.empty() ? libmesh_nullptr : &(*buf.begin())), req, tag);
2236 }
const class libmesh_nullptr_t libmesh_nullptr
void send(const unsigned int dest_processor_id, const T &buf, const MessageTag &tag=no_tag) const
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
inline

Definition at line 2241 of file parallel_implementation.h.

References libMesh::Parallel::send().

2245 {
2246  LOG_SCOPE("send()", "Parallel");
2247 
2248  std::vector<T> vecbuf(buf.begin(), buf.end());
2249  this->send(dest_processor_id, vecbuf, type, tag);
2250 }
void send(const unsigned int dest_processor_id, const T &buf, const MessageTag &tag=no_tag) const
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
inline

Definition at line 2255 of file parallel_implementation.h.

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

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

Definition at line 2278 of file parallel_implementation.h.

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

2281 {
2282  this->send(dest_processor_id, buf,
2283  StandardType<T>(buf.empty() ? libmesh_nullptr : &buf.front()), tag);
2284 }
const class libmesh_nullptr_t libmesh_nullptr
void send(const unsigned int dest_processor_id, const T &buf, const MessageTag &tag=no_tag) const
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
inline

Definition at line 2289 of file parallel_implementation.h.

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

2293 {
2294  this->send(dest_processor_id, buf,
2295  StandardType<T>(buf.empty() ? libmesh_nullptr : &buf.front()), req, tag);
2296 }
const class libmesh_nullptr_t libmesh_nullptr
void send(const unsigned int dest_processor_id, const T &buf, const MessageTag &tag=no_tag) const
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
inline

Definition at line 2301 of file parallel_implementation.h.

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

2305 {
2306  LOG_SCOPE("send()", "Parallel");
2307 
2308  libmesh_call_mpi
2309  (((this->send_mode() == SYNCHRONOUS) ?
2310  MPI_Ssend : MPI_Send) (buf.empty() ? libmesh_nullptr : const_cast<T*>(&buf[0]),
2311  cast_int<int>(buf.size()),
2312  type,
2313  dest_processor_id,
2314  tag.value(),
2315  this->get()));
2316 }
const class libmesh_nullptr_t libmesh_nullptr
SendMode send_mode() const
Definition: parallel.h:762
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
inline

Definition at line 2321 of file parallel_implementation.h.

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

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

Explicitly sets the SendMode type used for send operations.

Definition at line 757 of file parallel.h.

Referenced by duplicate(), and split().

757 { _send_mode = sm; }
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
inline

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

References 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().

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

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

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

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

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 2858 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().

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

Definition at line 2828 of file parallel_implementation.h.

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

2836 {
2837  LOG_SCOPE("send_receive()", "Parallel");
2838 
2839  if (dest_processor_id == this->rank() &&
2840  source_processor_id == this->rank())
2841  {
2842  recv = sendvec;
2843  return;
2844  }
2845 
2846  Parallel::Request req;
2847 
2848  this->send (dest_processor_id, sendvec, type1, req, send_tag);
2849 
2850  this->receive (source_processor_id, recv, type2, recv_tag);
2851 
2852  req.wait();
2853 }
void send(const unsigned int dest_processor_id, const T &buf, const MessageTag &tag=no_tag) const
Status receive(const unsigned int dest_processor_id, T &buf, const MessageTag &tag=any_tag) const
unsigned int rank() const
Definition: parallel.h:720
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
inline

Definition at line 2903 of file parallel_implementation.h.

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

2909 {
2910  if (dest_processor_id == this->rank() &&
2911  source_processor_id == this->rank())
2912  {
2913  LOG_SCOPE("send_receive()", "Parallel");
2914  recv = sendvec;
2915  return;
2916  }
2917 
2918  const T* example = sendvec.empty() ?
2919  (recv.empty() ? libmesh_nullptr : &recv[0]) : &sendvec[0];
2920 
2921  // Call the user-defined type version with automatic
2922  // type conversion based on template argument:
2923  this->send_receive (dest_processor_id, sendvec,
2924  StandardType<T>(example),
2925  source_processor_id, recv,
2926  StandardType<T>(example),
2927  send_tag, recv_tag);
2928 }
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
unsigned int rank() const
Definition: parallel.h:720
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
inline

Definition at line 2934 of file parallel_implementation.h.

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

2940 {
2941  // Call the user-defined type version with automatic
2942  // type conversion based on template argument:
2943  this->send_receive (dest_processor_id, sendvec,
2944  StandardType<T1>(sendvec.empty() ? libmesh_nullptr : &sendvec[0]),
2945  source_processor_id, recv,
2946  StandardType<T2>(recv.empty() ? libmesh_nullptr : &recv[0]),
2947  send_tag, recv_tag);
2948 }
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
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
inline

Definition at line 2954 of file parallel_implementation.h.

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

2960 {
2961  // FIXME - why aren't we honoring send_tag and recv_tag here?
2962  send_receive_vec_of_vec
2963  (dest_processor_id, sendvec, source_processor_id, recv,
2964  no_tag, any_tag, *this);
2965 }
const MessageTag no_tag
Definition: parallel.h:278
const MessageTag any_tag
Definition: parallel.h:273
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
inline

Definition at line 2972 of file parallel_implementation.h.

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

2978 {
2979  // FIXME - why aren't we honoring send_tag and recv_tag here?
2980  send_receive_vec_of_vec
2981  (dest_processor_id, sendvec, source_processor_id, recv,
2982  no_tag, any_tag, *this);
2983 }
const MessageTag no_tag
Definition: parallel.h:278
const MessageTag any_tag
Definition: parallel.h:273
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
inline

Send a range-of-pointers to one processor while simultaneously receiving another range from a (potentially different) processor. This function does not send or receive raw pointers, but rather constructs new objects at each receiver whose contents match the objects pointed to by the sender.

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

void 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.

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

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

Definition at line 2991 of file parallel_implementation.h.

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

Referenced by receive().

3001 {
3002  LOG_SCOPE("send_receive()", "Parallel");
3003 
3004  Parallel::Request req;
3005 
3006  this->send_packed_range (dest_processor_id, context1, send_begin, send_end,
3007  req, send_tag);
3008 
3009  this->receive_packed_range (source_processor_id, context2, out_iter,
3010  output_type, recv_tag);
3011 
3012  req.wait();
3013 }
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
void receive_packed_range(const unsigned int dest_processor_id, Context *context, OutputIter out, const T *output_type, const MessageTag &tag=any_tag) const
template<typename T >
void libMesh::Parallel::Communicator::set_union ( T &  data,
const unsigned int  root_id 
) const
inline

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 3924 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().

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

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

Definition at line 3921 of file parallel_implementation.h.

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

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
unsigned int rank() const
Definition: parallel.h:720
IterBase * data
template<typename T >
void libMesh::Parallel::Communicator::set_union ( std::set< T > &  data) const
inline

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
void allgather(const T &send, std::vector< T > &recv) const
void libMesh::Parallel::Communicator::split ( int  color,
int  key,
Communicator target 
) const
inline

Definition at line 646 of file parallel_implementation.h.

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

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
Definition: parallel.h:762
template<typename T >
void libMesh::Parallel::Communicator::sum ( T &  r) const
inline

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::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::CondensedEigenSystem::get_eigenpair(), libMesh::DofMap::get_info(), libMesh::DistributedVector< T >::init(), 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::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:722
void sum(T &r, const Communicator &comm=Communicator_World)
template<typename T >
void libMesh::Parallel::Communicator::sum ( std::vector< T > &  r) const
inline

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 }
unsigned int size() const
Definition: parallel.h:722
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
inline

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:722
void sum(T &r, const Communicator &comm=Communicator_World)
template<typename T >
void libMesh::Parallel::Communicator::sum ( std::vector< std::complex< T > > &  r) const
inline

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 }
unsigned int size() const
Definition: parallel.h:722
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
inline

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:722
static const bool has_min_max
Definition: parallel.h:445
template<>
bool libMesh::Parallel::Communicator::verify ( const bool &  r) const
inline

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 }

Member Data Documentation

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

Definition at line 742 of file parallel.h.

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

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

Definition at line 749 of file parallel.h.

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

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

Definition at line 743 of file parallel.h.

Referenced by assign().

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

Definition at line 744 of file parallel.h.

Referenced by assign().

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

Definition at line 743 of file parallel.h.

Referenced by assign().

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

Definition at line 748 of file parallel.h.


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