Dune Core Modules (2.5.0)

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