Tenncor
variable.hpp
Go to the documentation of this file.
1 
10 #include "eteq/ileaf.hpp"
11 #include "eteq/inode.hpp"
12 #include "eteq/shaped_arr.hpp"
13 
14 #ifndef ETEQ_VARIABLE_HPP
15 #define ETEQ_VARIABLE_HPP
16 
17 namespace eteq
18 {
19 
21 template <typename T>
22 struct Variable final : public iLeaf<T>
23 {
25  static Variable<T>* get (T* ptr, teq::Shape shape, std::string label = "");
26 
28  static Variable<T>* get (teq::Shape shape, std::string label = "")
29  {
30  return Variable<T>::get(std::vector<T>(shape.n_elems(), 0),
31  shape, label);
32  }
33 
35  static Variable<T>* get (T scalar, teq::Shape shape, std::string label = "")
36  {
37  if (label.empty())
38  {
39  label = fmts::to_string(scalar);
40  }
41  return Variable<T>::get(std::vector<T>(shape.n_elems(),scalar),
42  shape, label);
43  }
44 
46  static Variable<T>* get (std::vector<T> data, teq::Shape shape,
47  std::string label = "")
48  {
49  if (data.size() != shape.n_elems())
50  {
51  logs::fatalf("cannot create variable with data size %d "
52  "against shape %s", data.size(), shape.to_string().c_str());
53  }
54  return Variable<T>::get(data.data(), shape, label);
55  }
56 
58  static Variable<T>* get (const Variable<T>& other)
59  {
60  return new Variable<T>(other);
61  }
62 
64  static Variable<T>* get (Variable<T>&& other)
65  {
66  return new Variable<T>(std::move(other));
67  }
68 
69  Variable<T>& operator = (const Variable<T>& other) = default;
70 
71  Variable<T>& operator = (Variable<T>&& other) = default;
72 
74  Variable<T>& operator = (std::vector<T> input)
75  {
76  size_t ninput = input.size();
77  if (this->shape_.n_elems() != ninput)
78  {
79  logs::fatalf("cannot assign vector of %d elements to "
80  "internal data of shape %s", ninput,
81  this->shape_.to_string().c_str());
82  }
83  std::memcpy(this->data_.data(), input.data(), ninput * sizeof(T));
84  return *this;
85  }
86 
89  {
90  this->data_ = input;
91  return *this;
92  }
93 
95  void assign (const void* input, egen::_GENERATED_DTYPE dtype, teq::Shape shape)
96  {
97  if (false == shape.compatible_after(this->shape_, 0))
98  {
99  logs::fatalf("assigning data shaped %s to tensor %s",
100  shape.to_string().c_str(), this->shape_.to_string().c_str());
101  }
102  std::vector<T> data;
103  egen::type_convert(data, input, dtype, shape.n_elems());
104  this->data_ = make_tensmap<T>(data.data(), shape);
105  }
106 
108  std::string to_string (void) const override
109  {
110  return label_;
111  }
112 
114  bool is_const (void) const override
115  {
116  return false;
117  }
118 
120  std::string label_; // todo: make private
121 
122 private:
123  Variable (T* data, teq::Shape shape, std::string label) :
124  iLeaf<T>(data, shape), label_(label) {}
125 
126  Variable (const Variable<T>& other) = default;
127 
128  Variable (Variable<T>&& other) = default;
129 
130 };
131 
133 template <typename T>
134 struct VariableNode final : public iNode<T>
135 {
136  VariableNode (std::shared_ptr<Variable<T>> var) : var_(var) {}
137 
139  VariableNode<T>* clone (void) const
140  {
141  return static_cast<VariableNode<T>*>(clone_impl());
142  }
143 
145  T* data (void) override
146  {
147  return (T*) var_->data();
148  }
149 
151  void update (void) override {}
152 
154  teq::TensptrT get_tensor (void) const override
155  {
156  return var_;
157  }
158 
160  void assign (const T* input, teq::Shape shape)
161  {
162  var_->assign(input, egen::get_type<T>(), shape);
163  }
164 
166  void assign (const TensMapT<T>* tensmap)
167  {
168  var_->assign(tensmap->data(), egen::get_type<T>(), get_shape(*tensmap));
169  }
170 
172  void assign (const ShapedArr<T>& arr)
173  {
174  var_->assign(arr.data_.data(), egen::get_type<T>(), arr.shape_);
175  }
176 
178  std::string get_label (void) const
179  {
180  return var_->to_string();
181  }
182 
183 protected:
184  iNode<T>* clone_impl (void) const override
185  {
186  return new VariableNode(
187  std::shared_ptr<Variable<T>>(Variable<T>::get(*var_)));
188  }
189 
190 private:
191  std::shared_ptr<Variable<T>> var_;
192 };
193 
194 template <typename T>
195 Variable<T>* Variable<T>::get (T* ptr, teq::Shape shape, std::string label)
196 {
197  static bool registered = register_builder<Variable<T>,T>(
198  [](teq::TensptrT tens)
199  {
200  return std::make_shared<VariableNode<T>>(
201  std::static_pointer_cast<Variable<T>>(tens));
202  });
203  assert(registered);
204 
205  return new Variable<T>(ptr, shape, label);
206 }
207 
209 template <typename T>
210 using VarptrT = std::shared_ptr<VariableNode<T>>;
211 
213 template <typename T>
215 {
216  return std::static_pointer_cast<iNode<T>>(var);
217 }
218 
220 template <typename T>
221 VarptrT<T> make_variable_scalar (T scalar, teq::Shape shape, std::string label = "")
222 {
223  return std::make_shared<VariableNode<T>>(
224  std::shared_ptr<Variable<T>>(Variable<T>::get(scalar, shape, label))
225  );
226 }
227 
229 template <typename T>
230 VarptrT<T> make_variable (teq::Shape shape, std::string label = "")
231 {
232  return std::make_shared<VariableNode<T>>(
233  std::shared_ptr<Variable<T>>(Variable<T>::get(shape, label))
234  );
235 }
236 
238 template <typename T>
239 VarptrT<T> make_variable (T* data, teq::Shape shape, std::string label = "")
240 {
241  return std::make_shared<VariableNode<T>>(
242  std::shared_ptr<Variable<T>>(Variable<T>::get(data, shape, label))
243  );
244 }
245 
246 }
247 
248 #endif // ETEQ_VARIABLE_HPP
teq::TensptrT get_tensor(void) const override
Implementation of iNode<T>
Definition: variable.hpp:154
Shaped array wraps around a vector and shape.
Definition: shaped_arr.hpp:21
std::shared_ptr< VariableNode< T > > VarptrT
Smart pointer of variable nodes to preserve assign functions.
Definition: variable.hpp:210
std::string to_string(void) const
Return string representation of shape.
Definition: shape.hpp:148
teq::Shape get_shape(const TensorT< T > &tens)
Return the teq Shape representation of Eigen Tensor.
Definition: eigen.hpp:214
const teq::Shape & shape(void) const override
Implementation of iTensor.
Definition: ileaf.hpp:26
void assign(const TensMapT< T > *tensmap)
Assign Eigen tensor map to variable&#39;s internal data.
Definition: variable.hpp:166
std::vector< T > data_
Vector of size equal to shape_.n_elems()
Definition: shaped_arr.hpp:29
T * data(void) override
Implementation of iNode<T>
Definition: variable.hpp:145
Eigen::TensorMap< TensorT< T > > TensMapT
Eigen Tensor Map (reference)
Definition: eigen.hpp:39
Definition: constant.hpp:17
TensorT< T > data_
Data Source.
Definition: ileaf.hpp:67
Definition: shape.hpp:62
Interface node for wrapping typed tensor.
Definition: inode.hpp:23
bool compatible_after(const Shape &other, RankT idx) const
Definition: shape.hpp:136
Variable< T > & operator=(const Variable< T > &other)=default
teq::Shape shape_
Shape utility to avoid excessive conversion between data_.dimensions()
Definition: ileaf.hpp:70
void assign(const ShapedArr< T > &arr)
Assign ShapedArr representation to variable&#39;s internal data.
Definition: variable.hpp:172
void assign(const T *input, teq::Shape shape)
Wrapper around variable assign of the same signature.
Definition: variable.hpp:160
teq::Shape shape(void)
Return shape of internal tensor.
Definition: inode.hpp:37
VariableNode(std::shared_ptr< Variable< T >> var)
Definition: variable.hpp:136
Variable(T *data, teq::Shape shape, std::string label)
Definition: variable.hpp:123
void update(void) override
Implementation of iNode<T>
Definition: variable.hpp:151
std::string to_string(void) const override
Implementation of iTensor.
Definition: variable.hpp:108
VariableNode< T > * clone(void) const
Return deep copy of this instance (with a copied variable)
Definition: variable.hpp:139
std::shared_ptr< iTensor > TensptrT
Tensor smart pointer.
Definition: itensor.hpp:51
std::string to_string(teq::CoordptrT c)
Return brief hashable string representation of coordinate mapper.
std::string label_
Label for distinguishing variable nodes.
Definition: variable.hpp:120
Eigen::Tensor< T, 8 > TensorT
Eigen Tensor.
Definition: eigen.hpp:35
iNode< T > * clone_impl(void) const override
Definition: variable.hpp:184
void assign(const void *input, egen::_GENERATED_DTYPE dtype, teq::Shape shape)
Assign void pointer of specified data type enum and shape.
Definition: variable.hpp:95
NodeptrT< T > convert_to_node(VarptrT< T > var)
Return Node smart pointer of Variable smart pointer.
Definition: variable.hpp:214
bool is_const(void) const override
Implementation of iLeaf.
Definition: variable.hpp:114
std::shared_ptr< iNode< T > > NodeptrT
Smart pointer of node.
Definition: inode.hpp:63
teq::Shape shape_
Tensor shape of data_.
Definition: shaped_arr.hpp:32
Variable&#39;s node wrapper.
Definition: variable.hpp:134
iLeaf extension of TEQ iLeaf containing Eigen data objects
Definition: ileaf.hpp:21
std::string get_label(void) const
Return string representation of internal variable.
Definition: variable.hpp:178
static Variable< T > * get(T *ptr, teq::Shape shape, std::string label="")
Return Variable given raw pointer array whose size is denoted by shape.
Definition: variable.hpp:195
VarptrT< T > make_variable(teq::Shape shape, std::string label="")
Return zero-initialized variable node of specified shape.
Definition: variable.hpp:230
NElemT n_elems(void) const
Return the total number of elements represented by the shape.
Definition: shape.hpp:118
void * data(void) override
Implementation of iData.
Definition: ileaf.hpp:32
std::shared_ptr< Variable< T > > var_
Definition: variable.hpp:191
VarptrT< T > make_variable_scalar(T scalar, teq::Shape shape, std::string label="")
Return variable node given scalar and shape.
Definition: variable.hpp:221
Leaf node implementation containing mutable Eigen data.
Definition: variable.hpp:22