Tenncor
save.hpp
Go to the documentation of this file.
1 
9 #include <list>
10 #include <unordered_set>
11 
12 #include "teq/traveler.hpp"
13 #include "teq/functor.hpp"
14 
15 #include "pbm/data.hpp"
16 
17 #ifndef PBM_SAVE_HPP
18 #define PBM_SAVE_HPP
19 
20 namespace pbm
21 {
22 
24 template <typename SAVER,
25  typename std::enable_if<
26  std::is_base_of<iSaver,SAVER>::value>::type* = nullptr>
27 struct GraphSaver final : public teq::iTraveler
28 {
30  registry_(registry) {}
31 
33  void visit (teq::iLeaf* leaf) override
34  {
35  if (false == estd::has(visited_, leaf))
36  {
37  leaf->accept(stat);
38  leaves_.push_back(leaf);
39  visited_.emplace(leaf);
40  }
41  }
42 
44  void visit (teq::iFunctor* func) override
45  {
46  if (false == estd::has(visited_, func))
47  {
48  func->accept(stat);
49  funcs_.push_back(func);
50  visited_.emplace(func);
51 
52  teq::ArgsT children = func->get_children();
53  for (auto& child : children)
54  {
55  child.get_tensor()->accept(*this);
56  }
57  }
58  }
59 
61  void save (cortenn::Graph& out)
62  {
63  // sort functions from the root with the smallest subtree to the largest
64  // this ensures every children of a node appears before the parent,
65  // as is the order of node creations
66  funcs_.sort(
67  [&](teq::iTensor* a, teq::iTensor* b)
68  {
69  return stat.graphsize_[a].upper_ < stat.graphsize_[b].upper_;
70  });
71 
72  std::vector<teq::iFunctor*> funcs(funcs_.begin(), funcs_.end());
73  std::vector<teq::iLeaf*> leaves(leaves_.begin(), leaves_.end());
74 
75  // all nodes in leaf appear before funcs
76  std::unordered_map<teq::iTensor*,size_t> ordermap;
77  size_t nleaves = leaves.size();
78  for (size_t i = 0; i < nleaves; ++i)
79  {
80  teq::iLeaf* tens = leaves[i];
81  ordermap[tens] = i;
82 
83  cortenn::Node* pb_node = out.add_nodes();
84  pb_node->set_label(tens->to_string());
85  tag_node(pb_node, tens, registry_);
86  save_data(*pb_node->mutable_source(), tens);
87  }
88  for (size_t i = 0, n = funcs.size(); i < n; ++i)
89  {
90  teq::iFunctor* f = funcs[i];
91  ordermap[f] = nleaves + i;
92 
93  cortenn::Node* pb_node = out.add_nodes();
94  pb_node->set_label(f->to_string());
95  tag_node(pb_node, f, registry_);
96  cortenn::Functor* func = pb_node->mutable_functor();
97  teq::Opcode opcode = f->get_opcode();
98  func->set_opname(opcode.name_);
99  const teq::ArgsT& children = f->get_children();
100  for (auto& child : children)
101  {
102  cortenn::NodeArg* arg = func->add_args();
103  teq::iTensor* tens = child.get_tensor().get();
104  arg->set_idx(ordermap[tens]);
105  std::vector<double> shaper =
106  saver_.save_shaper(child.get_shaper());
107  std::vector<double> coorder =
108  saver_.save_coorder(child.get_coorder());
109  google::protobuf::RepeatedField<double> shaper_vec(
110  shaper.begin(), shaper.end());
111  google::protobuf::RepeatedField<double> coorder_vec(
112  coorder.begin(), coorder.end());
113  arg->mutable_shaper()->Swap(&shaper_vec);
114  arg->mutable_coord()->Swap(&coorder_vec);
115  arg->set_fwd(child.map_io());
116  }
117  }
118  }
119 
121  std::list<teq::iLeaf*> leaves_;
122 
124  std::list<teq::iFunctor*> funcs_;
125 
128 
131 
132 private:
133  void save_data (cortenn::Source& out, teq::iLeaf* in)
134  {
135  const teq::Shape& shape = in->shape();
136  google::protobuf::RepeatedField<google::protobuf::uint64> slist(
137  shape.begin(), shape.end());
138  out.mutable_shape()->Swap(&slist);
139  out.set_data(saver_.save_leaf(in));
140  out.set_typelabel(in->type_label());
141  out.set_is_const(in->is_const());
142  }
143 
144  void tag_node (cortenn::Node* node,
145  teq::iTensor* tens, tag::TagRegistry& registry)
146  {
147  google::protobuf::Map<std::string,cortenn::Tag>* tags =
148  node->mutable_tags();
149  tag::TagRepsT reps = registry.get_tags(tens);
150  for (auto reppair : reps)
151  {
152  google::protobuf::RepeatedPtrField<std::string> labels(
153  reppair.second.begin(), reppair.second.end());
154  google::protobuf::MapPair<std::string,cortenn::Tag> tagpair(
155  reppair.first);
156  tagpair.second.mutable_labels()->Swap(&labels);
157  tags->insert(tagpair);
158  }
159  }
160 
161  SAVER saver_;
162 
164 };
165 
166 }
167 
168 #endif // PBM_SAVE_HPP
std::list< teq::iFunctor * > funcs_
List of functions visited (by depth-first)
Definition: save.hpp:124
SAVER saver_
Definition: save.hpp:161
std::unordered_set< teq::iTensor * > TensSetT
Hash set of raw tensor pointers.
Definition: itensor.hpp:63
GraphSaver(tag::TagRegistry &registry=tag::get_reg())
Definition: save.hpp:29
std::unordered_map< iTensor *, estd::NumRange< size_t > > graphsize_
Definition: traveler.hpp:105
virtual const ArgsT & get_children(void) const =0
Return children nodes as a vector of raw pointers.
Encoding of operation.
Definition: ifunctor.hpp:18
std::list< teq::iLeaf * > leaves_
List of leaves visited (left to right)
Definition: save.hpp:121
void accept(iTraveler &visiter) override
Implementation of iTensor.
Definition: ifunctor.hpp:33
Interface of iOperation-defined operation node.
Definition: ifunctor.hpp:28
Registry for associating tensors to tag collectives.
Definition: tag.hpp:165
std::vector< FuncArg > ArgsT
Type of functor arguments.
Definition: funcarg.hpp:101
Definition: shape.hpp:62
std::string name_
String representation of operation.
Definition: ifunctor.hpp:21
void visit(teq::iLeaf *leaf) override
Implementation of iTraveler.
Definition: save.hpp:33
std::map< std::string, std::vector< std::string > > TagRepsT
Map tag key to a series of labels.
Definition: tag.hpp:21
virtual bool is_const(void) const =0
Return true if leaf is immutable, otherwise false.
void save_data(cortenn::Source &out, teq::iLeaf *in)
Definition: save.hpp:133
Traveler that maps each tensor to its subtree&#39;s maximum depth.
Definition: traveler.hpp:57
virtual std::string type_label(void) const =0
Return data type label (for better readability)
virtual Opcode get_opcode(void) const =0
Return operation encoding.
Interface to travel through graph, treating iLeaf and iFunctor differently.
Definition: itensor.hpp:24
void tag_node(cortenn::Node *node, teq::iTensor *tens, tag::TagRegistry &registry)
Definition: save.hpp:144
TagRegistry & get_reg(void)
Return reference to global tag registry.
TagRepsT get_tags(const teq::iTensor *tens)
Return all key-labels under the collective associated with tens.
Definition: tag.hpp:184
void save(cortenn::Graph &out)
Marshal all equation graphs in roots vector to protobuf object.
Definition: save.hpp:61
tag::TagRegistry & registry_
Definition: save.hpp:163
virtual std::string to_string(void) const =0
Return the string representation of the tensor.
Interface of traversible and differentiable nodes with shape information.
Definition: itensor.hpp:36
void visit(teq::iFunctor *func) override
Implementation of iTraveler.
Definition: save.hpp:44
iterator end(void)
Return end iterator of internal array.
Definition: shape.hpp:162
iterator begin(void)
Return begin iterator of internal array.
Definition: shape.hpp:156
teq::GraphStat stat
Internal traveler.
Definition: save.hpp:130
Graph serialization traveler.
Definition: save.hpp:27
teq::TensSetT visited_
Visited nodes.
Definition: save.hpp:127
Leaf of the graph commonly representing the variable in an equation.
Definition: ileaf.hpp:19
void accept(iTraveler &visiter) override
Implementation of iTensor.
Definition: ileaf.hpp:24
Definition: data.hpp:20
virtual const Shape & shape(void) const =0
Return the shape held by this tensor.