mpitraits.hh

Go to the documentation of this file.
00001 // $Id: mpitraits.hh 1083 2009-09-28 17:13:20Z mblatt $
00002 #ifndef DUNE_MPITRAITS_HH
00003 #define DUNE_MPITRAITS_HH
00004 
00005 #if HAVE_MPI
00006 #include"mpi.h"
00007 #endif
00008 
00009 namespace Dune
00010 {
00021 #if HAVE_MPI
00022 
00031   template<typename T>
00032   struct MPITraits
00033   {
00034   private:
00035     MPITraits(){}
00036     MPITraits(const MPITraits&){}
00037     static MPI_Datatype datatype;
00038     static MPI_Datatype vectortype;
00039   public:
00040     static inline MPI_Datatype getType()
00041     {
00042       if(datatype==MPI_DATATYPE_NULL){
00043         MPI_Type_contiguous(sizeof(T),MPI_BYTE,&datatype);
00044         MPI_Type_commit(&datatype);
00045       }
00046       return datatype;
00047     }
00048     
00049   };
00050   template<class T>
00051   MPI_Datatype MPITraits<T>::datatype = MPI_DATATYPE_NULL;
00052 
00053 #ifndef DOXYGEN
00054 #if HAVE_MPI
00055 
00056   // A Macro for defining traits for the primitive data types
00057 #define ComposeMPITraits(p,m) \
00058   template<> \
00059   struct MPITraits<p>{ \
00060     static inline MPI_Datatype getType(){ \
00061       return m; \
00062     } \
00063   }
00064 
00065   ComposeMPITraits(char, MPI_CHAR);
00066   ComposeMPITraits(unsigned char,MPI_UNSIGNED_CHAR);
00067   ComposeMPITraits(short,MPI_SHORT);
00068   ComposeMPITraits(unsigned short,MPI_UNSIGNED_SHORT);
00069   ComposeMPITraits(int,MPI_INT);
00070   ComposeMPITraits(unsigned int,MPI_UNSIGNED);
00071   ComposeMPITraits(long,MPI_LONG);
00072   ComposeMPITraits(unsigned long,MPI_UNSIGNED_LONG);
00073   ComposeMPITraits(float,MPI_FLOAT);
00074   ComposeMPITraits(double,MPI_DOUBLE);
00075   ComposeMPITraits(long double,MPI_LONG_DOUBLE);
00076   
00077 
00078 #undef ComposeMPITraits
00079 
00080   template<class K, int n> class FieldVector;
00081   
00082   template<class K, int n>
00083   struct MPITraits<FieldVector<K,n> >
00084   {
00085     static MPI_Datatype datatype;
00086     static MPI_Datatype vectortype;
00087     
00088     static inline MPI_Datatype getType()
00089     {
00090       if(datatype==MPI_DATATYPE_NULL){
00091         MPI_Type_contiguous(n, MPITraits<K>::getType(), &vectortype);
00092         MPI_Type_commit(&vectortype);
00093         FieldVector<K,n> fvector;
00094         MPI_Aint base;
00095         MPI_Aint displ;
00096         MPI_Address(&fvector, &base);
00097         MPI_Address(&(fvector[0]), &displ);
00098         displ -= base;
00099         int length[1]={1};
00100             
00101         MPI_Type_struct(1, length, &displ, &vectortype, &datatype);
00102         MPI_Type_commit(&datatype);
00103       }
00104       return datatype;
00105     }
00106         
00107   };
00108 
00109   template<class K, int n>
00110   MPI_Datatype MPITraits<FieldVector<K,n> >::datatype = MPI_DATATYPE_NULL;
00111   template<class K, int n>
00112   MPI_Datatype MPITraits<FieldVector<K,n> >::vectortype = {MPI_DATATYPE_NULL};
00113 
00114 
00115   template<int k>
00116   class bigunsignedint;
00117   
00118   template<int k>
00119   struct MPITraits<bigunsignedint<k> >
00120   {
00121     static MPI_Datatype datatype;
00122     static MPI_Datatype vectortype;
00123     
00124     static inline MPI_Datatype getType()
00125     {
00126       if(datatype==MPI_DATATYPE_NULL){
00127         MPI_Type_contiguous(bigunsignedint<k>::n, MPITraits<unsigned short>::getType(),
00128                             &vectortype);
00129         //MPI_Type_commit(&vectortype);
00130         bigunsignedint<k> data;
00131         MPI_Aint base;
00132         MPI_Aint displ;
00133         MPI_Address(&data, &base);
00134         MPI_Address(&(data.digit), &displ);
00135         displ -= base;
00136         int length[1]={1};      
00137         MPI_Type_struct(1, length, &displ, &vectortype, &datatype);
00138         MPI_Type_commit(&datatype);
00139       }
00140       return datatype;
00141     }
00142   };
00143 }
00144 namespace std
00145 {
00146   template<typename T1,typename T2> class pair;
00147 }
00148 
00149 namespace Dune
00150 {
00151   template<int k>
00152   MPI_Datatype MPITraits<bigunsignedint<k> >::datatype = MPI_DATATYPE_NULL;
00153   template<int k>
00154   MPI_Datatype MPITraits<bigunsignedint<k> >::vectortype = MPI_DATATYPE_NULL;
00155 
00156   template<typename T1, typename T2>
00157   struct MPITraits<std::pair<T1,T2 > >
00158   {
00159   public:
00160     inline static MPI_Datatype getType();
00161   private:
00162     static MPI_Datatype type;
00163   };
00164   template<typename T1, typename T2>
00165   MPI_Datatype MPITraits<std::pair<T1,T2> >::getType()
00166     {
00167     if(type==MPI_DATATYPE_NULL){
00168       int length[4];
00169       MPI_Aint disp[4];
00170       MPI_Datatype types[4] = {MPI_LB, MPITraits<T1>::getType(), 
00171                                MPITraits<T2>::getType(), MPI_UB};
00172       std::pair<T1,T2> rep[2];
00173       length[0]=length[1]=length[2]=length[3]=1;
00174       MPI_Address(rep, disp); // lower bound of the datatype
00175       MPI_Address(&(rep[0].first), disp+1);
00176       MPI_Address(&(rep[0].second), disp+2);
00177       MPI_Address(rep+1, disp+3); // upper bound of the datatype
00178       for(int i=3; i >= 0; --i)
00179         disp[i] -= disp[0];
00180       MPI_Type_struct(4, length, disp, types, &type);
00181       MPI_Type_commit(&type);
00182     }
00183     return type;
00184   }
00185 
00186   template<typename T1, typename T2>
00187   MPI_Datatype MPITraits<std::pair<T1,T2> >::type=MPI_DATATYPE_NULL;
00188 #endif
00189 #endif
00190 #endif
00191 
00192 }
00193 
00194 #endif

Generated on Fri Apr 29 2011 with Doxygen (ver 1.7.1) [doxygen-log,error-log].