G+Smo  25.01.0
Geometry + Simulation Modules
 
Loading...
Searching...
No Matches
gsMpiTraits.h
Go to the documentation of this file.
1
8#pragma once
9
10#include <utility>
11#include <cstddef>
12
13namespace 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:41
A vector with arbitrary coefficient type and fixed or dynamic size.
Definition gsVector.h:37
The G+Smo namespace, containing all definitions for the library.
A traits class describing the mapping of types onto MPI_Datatypes.
Definition gsMpiTraits.h:27