SUNphi  1.0
TensClass.hpp
Go to the documentation of this file.
1 #ifndef _TENSCLASS_HPP
2 #define _TENSCLASS_HPP
3 
4 /// \file TensClass.hpp
5 ///
6 /// \brief Header file for the Tens class
7 
8 #include <ios/Logger.hpp>
9 #include <metaprogramming/SFINAE.hpp>
10 #include <tens/TensKind.hpp>
11 #include <tens/TensStor.hpp>
12 #include <smet/Assign.hpp>
13 #include <smet/NnarySmET.hpp>
14 
15 namespace SUNphi
16 {
17  // Base type to qualify as Tens
19 
20  /// A Tensor class
21  ///
22  /// Container with a given TensKind structure and fundamental type,
23  /// holding resources for the storage of the data and providing
24  /// evaluator
25  template <typename TK, // List of tensor components
26  typename FUND> // Fundamental type
27  class Tens :
28  public BaseTens, // Inherit from BaseTens to detect in expression
29  public NnarySmET<Tens<TK,FUND>>, // Inherit from NnarySmET
30  public ConstrainIsTensKind<TK>, // Constrain the TK type to be a TensKind
31  public ConstrainIsFloatingPoint<FUND> // Constrain the Fund type to be a floating point
32  {
33  public:
34 
35  /// Tensor kind of the tensor
37 
38  /// Tensor fundamental type of the tensor
39  PROVIDE_FUND(FUND);
40 
41  // Attributes
45 
46  private:
47 
48  /// Internal storage, inited to null
49  TensStor<Tk,Fund>* v=
50  nullptr;
51 
52  /// Keep note of whether we need to free at destroy
54 
55  public:
56 
57  PROVIDE_MERGEABLE_COMPS(/* By default, all components can be merged */,IntSeq<0,Tk::nTypes>);
58 
59  /// Returns the size of a component
60  template <typename TC> // Name of the component
61  int compSize() const
62  {
63  return v->template compSize<TC>();
64  }
65 
66  /// Construct the Tens on the basis of the dynamical sizes passed
67  template <class...DynSizes, // Dynamic size types
68  typename=EnableIf<areIntegrals<Unqualified<DynSizes>...>>> // Constrain to be integers
69  explicit Tens(DynSizes&&...extDynSizes) : ///< Passed internal dynamic size
70  v(new TensStor<Tk,Fund>(forw<DynSizes>(extDynSizes)...)), // Construct the vector
71  freeAtDestroy(true) // We are allocating, so we need to free
72  {
73 #ifdef DEBUG_TENS
74  using namespace std;
75  cout<<"TensClass alloc: "<<this<<endl;
76 #endif
78  }
79 
80  /// Construct the Tens on the basis of a reference storage
81  explicit Tens(TensStor<Tk,Fund>* v) : ///< Provided storage
82  v(v), // The internal storage is built with the reference
83  freeAtDestroy(false) // We are not allocating, so we need not to free
84  {
85 #ifdef DEBUG_TENS
86  using namespace std;
87  cout<<"Creating a Tens of type "<<Tk::name()<<" NOT allocating"<<endl;
88 #endif
89  }
90 
91 // /// Copy constructor
92 // Tens(const Tens& oth) :
93 // v(new TensStor<Tk,Fund>(*oth.v)), // Copy the vector
94 // freeAtDestroy(true) // We are allocating, so we need
95 // {
96 // printf("Copying a Tens of type %s NOT allocating\n",Tk::name());
97 // #ifdef DEBUG_TENS
98 // using namespace std;
99 // cout<<"Tens copy constructor!"<<endl;
100 // #endif
101 // }
102 
103  /// Move constructor
104 // Tens(Tens&& oth) : freeAtDestroy(oth.freeAtDestroy) // Deallocate according to arg
105 // {
106 // oth.freeAtDestroy=false;
107 
108 // v=oth.v;
109 // oth.v=nullptr;
110 
111 // printf("Creating a Tens of type %s moving\n",Tk::name());
112 
113 // #ifdef DEBUG_TENS
114 // using namespace std;
115 // cout<<"Tens move constructor!"<<endl;
116 // #endif
117 // }
118 
119  /// Destructor
120  ~Tens()
121  {
122 #ifdef DEBUG_TENS
123  using namespace std;
124  cout<<"TensClass destroy: "<<this<<endl;
125 #endif
126 
127  if(freeAtDestroy)
128  {
129 #ifdef DEBUG_TENS
130  printf("Destroying a Tens of type %s deallocating\n",Tk::name());
131 #endif
132  delete v;
133  }
134 #ifdef DEBUG_TENS
135  else
136  {
137  printf("Destroying a Tens of type %s NOT deallocating\n",Tk::name());
138  }
139 #endif
140  }
141 
142  public:
143 
144  /// Returns a component-merged version
145  PROVIDE_GET_MERGED_COMPS_VIEW(/*! Create a reference to the same storage with appropriate DynSizes */,
146  /* Get a component-merged reference to the storage */
147  auto vMerged=
148  v->template mergedComps<Is>();
149  /* Returned TensKind */
150  using MergedTk=
151  typename Unqualified<decltype(*vMerged)>::Tk;
152  /* Returned type */
153  using TOut=
154  Tens<MergedTk,Fund>;
155 
156  return TOut(vMerged));
157 
158  /// Returns a constant reference to v
159  const TensStor<Tk,Fund>& getStor() const
160  {
161  return *v;
162  }
163 
164  /// Returns a non-constant reference to v
165  TensStor<Tk,Fund>& getStor()
166  {
167  return *v;
168  }
169 
170  /// Enable or not printing the components
171 #ifdef DEBUG_TENS
172  #define DEBUG_TENS_COMPONENTS 1
173 #else
174  #define DEBUG_TENS_COMPONENTS 0
175 #endif
176 
177  /// Provides either the const or non-const evaluator
178 #define PROVIDE_EVALUATOR(QUALIFIER)
179  /*! Evaluate the tensor (returns QUALIFIED reference to internal data) */
180  template <class...Comps, /* Component types */
181  class=ConstrainAreIntegrals<Comps...>, /* Force the components to be integer-like */
182  class=ConstrainNTypes<Tk::nTypes,Comps...>> /* Constrain the component to be in the same number of Tk */
183  QUALIFIER Fund& eval(const Comps&...comps) QUALIFIER /*!< Component values */
184  {
186  ((runLog()<<"Components: "<<&v) * ... *comps);
187 
188  return
189  v->eval(forw<const Comps>(comps)...);
190  }
191 
194 
195 #undef PROVIDE_EVALUATOR
196 
198  };
199 
200  // Check that a test \c Tens is a \c NnarySmET
201  STATIC_ASSERT_IS_SMET(Tens<TensKind<TensComp<double,1>>,double>);
202 
203  /// Get the storage of a \c SmET
204  ///
205  /// default case, asserting if smet is not a \c NnarySmET as needed
206  template <typename SMET, // Type of the \c SmET
208  void getStor(SMET&& smet, ///< \c SmET to be searched
210  {
213  }
214 
215  /// Get the storage of a \c SmET
216  ///
217  /// In this case we are treating a \c NnarySmET which is not a Tens
218  template <typename SMET, // Type of the SmET
220  DECLAUTO getStor(SMET&& smet) ///< \c SmET to be searched
221  {
222  return getStor(get<0>(smet.refs));
223  }
224 
225  /// Get the storage of a SmET
226  ///
227  /// In this case we are treating a UnarySmET which is a Tens
228  template <typename SMET, // Type of the SmET
230  auto& getStor(SMET&& smet) ///< SmET to be searched
231  {
232  return smet.getStor();
233  }
234 }
235 
236 #endif
#define STATIC_ASSERT_IS_SMET(...)
Definition: BaseSmET.hpp:257
#define STATIC_ASSERT_ARE_N_TYPES(N, UNEXP_PARPACK)
Static assert if not passing exactly N types.
Definition: TypeTraits.hpp:422
#define PROVIDE_TK(...)
Provides the Tk member.
Definition: BaseSmET.hpp:94
const TensStor< Tk, Fund > & getStor() const
Returns a constant reference to v.
Definition: TensClass.hpp:159
#define PROVIDE_FUND(...)
Provides the Fund member.
Definition: BaseSmET.hpp:108
#define STORING
Set the SmET to storing.
Definition: BaseSmET.hpp:82
#define PROVIDE_GET_MERGED_COMPS_VIEW(DESCRIPTION,...)
Provides a getMergedCompsView method, taking Is as template parameter.
Definition: BaseSmET.hpp:216
#define PROVIDE_EVALUATOR(QUALIFIER)
Provides either the const or non-const evaluator.
Definition: TensClass.hpp:178
#define NON_CONST_QUALIF
Empty token to be used in macro expecting qualifier.
Definition: TypeTraits.hpp:35
#define SFINAE_WORSEN_DEFAULT_VERSION_TEMPLATE_PARS
Definition: SFINAE.hpp:58
Forces the type to be a floating-point.
Definition: TypeTraits.hpp:446
TensStor< Tk, Fund > * v
Internal storage, inited to null.
Definition: TensClass.hpp:49
#define PROVIDE_MERGEABLE_COMPS(LONG_DESCRIPTION,...)
Definition: BaseSmET.hpp:179
~Tens()
Move constructor.
Definition: TensClass.hpp:120
~TensStor()
Destructor.
Definition: TensStor.hpp:215
#define STATIC_ASSERT_IS_NNARY_SMET(...)
Defines the check for a Nnary SmET.
Definition: NnarySmET.hpp:394
void getStor(SMET &&smet, DummyTypes...)
Definition: TensClass.hpp:208
#define SFINAE_ON_TEMPLATE_ARG(...)
Definition: SFINAE.hpp:24
static constexpr int element()
Get the I element of the sequence.
Definition: IntSeq.hpp:95
#define SFINAE_WORSEN_DEFAULT_VERSION_ARGS_CHECK
Check that no extra arg is passed.
Definition: SFINAE.hpp:66
#define IS_ALIASING_ACCORDING_TO_POINTER(_p)
Definition: BaseSmET.hpp:138
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 SFINAE_WORSEN_DEFAULT_VERSION_ARGS
Provide empty list of args, used to unprioritize default version.
Definition: SFINAE.hpp:62
#define DECLAUTO
Short name for decltype(auto)
#define PROVIDE_SMET_ASSIGNEMENT_OPERATOR(UNARY_SMET)
Defines the assignement operator, calling assign.
Definition: Assign.hpp:35
decltype(auto) evalThroughRepresentativeFunctionPassingCompsByName(Ts &&...ts)
Definition: NnarySmET.hpp:101
#define DEFINE_BASE_TYPE(TYPE,...)
Definition: TypeTraits.hpp:526
int compSize() const
Returns the size of a component.
Definition: TensClass.hpp:61
#define ASSIGNABLE
Set the SmET as assignable.
Definition: BaseSmET.hpp:159
#define DEBUG_TENS_COMPONENTS
Enable or not printing the components.
Definition: TensClass.hpp:174
TensStor< Tk, Fund > & getStor()
Returns a non-constant reference to v.
Definition: TensClass.hpp:165
bool freeAtDestroy
Keep note of whether we need to free at destroy.
Definition: TensClass.hpp:53