Tenncor
functor.hpp
Go to the documentation of this file.
1 //
8 
9 #include "teq/iopfunc.hpp"
10 
11 #include "eteq/generated/opcode.hpp"
12 
13 #include "eteq/funcarg.hpp"
14 #include "eteq/constant.hpp"
15 #include "eteq/operator.hpp"
16 
17 #ifndef ETEQ_FUNCTOR_HPP
18 #define ETEQ_FUNCTOR_HPP
19 
20 namespace eteq
21 {
22 
24 template <typename T>
25 struct Functor final : public teq::iOperableFunc
26 {
28  static Functor<T>* get (teq::Opcode opcode, ArgsT<T> args);
29 
31  static Functor<T>* get (Functor<T>&& other)
32  {
33  return new Functor<T>(std::move(other));
34  }
35 
36  Functor (const Functor<T>& other) = delete;
37 
38  Functor<T>& operator = (const Functor<T>& other) = delete;
39 
40  Functor<T>& operator = (Functor<T>&& other) = delete;
41 
43  const teq::Shape& shape (void) const override
44  {
45  return shape_;
46  }
47 
49  std::string to_string (void) const override
50  {
51  return opcode_.name_;
52  }
53 
55  teq::Opcode get_opcode (void) const override
56  {
57  return opcode_;
58  }
59 
61  const teq::ArgsT& get_children (void) const override
62  {
63  return args_;
64  }
65 
67  void update_child (teq::FuncArg arg, size_t index) override
68  {
69  teq::Shape arg_shape = arg.shape();
70  if (false == arg_shape.compatible_after(shape_, 0))
71  {
72  logs::fatalf("cannot update child %d to argument with "
73  "incompatible shape %s (requires shape %s)",
74  index, arg_shape.to_string().c_str(),
75  shape_.to_string().c_str());
76  }
77  args_[index] = arg;
78  uninitialize();
79  // warning: does not notify parents of data destruction
80  }
81 
83  void update (void) override
84  {
85  if (is_uninit())
86  {
87  initialize();
88  }
89  return out_->assign();
90  }
91 
93  void* data (void) override
94  {
95  if (is_uninit())
96  {
97  initialize();
98  }
99  return out_->get_ptr();
100  }
101 
103  const void* data (void) const override
104  {
105  if (is_uninit())
106  {
107  logs::fatal("cannot get data of uninitialized functor");
108  }
109  return out_->get_ptr();
110  }
111 
113  size_t type_code (void) const override
114  {
115  return egen::get_type<T>();
116  }
117 
119  std::string type_label (void) const override
120  {
121  return egen::name_type(egen::get_type<T>());
122  }
123 
125  size_t nbytes (void) const override
126  {
127  return sizeof(T) * shape_.n_elems();
128  }
129 
132  bool is_uninit (void) const
133  {
134  return nullptr == out_;
135  }
136 
138  void uninitialize (void)
139  {
140  out_ = nullptr;
141  }
142 
144  void initialize (void)
145  {
146  std::vector<OpArg<T>> datamaps;
147  for (const teq::FuncArg& arg : args_)
148  {
149  auto tens = arg.get_tensor();
150  auto coorder = static_cast<CoordMap*>(arg.get_coorder().get());
151  datamaps.push_back(OpArg<T>{
152  TO_NODE(tens)->data(),
153  tens->shape(),
154  coorder
155  });
156  }
157  egen::typed_exec<T>((egen::_GENERATED_OPCODE) opcode_.code_,
158  shape_, out_, datamaps);
159  }
160 
161 private:
163  opcode_(opcode), shape_(shape), args_(args) {}
164 
165  Functor (Functor<T>&& other) = default;
166 
167  EigenptrT<T> out_ = nullptr;
168 
171 
174 
177 };
178 
180 template <typename T>
181 struct FunctorNode final : public iNode<T>
182 {
183  FunctorNode (std::shared_ptr<Functor<T>> f) : func_(f) {}
184 
186  FunctorNode<T>* clone (void) const
187  {
188  return static_cast<FunctorNode<T>*>(clone_impl());
189  }
190 
192  T* data (void) override
193  {
194  return (T*) func_->data();
195  }
196 
198  void update (void) override
199  {
200  func_->update();
201  }
202 
204  teq::TensptrT get_tensor (void) const override
205  {
206  return func_;
207  }
208 
209 protected:
210  iNode<T>* clone_impl (void) const override
211  {
212  auto args = func_->get_children();
213  ArgsT<T> input_args;
214  input_args.reserve(args.size());
215  std::transform(args.begin(), args.end(),
216  std::back_inserter(input_args),
217  [](teq::FuncArg& arg)
218  {
219  return FuncArg<T>(
220  TO_NODE(arg.get_tensor()), arg.get_shaper(),
221  std::static_pointer_cast<CoordMap>(arg.get_coorder()));
222  });
223  return new FunctorNode(std::shared_ptr<Functor<T>>(
224  Functor<T>::get(func_->get_opcode(), input_args)));
225  }
226 
227 private:
228  std::shared_ptr<Functor<T>> func_;
229 };
230 
231 template <typename T>
233 {
234  static bool registered = register_builder<Functor<T>,T>(
235  [](teq::TensptrT tens)
236  {
237  return std::make_shared<FunctorNode<T>>(
238  std::static_pointer_cast<Functor<T>>(tens));
239  });
240  assert(registered);
241 
242  size_t nargs = args.size();
243  if (0 == nargs)
244  {
245  logs::fatalf("cannot perform `%s` with no arguments",
246  opcode.name_.c_str());
247  }
248 
249  teq::Shape shape = args[0].shape();
250  for (size_t i = 1, n = nargs; i < n; ++i)
251  {
252  teq::Shape ishape = args[i].shape();
253  if (false == ishape.compatible_after(shape, 0))
254  {
255  logs::fatalf("cannot perform `%s` with incompatible shapes %s "
256  "and %s", opcode.name_.c_str(), shape.to_string().c_str(),
257  ishape.to_string().c_str());
258  }
259  }
260 
261  teq::ArgsT input_args;
262  input_args.reserve(nargs);
263  std::transform(args.begin(), args.end(),
264  std::back_inserter(input_args),
265  [](FuncArg<T>& arg)
266  {
267  return teq::FuncArg(
268  arg.get_tensor(),
269  arg.get_shaper(),
270  arg.map_io(),
271  arg.get_coorder());
272  });
273  return new Functor<T>(opcode, shape, input_args);
274 }
275 
277 template <typename T>
279 {
280  return std::make_shared<FunctorNode<T>>(
281  std::shared_ptr<Functor<T>>(Functor<T>::get(opcode, args))
282  );
283 }
284 
285 }
286 
287 #endif // ETEQ_FUNCTOR_HPP
std::string to_string(void) const
Return string representation of shape.
Definition: shape.hpp:148
std::string to_string(void) const override
Implementation of iTensor.
Definition: functor.hpp:49
args
Definition: csv_to_png.py:105
void update(void) override
Implementation of iOperableFunc.
Definition: functor.hpp:83
A functor node with direct access to evaluated data.
Definition: iopfunc.hpp:20
Encoding of operation.
Definition: ifunctor.hpp:18
void * data(void) override
Implementation of iData.
Definition: functor.hpp:93
NodeptrT< T > make_functor(teq::Opcode opcode, ArgsT< T > args)
Return functor node given opcode and node arguments.
Definition: functor.hpp:278
Definition: constant.hpp:17
std::vector< FuncArg > ArgsT
Type of functor arguments.
Definition: funcarg.hpp:101
T * data(void) override
Implementation of iNode<T>
Definition: functor.hpp:192
nargs
Definition: csv_to_png.py:101
teq::Shape shape_
Shape info built at construction time according to arguments.
Definition: functor.hpp:173
Definition: shape.hpp:62
Shape shape(void) const
Return shape of tensor filtered through coordinate mapper.
Definition: funcarg.hpp:55
Interface node for wrapping typed tensor.
Definition: inode.hpp:23
static Functor< T > * get(teq::Opcode opcode, ArgsT< T > args)
Return Functor given opcodes mapped to Eigen operators in operator.hpp.
Definition: functor.hpp:232
Eigen node version of teq::FuncArg.
Definition: funcarg.hpp:22
const teq::Shape & shape(void) const override
Implementation of iTensor.
Definition: functor.hpp:43
bool compatible_after(const Shape &other, RankT idx) const
Definition: shape.hpp:136
size_t type_code(void) const override
Implementation of iData.
Definition: functor.hpp:113
std::string name_
String representation of operation.
Definition: ifunctor.hpp:21
Functor(teq::Opcode opcode, teq::Shape shape, teq::ArgsT args)
Definition: functor.hpp:162
std::shared_ptr< iEigen< T > > EigenptrT
Smart point of generic Eigen data object.
Definition: eigen.hpp:94
std::string type_label(void) const override
Implementation of iData.
Definition: functor.hpp:119
teq::ArgsT args_
Tensor arguments (and children)
Definition: functor.hpp:176
size_t nbytes(void) const override
Implementation of iData.
Definition: functor.hpp:125
iNode< T > * clone_impl(void) const override
Definition: functor.hpp:210
void uninitialize(void)
Removes internal Eigen data object.
Definition: functor.hpp:138
Coordinate mapper and tensor pair.
Definition: funcarg.hpp:21
const void * data(void) const override
Implementation of iData.
Definition: functor.hpp:103
bool is_uninit(void) const
Definition: functor.hpp:132
Eigen transformation wrapper implementation of iCoordMap.
Definition: coord.hpp:18
std::shared_ptr< Functor< T > > func_
Definition: functor.hpp:228
EigenptrT< T > out_
Definition: functor.hpp:167
void update_child(teq::FuncArg arg, size_t index) override
Implementation of iFunctor.
Definition: functor.hpp:67
size_t code_
Numerical encoding of operation.
Definition: ifunctor.hpp:24
std::shared_ptr< iTensor > TensptrT
Tensor smart pointer.
Definition: itensor.hpp:51
std::vector< FuncArg< T > > ArgsT
Type of typed functor arguments.
Definition: funcarg.hpp:84
void initialize(void)
Populate internal Eigen data object.
Definition: functor.hpp:144
Raw data, shape, and transformation argument struct.
Definition: operator.hpp:28
Functor(const Functor< T > &other)=delete
teq::Opcode opcode_
Operation encoding.
Definition: functor.hpp:170
Functor&#39;s node wrapper.
Definition: functor.hpp:181
teq::Opcode get_opcode(void) const override
Implementation of iFunctor.
Definition: functor.hpp:55
Functor implementation of operable functor of Eigen operators.
Definition: functor.hpp:25
NElemT index(Shape shape, CoordT coord)
std::shared_ptr< iNode< T > > NodeptrT
Smart pointer of node.
Definition: inode.hpp:63
void update(void) override
Implementation of iNode<T>
Definition: functor.hpp:198
teq::TensptrT get_tensor(void) const override
Implementation of iNode<T>
Definition: functor.hpp:204
Functor< T > & operator=(const Functor< T > &other)=delete
NElemT n_elems(void) const
Return the total number of elements represented by the shape.
Definition: shape.hpp:118
const teq::ArgsT & get_children(void) const override
Implementation of iFunctor.
Definition: functor.hpp:61
#define TO_NODE(tens)
Macro for converting tensor to node.
Definition: inode.hpp:106
FunctorNode(std::shared_ptr< Functor< T >> f)
Definition: functor.hpp:183
FunctorNode< T > * clone(void) const
Return deep copy of this instance (with a copied functor)
Definition: functor.hpp:186