Tenncor
parse.hpp
Go to the documentation of this file.
1 
8 #include "opt/parse.hpp"
9 
10 #include "eteq/eteq.hpp"
11 
12 #ifndef ETEQ_PARSE_HPP
13 #define ETEQ_PARSE_HPP
14 
15 namespace eteq
16 {
17 
18 static std::vector<double> vectorize (::NumList* list)
19 {
20  std::vector<double> arr;
21  for (auto it = list->head_; nullptr != it; it = it->next_)
22  {
23  arr.push_back(it->val_);
24  }
25  return arr;
26 }
27 
28 static CoordptrT coorderize (::NumList* list)
29 {
30  CoordptrT out = nullptr;
31  if (nullptr == list)
32  {
33  return out;
34  }
35  std::vector<double> clist = vectorize(list);
36  if (clist.size() > 0)
37  {
38  teq::CoordT carr;
39  std::copy(clist.begin(), clist.end(), carr.begin());
40  out = std::make_shared<CoordMap>(carr, false); // todo: figure out bijectivity
41  }
42  return out;
43 }
44 
46 template <typename T>
47 struct ScalarConvr final : public opt::iConverter
48 {
49  ScalarConvr (double scalar) : scalar_(scalar) {}
50 
53  teq::Shape outshape) const override
54  {
55  return make_constant_scalar((T) scalar_, outshape)->get_tensor();
56  }
57 
59  std::string to_string (void) const override
60  {
61  return fmts::to_string(scalar_);
62  }
63 
65  double scalar_;
66 };
67 
69 template <typename T>
70 struct AnyConvr final : public opt::iConverter
71 {
72  AnyConvr (std::string any_id) : any_id_(any_id) {}
73 
76  teq::Shape outshape) const override
77  {
78  const opt::CtxValT& val = estd::must_getf(ctx, any_id_,
79  "cannot find any id `%s` in conversion", any_id_.c_str());
80  if (val.size() != 1)
81  {
82  logs::fatal("context value is not any");
83  }
84  return *(val.begin());
85  }
86 
88  std::string to_string (void) const override
89  {
90  return any_id_;
91  }
92 
94  std::string any_id_;
95 };
96 
98 struct BuilderArg final
99 {
101  teq::CoordptrT shaper, CoordptrT coorder) :
102  arg_(arg), shaper_(shaper), coorder_(coorder)
103  {
104  if (nullptr == arg)
105  {
106  logs::fatal("created a rule argument with null argument");
107  }
108  }
109 
112 
115 
118 };
119 
121 using BuilderArgsT = std::vector<BuilderArg>;
122 
124 template <typename T>
125 struct FuncConvr final : public opt::iConverter
126 {
127  FuncConvr (std::string op, BuilderArgsT args) :
128  opcode_({op, egen::get_op(op)}), args_(args) {}
129 
132  teq::Shape outshape) const override
133  {
134  ArgsT<T> args;
135  for (auto& arg : args_)
136  {
137  teq::Shape childshape = outshape;
138  if (teq::is_identity(arg.shaper_.get()))
139  {
140  childshape = teq::apply_shaper(arg.shaper_, childshape);
141  }
142  auto tens = arg.arg_->build(ctx, childshape);
143  args.push_back(FuncArg<T>(
144  TO_NODE(tens),
145  arg.shaper_, arg.coorder_));
146  }
147  return make_functor(opcode_, args)->get_tensor();
148  }
149 
151  std::string to_string (void) const override
152  {
153  std::vector<std::string> args;
154  args.reserve(args_.size());
155  std::transform(args_.begin(), args_.end(),
156  std::back_inserter(args),
157  [](const BuilderArg& arg)
158  {
159  return arg.arg_->to_string();
160  });
161  return opcode_.name_ + fmts::sprintf("(%s)", fmts::join(",",
162  args.begin(), args.end()).c_str());
163  }
164 
167 
170 };
171 
173 template <typename T>
174 struct GroupConvr final : public opt::iConverter
175 {
176  GroupConvr (std::string group, BuilderArgsT args, std::string variadic) :
177  group_(group), args_(args), variadic_(variadic)
178  {
179  assert(group_ == "sum" || group_ == "prod"); // todo: generalize this for ordered-groups
180  }
181 
184  teq::Shape outshape) const override
185  {
187  for (auto& arg : args_)
188  {
189  teq::Shape childshape = outshape;
190  if (teq::is_identity(arg.shaper_.get()))
191  {
192  childshape = teq::apply_shaper(arg.shaper_, childshape);
193  }
194  args.push_back(arg.arg_->build(ctx, childshape));
195  }
196 
197  if (variadic_.size() > 0)
198  {
199  opt::CtxValT varargs = estd::try_get(
200  ctx, variadic_, opt::CtxValT());
201  args.insert(args.end(), varargs.begin(), varargs.end());
202  }
203  eteq::NodesT<T> outs;
204  outs.reserve(args.size());
205  std::transform(args.begin(), args.end(),
206  std::back_inserter(outs),
207  [](teq::TensptrT tens)
208  {
209  return TO_NODE(tens);
210  });
211  if (group_ == "sum")
212  {
213  return tenncor::sum(outs)->get_tensor();
214  }
215  return tenncor::prod(outs)->get_tensor();
216  }
217 
219  std::string to_string (void) const override
220  {
221  std::vector<std::string> args;
222  args.reserve(args_.size());
223  std::transform(args_.begin(), args_.end(),
224  std::back_inserter(args),
225  [](const BuilderArg& arg)
226  {
227  return arg.arg_->to_string();
228  });
229  if (variadic_.size() > 0)
230  {
231  args.push_back(".." + variadic_);
232  }
233  return fmts::sprintf("group:%s(%s)", group_.c_str(),
234  fmts::join(",", args.begin(), args.end()).c_str());
235  }
236 
238  std::string group_;
239 
242 
244  std::string variadic_;
245 };
246 
248 template <typename T>
250 {
252  opt::CstConvertF build_cconv (void) const override
253  {
254  return [](teq::iTensor* tens)
255  {
256  teq::TensptrT out = nullptr;
257  if (auto f = dynamic_cast<teq::iOperableFunc*>(tens))
258  {
259  f->update();
260  T* data = (T*) f->data();
261  out = make_constant(data, tens->shape())->get_tensor();
262  }
263  return out;
264  };
265  }
266 
268  opt::ConvptrT build (const ::Subgraph* sg,
269  const opt::RulesContext& ctx) const override
270  {
271  if (NULL == sg)
272  {
273  logs::fatal("cannot make builder with null subgraph");
274  }
275  opt::ConvptrT out;
276  switch (sg->type_)
277  {
278  case SCALAR:
279  out = std::make_shared<ScalarConvr<T>>(sg->val_.scalar_);
280  break;
281  case ANY:
282  {
283  std::string symbol(sg->val_.any_);
284  if (false == estd::has(ctx.symbols_, symbol))
285  {
286  logs::fatalf("undeclared symbol `%s`", symbol.c_str());
287  }
288  out = std::make_shared<AnyConvr<T>>(symbol);
289  }
290  break;
291  case BRANCH:
292  {
293  ::Branch* branch = sg->val_.branch_;
294  if (nullptr == branch)
295  {
296  logs::fatal("subgraph ended at nullptr branch");
297  }
299  for (auto it = branch->args_->head_; nullptr != it; it = it->next_)
300  {
301  ::Arg* arg = (::Arg*) it->val_;
302  opt::ConvptrT warg = build(arg->subgraph_, ctx);
303  teq::CoordptrT shaper = this->shaperize(arg->shaper_);
304  CoordptrT coorder = eteq::coorderize(arg->coorder_);
305  args.push_back(BuilderArg(warg, shaper, coorder));
306  }
307  std::string label(branch->label_);
308  if (branch->is_group_)
309  {
310  std::string variadic(branch->variadic_);
311  if (variadic.size() > 0 && false == estd::has(ctx.symbols_, variadic))
312  {
313  logs::warnf("unknown variadic %s", variadic.c_str());
314  variadic = "";
315  }
316  out = std::make_shared<GroupConvr<T>>(
317  label, args, variadic);
318  }
319  else
320  {
321  out = std::make_shared<FuncConvr<T>>(label, args);
322  }
323  }
324  break;
325  default:
326  logs::fatalf("unknown subgraph node type %d", sg->type_);
327  }
328  return out;
329  }
330 
332  teq::CoordptrT shaperize (::NumList* list) const override
333  {
334  teq::CoordptrT out = nullptr;
335  if (nullptr == list)
336  {
337  return out;
338  }
339  std::vector<double> slist = vectorize(list);
340  if (slist.size() > 0)
341  {
342  out = std::make_shared<teq::CoordMap>(
343  [&slist](teq::MatrixT m)
344  {
345  for (size_t i = 0; i < teq::mat_dim; ++i)
346  {
347  for (size_t j = 0; j < teq::mat_dim; ++j)
348  {
349  size_t index = i * teq::mat_dim + j;
350  if (index < slist.size())
351  {
352  m[i][j] = slist[index];
353  }
354  }
355  }
356  });
357  }
358  return out;
359  }
360 
362  teq::CoordptrT coorderize (::NumList* list) const override
363  {
364  return eteq::coorderize(list);
365  }
366 };
367 
369 template <typename T>
370 opt::OptCtx parse (std::string content)
371 {
372  static ConverterBuilder<T> builder;
373  return opt::parse(content, builder);
374 }
375 
377 template <typename T>
378 opt::OptCtx parse_file (std::string filename)
379 {
380  static ConverterBuilder<T> builder;
381  return opt::parse_file(filename, builder);
382 }
383 
384 }
385 
386 #endif // ETEQ_PARSE_HPP
std::array< CDimT, rank_cap > CoordT
Definition: shape.hpp:56
teq::CoordptrT coorderize(::NumList *list) const override
Implementation of iConverterBuilder.
Definition: parse.hpp:362
std::unordered_set< std::string > symbols_
Set of declared ANY typed rule node id.
Definition: parse.hpp:22
std::string to_string(void) const override
Implementation of iConverter.
Definition: parse.hpp:59
NodeptrT< T > make_constant_scalar(T scalar, teq::Shape shape)
Return constant node given scalar and shape.
Definition: constant.hpp:146
args
Definition: csv_to_png.py:105
std::vector< BuilderArg > BuilderArgsT
Vector of FuncArg.
Definition: parse.hpp:121
Implementation of optimization converter that represents and builds subgraphs of specific types...
Definition: parse.hpp:174
std::set< teq::TensptrT > CtxValT
Set of tensors that potentially matches some id.
Definition: candidate.hpp:23
FuncConvr(std::string op, BuilderArgsT args)
Definition: parse.hpp:127
teq::TensptrT build(const opt::ContexT &ctx, teq::Shape outshape) const override
Implementation of iConverter.
Definition: parse.hpp:131
Encoding of operation.
Definition: ifunctor.hpp:18
NodeptrT< T > make_functor(teq::Opcode opcode, ArgsT< T > args)
Return functor node given opcode and node arguments.
Definition: functor.hpp:278
GroupConvr(std::string group, BuilderArgsT args, std::string variadic)
Definition: parse.hpp:176
Implementation of optimization converter that represents and builds functors.
Definition: parse.hpp:125
Definition: constant.hpp:17
std::string to_string(void) const override
Implementation of iConverter.
Definition: parse.hpp:88
static CoordptrT coorderize(::NumList *list)
Definition: parse.hpp:28
Argument for a branching node.
Definition: def.h:54
Definition: shape.hpp:62
opt::ConvptrT arg_
Optimization IR node.
Definition: parse.hpp:111
struct NumNode * head_
Head of the linked list.
Definition: list.h:29
int is_group_
Definition: def.h:19
Eigen node version of teq::FuncArg.
Definition: funcarg.hpp:22
std::shared_ptr< iCoordMap > CoordptrT
Type of iCoordMap smartpointer.
Definition: coord.hpp:106
teq::TensptrT build(const opt::ContexT &ctx, teq::Shape outshape) const override
Implementation of iConverter.
Definition: parse.hpp:183
std::string name_
String representation of operation.
Definition: ifunctor.hpp:21
struct NumNode * next_
Next node in list (null denoting end of list)
Definition: list.h:19
Decimal linked list.
Definition: list.h:26
const RankT mat_dim
Number of rows and columns for the homogeneous matrix.
Definition: matops.hpp:22
Branching node.
Definition: def.h:33
Interface for TEQ extensions to construct conversion rules.
Definition: parse.hpp:30
std::vector< NodeptrT< T > > NodesT
Vector of nodes.
Definition: inode.hpp:67
AnyConvr(std::string any_id)
Definition: parse.hpp:72
std::shared_ptr< CoordMap > CoordptrT
Type of iCoordMap smartpointer.
Definition: coord.hpp:64
struct NumList * shaper_
Shape mapping meta-data.
Definition: def.h:60
struct PtrList * args_
Definition: def.h:20
Encapsulation of all conversion rules.
Definition: optimize.hpp:23
CoordptrT coorder_
Argument coordinate transformation data.
Definition: parse.hpp:117
Branching (Functor or Group) node.
Definition: def.h:17
opt::ConvptrT build(const ::Subgraph *sg, const opt::RulesContext &ctx) const override
Implementation of iConverterBuilder.
Definition: parse.hpp:268
std::map< std::string, CtxValT > ContexT
Map of rule graph leaf identifiers to corresponding matches.
Definition: candidate.hpp:26
struct NumList * coorder_
Coordinate mapping meta-data.
Definition: def.h:63
FuncArg equivalent for optimizer&#39;s IR of functor.
Definition: parse.hpp:98
static std::vector< double > vectorize(::NumList *list)
Definition: parse.hpp:18
teq::CoordptrT shaper_
Argument shaper.
Definition: parse.hpp:114
BuilderArg(opt::ConvptrT arg, teq::CoordptrT shaper, CoordptrT coorder)
Definition: parse.hpp:100
teq::CoordptrT shaperize(::NumList *list) const override
Implementation of iConverterBuilder.
Definition: parse.hpp:332
opt::CstConvertF build_cconv(void) const override
Implementation of iConverterBuilder.
Definition: parse.hpp:252
Rule tree leaf that represents any real node.
Definition: def.h:31
std::shared_ptr< iConverter > ConvptrT
Smart pointer of converter.
Definition: iconverter.hpp:36
double scalar_
Scalar represented.
Definition: parse.hpp:65
std::string to_string(void) const override
Implementation of iConverter.
Definition: parse.hpp:151
char variadic_[32]
Definition: def.h:22
OptCtx parse(std::string content, const iConverterBuilder &builder)
Return all parsed optimization rules of string content.
std::shared_ptr< iTensor > TensptrT
Tensor smart pointer.
Definition: itensor.hpp:51
std::function< teq::TensptrT(teq::iTensor *)> CstConvertF
Definition: optimize.hpp:20
std::string to_string(teq::CoordptrT c)
Return brief hashable string representation of coordinate mapper.
std::vector< TensptrT > TensptrsT
Vector of tensor smart pointers.
Definition: itensor.hpp:60
Global statements shared between all rule statements.
Definition: parse.hpp:19
std::vector< FuncArg< T > > ArgsT
Type of typed functor arguments.
Definition: funcarg.hpp:84
opt::OptCtx parse(std::string content)
Return optimization rules tied to ETEQ Builder specified in content.
Definition: parse.hpp:370
teq::Opcode opcode_
Operator being represented.
Definition: parse.hpp:166
teq::TensptrT build(const opt::ContexT &ctx, teq::Shape outshape) const override
Implementation of iConverter.
Definition: parse.hpp:52
Optimization builder&#39;s implementation for building ETEQ nodes.
Definition: parse.hpp:249
OptCtx parse_file(std::string filename, const iConverterBuilder &builder)
Return all parsed optimization rules of a file.
Interface of traversible and differentiable nodes with shape information.
Definition: itensor.hpp:36
std::string any_id_
String id of the any node.
Definition: parse.hpp:94
NElemT index(Shape shape, CoordT coord)
BuilderArgsT args_
Arguments of the functor.
Definition: parse.hpp:169
Implementation of optimization converter that represents any node.
Definition: parse.hpp:70
Implementation of optimization converter that represents and builds scalar constants.
Definition: parse.hpp:47
std::string group_
Group name.
Definition: parse.hpp:238
Converter interface for building TEQ graphs.
Definition: iconverter.hpp:22
struct PtrNode * head_
Head of the linked list.
Definition: list.h:62
ScalarConvr(double scalar)
Definition: parse.hpp:49
opt::OptCtx parse_file(std::string filename)
Return optimization rules tied to ETEQ Builder specified in file.
Definition: parse.hpp:378
char label_[32]
Definition: def.h:21
NodeptrT< T > make_constant(T *data, teq::Shape shape)
Return constant node given raw array and shape.
Definition: constant.hpp:157
Shape apply_shaper(const CoordptrT &shaper, Shape inshape)
struct Subgraph * subgraph_
Subgraph node.
Definition: def.h:57
double[mat_dim][mat_dim] MatrixT
Coordinate transformation matrix (using homogeneous)
Definition: matops.hpp:28
std::string variadic_
Variadic Any id.
Definition: parse.hpp:244
struct PtrNode * next_
Next node in list (null denoting end of list)
Definition: list.h:52
Definitive scalar constant.
Definition: def.h:29
#define TO_NODE(tens)
Macro for converting tensor to node.
Definition: inode.hpp:106
std::string to_string(void) const override
Implementation of iConverter.
Definition: parse.hpp:219
bool is_identity(iCoordMap *coorder)
Checks if the coord mapper is an identity mapper.
teq::TensptrT build(const opt::ContexT &ctx, teq::Shape outshape) const override
Implementation of iConverter.
Definition: parse.hpp:75
BuilderArgsT args_
Arguments of the group.
Definition: parse.hpp:241