SUNphi  1.0
TensStor.hpp
Go to the documentation of this file.
1 #ifndef _TENSSTOR_HPP
2 #define _TENSSTOR_HPP
3 
4 /// \file TensStor.hpp
5 ///
6 /// \brief Header file for the definition of a storage space for a tensor
7 
8 #include <metaprogramming/SFINAE.hpp>
9 #include <metaprogramming/SwallowSemicolon.hpp>
10 #include <system/Memory.hpp>
11 #include <tens/Indexer.hpp>
12 #include <tens/TensKind.hpp>
13 
14 #include <cstdio>
15 
16 namespace SUNphi
17 {
18  /// Tensor Storage holding the resources for a tensor
19  ///
20  /// The tensor storage allocates and deallocates the memory location
21  /// where a tensor is materially stored, keeping track of the amount
22  /// of memory allocated. Facilities to reallocate the memory are
23  /// provided.
24  ///
25  /// \todo many things, including considering a static storage if
26  /// size is small and statically known
27  template <class TK,
28  class T>
29  class TensStor :
30  public ConstrainIsTensKind<TK> // Check that TK is a TensKind
31  {
32  /// Tuple containg all mapped type
33  using type=
34  typename TK::types;
35 
36  /// Internal storage
37  T* v;
38 
39  /// Store whether this has been created or is a reference
40  bool created=
41  false;
42 
43  public:
44 
45  /// Tensor Kind mapped
46  using Tk=
47  TK;
48 
49  /// Debug access to internal storage
50  T* &_v=
51  v;
52 
53  /// Debug store size
54  int totSize;
55 
56  /// Defines a const or non-const evaluator
57 #define PROVIDE_EVAL(QUALIFIER)
58  /*! Returns a QUALIFIER reference to a TensStor given a set of components */
59  template <class...Args, /* Arguments type */
60  class=ConstrainAreSame<int,Args...>> /* Constrain all args to be integer */
61  QUALIFIER T& eval(const Args&...args) QUALIFIER /*!< Components to extract */
62  {
63  const int id=index<TK>(dynSizes,forw<const Args>(args)...);
64  /* printf("Index: %d\n",id);*/ /*debug*/
65 
66  return v[id];
67  }
68 
71 
72  // Undefine the macro
73 #undef PROVIDE_EVAL
74 
75  /// Dynamic sizes
77 
78  /// Returns the size of a given component in the case it is Dynamic
79  template <typename TC,
81  constexpr int compSize() const
82  {
83  return dynSizes[TK::template dynCompPos<TC>];
84  }
85 
86  /// Returns the size of a given component in the case it is not Dynamic
87  template <typename TC,
89  int compSize() const
90  {
91  return TC::size;
92  }
93 
94  /// Returns the total size of the range [Beg, End)
95  template <int Beg, // Begin of the range
96  int End> // End of the range
97  int compsRangeSize() const
98  {
99  // If empty range, returns 0
100  if constexpr(Beg>=End)
101  return 0;
102  else
103  {
104  // TensComp number Beg
105  using Tc=TupleElementType<Beg,typename TK::types>;
106  // Compute this comp size
107  int tmp=compSize<Tc>();
108  // If more components present, nest
109  if constexpr(Beg+1<End)
110  return tmp*compsRangeSize<Beg+1,End>();
111  // Otherwise return
112  else
113  return tmp;
114  }
115  }
116 
117  /// Creat the full list of dynamical sizes of the grouped comps
118  template <int...Delims, // Delimiters of the groups
119  int...DynComps> // List of dynamical comps
121  const IntSeq<DynComps...>& mergedDynCompPos) const
122  {
123  using Is=IntSeq<Delims...>;
124 
125  DynSizes<sizeof...(DynComps)> sizes=
126  {{compsRangeSize<
127  Is::template element<DynComps>(),
128  Is::template element<DynComps+1>()>()...}};
129 
130  return sizes;
131  }
132 
133  /// Returns a components-merged version of the TensStor
134  template <typename Is> // Integer sequence containing the delimiters
136  {
137  /// Returned TensKind
138  using MergedTk=
139  typename TK::template Merged<Is>;
140 
141  /// Returned type
142  using TOut=
144 
145  /// Position of the merged dynamical components
146  using MergedDynCompPos=
147  typename MergedTk::DynCompsPos;
148 
149  /// Dynamic sizes after merge
152 
153  return new TOut(mergedDynSizes,v);
154  }
155 
156  /// Allocator
157  void alloc()
158  {
159  // Mark down that we are creating
160  created=
161  true;
162 
163  // Compute the size
164  totSize=
165  TK::maxStaticIdx;
166  for(const auto &i : dynSizes)
167  totSize*=
168  i;
169 
170  // Allocate
171  v=
173 
174 #ifdef DEBUG_STOR
175  runLog()<<"TensStor constructor: "<<v<<", "<<__PRETTY_FUNCTION__;
176 #endif
177  }
178 
179  /// Constructor (test)
180  template <class...DynSizes, // Arguments (sizes)
181  typename=EnableIf<areIntegrals<Unqualified<DynSizes>...>>, // Constrain to be integers
182  class=ConstrainNTypes<TK::nDynamic,DynSizes...>> // Constrain to be in the correct number
183  explicit TensStor(DynSizes&&...extDynSizes) :
184  dynSizes({{extDynSizes...}}) // Store the sizes
185  {
186  // Constrain the arguments to be all integer-like
188  //printf("Ah ah! %d\n",TK::nDynamic);
189 
190  alloc();
191  }
192 
193  /// Constructor taking dynSizes and pointer (test)
194  explicit TensStor(const DynSizes<TK::nDynamic>& dynSizes,
195  T* v) :
196  v(v), // Copy the ref
197  dynSizes(dynSizes) // Store the sizes
198  {
199  }
200 
201  /// Copy constructor (test)
202  ///
203  /// \todo improve memcpy, this could be parallelized in many ways,
204  /// we have to implement memory manager soon
205  explicit TensStor(const TensStor& oth) :
207  {
208  alloc();
209 
210  for(int i=0;i<totSize;i++)
211  v[i]=oth.v[i];
212  }
213 
214  /// Destructor
216  {
217 #ifdef DEBUG_STOR
218  runLog()<<"TensStor destructor: "<<v<<", "<<__PRETTY_FUNCTION__;
219 #endif
220 
221  // Free
222  if(created)
223  memory.release(v);
224  }
225  };
226 
227 }
228 
229 #endif
#define PROVIDE_EVAL(QUALIFIER)
Defines a const or non-const evaluator.
Definition: TensStor.hpp:57
bool created
Store whether this has been created or is a reference.
Definition: TensStor.hpp:40
T *& _v
Debug access to internal storage.
Definition: TensStor.hpp:50
#define NON_CONST_QUALIF
Empty token to be used in macro expecting qualifier.
Definition: TypeTraits.hpp:35
#define STATIC_ASSERT_ARE_INTEGRALS(...)
Static assert if the types T are not an integer-like.
Definition: TypeTraits.hpp:484
T * v
Internal storage.
Definition: TensStor.hpp:37
~TensStor()
Destructor.
Definition: TensStor.hpp:215
#define SFINAE_ON_TEMPLATE_ARG(...)
Definition: SFINAE.hpp:24
int totSize
Debug store size.
Definition: TensStor.hpp:54
decltype(auto) operator+(T1 &&smet1, T2 &&smet2)
Implement smet1+smet2.
Definition: Add.hpp:87
#define CONST_QUALIF
Token to be used in macro indicating "const" keyword.
Definition: TypeTraits.hpp:38
#define DECLAUTO
Short name for decltype(auto)