libMesh
Public Member Functions | Protected Attributes | List of all members
libMesh::Parallel::StandardType< std::pair< T1, T2 > > Class Template Reference

#include <parallel_implementation.h>

Inheritance diagram for libMesh::Parallel::StandardType< std::pair< T1, T2 > >:
[legend]

Public Member Functions

 StandardType (const std::pair< T1, T2 > *example=libmesh_nullptr)
 
 ~StandardType ()
 
 operator const data_type & () const
 
 operator data_type & ()
 
void commit ()
 
void free ()
 

Protected Attributes

data_type _datatype
 

Detailed Description

template<typename T1, typename T2>
class libMesh::Parallel::StandardType< std::pair< T1, T2 > >

Definition at line 192 of file parallel_implementation.h.

Constructor & Destructor Documentation

template<typename T1 , typename T2 >
libMesh::Parallel::StandardType< std::pair< T1, T2 > >::StandardType ( const std::pair< T1, T2 > *  example = libmesh_nullptr)
explicit

Definition at line 196 of file parallel_implementation.h.

References libMesh::Parallel::DataType::_datatype, and libMesh::libMeshPrivateData::_is_initialized.

196  {
197  // We need an example for MPI_Address to use
198  static const std::pair<T1, T2> p;
199  if (!example)
200  example = &p;
201 
202  // _static_type never gets freed, but it only gets committed once
203  // per T, so it's not a *huge* memory leak...
204  static data_type _static_type;
205  static bool _is_initialized = false;
206  if (!_is_initialized)
207  {
208 #ifdef LIBMESH_HAVE_MPI
209 
210  // Get the sub-data-types, and make sure they live long enough
211  // to construct the derived type
212  StandardType<T1> d1(&example->first);
213  StandardType<T2> d2(&example->second);
214 
215 #if MPI_VERSION == 1
216 
217  // Use MPI_LB and MPI_UB here to workaround potential bugs from
218  // nested MPI_LB and MPI_UB in the specifications of d1 and/or d2:
219  // https://github.com/libMesh/libmesh/issues/631
220  MPI_Datatype types[] = { MPI_LB, (data_type)d1, (data_type)d2, MPI_UB };
221  int blocklengths[] = {1,1,1,1};
222  MPI_Aint displs[4];
223 
224  libmesh_call_mpi
225  (MPI_Address (const_cast<std::pair<T1,T2> *>(example),
226  &displs[0]));
227  libmesh_call_mpi
228  (MPI_Address (const_cast<T1*>(&example->first),
229  &displs[1]));
230  libmesh_call_mpi
231  (MPI_Address (const_cast<T2*>(&example->second),
232  &displs[2]));
233  libmesh_call_mpi
234  (MPI_Address (const_cast<std::pair<T1,T2> *>(example+1),
235  &displs[3]));
236 
237  displs[1] -= displs[0];
238  displs[2] -= displs[0];
239  displs[3] -= displs[0];
240  displs[0] = 0;
241 
242  libmesh_call_mpi
243  (MPI_Type_struct (4, blocklengths, displs, types,
244  &_static_type));
245 #else
246  MPI_Datatype types[] = { (data_type)d1, (data_type)d2 };
247  int blocklengths[] = {1,1};
248  MPI_Aint displs[2], start;
249 
250  libmesh_call_mpi
251  (MPI_Get_address (const_cast<std::pair<T1,T2> *>(example),
252  &start));
253  libmesh_call_mpi
254  (MPI_Get_address (const_cast<T1*>(&example->first),
255  &displs[0]));
256  libmesh_call_mpi
257  (MPI_Get_address (const_cast<T2*>(&example->second),
258  &displs[1]));
259  displs[0] -= start;
260  displs[1] -= start;
261 
262  // create a prototype structure
263  MPI_Datatype tmptype;
264  libmesh_call_mpi
265  (MPI_Type_create_struct (2, blocklengths, displs, types,
266  &tmptype));
267  libmesh_call_mpi
268  (MPI_Type_commit (&tmptype));
269 
270  // resize the structure type to account for padding, if any
271  libmesh_call_mpi
272  (MPI_Type_create_resized (tmptype, 0,
273  sizeof(std::pair<T1,T2>),
274  &_static_type));
275 #endif
276 
277  libmesh_call_mpi
278  (MPI_Type_commit (&_static_type));
279 #endif // LIBMESH_HAVE_MPI
280 
281  _is_initialized = true;
282  }
283 
284  _datatype = _static_type;
285  }
MPI_Datatype data_type
Data types for communication.
Definition: parallel.h:166
bool _is_initialized
Flag that tells if init() has been called.
Definition: libmesh.C:255
template<typename T1 , typename T2 >
libMesh::Parallel::StandardType< std::pair< T1, T2 > >::~StandardType ( )

Definition at line 288 of file parallel_implementation.h.

288 {}

Member Function Documentation

void libMesh::Parallel::DataType::commit ( )
inherited

Definition at line 334 of file parallel.h.

335  {
336 #ifdef LIBMESH_HAVE_MPI
337  MPI_Type_commit (&_datatype);
338 #endif
339  }
void libMesh::Parallel::DataType::free ( )
inherited
libMesh::Parallel::DataType::operator const data_type & ( ) const
inherited

Definition at line 322 of file parallel.h.

323  { return _datatype; }
libMesh::Parallel::DataType::operator data_type & ( )
inherited

Definition at line 325 of file parallel.h.

326  { return _datatype; }

Member Data Documentation

data_type libMesh::Parallel::DataType::_datatype
protectedinherited

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