1 #ifndef LIBGEODECOMP_STORAGE_FILTER_H
2 #define LIBGEODECOMP_STORAGE_FILTER_H
3 
4 #include <libgeodecomp/config.h>
5 #include <libgeodecomp/io/logger.h>
6 #include <libgeodecomp/storage/filterbase.h>
7 
8 #ifdef LIBGEODECOMP_WITH_SILO
9 #include <silo.h>
10 #endif
11 
12 #ifdef LIBGEODECOMP_WITH_MPI
13 #include <libgeodecomp/communication/typemaps.h>
14 #endif
15 
16 namespace LibGeoDecomp {
17 
18 namespace FilterHelpers {
19 
20 #ifdef LIBGEODECOMP_WITH_SILO
21 
22 /**
23  * some helper classes required to set the type constant for SILO's
24  * library calls:
25  */
26 template<typename MEMBER>
27 class GetSiloTypeID
28 {
29 public:
operator()30     inline int operator()()
31     {
32         LOG(WARN, "Warning: using type unknown to Silo for output");
33         return DB_NOTYPE;
34     }
35 };
36 
37 /**
38  * ditto
39  */
40 template<>
41 class GetSiloTypeID<int>
42 {
43 public:
operator()44     inline int operator()()
45     {
46         return DB_INT;
47     }
48 };
49 
50 /**
51  * ditto
52  */
53 template<>
54 class GetSiloTypeID<short int>
55 {
56 public:
operator()57     inline int operator()()
58     {
59         return DB_SHORT;
60     }
61 };
62 
63 /**
64  * ditto
65  */
66 template<>
67 class GetSiloTypeID<float>
68 {
69 public:
operator()70     inline int operator()()
71     {
72         return DB_FLOAT;
73     }
74 };
75 
76 /**
77  * ditto
78  */
79 template<>
80 class GetSiloTypeID<double>
81 {
82 public:
operator()83     inline int operator()()
84     {
85         return DB_DOUBLE;
86     }
87 };
88 
89 /**
90  * ditto
91  */
92 template<>
93 class GetSiloTypeID<char>
94 {
95 public:
operator()96     inline int operator()()
97     {
98         return DB_CHAR;
99     }
100 };
101 
102 /**
103  * ditto
104  */
105 template<>
106 class GetSiloTypeID<long long>
107 {
108 public:
operator()109     inline int operator()()
110     {
111         return DB_LONG_LONG;
112     }
113 };
114 
115 #endif
116 
117 #ifdef LIBGEODECOMP_WITH_MPI
118 
119 /**
120  * see below
121  */
122 template<typename MEMBER, int FLAG>
123 class GetMPIDatatype0;
124 
125 /**
126  * see below
127  */
128 template<typename MEMBER, int FLAG>
129 class GetMPIDatatype1;
130 
131 /**
132  * see below
133  */
134 template<typename MEMBER>
135 class GetMPIDatatype0<MEMBER, 0>
136 {
137 public:
operator()138     inline MPI_Datatype operator()()
139     {
140         throw std::invalid_argument("no MPI data type defined for this type");
141     }
142 };
143 
144 /**
145  * see below
146  */
147 template<typename MEMBER>
148 class GetMPIDatatype0<MEMBER, 1>
149 {
150 public:
operator()151     inline MPI_Datatype operator()()
152     {
153         return Typemaps::lookup<MEMBER>();
154     }
155 };
156 
157 /**
158  * see below
159  */
160 template<typename MEMBER>
161 class GetMPIDatatype1<MEMBER, 0>
162 {
163 public:
operator()164     inline MPI_Datatype operator()()
165     {
166         return GetMPIDatatype0<MEMBER, APITraits::HasLookupMemberFunction<Typemaps, MPI_Datatype, MEMBER>::value>()();
167     }
168 };
169 
170 /**
171  * see below
172  */
173 template<typename MEMBER>
174 class GetMPIDatatype1<MEMBER, 1>
175 {
176 public:
operator()177     inline MPI_Datatype operator()()
178     {
179         return APITraits::SelectMPIDataType<MEMBER>::value();
180     }
181 };
182 
183 /**
184  * This class is a shim to deduce a member's MPI data type via, different methods are tried:
185  */
186 template<typename MEMBER>
187 class GetMPIDatatype
188 {
189 public:
operator()190     inline MPI_Datatype operator()()
191     {
192         return GetMPIDatatype1<
193             MEMBER,
194             APITraits::HasValueFunction<APITraits::SelectMPIDataType<MEMBER>, MPI_Datatype>::value>()();
195     }
196 };
197 
198 #endif
199 
200 /**
201  * We're intentionally giving only few specializations for this helper
202  * as it's mostly meant to be used with VisIt's BOV format, and this
203  * is only defined on tree types.
204  */
205 template<typename MEMBER>
206 class GetTypeName
207 {
208 public:
operator()209     std::string operator()() const
210     {
211         throw std::invalid_argument("no string representation known for member type");
212     }
213 };
214 
215 /**
216  * see above
217  */
218 template<>
219 class GetTypeName<bool>
220 {
221 public:
operator()222     std::string operator()() const
223     {
224         return "BYTE";
225     }
226 };
227 
228 /**
229  * see above
230  */
231 template<>
232 class GetTypeName<char>
233 {
234 public:
operator()235     std::string operator()() const
236     {
237         return "BYTE";
238     }
239 };
240 
241 /**
242  * see above
243  */
244 template<>
245 class GetTypeName<float>
246 {
247 public:
operator()248     std::string operator()() const
249     {
250         return "FLOAT";
251     }
252 };
253 
254 /**
255  * see above
256  */
257 template<>
258 class GetTypeName<double>
259 {
260 public:
operator()261     std::string operator()() const
262     {
263         return "DOUBLE";
264     }
265 };
266 
267 /**
268  * see above
269  */
270 template<>
271 class GetTypeName<int>
272 {
273 public:
operator()274     std::string operator()() const
275     {
276         return "INT";
277     }
278 };
279 
280 /**
281  * see above
282  */
283 template<>
284 class GetTypeName<long>
285 {
286 public:
operator()287     std::string operator()() const
288     {
289         return "LONG";
290     }
291 };
292 
293 }
294 
295 /**
296  * Derive from this class if you wish to add custom data
297  * adapters/converters to your Selector.
298  */
299 template<typename CELL, typename MEMBER, typename EXTERNAL, int ARITY = 1>
300 class Filter : public FilterBase<CELL>
301 {
302 public:
303     friend class Serialization;
304 
sizeOf()305     std::size_t sizeOf() const
306     {
307         return sizeof(EXTERNAL);
308     }
309 
310 #ifdef LIBGEODECOMP_WITH_SILO
siloTypeID()311     int siloTypeID() const
312     {
313         return FilterHelpers::GetSiloTypeID<EXTERNAL>()();
314     }
315 #endif
316 
317 #ifdef LIBGEODECOMP_WITH_MPI
mpiDatatype()318     virtual MPI_Datatype mpiDatatype() const
319     {
320         return FilterHelpers::GetMPIDatatype<EXTERNAL>()();
321     }
322 #endif
323 
typeName()324     virtual std::string typeName() const
325     {
326         return FilterHelpers::GetTypeName<EXTERNAL>()();
327     }
328 
arity()329     virtual int arity() const
330     {
331         return ARITY;
332     }
333 
334     /**
335      * Copy a streak of variables to an AoS layout.
336      */
337     virtual void copyStreakInImpl(const EXTERNAL *first, const EXTERNAL *last, MEMBER *target) = 0;
338 
339     /**
340      * Extract a steak of members from an AoS layout.
341      */
342     virtual void copyStreakOutImpl(const MEMBER *first, const MEMBER *last, EXTERNAL *target) = 0;
343 
344     /**
345      * Copy a streak of variables to the members of a streak of cells.
346      */
347     virtual void copyMemberInImpl(
348         const EXTERNAL *source, CELL *target, int num, MEMBER CELL:: *memberPointer) = 0;
349 
350     /**
351      * Extract a streak of members from a streak of cells.
352      */
353     virtual void copyMemberOutImpl(
354         const CELL *source, EXTERNAL *target, int num, MEMBER CELL:: *memberPointer) = 0;
355 
356     /**
357      * Do not override this function! It is final.
358      */
copyStreakIn(const char * first,const char * last,char * target)359     void copyStreakIn(const char *first, const char *last, char *target)
360     {
361         copyStreakInImpl(
362             reinterpret_cast<const EXTERNAL*>(first),
363             reinterpret_cast<const EXTERNAL*>(last),
364             reinterpret_cast<MEMBER*>(target));
365     }
366 
367     /**
368      * Do not override this function! It is final.
369      */
copyStreakOut(const char * first,const char * last,char * target)370     void copyStreakOut(const char *first, const char *last, char *target)
371     {
372         copyStreakOutImpl(
373             reinterpret_cast<const MEMBER*>(first),
374             reinterpret_cast<const MEMBER*>(last),
375             reinterpret_cast<EXTERNAL*>(target));
376     }
377 
378     /**
379      * Do not override this function! It is final.
380      */
copyMemberIn(const char * source,CELL * target,int num,char CELL::* memberPointer)381     void copyMemberIn(
382         const char *source, CELL *target, int num, char CELL:: *memberPointer)
383     {
384         copyMemberInImpl(
385             reinterpret_cast<const EXTERNAL*>(source),
386             target,
387             num,
388             reinterpret_cast<MEMBER CELL:: *>(memberPointer));
389     }
390 
391     /**
392      * Do not override this function! It is final.
393      */
copyMemberOut(const CELL * source,char * target,int num,char CELL::* memberPointer)394     void copyMemberOut(
395         const CELL *source, char *target, int num, char CELL:: *memberPointer)
396     {
397         copyMemberOutImpl(
398             source,
399             reinterpret_cast<EXTERNAL*>(target),
400             num,
401             reinterpret_cast<MEMBER CELL:: *>(memberPointer));
402     }
403 
checkExternalTypeID(const std::type_info & otherID)404     bool checkExternalTypeID(const std::type_info& otherID) const
405     {
406         return typeid(EXTERNAL) == otherID;
407     }
408 };
409 
410 }
411 
412 #endif
413