Dune Core Modules (2.7.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 
16 #if HAVE_MPI
17 
18 #include <cstddef>
19 #include <cstdint>
20 #include <type_traits>
21 #include <utility>
22 
23 #include <mpi.h>
24 
25 namespace 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 
150 namespace 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
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.80.0 (May 9, 22:29, 2024)