G+Smo  24.08.0
Geometry + Simulation Modules
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
gsMpiTraits.h
Go to the documentation of this file.
1 
8 #pragma once
9 
10 #include <utility>
11 #include <cstddef>
12 
13 namespace gismo
14 {
15 
25  template<typename T>
26  struct MPITraits
27  {
28  private:
29  MPITraits(){}
30  MPITraits(const MPITraits&){}
31  static MPI_Datatype datatype;
32  static MPI_Datatype vectortype;
33  public:
34  static inline MPI_Datatype getType()
35  {
36  if(datatype==MPI_DATATYPE_NULL) {
37  MPI_Type_contiguous(sizeof(T),MPI_BYTE,&datatype);
38  MPI_Type_commit(&datatype);
39  }
40  return datatype;
41  }
42 
43  };
44  template<class T>
45  MPI_Datatype MPITraits<T>::datatype = MPI_DATATYPE_NULL;
46 
47 #ifndef DOXYGEN
48 
49  // A Macro for defining traits for the primitive data types
50 #define ComposeMPITraits(p,m) \
51  template<> \
52  struct MPITraits<p>{ \
53  static inline MPI_Datatype getType(){ \
54  return m; \
55  } \
56  }
57 
58  // Identify inbuild MPI types with the C types
59  ComposeMPITraits(char, MPI_CHAR);
60  ComposeMPITraits(unsigned char,MPI_UNSIGNED_CHAR);
61  ComposeMPITraits(short,MPI_SHORT);
62  ComposeMPITraits(unsigned short,MPI_UNSIGNED_SHORT);
63  ComposeMPITraits(int,MPI_INT);
64  ComposeMPITraits(unsigned int,MPI_UNSIGNED);
65  ComposeMPITraits(long,MPI_LONG);
66  ComposeMPITraits(unsigned long,MPI_UNSIGNED_LONG);
67  ComposeMPITraits(float,MPI_FLOAT);
68  ComposeMPITraits(double,MPI_DOUBLE);
69  ComposeMPITraits(long double,MPI_LONG_DOUBLE);
70 
71 
72 #undef ComposeMPITraits
73 
75  template<class T, int _Rows, int _Options> class gsVector;
76 
78  template<class T, int _Rows, int _Options>
79  struct MPITraits<gsVector<T, _Rows, _Options> >
80  {
81  public:
82  static inline MPI_Datatype getType()
83  {
84  if(datatype==MPI_DATATYPE_NULL)
85  {
86  MPI_Type_contiguous(_Rows, MPITraits<T>::getType(), &vectortype);
87  MPI_Type_commit(&vectortype);
89  MPI_Aint base;
90  MPI_Aint displ;
91  MPI_Get_address(&fvector, &base);
92  MPI_Get_address(&(fvector[0]), &displ);
93  displ -= base;
94  int length[1]={1};
95 
96  MPI_Type_create_struct(1, length, &displ, &vectortype, &datatype);
97  MPI_Type_commit(&datatype);
98  }
99  return datatype;
100  }
101 
102  private:
103  static MPI_Datatype datatype;
104  static MPI_Datatype vectortype;
105  };
106 
107  template<class T, int _Rows, int _Options>
108  MPI_Datatype MPITraits<gsVector<T, _Rows, _Options> >::datatype = MPI_DATATYPE_NULL;
109  template<class T, int _Rows, int _Options>
110  MPI_Datatype MPITraits<gsVector<T, _Rows, _Options> >::vectortype = {MPI_DATATYPE_NULL};
111 
112 
113 
115  template<class T, int _Rows, int _Cols, int _Options> class gsMatrix;
116 
118  template<class T, int _Rows, int _Cols, int _Options>
119  struct MPITraits<gsMatrix<T, _Rows, _Cols, _Options> >
120  {
121  public:
122  static inline MPI_Datatype getType()
123  {
124  if(datatype==MPI_DATATYPE_NULL)
125  {
126  MPI_Type_contiguous(_Rows*_Cols, MPITraits<T>::getType(), &matrixtype);
127  MPI_Type_commit(&matrixtype);
129  MPI_Aint base;
130  MPI_Aint displ;
131  MPI_Get_address(&fmatrix, &base);
132  MPI_Get_address(&(fmatrix(0,0)), &displ);
133  displ -= base;
134  int length[1]={1};
135 
136  MPI_Type_create_struct(1, length, &displ, &matrixtype, &datatype);
137  MPI_Type_commit(&datatype);
138  }
139  return datatype;
140  }
141 
142  private:
143  static MPI_Datatype datatype;
144  static MPI_Datatype matrixtype;
145  };
146 
147  template<class T, int _Rows, int _Cols, int _Options>
148  MPI_Datatype MPITraits<gsMatrix<T, _Rows, _Cols, _Options> >::datatype = MPI_DATATYPE_NULL;
149  template<class T, int _Rows, int _Cols, int _Options>
150  MPI_Datatype MPITraits<gsMatrix<T, _Rows, _Cols, _Options> >::matrixtype = {MPI_DATATYPE_NULL};
151 
152 
154  template<typename T, int _Options, typename _Index> class gsSparseMatrix;
155 
156  template<typename T, int _Options, typename _Index>
157  struct MPITraits<gsSparseMatrix<T, _Options, _Index> >
158  {
159  public:
160  static inline MPI_Datatype getType()
161  {
162  if (datatype==MPI_DATATYPE_NULL)
163  {
164  gsSparseMatrix<T, _Options, _Index> mat;
165  MPI_Aint base;
166  MPI_Get_address(mat.data, &base);
167  //MPI_Aint* displ = new int[n];
168  //for (int i=0; i<n; ++i)
169  // {
170  // MPI_Get_address(mat[i], &displ[i]);
171  // displ[i] -= base;
172  // }
173 
174  //MPI_Type_hindexed(n, m, displ, MPITraits<T>::getType(), &datatype);
175  //MPI_Type_commit(&datatype);
176  }
177  return datatype;
178  }
179 
180  private:
181  static MPI_Datatype datatype;
182  static MPI_Datatype matrixtype;
183  };
184 
185  template<class T, int _Options, typename _Index>
186  MPI_Datatype MPITraits<gsSparseMatrix<T, _Options, _Index> >::datatype = MPI_DATATYPE_NULL;
187  template<class T, int _Options, typename _Index>
188  MPI_Datatype MPITraits<gsSparseMatrix<T, _Options, _Index> >::matrixtype = {MPI_DATATYPE_NULL};
189 
190  /*
191  template<int k>
192  class bigunsignedint;
193 
194  template<int k>
195  struct MPITraits<bigunsignedint<k> >
196  {
197  static MPI_Datatype datatype;
198  static MPI_Datatype vectortype;
199 
200  static inline MPI_Datatype getType()
201  {
202  if(datatype==MPI_DATATYPE_NULL) {
203  MPI_Type_contiguous(bigunsignedint<k>::n, MPITraits<std::uint16_t>::getType(),
204  &vectortype);
205  //MPI_Type_commit(&vectortype);
206  bigunsignedint<k> data;
207  MPI_Aint base;
208  MPI_Aint displ;
209  MPI_Get_address(&data, &base);
210  MPI_Get_address(&(data.digit), &displ);
211  displ -= base;
212  int length[1]={1};
213  MPI_Type_create_struct(1, length, &displ, &vectortype, &datatype);
214  MPI_Type_commit(&datatype);
215  }
216  return datatype;
217  }
218  };
219 
220  template<int k>
221  MPI_Datatype MPITraits<bigunsignedint<k> >::datatype = MPI_DATATYPE_NULL;
222  template<int k>
223  MPI_Datatype MPITraits<bigunsignedint<k> >::vectortype = MPI_DATATYPE_NULL;
224 */
225 
226  template<typename T1, typename T2>
227  struct MPITraits<std::pair<T1,T2> >
228  {
229  public:
230  inline static MPI_Datatype getType();
231  private:
232  static MPI_Datatype type;
233  };
234  template<typename T1, typename T2>
235  MPI_Datatype MPITraits<std::pair<T1,T2> >::getType()
236  {
237  if(type==MPI_DATATYPE_NULL)
238  {
239  int length[2] = {1, 1};
240  MPI_Aint disp[2];
241  MPI_Datatype types[2] = {MPITraits<T1>::getType(),
242  MPITraits<T2>::getType()};
243 
244  typedef std::pair<T1, T2> Pair;
245  //static_assert(std::is_standard_layout<Pair>::value, "offsetof() is only defined for standard layout types");
246  disp[0] = offsetof(Pair, first);
247  disp[1] = offsetof(Pair, second);
248 
249  MPI_Datatype tmp;
250  MPI_Type_create_struct(2, length, disp, types, &tmp);
251 
252  MPI_Type_create_resized(tmp, 0, sizeof(Pair), &type);
253  MPI_Type_commit(&type);
254  MPI_Type_free(&tmp);
255  }
256  return type;
257  }
258 
259  template<typename T1, typename T2>
260  MPI_Datatype MPITraits<std::pair<T1,T2> >::type=MPI_DATATYPE_NULL;
261 
262 
263  template<typename T1, typename T2, typename T3>
264  struct MPITraits<std::tuple<T1,T2,T3> >
265  {
266  public:
267  inline static MPI_Datatype getType();
268  private:
269  static MPI_Datatype type;
270  };
271  template<typename T1, typename T2, typename T3>
272  MPI_Datatype MPITraits<std::tuple<T1,T2,T3> >::getType()
273  {
274  if(type==MPI_DATATYPE_NULL)
275  {
276  int length[3] = {1, 1, 1};
277  MPI_Aint disp[3];
278  MPI_Datatype types[3] = {MPITraits<T1>::getType(),
279  MPITraits<T2>::getType(),
280  MPITraits<T3>::getType()};
281 
282  typedef std::tuple<T1, T2, T3> Tuple3;
283  Tuple3 dummy_tuple;
284  MPI_Aint base_address;
285 
286  MPI_Get_address(&dummy_tuple, &base_address);
287  MPI_Get_address(&(std::get<0>(dummy_tuple)), &disp[0]);
288  MPI_Get_address(&(std::get<1>(dummy_tuple)), &disp[1]);
289  MPI_Get_address(&(std::get<2>(dummy_tuple)), &disp[2]);
290  disp[0] = MPI_Aint_diff(disp[0], base_address);
291  disp[1] = MPI_Aint_diff(disp[1], base_address);
292  disp[2] = MPI_Aint_diff(disp[2], base_address);
293 
294 
295  MPI_Datatype tmp;
296  MPI_Type_create_struct(3, length, disp, types, &tmp);
297 
298  MPI_Type_create_resized(tmp, 0, sizeof(Tuple3), &type);
299  MPI_Type_commit(&type);
300  MPI_Type_free(&tmp);
301  }
302  return type;
303  }
304 
305  template<typename T1, typename T2, typename T3>
306  MPI_Datatype MPITraits<std::tuple<T1,T2,T3> >::type=MPI_DATATYPE_NULL;
307 
308  template<typename T1, typename T2, typename T3, typename T4>
309  struct MPITraits<std::tuple<T1,T2,T3,T4> >
310  {
311  public:
312  inline static MPI_Datatype getType();
313  private:
314  static MPI_Datatype type;
315  };
316  template<typename T1, typename T2, typename T3, typename T4>
317  MPI_Datatype MPITraits<std::tuple<T1,T2,T3,T4> >::getType()
318  {
319  if(type==MPI_DATATYPE_NULL)
320  {
321  int length[4] = {1, 1, 1, 1};
322  MPI_Aint disp[4];
323  MPI_Datatype types[4] = {MPITraits<T1>::getType(),
324  MPITraits<T2>::getType(),
325  MPITraits<T3>::getType(),
326  MPITraits<T4>::getType()};
327 
328  typedef std::tuple<T1, T2, T3, T4> Tuple4;
329  Tuple4 dummy_tuple;
330  MPI_Aint base_address;
331 
332  MPI_Get_address(&dummy_tuple, &base_address);
333  MPI_Get_address(&(std::get<0>(dummy_tuple)), &disp[0]);
334  MPI_Get_address(&(std::get<1>(dummy_tuple)), &disp[1]);
335  MPI_Get_address(&(std::get<2>(dummy_tuple)), &disp[2]);
336  MPI_Get_address(&(std::get<3>(dummy_tuple)), &disp[3]);
337  disp[0] = MPI_Aint_diff(disp[0], base_address);
338  disp[1] = MPI_Aint_diff(disp[1], base_address);
339  disp[2] = MPI_Aint_diff(disp[2], base_address);
340  disp[3] = MPI_Aint_diff(disp[3], base_address);
341 
342  MPI_Datatype tmp;
343  MPI_Type_create_struct(4, length, disp, types, &tmp);
344 
345  MPI_Type_create_resized(tmp, 0, sizeof(Tuple4), &type);
346  MPI_Type_commit(&type);
347  MPI_Type_free(&tmp);
348  }
349  return type;
350  }
351 
352  template<typename T1, typename T2, typename T3, typename T4>
353  MPI_Datatype MPITraits<std::tuple<T1,T2,T3,T4> >::type=MPI_DATATYPE_NULL;
354 
355  template<typename T1, typename T2, typename T3, typename T4, typename T5>
356  struct MPITraits<std::tuple<T1,T2,T3,T4,T5> >
357  {
358  public:
359  inline static MPI_Datatype getType();
360  private:
361  static MPI_Datatype type;
362  };
363  template<typename T1, typename T2, typename T3, typename T4, typename T5>
364  MPI_Datatype MPITraits<std::tuple<T1,T2,T3,T4,T5> >::getType()
365  {
366  if(type==MPI_DATATYPE_NULL)
367  {
368  int length[5] = {1, 1, 1, 1, 1};
369  MPI_Aint disp[5];
370  MPI_Datatype types[5] = {MPITraits<T1>::getType(),
371  MPITraits<T2>::getType(),
372  MPITraits<T3>::getType(),
373  MPITraits<T4>::getType(),
374  MPITraits<T5>::getType()};
375 
376  typedef std::tuple<T1, T2, T3, T4, T5> Tuple5;
377  Tuple5 dummy_tuple;
378  MPI_Aint base_address;
379 
380  MPI_Get_address(&dummy_tuple, &base_address);
381  MPI_Get_address(&(std::get<0>(dummy_tuple)), &disp[0]);
382  MPI_Get_address(&(std::get<1>(dummy_tuple)), &disp[1]);
383  MPI_Get_address(&(std::get<2>(dummy_tuple)), &disp[2]);
384  MPI_Get_address(&(std::get<3>(dummy_tuple)), &disp[3]);
385  MPI_Get_address(&(std::get<4>(dummy_tuple)), &disp[4]);
386  disp[0] = MPI_Aint_diff(disp[0], base_address);
387  disp[1] = MPI_Aint_diff(disp[1], base_address);
388  disp[2] = MPI_Aint_diff(disp[2], base_address);
389  disp[3] = MPI_Aint_diff(disp[3], base_address);
390  disp[4] = MPI_Aint_diff(disp[4], base_address);
391 
392  MPI_Datatype tmp;
393  MPI_Type_create_struct(5, length, disp, types, &tmp);
394 
395  MPI_Type_create_resized(tmp, 0, sizeof(Tuple5), &type);
396  MPI_Type_commit(&type);
397  MPI_Type_free(&tmp);
398  }
399  return type;
400  }
401 
402  template<typename T1, typename T2, typename T3, typename T4, typename T5>
403  MPI_Datatype MPITraits<std::tuple<T1,T2,T3,T4,T5> >::type=MPI_DATATYPE_NULL;
404 
405  template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
406  struct MPITraits<std::tuple<T1,T2,T3,T4,T5,T6> >
407  {
408  public:
409  inline static MPI_Datatype getType();
410  private:
411  static MPI_Datatype type;
412  };
413  template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
414  MPI_Datatype MPITraits<std::tuple<T1,T2,T3,T4,T5,T6> >::getType()
415  {
416  if(type==MPI_DATATYPE_NULL)
417  {
418  int length[6] = {1, 1, 1, 1, 1, 1};
419  MPI_Aint disp[6];
420  MPI_Datatype types[6] = {MPITraits<T1>::getType(),
421  MPITraits<T2>::getType(),
422  MPITraits<T3>::getType(),
423  MPITraits<T4>::getType(),
424  MPITraits<T5>::getType(),
425  MPITraits<T6>::getType()};
426 
427  typedef std::tuple<T1, T2, T3, T4, T5, T6> Tuple6;
428  Tuple6 dummy_tuple;
429  MPI_Aint base_address;
430 
431  MPI_Get_address(&dummy_tuple, &base_address);
432  MPI_Get_address(&(std::get<0>(dummy_tuple)), &disp[0]);
433  MPI_Get_address(&(std::get<1>(dummy_tuple)), &disp[1]);
434  MPI_Get_address(&(std::get<2>(dummy_tuple)), &disp[2]);
435  MPI_Get_address(&(std::get<3>(dummy_tuple)), &disp[3]);
436  MPI_Get_address(&(std::get<4>(dummy_tuple)), &disp[4]);
437  MPI_Get_address(&(std::get<5>(dummy_tuple)), &disp[5]);
438  disp[0] = MPI_Aint_diff(disp[0], base_address);
439  disp[1] = MPI_Aint_diff(disp[1], base_address);
440  disp[2] = MPI_Aint_diff(disp[2], base_address);
441  disp[3] = MPI_Aint_diff(disp[3], base_address);
442  disp[4] = MPI_Aint_diff(disp[4], base_address);
443  disp[5] = MPI_Aint_diff(disp[5], base_address);
444 
445  MPI_Datatype tmp;
446  MPI_Type_create_struct(6, length, disp, types, &tmp);
447 
448  MPI_Type_create_resized(tmp, 0, sizeof(Tuple6), &type);
449  MPI_Type_commit(&type);
450  MPI_Type_free(&tmp);
451  }
452  return type;
453  }
454 
455  template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
456  MPI_Datatype MPITraits<std::tuple<T1,T2,T3,T4,T5,T6> >::type=MPI_DATATYPE_NULL;
457 
458  template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7>
459  struct MPITraits<std::tuple<T1,T2,T3,T4,T5,T6,T7> >
460  {
461  public:
462  inline static MPI_Datatype getType();
463  private:
464  static MPI_Datatype type;
465  };
466  template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7>
467  MPI_Datatype MPITraits<std::tuple<T1,T2,T3,T4,T5,T6,T7> >::getType()
468  {
469  if(type==MPI_DATATYPE_NULL)
470  {
471  int length[7] = {1, 1, 1, 1, 1, 1, 1};
472  MPI_Aint disp[7];
473  MPI_Datatype types[7] = {MPITraits<T1>::getType(),
474  MPITraits<T2>::getType(),
475  MPITraits<T3>::getType(),
476  MPITraits<T4>::getType(),
477  MPITraits<T5>::getType(),
478  MPITraits<T6>::getType(),
479  MPITraits<T7>::getType()};
480 
481  typedef std::tuple<T1, T2, T3, T4, T5, T6, T7> Tuple7;
482  Tuple7 dummy_tuple;
483  MPI_Aint base_address;
484 
485  MPI_Get_address(&dummy_tuple, &base_address);
486  MPI_Get_address(&(std::get<0>(dummy_tuple)), &disp[0]);
487  MPI_Get_address(&(std::get<1>(dummy_tuple)), &disp[1]);
488  MPI_Get_address(&(std::get<2>(dummy_tuple)), &disp[2]);
489  MPI_Get_address(&(std::get<3>(dummy_tuple)), &disp[3]);
490  MPI_Get_address(&(std::get<4>(dummy_tuple)), &disp[4]);
491  MPI_Get_address(&(std::get<5>(dummy_tuple)), &disp[5]);
492  MPI_Get_address(&(std::get<6>(dummy_tuple)), &disp[6]);
493  disp[0] = MPI_Aint_diff(disp[0], base_address);
494  disp[1] = MPI_Aint_diff(disp[1], base_address);
495  disp[2] = MPI_Aint_diff(disp[2], base_address);
496  disp[3] = MPI_Aint_diff(disp[3], base_address);
497  disp[4] = MPI_Aint_diff(disp[4], base_address);
498  disp[5] = MPI_Aint_diff(disp[5], base_address);
499  disp[6] = MPI_Aint_diff(disp[6], base_address);
500 
501  MPI_Datatype tmp;
502  MPI_Type_create_struct(7, length, disp, types, &tmp);
503 
504  MPI_Type_create_resized(tmp, 0, sizeof(Tuple7), &type);
505  MPI_Type_commit(&type);
506  MPI_Type_free(&tmp);
507  }
508  return type;
509  }
510 
511  template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7>
512  MPI_Datatype MPITraits<std::tuple<T1,T2,T3,T4,T5,T6,T7> >::type=MPI_DATATYPE_NULL;
513 }
514 
515 #endif
A matrix with arbitrary coefficient type and fixed or dynamic size.
Definition: gsMatrix.h:38
A traits class describing the mapping of types onto MPI_Datatypes.
Definition: gsMpiTraits.h:26
A vector with arbitrary coefficient type and fixed or dynamic size.
Definition: gsVector.h:35