DUNE PDELab (2.7)

mpitraits.hh
Go to the documentation of this file.
1// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2// vi: set et ts=4 sw=2 sts=2:
3#ifndef DUNE_MPITRAITS_HH
4#define DUNE_MPITRAITS_HH
5
16#if HAVE_MPI
17
18#include <cstddef>
19#include <cstdint>
20#include <type_traits>
21#include <utility>
22
23#include <mpi.h>
24
25namespace Dune
26{
36 template<typename T>
37 struct MPITraits
38 {
39 private:
40 MPITraits(){}
41 MPITraits(const MPITraits&){}
42 static MPI_Datatype datatype;
43 static MPI_Datatype vectortype;
44 public:
45 static inline MPI_Datatype getType()
46 {
47 if(datatype==MPI_DATATYPE_NULL) {
48 MPI_Type_contiguous(sizeof(T),MPI_BYTE,&datatype);
49 MPI_Type_commit(&datatype);
50 }
51 return datatype;
52 }
53 static constexpr bool is_intrinsic = false;
54 };
55 template<class T>
56 MPI_Datatype MPITraits<T>::datatype = MPI_DATATYPE_NULL;
57
58#ifndef DOXYGEN
59
60 // A Macro for defining traits for the primitive data types
61#define ComposeMPITraits(p,m) \
62 template<> \
63 struct MPITraits<p>{ \
64 static inline MPI_Datatype getType(){ \
65 return m; \
66 } \
67 static constexpr bool is_intrinsic = true; \
68 }
69
70 ComposeMPITraits(char, MPI_CHAR);
71 ComposeMPITraits(unsigned char,MPI_UNSIGNED_CHAR);
72 ComposeMPITraits(short,MPI_SHORT);
73 ComposeMPITraits(unsigned short,MPI_UNSIGNED_SHORT);
74 ComposeMPITraits(int,MPI_INT);
75 ComposeMPITraits(unsigned int,MPI_UNSIGNED);
76 ComposeMPITraits(long,MPI_LONG);
77 ComposeMPITraits(unsigned long,MPI_UNSIGNED_LONG);
78 ComposeMPITraits(float,MPI_FLOAT);
79 ComposeMPITraits(double,MPI_DOUBLE);
80 ComposeMPITraits(long double,MPI_LONG_DOUBLE);
81
82
83#undef ComposeMPITraits
84
85 template<class K, int n> class FieldVector;
86
87 template<class K, int n>
88 struct MPITraits<FieldVector<K,n> >
89 {
90 static MPI_Datatype datatype;
91 static MPI_Datatype vectortype;
92
93 static inline MPI_Datatype getType()
94 {
95 if(datatype==MPI_DATATYPE_NULL) {
96 MPI_Type_contiguous(n, MPITraits<K>::getType(), &vectortype);
97 MPI_Type_commit(&vectortype);
98 FieldVector<K,n> fvector;
99 MPI_Aint base;
100 MPI_Aint displ;
101 MPI_Get_address(&fvector, &base);
102 MPI_Get_address(&(fvector[0]), &displ);
103 displ -= base;
104 int length[1]={1};
105
106 MPI_Type_create_struct(1, length, &displ, &vectortype, &datatype);
107 MPI_Type_commit(&datatype);
108 }
109 return datatype;
110 }
111
112 };
113
114 template<class K, int n>
115 MPI_Datatype MPITraits<FieldVector<K,n> >::datatype = MPI_DATATYPE_NULL;
116 template<class K, int n>
117 MPI_Datatype MPITraits<FieldVector<K,n> >::vectortype = {MPI_DATATYPE_NULL};
118
119
120 template<int k>
121 class bigunsignedint;
122
123 template<int k>
124 struct MPITraits<bigunsignedint<k> >
125 {
126 static MPI_Datatype datatype;
127 static MPI_Datatype vectortype;
128
129 static inline MPI_Datatype getType()
130 {
131 if(datatype==MPI_DATATYPE_NULL) {
132 MPI_Type_contiguous(bigunsignedint<k>::n, MPITraits<std::uint16_t>::getType(),
133 &vectortype);
134 //MPI_Type_commit(&vectortype);
135 bigunsignedint<k> data;
136 MPI_Aint base;
137 MPI_Aint displ;
138 MPI_Get_address(&data, &base);
139 MPI_Get_address(&(data.digit), &displ);
140 displ -= base;
141 int length[1]={1};
142 MPI_Type_create_struct(1, length, &displ, &vectortype, &datatype);
143 MPI_Type_commit(&datatype);
144 }
145 return datatype;
146 }
147 };
148}
149
150namespace Dune
151{
152 template<int k>
153 MPI_Datatype MPITraits<bigunsignedint<k> >::datatype = MPI_DATATYPE_NULL;
154 template<int k>
155 MPI_Datatype MPITraits<bigunsignedint<k> >::vectortype = MPI_DATATYPE_NULL;
156
157 template<typename T1, typename T2>
158 struct MPITraits<std::pair<T1,T2 > >
159 {
160 public:
161 inline static MPI_Datatype getType();
162 private:
163 static MPI_Datatype type;
164 };
165 template<typename T1, typename T2>
166 MPI_Datatype MPITraits<std::pair<T1,T2> >::getType()
167 {
168 if(type==MPI_DATATYPE_NULL) {
169 int length[2] = {1, 1};
170 MPI_Aint disp[2];
171 MPI_Datatype types[2] = {MPITraits<T1>::getType(),
172 MPITraits<T2>::getType()};
173
174 using Pair = std::pair<T1, T2>;
175 static_assert(std::is_standard_layout<Pair>::value, "offsetof() is only defined for standard layout types");
176 disp[0] = offsetof(Pair, first);
177 disp[1] = offsetof(Pair, second);
178
179 MPI_Datatype tmp;
180 MPI_Type_create_struct(2, length, disp, types, &tmp);
181
182 MPI_Type_create_resized(tmp, 0, sizeof(Pair), &type);
183 MPI_Type_commit(&type);
184
185 MPI_Type_free(&tmp);
186 }
187 return type;
188 }
189
190 template<typename T1, typename T2>
191 MPI_Datatype MPITraits<std::pair<T1,T2> >::type=MPI_DATATYPE_NULL;
192
193#endif // !DOXYGEN
194
195} // namespace Dune
196
197#endif // HAVE_MPI
198
201#endif
vector space out of a tensor product of fields.
Definition: fvector.hh:96
Dune namespace.
Definition: alignedallocator.hh:14
STL namespace.
A traits class describing the mapping of types onto MPI_Datatypes.
Definition: mpitraits.hh:38
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.111.3 (Jul 15, 22:36, 2024)