dune-common
2.2.0
|
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> struct 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