Changeset 5d57155 for GenericIO.h


Ignore:
Timestamp:
09/25/17 16:15:39 (7 years ago)
Author:
Hal Finkel <hfinkel@…>
Branches:
master, pympi
Children:
b02d091
Parents:
fb69232
git-author:
Hal Finkel <hfinkel@…> (09/25/17 16:15:39)
git-committer:
Hal Finkel <hfinkel@…> (09/25/17 16:15:39)
Message:

Add support for float4 (and other homogeneous aggregates)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • GenericIO.h

    r14e73bb r5d57155  
    117117  int FH; 
    118118}; 
     119 
     120namespace detail { 
     121// A standard enable_if idiom (we include our own here for pre-C++11 support). 
     122template <bool B, typename T = void> 
     123struct enable_if {}; 
     124 
     125template <typename T> 
     126struct enable_if<true, T> { typedef T type; }; 
     127 
     128// A SFINAE-based trait to detect whether a type has a member named x. This is 
     129// designed to work both with structs/classes and also with OpenCL-style vector 
     130// types. 
     131template <typename T> 
     132class has_x { 
     133  typedef char yes[1]; 
     134  typedef char no[2]; 
     135 
     136  template <typename C> 
     137  static yes &test(char(*)[sizeof((*((C *) 0)).x)]); 
     138 
     139  template <typename C> 
     140  static no &test(...); 
     141 
     142public: 
     143  enum { value = sizeof(test<T>(0)) == sizeof(yes) }; 
     144}; 
     145 
     146// A SFINAE-based trait to detect whether a type is array-like (i.e. supports 
     147// the [] operator). 
     148template <typename T> 
     149class is_array { 
     150  typedef char yes[1]; 
     151  typedef char no[2]; 
     152 
     153  template <typename C> 
     154  static yes &test(char(*)[sizeof((*((C *) 0))[0])]); 
     155 
     156  template <typename C> 
     157  static no &test(...); 
     158 
     159public: 
     160  enum { value = sizeof(test<T>(0)) == sizeof(yes) }; 
     161}; 
     162} // namespace detail 
    119163 
    120164class GenericIO { 
     
    133177  struct VariableInfo { 
    134178    VariableInfo(const std::string &N, std::size_t S, bool IF, bool IS, 
    135                  bool PCX, bool PCY, bool PCZ, bool PG) 
     179                 bool PCX, bool PCY, bool PCZ, bool PG, std::size_t ES = 0) 
    136180      : Name(N), Size(S), IsFloat(IF), IsSigned(IS), 
    137181        IsPhysCoordX(PCX), IsPhysCoordY(PCY), IsPhysCoordZ(PCZ), 
    138         MaybePhysGhost(PG) {} 
     182        MaybePhysGhost(PG), ElementSize(ES ? ES : S) {} 
    139183 
    140184    std::string Name; 
     
    144188    bool IsPhysCoordX, IsPhysCoordY, IsPhysCoordZ; 
    145189    bool MaybePhysGhost; 
     190    std::size_t ElementSize; 
    146191  }; 
    147192 
    148193public: 
    149   struct Variable { 
     194  class Variable { 
     195  private: 
     196    template <typename ET> 
     197    void deduceTypeInfoFromElement(ET *) { 
     198      ElementSize = sizeof(ET); 
     199      IsFloat = !std::numeric_limits<ET>::is_integer; 
     200      IsSigned = std::numeric_limits<ET>::is_signed; 
     201    } 
     202 
     203    // There are specializations here to handle array types 
     204    // (e.g. typedef float float4[4];), struct types 
     205    // (e.g. struct float4 { float x, y, z, w; };), and scalar types. 
     206    // Builtin vector types 
     207    // (e.g. typedef float float4 __attribute__((ext_vector_type(4)));) should 
     208    // also work. 
     209    template <typename T> 
     210    typename detail::enable_if<detail::is_array<T>::value, void>::type 
     211    deduceTypeInfo(T *D) { 
     212      Size = sizeof(T); 
     213      deduceTypeInfoFromElement(&(*D)[0]); 
     214    } 
     215 
     216    template <typename T> 
     217    typename detail::enable_if<detail::has_x<T>::value && 
     218                               !detail::is_array<T>::value, void>::type 
     219    deduceTypeInfo(T *D) { 
     220      Size = sizeof(T); 
     221      deduceTypeInfoFromElement(&(*D).x); 
     222    } 
     223 
     224    template <typename T> 
     225    typename detail::enable_if<!detail::has_x<T>::value && 
     226                               !detail::is_array<T>::value, void>::type 
     227    deduceTypeInfo(T *D) { 
     228      Size = sizeof(T); 
     229      deduceTypeInfoFromElement(D); 
     230    } 
     231 
     232  public: 
    150233    template <typename T> 
    151234    Variable(const std::string &N, T* D, unsigned Flags = 0) 
    152       : Name(N), Size(sizeof(T)), 
    153         IsFloat(!std::numeric_limits<T>::is_integer), 
    154         IsSigned(std::numeric_limits<T>::is_signed), 
    155         Data((void *) D), HasExtraSpace(Flags & VarHasExtraSpace), 
     235      : Name(N), Data((void *) D), HasExtraSpace(Flags & VarHasExtraSpace), 
    156236        IsPhysCoordX(Flags & VarIsPhysCoordX), 
    157237        IsPhysCoordY(Flags & VarIsPhysCoordY), 
    158238        IsPhysCoordZ(Flags & VarIsPhysCoordZ), 
    159         MaybePhysGhost(Flags & VarMaybePhysGhost) {} 
     239        MaybePhysGhost(Flags & VarMaybePhysGhost) { 
     240      deduceTypeInfo(D); 
     241    } 
     242 
     243    template <typename T> 
     244    Variable(const std::string &N, std::size_t NumElements, T* D, 
     245             unsigned Flags = 0) 
     246      : Name(N), Data((void *) D), HasExtraSpace(Flags & VarHasExtraSpace), 
     247        IsPhysCoordX(Flags & VarIsPhysCoordX), 
     248        IsPhysCoordY(Flags & VarIsPhysCoordY), 
     249        IsPhysCoordZ(Flags & VarIsPhysCoordZ), 
     250        MaybePhysGhost(Flags & VarMaybePhysGhost) { 
     251      deduceTypeInfoFromElement(D); 
     252      Size = ElementSize*NumElements; 
     253    } 
    160254 
    161255    Variable(const VariableInfo &VI, void *D, unsigned Flags = 0) 
     
    166260        IsPhysCoordY((Flags & VarIsPhysCoordY) || VI.IsPhysCoordY), 
    167261        IsPhysCoordZ((Flags & VarIsPhysCoordZ) || VI.IsPhysCoordZ), 
    168         MaybePhysGhost((Flags & VarMaybePhysGhost) || VI.MaybePhysGhost) {} 
     262        MaybePhysGhost((Flags & VarMaybePhysGhost) || VI.MaybePhysGhost), 
     263        ElementSize(VI.ElementSize) {} 
    169264 
    170265    std::string Name; 
     
    176271    bool IsPhysCoordX, IsPhysCoordY, IsPhysCoordZ; 
    177272    bool MaybePhysGhost; 
     273    std::size_t ElementSize; 
    178274  }; 
    179275 
     
    261357  } 
    262358 
     359  template <typename T> 
     360  void addScalarizedVariable(const std::string &Name, T *Data, 
     361                             std::size_t NumElements, unsigned Flags = 0) { 
     362    Vars.push_back(Variable(Name, NumElements, Data, Flags)); 
     363  } 
     364 
     365  template <typename T, typename A> 
     366  void addScalarizedVariable(const std::string &Name, std::vector<T, A> &Data, 
     367                             std::size_t NumElements, unsigned Flags = 0) { 
     368    T *D = Data.empty() ? 0 : &Data[0]; 
     369    addScalarizedVariable(Name, D, NumElements, Flags); 
     370  } 
     371 
    263372#ifndef GENERICIO_NO_MPI 
    264373  // Writing 
Note: See TracChangeset for help on using the changeset viewer.