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