Skip to content
Snippets Groups Projects
Commit 66acccf4 authored by Oliver Sander's avatar Oliver Sander
Browse files

Copy file mpitraits.hh from dune-istl to here. The file disappeared

in dune-istl in revision 1220.  The new file here is intended to be
merged with mpicollectivecommunication.  That will happen in a separate
step.

[[Imported from SVN: r6018]]
parent c000c5c8
No related branches found
No related tags found
No related merge requests found
......@@ -13,7 +13,7 @@ commoninclude_HEADERS = alignment.hh array.hh \
enumset.hh exceptions.hh fixedarray.hh fmatrix.hh fmatrixev.hh \
fvector.hh ftraits.hh genericiterator.hh \
iteratorfacades.hh \
misc.hh poolallocator.hh finitestack.hh \
misc.hh mpitraits.hh poolallocator.hh finitestack.hh \
sllist.hh shared_ptr.hh stdstreams.hh timer.hh tuples.hh \
typetraits.hh precision.hh bigunsignedint.hh \
gcd.hh lcm.hh configparser.hh propertymap.hh \
......
// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
// vi: set et ts=4 sw=2 sts=2:
// $Id: mpitraits.hh 1083 2009-09-28 17:13:20Z mblatt $
#ifndef DUNE_MPITRAITS_HH
#define DUNE_MPITRAITS_HH
#if HAVE_MPI
#include "mpi.h"
#endif
namespace Dune
{
/**
* @file
* @brief Traits classes for mapping types onto MPI_Datatype.
* @author Markus Blatt
*/
/** @addtogroup ISTL_Comm
*
* @{
*/
/**
* @brief A traits class describing the mapping of types onto MPI_Datatypes.
*
* Specializations exist for the default types.
* Specializations should provide a static method
* \code
* static MPI_Datatype getType();
* \endcode
*/
template<typename T>
class MPITraits
{};
#if HAVE_MPI
// A Macro for defining traits for the primitive data types
#define ComposeMPITraits(p,m) \
template<> \
struct MPITraits<p>{ \
static inline MPI_Datatype getType(){ \
return m; \
} \
}
ComposeMPITraits(char, MPI_CHAR);
ComposeMPITraits(unsigned char,MPI_UNSIGNED_CHAR);
ComposeMPITraits(short,MPI_SHORT);
ComposeMPITraits(unsigned short,MPI_UNSIGNED_SHORT);
ComposeMPITraits(int,MPI_INT);
ComposeMPITraits(unsigned int,MPI_UNSIGNED);
ComposeMPITraits(long,MPI_LONG);
ComposeMPITraits(unsigned long,MPI_UNSIGNED_LONG);
ComposeMPITraits(float,MPI_FLOAT);
ComposeMPITraits(double,MPI_DOUBLE);
ComposeMPITraits(long double,MPI_LONG_DOUBLE);
#undef ComposeMPITraits
template<class K, int n> class FieldVector;
template<class K, int n>
struct MPITraits<FieldVector<K,n> >
{
static MPI_Datatype datatype;
static MPI_Datatype vectortype;
static inline MPI_Datatype getType()
{
if(datatype==MPI_DATATYPE_NULL) {
MPI_Type_contiguous(n, MPITraits<K>::getType(), &vectortype);
MPI_Type_commit(&vectortype);
FieldVector<K,n> fvector;
MPI_Aint base;
MPI_Aint displ;
MPI_Address(&fvector, &base);
MPI_Address(&(fvector[0]), &displ);
displ -= base;
int length[1]={1};
MPI_Type_struct(1, length, &displ, &vectortype, &datatype);
MPI_Type_commit(&datatype);
}
return datatype;
}
};
template<class K, int n>
MPI_Datatype MPITraits<FieldVector<K,n> >::datatype = MPI_DATATYPE_NULL;
template<class K, int n>
MPI_Datatype MPITraits<FieldVector<K,n> >::vectortype = {MPI_DATATYPE_NULL};
template<int k>
class bigunsignedint;
template<int k>
struct MPITraits<bigunsignedint<k> >
{
static MPI_Datatype datatype;
static MPI_Datatype vectortype;
static inline MPI_Datatype getType()
{
if(datatype==MPI_DATATYPE_NULL) {
MPI_Type_contiguous(bigunsignedint<k>::n, MPITraits<unsigned short>::getType(),
&vectortype);
//MPI_Type_commit(&vectortype);
bigunsignedint<k> data;
MPI_Aint base;
MPI_Aint displ;
MPI_Address(&data, &base);
MPI_Address(&(data.digit), &displ);
displ -= base;
int length[1]={1};
MPI_Type_struct(1, length, &displ, &vectortype, &datatype);
MPI_Type_commit(&datatype);
}
return datatype;
}
};
}
namespace std
{
template<typename T1,typename T2> class pair;
}
namespace Dune
{
template<int k>
MPI_Datatype MPITraits<bigunsignedint<k> >::datatype = MPI_DATATYPE_NULL;
template<int k>
MPI_Datatype MPITraits<bigunsignedint<k> >::vectortype = MPI_DATATYPE_NULL;
template<typename T1, typename T2>
class MPITraits<std::pair<T1,T2 > >
{
public:
inline static MPI_Datatype getType();
private:
static MPI_Datatype type;
};
template<typename T1, typename T2>
MPI_Datatype MPITraits<std::pair<T1,T2> >::getType()
{
if(type==MPI_DATATYPE_NULL) {
int length[4];
MPI_Aint disp[4];
MPI_Datatype types[4] = {MPI_LB, MPITraits<T1>::getType(),
MPITraits<T2>::getType(), MPI_UB};
std::pair<T1,T2> rep[2];
length[0]=length[1]=length[2]=length[3]=1;
MPI_Address(rep, disp); // lower bound of the datatype
MPI_Address(&(rep[0].first), disp+1);
MPI_Address(&(rep[0].second), disp+2);
MPI_Address(rep+1, disp+3); // upper bound of the datatype
for(int i=3; i >= 0; --i)
disp[i] -= disp[0];
MPI_Type_struct(4, length, disp, types, &type);
MPI_Type_commit(&type);
}
return type;
}
template<typename T1, typename T2>
MPI_Datatype MPITraits<std::pair<T1,T2> >::type=MPI_DATATYPE_NULL;
#endif
/** @} */
}
#endif
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment