dune-common  2.2.0
mpitraits.hh
Go to the documentation of this file.
1 // $Id: mpitraits.hh 1083 2009-09-28 17:13:20Z mblatt $
2 #ifndef DUNE_MPITRAITS_HH
3 #define DUNE_MPITRAITS_HH
4 
5 #if HAVE_MPI
6 #include"mpi.h"
7 #endif
8 
9 namespace Dune
10 {
21 #if HAVE_MPI
22 
31  template<typename T>
32  struct MPITraits
33  {
34  private:
35  MPITraits(){}
36  MPITraits(const MPITraits&){}
37  static MPI_Datatype datatype;
38  static MPI_Datatype vectortype;
39  public:
40  static inline MPI_Datatype getType()
41  {
42  if(datatype==MPI_DATATYPE_NULL){
43  MPI_Type_contiguous(sizeof(T),MPI_BYTE,&datatype);
44  MPI_Type_commit(&datatype);
45  }
46  return datatype;
47  }
48 
49  };
50  template<class T>
51  MPI_Datatype MPITraits<T>::datatype = MPI_DATATYPE_NULL;
52 
53 #ifndef DOXYGEN
54 #if HAVE_MPI
55 
56  // A Macro for defining traits for the primitive data types
57 #define ComposeMPITraits(p,m) \
58  template<> \
59  struct MPITraits<p>{ \
60  static inline MPI_Datatype getType(){ \
61  return m; \
62  } \
63  }
64 
65  ComposeMPITraits(char, MPI_CHAR);
66  ComposeMPITraits(unsigned char,MPI_UNSIGNED_CHAR);
67  ComposeMPITraits(short,MPI_SHORT);
68  ComposeMPITraits(unsigned short,MPI_UNSIGNED_SHORT);
69  ComposeMPITraits(int,MPI_INT);
70  ComposeMPITraits(unsigned int,MPI_UNSIGNED);
71  ComposeMPITraits(long,MPI_LONG);
72  ComposeMPITraits(unsigned long,MPI_UNSIGNED_LONG);
73  ComposeMPITraits(float,MPI_FLOAT);
74  ComposeMPITraits(double,MPI_DOUBLE);
75  ComposeMPITraits(long double,MPI_LONG_DOUBLE);
76 
77 
78 #undef ComposeMPITraits
79 
80  template<class K, int n> class FieldVector;
81 
82  template<class K, int n>
83  struct MPITraits<FieldVector<K,n> >
84  {
85  static MPI_Datatype datatype;
86  static MPI_Datatype vectortype;
87 
88  static inline MPI_Datatype getType()
89  {
90  if(datatype==MPI_DATATYPE_NULL){
91  MPI_Type_contiguous(n, MPITraits<K>::getType(), &vectortype);
92  MPI_Type_commit(&vectortype);
93  FieldVector<K,n> fvector;
94  MPI_Aint base;
95  MPI_Aint displ;
96  MPI_Address(&fvector, &base);
97  MPI_Address(&(fvector[0]), &displ);
98  displ -= base;
99  int length[1]={1};
100 
101  MPI_Type_struct(1, length, &displ, &vectortype, &datatype);
102  MPI_Type_commit(&datatype);
103  }
104  return datatype;
105  }
106 
107  };
108 
109  template<class K, int n>
110  MPI_Datatype MPITraits<FieldVector<K,n> >::datatype = MPI_DATATYPE_NULL;
111  template<class K, int n>
112  MPI_Datatype MPITraits<FieldVector<K,n> >::vectortype = {MPI_DATATYPE_NULL};
113 
114 
115  template<int k>
116  class bigunsignedint;
117 
118  template<int k>
119  struct MPITraits<bigunsignedint<k> >
120  {
121  static MPI_Datatype datatype;
122  static MPI_Datatype vectortype;
123 
124  static inline MPI_Datatype getType()
125  {
126  if(datatype==MPI_DATATYPE_NULL){
127  MPI_Type_contiguous(bigunsignedint<k>::n, MPITraits<unsigned short>::getType(),
128  &vectortype);
129  //MPI_Type_commit(&vectortype);
130  bigunsignedint<k> data;
131  MPI_Aint base;
132  MPI_Aint displ;
133  MPI_Address(&data, &base);
134  MPI_Address(&(data.digit), &displ);
135  displ -= base;
136  int length[1]={1};
137  MPI_Type_struct(1, length, &displ, &vectortype, &datatype);
138  MPI_Type_commit(&datatype);
139  }
140  return datatype;
141  }
142  };
143 }
144 namespace std
145 {
146  template<typename T1,typename T2> struct pair;
147 }
148 
149 namespace Dune
150 {
151  template<int k>
152  MPI_Datatype MPITraits<bigunsignedint<k> >::datatype = MPI_DATATYPE_NULL;
153  template<int k>
154  MPI_Datatype MPITraits<bigunsignedint<k> >::vectortype = MPI_DATATYPE_NULL;
155 
156  template<typename T1, typename T2>
157  struct MPITraits<std::pair<T1,T2 > >
158  {
159  public:
160  inline static MPI_Datatype getType();
161  private:
162  static MPI_Datatype type;
163  };
164  template<typename T1, typename T2>
165  MPI_Datatype MPITraits<std::pair<T1,T2> >::getType()
166  {
167  if(type==MPI_DATATYPE_NULL){
168  int length[4];
169  MPI_Aint disp[4];
170  MPI_Datatype types[4] = {MPI_LB, MPITraits<T1>::getType(),
171  MPITraits<T2>::getType(), MPI_UB};
172  std::pair<T1,T2> rep[2];
173  length[0]=length[1]=length[2]=length[3]=1;
174  MPI_Address(rep, disp); // lower bound of the datatype
175  MPI_Address(&(rep[0].first), disp+1);
176  MPI_Address(&(rep[0].second), disp+2);
177  MPI_Address(rep+1, disp+3); // upper bound of the datatype
178  for(int i=3; i >= 0; --i)
179  disp[i] -= disp[0];
180  MPI_Type_struct(4, length, disp, types, &type);
181  MPI_Type_commit(&type);
182  }
183  return type;
184  }
185 
186  template<typename T1, typename T2>
187  MPI_Datatype MPITraits<std::pair<T1,T2> >::type=MPI_DATATYPE_NULL;
188 #endif
189 #endif
190 #endif
191 
192 }
193 
194 #endif