Dune Core Modules (2.5.2)

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 
15 namespace 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 
151 namespace 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
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.80.0 (May 16, 22:29, 2024)