$extrastylesheet
#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) |
| communicator & | get () |
| const communicator & | get () const |
| MessageTag | get_unique_tag (int tagvalue) const |
| void | reference_unique_tag (int tagvalue) const |
| void | dereference_unique_tag (int tagvalue) const |
| void | clear () |
| Communicator & | operator= (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 > | |
| void | send (const unsigned int dest_processor_id, T &buf, const MessageTag &tag=no_tag) const |
| template<typename T > | |
| void | send (const unsigned int dest_processor_id, T &buf, Request &req, const MessageTag &tag=no_tag) const |
| template<typename T > | |
| void | send (const unsigned int dest_processor_id, T &buf, const DataType &type, const MessageTag &tag=no_tag) const |
| template<typename T > | |
| void | send (const unsigned int dest_processor_id, 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 OutputIter > | |
| void | receive_packed_range (const unsigned int dest_processor_id, Context *context, OutputIter out, const MessageTag &tag=any_tag) const |
| template<typename T1 , typename T2 > | |
| void | send_receive (const unsigned int dest_processor_id, 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 > | |
| 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 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, 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, T send, std::vector< T > &recv) const |
| template<typename T > | |
| void | gather (const unsigned int root_id, std::vector< T > &r) const |
| template<typename T > | |
| void | allgather (T send, std::vector< T > &recv) const |
| template<typename T > | |
| void | allgather (std::vector< T > &r, 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<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, std::basic_string< T > &buf, const MessageTag &tag) const |
| template<typename T > | |
| void | send (const unsigned int dest_processor_id, std::basic_string< T > &buf, Request &req, const MessageTag &tag) const |
| template<typename T > | |
| void | send (const unsigned int dest_processor_id, std::set< T > &buf, const MessageTag &tag) const |
| template<typename T > | |
| void | send (const unsigned int dest_processor_id, std::set< T > &buf, Request &req, const MessageTag &tag) const |
| template<typename T > | |
| void | send (const unsigned int dest_processor_id, std::set< T > &buf, const DataType &type, const MessageTag &tag) const |
| template<typename T > | |
| void | send (const unsigned int dest_processor_id, std::set< T > &buf, const DataType &type, Request &req, const MessageTag &tag) const |
| template<typename T > | |
| void | send (const unsigned int dest_processor_id, std::vector< T > &buf, const MessageTag &tag) const |
| template<typename T > | |
| void | send (const unsigned int dest_processor_id, std::vector< T > &buf, Request &req, const MessageTag &tag) const |
| template<typename T > | |
| void | send (const unsigned int dest_processor_id, std::vector< T > &buf, const DataType &type, const MessageTag &tag) const |
| template<typename T > | |
| void | send (const unsigned int dest_processor_id, 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, 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, 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, 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, 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, std::vector< std::vector< T > > &sendvec, const unsigned int source_processor_id, std::vector< std::vector< T > > &recv, const MessageTag &, const MessageTag &) 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 |
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 |
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 579 of file parallel.h.
Whether to use default or synchronous sends?
Definition at line 652 of file parallel.h.
{ DEFAULT=0, SYNCHRONOUS };
| libMesh::Parallel::Communicator::Communicator | ( | ) | [inline] |
Default Constructor.
Definition at line 469 of file parallel_implementation.h.
: #ifdef LIBMESH_HAVE_MPI _communicator(MPI_COMM_SELF), #endif _rank(0), _size(1), _send_mode(DEFAULT), used_tag_values(), _I_duped_it(false) {}
| libMesh::Parallel::Communicator::Communicator | ( | const communicator & | comm | ) | [inline, explicit] |
Definition at line 479 of file parallel_implementation.h.
References assign().
: #ifdef LIBMESH_HAVE_MPI _communicator(MPI_COMM_SELF), #endif _rank(0), _size(1), _send_mode(DEFAULT), used_tag_values(), _I_duped_it(false) { this->assign(comm); }
| libMesh::Parallel::Communicator::~Communicator | ( | ) | [inline] |
| libMesh::Parallel::Communicator::Communicator | ( | const Communicator & | ) | [inline, explicit, private] |
Definition at line 547 of file parallel_implementation.h.
: #ifdef LIBMESH_HAVE_MPI _communicator(MPI_COMM_NULL), #endif _rank(0), _size(1), _send_mode(DEFAULT), used_tag_values(), _I_duped_it(false) { libmesh_not_implemented(); }
| void libMesh::Parallel::Communicator::allgather | ( | 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 2892 of file parallel_implementation.h.
References libMesh::libmesh_assert(), size(), and libMesh::START_LOG().
Referenced by libMesh::Parallel::allgather(), libMesh::LaplaceMeshSmoother::allgather_graph(), 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::DofMap::set_nonlocal_dof_objects(), and set_union().
{
START_LOG ("allgather()","Parallel");
libmesh_assert(this->size());
recv.resize(this->size());
unsigned int comm_size = this->size();
if (comm_size > 1)
{
StandardType<T> send_type(&sendval);
MPI_Allgather (&sendval,
1,
send_type,
&recv[0],
1,
send_type,
this->get());
}
else if (comm_size > 0)
recv[0] = sendval;
STOP_LOG ("allgather()","Parallel");
}
| 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 2923 of file parallel_implementation.h.
References libMesh::Parallel::allgather(), libMesh::ierr, libMesh::libmesh_assert(), libMesh::START_LOG(), and libMesh::Parallel::verify().
{
if (this->size() < 2)
return;
START_LOG("allgather()", "Parallel");
if (identical_buffer_sizes)
{
if (r.empty())
return;
libmesh_assert(this->verify(r.size()));
std::vector<T> r_src(r.size()*this->size());
r_src.swap(r);
StandardType<T> send_type(&r_src[0]);
MPI_Allgather (&r_src[0],
cast_int<int>(r_src.size()),
send_type,
&r[0],
cast_int<int>(r_src.size()),
send_type,
this->get());
libmesh_assert(this->verify(r));
STOP_LOG("allgather()", "Parallel");
return;
}
std::vector<int>
sendlengths (this->size(), 0),
displacements(this->size(), 0);
const int mysize = static_cast<int>(r.size());
this->allgather(mysize, sendlengths);
// Find the total size of the final array and
// set up the displacement offsets for each processor.
unsigned int globalsize = 0;
for (unsigned int i=0; i != this->size(); ++i)
{
displacements[i] = globalsize;
globalsize += sendlengths[i];
}
// Check for quick return
if (globalsize == 0)
{
STOP_LOG("allgather()", "Parallel");
return;
}
// copy the input buffer
std::vector<T> r_src(globalsize);
r_src.swap(r);
StandardType<T> send_type(&r[0]);
// and get the data from the remote processors.
// Pass NULL if our vector is empty.
#ifndef NDEBUG
// Only catch the return value when asserts are active.
const int ierr =
#endif
MPI_Allgatherv (r_src.empty() ? NULL : &r_src[0], mysize, send_type,
&r[0], &sendlengths[0],
&displacements[0], send_type, this->get());
libmesh_assert (ierr == MPI_SUCCESS);
STOP_LOG("allgather()", "Parallel");
}
| 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 3033 of file parallel_implementation.h.
References libMesh::Parallel::allgather(), libMesh::libmesh_assert(), libMesh::Parallel::max(), libMesh::Parallel::pack_range(), and libMesh::Parallel::unpack_range().
Referenced by libMesh::Parallel::allgather_packed_range().
{
typedef typename std::iterator_traits<Iter>::value_type T;
typedef typename Parallel::BufferType<T>::type buffer_t;
bool nonempty_range = (range_begin != range_end);
this->max(nonempty_range);
while (nonempty_range)
{
// We will serialize variable size objects from *range_begin to
// *range_end as a sequence of ints in this buffer
std::vector<buffer_t> buffer;
range_begin = Parallel::pack_range(context, range_begin, range_end, buffer);
this->allgather(buffer, false);
libmesh_assert(buffer.size());
Parallel::unpack_range(buffer, context, out);
nonempty_range = (range_begin != range_end);
this->max(nonempty_range);
}
}
| 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 3065 of file parallel_implementation.h.
References libMesh::ierr, libMesh::libmesh_assert(), size(), libMesh::START_LOG(), and verify().
Referenced by libMesh::Parallel::alltoall(), and libMesh::Nemesis_IO::read().
{
if (this->size() < 2 || buf.empty())
return;
START_LOG("alltoall()", "Parallel");
// the per-processor size. this is the same for all
// processors using MPI_Alltoall, could be variable
// using MPI_Alltoallv
const int size_per_proc =
cast_int<int>(buf.size()/this->size());
libmesh_assert_equal_to (buf.size()%this->size(), 0);
libmesh_assert(this->verify(size_per_proc));
std::vector<T> tmp(buf);
StandardType<T> send_type(&tmp[0]);
#ifndef NDEBUG
// Only catch the return value when asserts are active.
const int ierr =
#endif
MPI_Alltoall (&tmp[0],
size_per_proc,
send_type,
&buf[0],
size_per_proc,
send_type,
this->get());
libmesh_assert (ierr == MPI_SUCCESS);
STOP_LOG("alltoall()", "Parallel");
}
| void libMesh::Parallel::Communicator::assign | ( | const communicator & | comm | ) | [inline, private] |
Utility function for setting our member variables from an MPI communicator
Definition at line 560 of file parallel_implementation.h.
References _communicator, _rank, _send_mode, _size, and DEFAULT.
Referenced by Communicator(), duplicate(), operator=(), and split().
{
_communicator = comm;
#ifdef LIBMESH_HAVE_MPI
if (_communicator != MPI_COMM_NULL)
{
int i;
MPI_Comm_size(_communicator, &i);
libmesh_assert_greater_equal (i, 0);
_size = static_cast<unsigned int>(i);
MPI_Comm_rank(_communicator, &i);
libmesh_assert_greater_equal (i, 0);
_rank = static_cast<unsigned int>(i);
}
else
{
_rank = 0;
_size = 1;
}
#endif
_send_mode = DEFAULT;
}
| void libMesh::Parallel::Communicator::barrier | ( | ) | const [inline] |
Pause execution until all processors reach a certain point.
Definition at line 832 of file parallel_implementation.h.
References size(), and libMesh::START_LOG().
Referenced by libMesh::Parallel::barrier(), libMesh::NameBasedIO::write(), libMesh::CheckpointIO::write(), and libMesh::XdrIO::write().
| 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 3105 of file parallel_implementation.h.
References libMesh::ierr, libMesh::libmesh_assert(), rank(), size(), and libMesh::START_LOG().
Referenced by libMesh::MetisPartitioner::_do_partition(), libMesh::EquationSystems::_read_impl(), libMesh::Parallel::broadcast(), broadcast(), libMesh::System::point_gradient(), libMesh::System::point_hessian(), libMesh::System::point_value(), libMesh::XdrIO::read(), libMesh::System::read_header(), libMesh::System::read_legacy_data(), libMesh::XdrIO::read_serialized_bc_names(), libMesh::XdrIO::read_serialized_bcs(), libMesh::XdrIO::read_serialized_connectivity(), libMesh::XdrIO::read_serialized_nodes(), libMesh::XdrIO::read_serialized_nodesets(), libMesh::XdrIO::read_serialized_subdomain_names(), libMesh::System::read_serialized_vector(), libMesh::NameBasedIO::write(), and libMesh::System::write_serialized_blocked_dof_objects().
{
if (this->size() == 1)
{
libmesh_assert (!this->rank());
libmesh_assert (!root_id);
return;
}
libmesh_assert_less (root_id, this->size());
START_LOG("broadcast()", "Parallel");
// Spread data to remote processors.
#ifndef NDEBUG
// Only catch the return value when asserts are active.
const int ierr =
#endif
MPI_Bcast (&data, 1, StandardType<T>(&data), root_id, this->get());
libmesh_assert (ierr == MPI_SUCCESS);
STOP_LOG("broadcast()", "Parallel");
}
| void libMesh::Parallel::Communicator::broadcast | ( | std::basic_string< T > & | data, |
| const unsigned int | root_id | ||
| ) | const [inline] |
Definition at line 3132 of file parallel_implementation.h.
References broadcast(), libMesh::libmesh_assert(), rank(), size(), and libMesh::START_LOG().
{
if (this->size() == 1)
{
libmesh_assert (!this->rank());
libmesh_assert (!root_id);
return;
}
libmesh_assert_less (root_id, this->size());
START_LOG("broadcast()", "Parallel");
std::size_t data_size = data.size();
this->broadcast(data_size, root_id);
std::vector<T> data_c(data_size);
#ifndef NDEBUG
std::string orig(data);
#endif
if (this->rank() == root_id)
for(std::size_t i=0; i<data.size(); i++)
data_c[i] = data[i];
this->broadcast (data_c, root_id);
data.assign(data_c.begin(), data_c.end());
#ifndef NDEBUG
if (this->rank() == root_id)
libmesh_assert_equal_to (data, orig);
#endif
STOP_LOG("broadcast()", "Parallel");
}
| void libMesh::Parallel::Communicator::broadcast | ( | std::vector< T > & | data, |
| const unsigned int | root_id | ||
| ) | const [inline] |
Definition at line 3173 of file parallel_implementation.h.
References libMesh::ierr, libMesh::libmesh_assert(), rank(), size(), and libMesh::START_LOG().
{
if (this->size() == 1)
{
libmesh_assert (!this->rank());
libmesh_assert (!root_id);
return;
}
libmesh_assert_less (root_id, this->size());
START_LOG("broadcast()", "Parallel");
// and get the data from the remote processors.
// Pass NULL if our vector is empty.
T *data_ptr = data.empty() ? NULL : &data[0];
#ifndef NDEBUG
// Only catch the return value when asserts are active.
const int ierr =
#endif
MPI_Bcast (data_ptr, cast_int<int>(data.size()),
StandardType<T>(data_ptr), root_id, this->get());
libmesh_assert (ierr == MPI_SUCCESS);
STOP_LOG("broadcast()", "Parallel");
}
| 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 preceeding the actual characters
Definition at line 3205 of file parallel_implementation.h.
References broadcast(), libMesh::libmesh_assert(), rank(), size(), and libMesh::START_LOG().
{
if (this->size() == 1)
{
libmesh_assert (!this->rank());
libmesh_assert (!root_id);
return;
}
libmesh_assert_less (root_id, this->size());
START_LOG("broadcast()", "Parallel");
std::size_t bufsize=0;
if (root_id == this->rank())
{
for (std::size_t i=0; i<data.size(); ++i)
bufsize += data[i].size() + 1; // Add one for the string length word
}
this->broadcast(bufsize, root_id);
// Here we use unsigned int to store up to 32-bit characters
std::vector<unsigned int> temp; temp.reserve(bufsize);
// Pack the strings
if (root_id == this->rank())
{
for (unsigned int i=0; i<data.size(); ++i)
{
temp.push_back(cast_int<unsigned int>(data[i].size()));
for (std::size_t j=0; j != data[i].size(); ++j)
temp.push_back(data[i][j]);
}
}
else
temp.resize(bufsize);
// broad cast the packed strings
this->broadcast(temp, root_id);
// Unpack the strings
if (root_id != this->rank())
{
data.clear();
std::vector<unsigned int>::const_iterator iter = temp.begin();
while (iter != temp.end())
{
std::size_t curr_len = *iter++;
data.push_back(std::string(iter, iter+curr_len));
iter += curr_len;
}
}
STOP_LOG("broadcast()", "Parallel");
}
| void libMesh::Parallel::Communicator::broadcast | ( | std::set< T > & | data, |
| const unsigned int | root_id | ||
| ) | const [inline] |
Definition at line 3269 of file parallel_implementation.h.
References broadcast(), libMesh::libmesh_assert(), rank(), size(), and libMesh::START_LOG().
{
if (this->size() == 1)
{
libmesh_assert (!this->rank());
libmesh_assert (!root_id);
return;
}
libmesh_assert_less (root_id, this->size());
START_LOG("broadcast()", "Parallel");
std::vector<T> vecdata;
if (this->rank() == root_id)
vecdata.assign(data.begin(), data.end());
std::size_t vecsize = vecdata.size();
this->broadcast(vecsize, root_id);
if (this->rank() != root_id)
vecdata.resize(vecsize);
this->broadcast(vecdata, root_id);
if (this->rank() != root_id)
{
data.clear();
data.insert(vecdata.begin(), vecdata.end());
}
STOP_LOG("broadcast()", "Parallel");
}
| 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 3359 of file parallel_implementation.h.
References libMesh::Parallel::broadcast(), libMesh::Parallel::pack_range(), and libMesh::Parallel::unpack_range().
Referenced by libMesh::Parallel::broadcast_packed_range().
{
typedef typename std::iterator_traits<Iter>::value_type T;
typedef typename Parallel::BufferType<T>::type buffer_t;
do
{
// We will serialize variable size objects from *range_begin to
// *range_end as a sequence of ints in this buffer
std::vector<buffer_t> buffer;
if (this->rank() == root_id)
range_begin = Parallel::pack_range(context1, range_begin, range_end, buffer);
// this->broadcast(vector) requires the receiving vectors to
// already be the appropriate size
std::size_t buffer_size = buffer.size();
this->broadcast (buffer_size, root_id);
// We continue until there's nothing left to broadcast
if (!buffer_size)
break;
buffer.resize(buffer_size);
// Broadcast the packed data
this->broadcast (buffer, root_id);
if (this->rank() != root_id)
Parallel::unpack_range(buffer, context2, out);
} while (true); // break above when we reach buffer_size==0
}
| void libMesh::Parallel::Communicator::clear | ( | ) | [inline] |
Free and reset this communicator
Definition at line 528 of file parallel_implementation.h.
References _communicator, _I_duped_it, and libMesh::libmesh_assert().
Referenced by operator=(), split(), ~Communicator(), and libMesh::LibMeshInit::~LibMeshInit().
{
#ifdef LIBMESH_HAVE_MPI
if (_I_duped_it)
{
libmesh_assert (_communicator != MPI_COMM_NULL);
MPI_Comm_free(&_communicator);
_communicator = MPI_COMM_NULL;
}
_I_duped_it = false;
#endif
}
| 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 1197 of file parallel_implementation.h.
References libMesh::libmesh_assert(), and used_tag_values.
Referenced by libMesh::Parallel::MessageTag::~MessageTag().
{
// This has better be an already-acquired tag.
libmesh_assert(used_tag_values.count(tagvalue));
used_tag_values[tagvalue]--;
// If we don't have any more outstanding references, we
// don't even need to keep this tag in our "used" set.
if (!used_tag_values[tagvalue])
used_tag_values.erase(tagvalue);
}
| void libMesh::Parallel::Communicator::duplicate | ( | const Communicator & | comm | ) | [inline] |
Definition at line 510 of file parallel_implementation.h.
References _communicator, and send_mode().
| void libMesh::Parallel::Communicator::duplicate | ( | const communicator & | comm | ) | [inline] |
Definition at line 516 of file parallel_implementation.h.
References _communicator, _I_duped_it, and assign().
{
if (_communicator != MPI_COMM_NULL)
{
MPI_Comm_dup(comm, &_communicator);
_I_duped_it = true;
}
this->assign(_communicator);
}
| void libMesh::Parallel::Communicator::gather | ( | const unsigned int | root_id, |
| T | send_val, | ||
| std::vector< T > & | recv_val | ||
| ) | 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
Gather-to-root on one processor.
Definition at line 2796 of file parallel_implementation.h.
References rank(), size(), and libMesh::START_LOG().
Referenced by libMesh::Parallel::gather(), set_union(), libMesh::XdrIO::write_serialized_bcs(), libMesh::XdrIO::write_serialized_connectivity(), libMesh::XdrIO::write_serialized_nodes(), and libMesh::XdrIO::write_serialized_nodesets().
{
libmesh_assert_less (root_id, this->size());
if (this->rank() == root_id)
recv.resize(this->size());
if (this->size() > 1)
{
START_LOG("gather()", "Parallel");
StandardType<T> send_type(&sendval);
MPI_Gather(&sendval,
1,
send_type,
recv.empty() ? NULL : &recv[0],
1,
send_type,
root_id,
this->get());
STOP_LOG("gather()", "Parallel");
}
else
recv[0] = sendval;
}
| 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 2829 of file parallel_implementation.h.
References allgather(), libMesh::ierr, libMesh::libmesh_assert(), rank(), size(), and libMesh::START_LOG().
{
if (this->size() == 1)
{
libmesh_assert (!this->rank());
libmesh_assert (!root_id);
return;
}
libmesh_assert_less (root_id, this->size());
std::vector<int>
sendlengths (this->size(), 0),
displacements(this->size(), 0);
const int mysize = static_cast<int>(r.size());
this->allgather(mysize, sendlengths);
START_LOG("gather()", "Parallel");
// Find the total size of the final array and
// set up the displacement offsets for each processor.
unsigned int globalsize = 0;
for (unsigned int i=0; i != this->size(); ++i)
{
displacements[i] = globalsize;
globalsize += sendlengths[i];
}
// Check for quick return
if (globalsize == 0)
{
STOP_LOG("gather()", "Parallel");
return;
}
// copy the input buffer
std::vector<T> r_src(r);
// now resize it to hold the global data
// on the receiving processor
if (root_id == this->rank())
r.resize(globalsize);
// and get the data from the remote processors
#ifndef NDEBUG
// Only catch the return value when asserts are active.
const int ierr =
#endif
MPI_Gatherv (r_src.empty() ? NULL : &r_src[0], mysize, StandardType<T>(),
r.empty() ? NULL : &r[0], &sendlengths[0],
&displacements[0], StandardType<T>(),
root_id,
this->get());
libmesh_assert (ierr == MPI_SUCCESS);
STOP_LOG("gather()", "Parallel");
}
| 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 3001 of file parallel_implementation.h.
References libMesh::Parallel::gather(), libMesh::Parallel::max(), libMesh::Parallel::pack_range(), and libMesh::Parallel::unpack_range().
Referenced by libMesh::Parallel::gather_packed_range().
{
typedef typename std::iterator_traits<Iter>::value_type T;
typedef typename Parallel::BufferType<T>::type buffer_t;
bool nonempty_range = (range_begin != range_end);
this->max(nonempty_range);
while (nonempty_range)
{
// We will serialize variable size objects from *range_begin to
// *range_end as a sequence of ints in this buffer
std::vector<buffer_t> buffer;
range_begin = Parallel::pack_range(context, range_begin, range_end, buffer);
this->gather(root_id, buffer);
Parallel::unpack_range(buffer, context, out);
nonempty_range = (range_begin != range_end);
this->max(nonempty_range);
}
}
| communicator& libMesh::Parallel::Communicator::get | ( | ) | [inline] |
Definition at line 614 of file parallel.h.
References _communicator.
Referenced by libMesh::__libmesh_petsc_diff_solver_monitor(), libMesh::__libmesh_petsc_snes_residual(), libMesh::ParmetisPartitioner::_do_repartition(), libMesh::PetscLinearSolver< T >::_petsc_shell_matrix_get_diagonal(), libMesh::PetscLinearSolver< T >::_petsc_shell_matrix_mult(), libMesh::PetscLinearSolver< T >::_petsc_shell_matrix_mult_add(), and EXTERN_C_FOR_PETSC_END::indices_to_fieldsplit().
{ return _communicator; }
| const communicator& libMesh::Parallel::Communicator::get | ( | ) | const [inline] |
| MessageTag libMesh::Parallel::Communicator::get_unique_tag | ( | int | tagvalue | ) | const [inline] |
Get a tag that is unique to this Communicator. Note that 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 1163 of file parallel_implementation.h.
References libMesh::libmesh_assert(), and used_tag_values.
Referenced by libMesh::Nemesis_IO::read(), libMesh::System::read_SCALAR_dofs(), libMesh::System::read_serialized_blocked_dof_objects(), libMesh::System::write_serialized_blocked_dof_objects(), and libMesh::XdrIO::write_serialized_nodes().
{
if (used_tag_values.count(tagvalue))
{
// Get the largest value in the used values, and pick one
// larger
tagvalue = used_tag_values.rbegin()->first+1;
libmesh_assert(!used_tag_values.count(tagvalue));
}
used_tag_values[tagvalue] = 1;
// #ifndef NDEBUG
// // Make sure everyone called get_unique_tag and make sure
// // everyone got the same value
// int maxval = tagvalue;
// this->max(maxval);
// libmesh_assert_equal_to (tagvalue, maxval);
// #endif
return MessageTag(tagvalue, this);
}
| 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 1576 of file parallel_implementation.h.
References size(), and libMesh::START_LOG().
Referenced by libMesh::MeshRefinement::_coarsen_elements(), libMesh::MeshRefinement::_refine_elements(), libMesh::UnstructuredMesh::all_second_order(), libMesh::DofMap::attach_matrix(), libMesh::MeshTools::bounding_box(), libMesh::System::calculate_norm(), libMesh::EpetraVector< T >::close(), libMesh::MeshRefinement::coarsen_elements(), libMesh::MeshRefinement::eliminate_unrefined_patches(), libMesh::MeshRefinement::flag_elements_by_error_fraction(), libMesh::MeshRefinement::flag_elements_by_nelem_target(), libMesh::LocationMap< T >::init(), libMesh::MeshTools::libmesh_assert_valid_dof_ids(), libMesh::MeshTools::libmesh_assert_valid_procids< Elem >(), libMesh::MeshTools::libmesh_assert_valid_procids< Node >(), libMesh::MeshRefinement::limit_level_mismatch_at_edge(), libMesh::MeshRefinement::limit_level_mismatch_at_node(), libMesh::Parallel::max(), libMesh::MeshTools::n_active_levels(), libMesh::MeshTools::n_levels(), libMesh::MeshTools::n_p_levels(), libMesh::ParallelMesh::parallel_max_elem_id(), libMesh::ParallelMesh::parallel_max_node_id(), libMesh::Nemesis_IO::read(), libMesh::MeshBase::recalculate_n_partitions(), libMesh::MeshRefinement::refine_and_coarsen_elements(), libMesh::MeshRefinement::refine_elements(), semiverify(), libMesh::Parallel::sync_dofobject_data_by_xyz(), libMesh::MeshRefinement::test_level_one(), libMesh::MeshRefinement::test_unflagged(), and verify().
| void libMesh::Parallel::Communicator::max | ( | std::vector< T > & | r | ) | const [inline] |
Definition at line 1618 of file parallel_implementation.h.
References libMesh::libmesh_assert(), size(), libMesh::START_LOG(), and verify().
{
if (this->size() > 1 && !r.empty())
{
START_LOG("max(vector)", "Parallel");
libmesh_assert(this->verify(r.size()));
std::vector<T> temp(r);
MPI_Allreduce (&temp[0],
&r[0],
cast_int<int>(r.size()),
StandardType<T>(&temp[0]),
MPI_MAX,
this->get());
STOP_LOG("max(vector)", "Parallel");
}
}
| 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 1664 of file parallel_implementation.h.
References libMesh::out, libMesh::Parallel::DataPlusInt< T >::rank, rank(), size(), libMesh::START_LOG(), and libMesh::Parallel::DataPlusInt< T >::val.
Referenced by libMesh::Parallel::maxloc().
{
if (this->size() > 1)
{
START_LOG("maxloc(scalar)", "Parallel");
DataPlusInt<T> in;
in.val = r;
in.rank = this->rank();
DataPlusInt<T> out;
MPI_Allreduce (&in,
&out,
1,
dataplusint_type<T>(),
MPI_MAXLOC,
this->get());
r = out.val;
max_id = out.rank;
STOP_LOG("maxloc(scalar)", "Parallel");
}
else
max_id = this->rank();
}
| 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 1719 of file parallel_implementation.h.
References libMesh::libmesh_assert(), libMesh::out, libMesh::Parallel::DataPlusInt< T >::rank, rank(), size(), libMesh::START_LOG(), libMesh::Parallel::DataPlusInt< T >::val, and verify().
{
if (this->size() > 1 && !r.empty())
{
START_LOG("maxloc(vector)", "Parallel");
libmesh_assert(this->verify(r.size()));
std::vector<DataPlusInt<T> > in(r.size());
for (std::size_t i=0; i != r.size(); ++i)
{
in[i].val = r[i];
in[i].rank = this->rank();
}
std::vector<DataPlusInt<T> > out(r.size());
MPI_Allreduce (&in[0],
&out[0],
cast_int<int>(r.size()),
dataplusint_type<T>(),
MPI_MAXLOC,
this->get());
for (std::size_t i=0; i != r.size(); ++i)
{
r[i] = out[i].val;
max_id[i] = out[i].rank;
}
STOP_LOG("maxloc(vector)", "Parallel");
}
else if (!r.empty())
{
for (std::size_t i=0; i != r.size(); ++i)
max_id[i] = this->rank();
}
}
| 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 1357 of file parallel_implementation.h.
References size(), and libMesh::START_LOG().
Referenced by libMesh::MeshTools::bounding_box(), libMesh::MeshRefinement::coarsen_elements(), libMesh::MeshRefinement::flag_elements_by_error_fraction(), libMesh::LocationMap< T >::init(), libMesh::ParallelMesh::libmesh_assert_valid_parallel_flags(), libMesh::MeshTools::libmesh_assert_valid_procids< Elem >(), libMesh::MeshTools::libmesh_assert_valid_procids< Node >(), libMesh::MeshTools::libmesh_assert_valid_refinement_flags(), libMesh::MeshRefinement::make_coarsening_compatible(), libMesh::MeshRefinement::make_flags_parallel_consistent(), libMesh::MeshRefinement::make_refinement_compatible(), libMesh::Parallel::min(), libMesh::System::point_gradient(), libMesh::System::point_hessian(), libMesh::System::point_value(), libMesh::MeshRefinement::refine_and_coarsen_elements(), libMesh::MeshRefinement::refine_elements(), semiverify(), and verify().
| void libMesh::Parallel::Communicator::min | ( | std::vector< T > & | r | ) | const [inline] |
Definition at line 1398 of file parallel_implementation.h.
References libMesh::libmesh_assert(), size(), libMesh::START_LOG(), and verify().
{
if (this->size() > 1 && !r.empty())
{
START_LOG("min(vector)", "Parallel");
libmesh_assert(this->verify(r.size()));
std::vector<T> temp(r);
MPI_Allreduce (&temp[0],
&r[0],
cast_int<int>(r.size()),
StandardType<T>(&temp[0]),
MPI_MIN,
this->get());
STOP_LOG("min(vector)", "Parallel");
}
}
| 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 1444 of file parallel_implementation.h.
References libMesh::out, libMesh::Parallel::DataPlusInt< T >::rank, rank(), size(), libMesh::START_LOG(), and libMesh::Parallel::DataPlusInt< T >::val.
Referenced by libMesh::Parallel::minloc().
{
if (this->size() > 1)
{
START_LOG("minloc(scalar)", "Parallel");
DataPlusInt<T> in;
in.val = r;
in.rank = this->rank();
DataPlusInt<T> out;
MPI_Allreduce (&in,
&out,
1,
dataplusint_type<T>(),
MPI_MINLOC,
this->get());
r = out.val;
min_id = out.rank;
STOP_LOG("minloc(scalar)", "Parallel");
}
else
min_id = this->rank();
}
| 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 1499 of file parallel_implementation.h.
References libMesh::libmesh_assert(), libMesh::out, libMesh::Parallel::DataPlusInt< T >::rank, rank(), size(), libMesh::START_LOG(), libMesh::Parallel::DataPlusInt< T >::val, and verify().
{
if (this->size() > 1 && !r.empty())
{
START_LOG("minloc(vector)", "Parallel");
libmesh_assert(this->verify(r.size()));
std::vector<DataPlusInt<T> > in(r.size());
for (std::size_t i=0; i != r.size(); ++i)
{
in[i].val = r[i];
in[i].rank = this->rank();
}
std::vector<DataPlusInt<T> > out(r.size());
MPI_Allreduce (&in[0],
&out[0],
cast_int<int>(r.size()),
dataplusint_type<T>(),
MPI_MINLOC,
this->get());
for (std::size_t i=0; i != r.size(); ++i)
{
r[i] = out[i].val;
min_id[i] = out[i].rank;
}
STOP_LOG("minloc(vector)", "Parallel");
}
else if (!r.empty())
{
for (std::size_t i=0; i != r.size(); ++i)
min_id[i] = this->rank();
}
}
| Communicator & libMesh::Parallel::Communicator::operator= | ( | const communicator & | comm | ) | [inline] |
| 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 1925 of file parallel_implementation.h.
References libMesh::START_LOG(), and libMesh::Parallel::MessageTag::value().
Referenced by libMesh::Parallel::probe(), and receive().
| unsigned int libMesh::Parallel::Communicator::rank | ( | ) | const [inline] |
Definition at line 645 of file parallel.h.
References _rank.
Referenced by broadcast(), libMesh::MeshCommunication::find_global_indices(), gather(), maxloc(), minloc(), libMesh::ParallelObject::processor_id(), send_receive(), set_union(), libMesh::Parallel::sync_dofobject_data_by_id(), and libMesh::Parallel::sync_dofobject_data_by_xyz().
{ return _rank; }
| 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 2341 of file parallel_implementation.h.
References libMesh::Parallel::Status::get(), libMesh::ierr, libMesh::libmesh_assert(), probe(), libMesh::START_LOG(), and libMesh::Parallel::MessageTag::value().
Referenced by libMesh::SystemSubsetBySubdomain::init(), libMesh::Parallel::nonblocking_receive(), libMesh::Nemesis_IO::read(), libMesh::System::read_SCALAR_dofs(), libMesh::System::read_serialized_blocked_dof_objects(), libMesh::Parallel::receive(), receive(), receive_packed_range(), send_receive(), libMesh::System::write_SCALAR_dofs(), libMesh::XdrIO::write_serialized_bcs(), libMesh::System::write_serialized_blocked_dof_objects(), libMesh::XdrIO::write_serialized_connectivity(), libMesh::XdrIO::write_serialized_nodes(), and libMesh::XdrIO::write_serialized_nodesets().
{
START_LOG("receive()", "Parallel");
// Get the status of the message, explicitly provide the
// datatype so we can later query the size
Status stat(this->probe(src_processor_id, tag), StandardType<T>(&buf));
#ifndef NDEBUG
// Only catch the return value when asserts are active.
const int ierr =
#endif
MPI_Recv (&buf,
1,
StandardType<T>(&buf),
src_processor_id,
tag.value(),
this->get(),
stat.get());
libmesh_assert (ierr == MPI_SUCCESS);
STOP_LOG("receive()", "Parallel");
return stat;
}
| 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 2372 of file parallel_implementation.h.
References libMesh::Parallel::Request::get(), libMesh::ierr, libMesh::libmesh_assert(), libMesh::START_LOG(), and libMesh::Parallel::MessageTag::value().
{
START_LOG("receive()", "Parallel");
#ifndef NDEBUG
// Only catch the return value when asserts are active.
const int ierr =
#endif
MPI_Irecv (&buf,
1,
StandardType<T>(&buf),
src_processor_id,
tag.value(),
this->get(),
req.get());
libmesh_assert (ierr == MPI_SUCCESS);
STOP_LOG("receive()", "Parallel");
}
| 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 3492 of file parallel_implementation.h.
{ libmesh_not_implemented(); return Status(); }
| 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 3497 of file parallel_implementation.h.
{ libmesh_not_implemented(); }
| Status libMesh::Parallel::Communicator::receive | ( | const unsigned int | src_processor_id, |
| std::basic_string< T > & | buf, | ||
| const MessageTag & | tag | ||
| ) | const [inline] |
Definition at line 2297 of file parallel_implementation.h.
References receive().
{
std::vector<T> tempbuf; // Officially C++ won't let us get a
// modifiable array from a string
Status stat = this->receive(src_processor_id, tempbuf, tag);
buf.assign(tempbuf.begin(), tempbuf.end());
return stat;
}
| 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 2312 of file parallel_implementation.h.
References libMesh::Parallel::Request::add_post_wait_work(), and receive().
{
// Officially C++ won't let us get a modifiable array from a
// string, and we can't even put one on the stack for the
// non-blocking case.
std::vector<T> *tempbuf = new std::vector<T>();
// We can clear the string, but the Request::wait() will need to
// handle copying our temporary buffer to it
buf.clear();
req.add_post_wait_work
(new Parallel::PostWaitCopyBuffer<std::vector<T>,
std::back_insert_iterator<std::basic_string<T> > >
(tempbuf, std::back_inserter(buf)));
// Make the Request::wait() then handle deleting the buffer
req.add_post_wait_work
(new Parallel::PostWaitDeleteBuffer<std::vector<T> >(tempbuf));
this->receive(src_processor_id, tempbuf, req, tag);
}
| Status libMesh::Parallel::Communicator::receive | ( | const unsigned int | src_processor_id, |
| std::set< T > & | buf, | ||
| const MessageTag & | tag | ||
| ) | const [inline] |
Definition at line 2398 of file parallel_implementation.h.
References receive().
{
return this->receive
(src_processor_id, buf,
StandardType<T>(buf.empty() ? NULL : &buf.front()), tag);
}
| 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 2410 of file parallel_implementation.h.
References receive().
{
this->receive (src_processor_id, buf,
StandardType<T>(buf.empty() ? NULL : &buf.front()), req, tag);
}
| 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 2422 of file parallel_implementation.h.
References receive(), and libMesh::START_LOG().
| 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 2442 of file parallel_implementation.h.
References libMesh::Parallel::Request::add_post_wait_work(), receive(), and libMesh::START_LOG().
{
START_LOG("receive()", "Parallel");
// Allocate temporary buffer on the heap so it lives until after
// the non-blocking send completes
std::vector<T> *vecbuf = new std::vector<T>();
// We can clear the set, but the Request::wait() will need to
// handle copying our temporary buffer to it
buf.clear();
req.add_post_wait_work
(new Parallel::PostWaitCopyBuffer<std::vector<T>,
std::back_insert_iterator<std::set<T> > >
(vecbuf, std::back_inserter(buf)));
// Make the Request::wait() then handle deleting the buffer
req.add_post_wait_work
(new Parallel::PostWaitDeleteBuffer<std::vector<T> >(vecbuf));
this->receive(src_processor_id, *vecbuf, type, req, tag);
STOP_LOG("receive()", "Parallel");
}
| Status libMesh::Parallel::Communicator::receive | ( | const unsigned int | src_processor_id, |
| std::vector< T > & | buf, | ||
| const MessageTag & | tag | ||
| ) | const [inline] |
Definition at line 2475 of file parallel_implementation.h.
References receive().
{
return this->receive
(src_processor_id, buf,
StandardType<T>(buf.empty() ? NULL : &buf.front()), tag);
}
| 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 2487 of file parallel_implementation.h.
References receive().
{
this->receive (src_processor_id, buf,
StandardType<T>(buf.empty() ? NULL : &buf.front()), req, tag);
}
| 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 2499 of file parallel_implementation.h.
References libMesh::Parallel::Status::get(), libMesh::ierr, libMesh::libmesh_assert(), probe(), libMesh::Parallel::Status::size(), libMesh::START_LOG(), and libMesh::Parallel::MessageTag::value().
{
START_LOG("receive()", "Parallel");
// Get the status of the message, explicitly provide the
// datatype so we can later query the size
Status stat(this->probe(src_processor_id, tag), type);
buf.resize(stat.size());
#ifndef NDEBUG
// Only catch the return value when asserts are active.
const int ierr =
#endif
MPI_Recv (buf.empty() ? NULL : &buf[0],
cast_int<int>(buf.size()),
type,
src_processor_id,
tag.value(),
this->get(),
stat.get());
libmesh_assert (ierr == MPI_SUCCESS);
STOP_LOG("receive()", "Parallel");
return stat;
}
| 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 2533 of file parallel_implementation.h.
References libMesh::Parallel::Request::get(), libMesh::ierr, libMesh::libmesh_assert(), libMesh::START_LOG(), and libMesh::Parallel::MessageTag::value().
{
START_LOG("receive()", "Parallel");
#ifndef NDEBUG
// Only catch the return value when asserts are active.
const int ierr =
#endif
MPI_Irecv (buf.empty() ? NULL : &buf[0],
cast_int<int>(buf.size()),
type,
src_processor_id,
tag.value(),
this->get(),
req.get());
libmesh_assert (ierr == MPI_SUCCESS);
STOP_LOG("receive()", "Parallel");
}
| void libMesh::Parallel::Communicator::receive_packed_range | ( | const unsigned int | dest_processor_id, |
| Context * | context, | ||
| OutputIter | out, | ||
| 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 2559 of file parallel_implementation.h.
References receive(), and libMesh::Parallel::unpack_range().
Referenced by libMesh::Parallel::receive_packed_range().
{
typedef typename std::iterator_traits<OutputIter>::value_type T;
typedef typename Parallel::BufferType<T>::type buffer_t;
// Receive serialized variable size objects as sequences of buffer_t
std::size_t total_buffer_size = 0;
this->receive(src_processor_id, total_buffer_size, tag);
std::size_t received_buffer_size = 0;
while (received_buffer_size < total_buffer_size)
{
std::vector<buffer_t> buffer;
this->receive(src_processor_id, buffer, tag);
received_buffer_size += buffer.size();
Parallel::unpack_range(buffer, context, out);
}
}
| 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 1187 of file parallel_implementation.h.
References libMesh::libmesh_assert(), and used_tag_values.
Referenced by libMesh::Parallel::MessageTag::MessageTag().
{
// This has better be an already-acquired tag.
libmesh_assert(used_tag_values.count(tagvalue));
used_tag_values[tagvalue]++;
}
| 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 1248 of file parallel_implementation.h.
References max(), min(), and size().
Referenced by semiverify().
{
if (this->size() > 1 && Attributes<T>::has_min_max == true)
{
T tempmin, tempmax;
if (r)
tempmin = tempmax = *r;
else
{
Attributes<T>::set_highest(tempmin);
Attributes<T>::set_lowest(tempmax);
}
this->min(tempmin);
this->max(tempmax);
bool invalid = r && ((*r != tempmin) &&
(*r != tempmax));
this->max(invalid);
return !invalid;
}
return true;
}
| bool libMesh::Parallel::Communicator::semiverify | ( | const std::vector< T > * | r | ) | const [inline] |
Definition at line 1273 of file parallel_implementation.h.
References max(), min(), semiverify(), and size().
{
if (this->size() > 1 && Attributes<T>::has_min_max == true)
{
std::size_t rsize = r ? r->size() : 0;
std::size_t *psize = r ? &rsize : NULL;
if (!this->semiverify(psize))
return false;
this->max(rsize);
std::vector<T> tempmin, tempmax;
if (r)
{
tempmin = tempmax = *r;
}
else
{
tempmin.resize(rsize);
tempmax.resize(rsize);
Attributes<std::vector<T> >::set_highest(tempmin);
Attributes<std::vector<T> >::set_lowest(tempmax);
}
this->min(tempmin);
this->max(tempmax);
bool invalid = r && ((*r != tempmin) &&
(*r != tempmax));
this->max(invalid);
return !invalid;
}
return true;
}
| void libMesh::Parallel::Communicator::send | ( | const unsigned int | dest_processor_id, |
| 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 2003 of file parallel_implementation.h.
References libMesh::ierr, libMesh::libmesh_assert(), send_mode(), libMesh::START_LOG(), SYNCHRONOUS, and libMesh::Parallel::MessageTag::value().
Referenced by libMesh::SystemSubsetBySubdomain::init(), libMesh::Parallel::nonblocking_send(), libMesh::Nemesis_IO::read(), libMesh::System::read_SCALAR_dofs(), libMesh::System::read_serialized_blocked_dof_objects(), libMesh::Parallel::send(), send(), send_packed_range(), send_receive(), libMesh::System::write_SCALAR_dofs(), libMesh::XdrIO::write_serialized_bcs(), libMesh::System::write_serialized_blocked_dof_objects(), libMesh::XdrIO::write_serialized_connectivity(), libMesh::XdrIO::write_serialized_nodes(), and libMesh::XdrIO::write_serialized_nodesets().
{
START_LOG("send()", "Parallel");
T* dataptr = &buf;
#ifndef NDEBUG
// Only catch the return value when asserts are active.
const int ierr =
#endif
((this->send_mode() == SYNCHRONOUS) ?
MPI_Ssend : MPI_Send) (dataptr,
1,
StandardType<T>(dataptr),
dest_processor_id,
tag.value(),
this->get());
libmesh_assert (ierr == MPI_SUCCESS);
STOP_LOG("send()", "Parallel");
}
| void libMesh::Parallel::Communicator::send | ( | const unsigned int | dest_processor_id, |
| T & | buf, | ||
| Request & | req, | ||
| const MessageTag & | tag = no_tag |
||
| ) | const [inline] |
Nonblocking-send to one processor with data-defined type.
Definition at line 2031 of file parallel_implementation.h.
References libMesh::Parallel::Request::get(), libMesh::ierr, libMesh::libmesh_assert(), send_mode(), libMesh::START_LOG(), SYNCHRONOUS, and libMesh::Parallel::MessageTag::value().
{
START_LOG("send()", "Parallel");
T* dataptr = &buf;
#ifndef NDEBUG
// Only catch the return value when asserts are active.
const int ierr =
#endif
((this->send_mode() == SYNCHRONOUS) ?
MPI_Issend : MPI_Isend) (dataptr,
1,
StandardType<T>(dataptr),
dest_processor_id,
tag.value(),
this->get(),
req.get());
libmesh_assert (ierr == MPI_SUCCESS);
STOP_LOG("send()", "Parallel");
}
| void libMesh::Parallel::Communicator::send | ( | const unsigned int | dest_processor_id, |
| T & | buf, | ||
| const DataType & | type, | ||
| const MessageTag & | tag = no_tag |
||
| ) | const [inline] |
Blocking-send to one processor with user-defined type.
Definition at line 3458 of file parallel_implementation.h.
{ libmesh_not_implemented(); }
| void libMesh::Parallel::Communicator::send | ( | const unsigned int | dest_processor_id, |
| 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 3463 of file parallel_implementation.h.
{ libmesh_not_implemented(); }
| void libMesh::Parallel::Communicator::send | ( | const unsigned int | dest_processor_id, |
| std::basic_string< T > & | buf, | ||
| const MessageTag & | tag | ||
| ) | const [inline] |
Definition at line 1945 of file parallel_implementation.h.
References libMesh::ierr, libMesh::libmesh_assert(), send_mode(), libMesh::START_LOG(), SYNCHRONOUS, and libMesh::Parallel::MessageTag::value().
{
START_LOG("send()", "Parallel");
T* dataptr = buf.empty() ? NULL : const_cast<T*>(buf.data());
#ifndef NDEBUG
// Only catch the return value when asserts are active.
const int ierr =
#endif
((this->send_mode() == SYNCHRONOUS) ?
MPI_Ssend : MPI_Send) (dataptr,
cast_int<int>(buf.size()),
StandardType<T>(dataptr),
dest_processor_id,
tag.value(),
this->get());
libmesh_assert (ierr == MPI_SUCCESS);
STOP_LOG("send()", "Parallel");
}
| void libMesh::Parallel::Communicator::send | ( | const unsigned int | dest_processor_id, |
| std::basic_string< T > & | buf, | ||
| Request & | req, | ||
| const MessageTag & | tag | ||
| ) | const [inline] |
Definition at line 1973 of file parallel_implementation.h.
References libMesh::Parallel::Request::get(), libMesh::ierr, libMesh::libmesh_assert(), send_mode(), libMesh::START_LOG(), SYNCHRONOUS, and libMesh::Parallel::MessageTag::value().
{
START_LOG("send()", "Parallel");
T* dataptr = buf.empty() ? NULL : const_cast<T*>(buf.data());
#ifndef NDEBUG
// Only catch the return value when asserts are active.
const int ierr =
#endif
((this->send_mode() == SYNCHRONOUS) ?
MPI_Issend : MPI_Isend) (dataptr,
cast_int<int>(buf.size()),
StandardType<T>(dataptr),
dest_processor_id,
tag.value(),
this->get(),
req.get());
libmesh_assert (ierr == MPI_SUCCESS);
STOP_LOG("send()", "Parallel");
}
| void libMesh::Parallel::Communicator::send | ( | const unsigned int | dest_processor_id, |
| std::set< T > & | buf, | ||
| const MessageTag & | tag | ||
| ) | const [inline] |
Definition at line 2061 of file parallel_implementation.h.
References send().
{
this->send(dest_processor_id,
StandardType<T>(buf.empty() ? NULL : &buf.front()), tag);
}
| void libMesh::Parallel::Communicator::send | ( | const unsigned int | dest_processor_id, |
| std::set< T > & | buf, | ||
| Request & | req, | ||
| const MessageTag & | tag | ||
| ) | const [inline] |
Definition at line 2072 of file parallel_implementation.h.
References send().
{
this->send(dest_processor_id,
StandardType<T>(buf.empty() ? NULL : &buf.front()), req, tag);
}
| void libMesh::Parallel::Communicator::send | ( | const unsigned int | dest_processor_id, |
| std::set< T > & | buf, | ||
| const DataType & | type, | ||
| const MessageTag & | tag | ||
| ) | const [inline] |
Definition at line 2084 of file parallel_implementation.h.
References send(), and libMesh::START_LOG().
| void libMesh::Parallel::Communicator::send | ( | const unsigned int | dest_processor_id, |
| std::set< T > & | buf, | ||
| const DataType & | type, | ||
| Request & | req, | ||
| const MessageTag & | tag | ||
| ) | const [inline] |
Definition at line 2100 of file parallel_implementation.h.
References libMesh::Parallel::Request::add_post_wait_work(), send(), and libMesh::START_LOG().
{
START_LOG("send()", "Parallel");
// Allocate temporary buffer on the heap so it lives until after
// the non-blocking send completes
std::vector<T> *vecbuf =
new std::vector<T>(buf.begin(), buf.end());
// Make the Request::wait() handle deleting the buffer
req.add_post_wait_work
(new Parallel::PostWaitDeleteBuffer<std::vector<T> >(vecbuf));
this->send(dest_processor_id, *vecbuf, type, req, tag);
STOP_LOG("send()", "Parallel");
}
| void libMesh::Parallel::Communicator::send | ( | const unsigned int | dest_processor_id, |
| std::vector< T > & | buf, | ||
| const MessageTag & | tag | ||
| ) | const [inline] |
Definition at line 2125 of file parallel_implementation.h.
References send().
{
this->send(dest_processor_id, buf,
StandardType<T>(buf.empty() ? NULL : &buf.front()), tag);
}
| void libMesh::Parallel::Communicator::send | ( | const unsigned int | dest_processor_id, |
| std::vector< T > & | buf, | ||
| Request & | req, | ||
| const MessageTag & | tag | ||
| ) | const [inline] |
Definition at line 2136 of file parallel_implementation.h.
References send().
{
this->send(dest_processor_id, buf,
StandardType<T>(buf.empty() ? NULL : &buf.front()), req, tag);
}
| void libMesh::Parallel::Communicator::send | ( | const unsigned int | dest_processor_id, |
| std::vector< T > & | buf, | ||
| const DataType & | type, | ||
| const MessageTag & | tag | ||
| ) | const [inline] |
Definition at line 2148 of file parallel_implementation.h.
References libMesh::ierr, libMesh::libmesh_assert(), send_mode(), libMesh::START_LOG(), SYNCHRONOUS, and libMesh::Parallel::MessageTag::value().
{
START_LOG("send()", "Parallel");
#ifndef NDEBUG
// Only catch the return value when asserts are active.
const int ierr =
#endif
((this->send_mode() == SYNCHRONOUS) ?
MPI_Ssend : MPI_Send) (buf.empty() ? NULL : &buf[0],
cast_int<int>(buf.size()),
type,
dest_processor_id,
tag.value(),
this->get());
libmesh_assert (ierr == MPI_SUCCESS);
STOP_LOG("send()", "Parallel");
}
| void libMesh::Parallel::Communicator::send | ( | const unsigned int | dest_processor_id, |
| std::vector< T > & | buf, | ||
| const DataType & | type, | ||
| Request & | req, | ||
| const MessageTag & | tag | ||
| ) | const [inline] |
Definition at line 2175 of file parallel_implementation.h.
References libMesh::Parallel::Request::get(), libMesh::ierr, libMesh::libmesh_assert(), send_mode(), libMesh::START_LOG(), SYNCHRONOUS, and libMesh::Parallel::MessageTag::value().
{
START_LOG("send()", "Parallel");
#ifndef NDEBUG
// Only catch the return value when asserts are active.
const int ierr =
#endif
((this->send_mode() == SYNCHRONOUS) ?
MPI_Issend : MPI_Isend) (buf.empty() ? NULL : &buf[0],
cast_int<int>(buf.size()),
type,
dest_processor_id,
tag.value(),
this->get(),
req.get());
libmesh_assert (ierr == MPI_SUCCESS);
STOP_LOG("send()", "Parallel");
}
| void libMesh::Parallel::Communicator::send_mode | ( | const SendMode | sm | ) | [inline] |
Explicitly sets the SendMode type used for send operations.
Definition at line 682 of file parallel.h.
References _send_mode.
Referenced by duplicate(), and split().
{ _send_mode = sm; }
| SendMode libMesh::Parallel::Communicator::send_mode | ( | ) | const [inline] |
Gets the user-requested SendMode.
Definition at line 687 of file parallel.h.
References _send_mode.
Referenced by duplicate(), send(), and split().
{ return _send_mode; }
| 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 2203 of file parallel_implementation.h.
References libMesh::Parallel::pack_range(), libMesh::Parallel::packed_range_size(), and send().
Referenced by libMesh::Parallel::send_packed_range().
{
// We will serialize variable size objects from *range_begin to
// *range_end as a sequence of plain data (e.g. ints) in this buffer
typedef typename std::iterator_traits<Iter>::value_type T;
std::size_t total_buffer_size =
Parallel::packed_range_size(context, range_begin, range_end);
this->send(dest_processor_id, total_buffer_size, tag);
#ifdef DEBUG
std::size_t used_buffer_size = 0;
#endif
while (range_begin != range_end)
{
std::vector<typename Parallel::BufferType<T>::type> buffer;
range_begin = Parallel::pack_range(context, range_begin, range_end, buffer);
#ifdef DEBUG
used_buffer_size += buffer.size();
#endif
// Blocking send of the buffer
this->send(dest_processor_id, buffer, tag);
}
#ifdef DEBUG
libmesh_assert_equal_to(used_buffer_size, total_buffer_size);
#endif
}
| 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 2243 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 send().
{
// Allocate a buffer on the heap so we don't have to free it until
// after the Request::wait()
typedef typename std::iterator_traits<Iter>::value_type T;
typedef typename Parallel::BufferType<T>::type buffer_t;
std::size_t total_buffer_size =
Parallel::packed_range_size(context, range_begin, range_end);
Request intermediate_req = request();
this->send(dest_processor_id, total_buffer_size, intermediate_req, tag);
req.add_prior_request(intermediate_req);
#ifdef DEBUG
std::size_t used_buffer_size = 0;
#endif
while (range_begin != range_end)
{
std::vector<buffer_t> *buffer = new std::vector<buffer_t>();
range_begin = Parallel::pack_range(context, range_begin, range_end, *buffer);
#ifdef DEBUG
used_buffer_size += buffer->size();
#endif
Request next_intermediate_req;
Request *my_req = (range_begin == range_end) ? &req : &next_intermediate_req;
// Make the Request::wait() handle deleting the buffer
my_req->add_post_wait_work
(new Parallel::PostWaitDeleteBuffer<std::vector<buffer_t> >
(buffer));
// Non-blocking send of the buffer
this->send(dest_processor_id, *buffer, *my_req, tag);
if (range_begin != range_end)
req.add_prior_request(*my_req);
}
}
| void libMesh::Parallel::Communicator::send_receive | ( | const unsigned int | send_tgt, |
| 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] |
Nonblocking-receive range-of-pointers from one processor. Not yet implemented. 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 2646 of file parallel_implementation.h.
References rank(), libMesh::START_LOG(), and libMesh::Parallel::MessageTag::value().
Referenced by libMesh::ParmetisPartitioner::assign_partitioning(), libMesh::MeshCommunication::find_global_indices(), libMesh::Parallel::send_receive(), send_receive(), 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().
{
START_LOG("send_receive()", "Parallel");
if (dest_processor_id == this->rank() &&
source_processor_id == this->rank())
{
recv = sendvec;
STOP_LOG("send_receive()", "Parallel");
return;
}
MPI_Sendrecv(&sendvec, 1, StandardType<T1>(&sendvec),
dest_processor_id, send_tag.value(),
&recv, 1, StandardType<T2>(&recv),
source_processor_id, recv_tag.value(),
this->get(),
MPI_STATUS_IGNORE);
STOP_LOG("send_receive()", "Parallel");
}
| void libMesh::Parallel::Communicator::send_receive | ( | const unsigned int | dest_processor_id, |
| 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.
| void libMesh::Parallel::Communicator::send_receive | ( | const unsigned int | dest_processor_id, |
| 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 2613 of file parallel_implementation.h.
References rank(), receive(), send(), libMesh::START_LOG(), and libMesh::Parallel::Request::wait().
{
START_LOG("send_receive()", "Parallel");
if (dest_processor_id == this->rank() &&
source_processor_id == this->rank())
{
recv = sendvec;
STOP_LOG("send_receive()", "Parallel");
return;
}
Parallel::Request req;
this->send (dest_processor_id, sendvec, type1, req, send_tag);
this->receive (source_processor_id, recv, type2, recv_tag);
req.wait();
STOP_LOG("send_receive()", "Parallel");
}
| void libMesh::Parallel::Communicator::send_receive | ( | const unsigned int | dest_processor_id, |
| 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 2683 of file parallel_implementation.h.
References rank(), send_receive(), and libMesh::START_LOG().
{
if (dest_processor_id == this->rank() &&
source_processor_id == this->rank())
{
START_LOG("send_receive()", "Parallel");
recv = sendvec;
STOP_LOG("send_receive()", "Parallel");
return;
}
// Call the user-defined type version with automatic
// type conversion based on template argument:
this->send_receive (dest_processor_id, sendvec,
StandardType<T>(sendvec.empty() ? NULL : &sendvec[0]),
source_processor_id, recv,
StandardType<T>(recv.empty() ? NULL : &recv[0]),
send_tag, recv_tag);
}
| void libMesh::Parallel::Communicator::send_receive | ( | const unsigned int | dest_processor_id, |
| 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 2712 of file parallel_implementation.h.
References send_receive().
{
// Call the user-defined type version with automatic
// type conversion based on template argument:
this->send_receive (dest_processor_id, sendvec,
StandardType<T1>(sendvec.empty() ? NULL : &sendvec[0]),
source_processor_id, recv,
StandardType<T2>(recv.empty() ? NULL : &recv[0]),
send_tag, recv_tag);
}
| void libMesh::Parallel::Communicator::send_receive | ( | const unsigned int | dest_processor_id, |
| 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 2732 of file parallel_implementation.h.
References libMesh::Parallel::any_tag, and libMesh::Parallel::no_tag.
| void libMesh::Parallel::Communicator::send_receive | ( | const unsigned int | dest_processor_id, |
| 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 2750 of file parallel_implementation.h.
References libMesh::Parallel::any_tag, and libMesh::Parallel::no_tag.
| 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, | ||
| 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.
We do not currently support this operation on one processor without MPI.
Definition at line 2768 of file parallel_implementation.h.
References libMesh::Parallel::receive_packed_range(), libMesh::Parallel::send_packed_range(), libMesh::START_LOG(), and libMesh::Parallel::Request::wait().
Referenced by libMesh::Parallel::send_receive_packed_range().
{
START_LOG("send_receive()", "Parallel");
Parallel::Request req;
this->send_packed_range (dest_processor_id, context1, send_begin, send_end,
req, send_tag);
this->receive_packed_range (source_processor_id, context2, out, recv_tag);
req.wait();
STOP_LOG("send_receive()", "Parallel");
}
| 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 3435 of file parallel_implementation.h.
Referenced by libMesh::MeshBase::cache_elem_dims(), libMesh::Nemesis_IO_Helper::compute_num_global_nodesets(), libMesh::Nemesis_IO_Helper::compute_num_global_sidesets(), libMesh::Parallel::set_union(), libMesh::MeshBase::subdomain_ids(), and libMesh::BoundaryInfo::sync().
{ libmesh_assert_equal_to(root_id, 0); }
| 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 3432 of file parallel_implementation.h.
{}
| void libMesh::Parallel::Communicator::set_union | ( | std::set< T > & | data, |
| const unsigned int | root_id | ||
| ) | const [inline] |
| void libMesh::Parallel::Communicator::set_union | ( | std::set< T > & | data | ) | const [inline] |
Definition at line 1894 of file parallel_implementation.h.
References allgather().
| unsigned int libMesh::Parallel::Communicator::size | ( | ) | const [inline] |
Definition at line 647 of file parallel.h.
References _size.
Referenced by allgather(), alltoall(), barrier(), broadcast(), libMesh::MeshCommunication::find_global_indices(), gather(), max(), maxloc(), min(), minloc(), libMesh::ParallelObject::n_processors(), semiverify(), libMesh::PetscPreconditioner< T >::set_petsc_preconditioner_type(), sum(), libMesh::Parallel::sync_dofobject_data_by_id(), libMesh::Parallel::sync_dofobject_data_by_xyz(), and verify().
{ return _size; }
| void libMesh::Parallel::Communicator::split | ( | int | color, |
| int | key, | ||
| Communicator & | target | ||
| ) | const [inline] |
Definition at line 497 of file parallel_implementation.h.
References assign(), clear(), and send_mode().
{
target.clear();
MPI_Comm newcomm;
MPI_Comm_split(this->get(), color, key, &newcomm);
target.assign(newcomm);
target.send_mode(this->send_mode());
}
| 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 1796 of file parallel_implementation.h.
References size(), and libMesh::START_LOG().
Referenced by libMesh::System::calculate_norm(), 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::CondensedEigenSystem::get_eigenpair(), libMesh::ParallelMesh::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::ParallelMesh::parallel_n_elem(), libMesh::ParallelMesh::parallel_n_nodes(), libMesh::Nemesis_IO::read(), libMesh::System::read_serialized_blocked_dof_objects(), libMesh::System::read_serialized_vector(), libMesh::ErrorEstimator::reduce_error(), libMesh::Parallel::sum(), libMesh::MeshTools::total_weight(), and libMesh::XdrIO::write_serialized_connectivity().
| void libMesh::Parallel::Communicator::sum | ( | std::vector< T > & | r | ) | const [inline] |
Definition at line 1816 of file parallel_implementation.h.
References libMesh::libmesh_assert(), size(), libMesh::START_LOG(), and verify().
{
if (this->size() > 1 && !r.empty())
{
START_LOG("sum()", "Parallel");
libmesh_assert(this->verify(r.size()));
std::vector<T> temp(r);
MPI_Allreduce (&temp[0],
&r[0],
cast_int<int>(r.size()),
StandardType<T>(&temp[0]),
MPI_SUM,
this->get());
STOP_LOG("sum()", "Parallel");
}
}
| void libMesh::Parallel::Communicator::sum | ( | std::complex< T > & | r | ) | const [inline] |
Definition at line 1840 of file parallel_implementation.h.
References size(), and libMesh::START_LOG().
| void libMesh::Parallel::Communicator::sum | ( | std::vector< std::complex< T > > & | r | ) | const [inline] |
Definition at line 1860 of file parallel_implementation.h.
References libMesh::libmesh_assert(), size(), libMesh::START_LOG(), and verify().
{
if (this->size() > 1 && !r.empty())
{
START_LOG("sum()", "Parallel");
libmesh_assert(this->verify(r.size()));
std::vector<std::complex<T> > temp(r);
MPI_Allreduce (&temp[0],
&r[0],
cast_int<int>(r.size() * 2),
StandardType<T>(NULL),
MPI_SUM,
this->get());
STOP_LOG("sum()", "Parallel");
}
}
| 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 1230 of file parallel_implementation.h.
References max(), min(), and size().
Referenced by alltoall(), libMesh::MeshCommunication::delete_remote_elements(), max(), maxloc(), min(), minloc(), libMesh::System::point_gradient(), libMesh::System::point_hessian(), libMesh::System::point_value(), sum(), and libMesh::Parallel::verify().
Definition at line 667 of file parallel.h.
Referenced by assign(), clear(), duplicate(), get(), and libMesh::ParallelObject::operator=().
bool libMesh::Parallel::Communicator::_I_duped_it [private] |
Definition at line 674 of file parallel.h.
Referenced by clear(), and duplicate().
unsigned int libMesh::Parallel::Communicator::_rank [private] |
Definition at line 668 of file parallel.h.
Definition at line 669 of file parallel.h.
Referenced by assign(), and send_mode().
unsigned int libMesh::Parallel::Communicator::_size [private] |
Definition at line 668 of file parallel.h.
std::map<int, unsigned int> libMesh::Parallel::Communicator::used_tag_values [mutable, private] |
Definition at line 673 of file parallel.h.
Referenced by dereference_unique_tag(), get_unique_tag(), and reference_unique_tag().