TPIE

2362a60
factory_base.h
1 // -*- mode: c++; tab-width: 4; indent-tabs-mode: t; eval: (progn (c-set-style "stroustrup") (c-set-offset 'innamespace 0)); -*-
2 // vi:set ts=4 sts=4 sw=4 noet :
3 // Copyright 2011, 2012, 2013, The TPIE development team
4 //
5 // This file is part of TPIE.
6 //
7 // TPIE is free software: you can redistribute it and/or modify it under
8 // the terms of the GNU Lesser General Public License as published by the
9 // Free Software Foundation, either version 3 of the License, or (at your
10 // option) any later version.
11 //
12 // TPIE is distributed in the hope that it will be useful, but WITHOUT ANY
13 // WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
15 // License for more details.
16 //
17 // You should have received a copy of the GNU Lesser General Public License
18 // along with TPIE. If not, see <http://www.gnu.org/licenses/>
19 
23 
24 #ifndef __TPIE_PIPELINING_FACTORY_BASE_H__
25 #define __TPIE_PIPELINING_FACTORY_BASE_H__
26 #include <tpie/pipelining/node_set.h>
27 #include <tpie/pipelining/node.h>
28 #include <tpie/pipelining/tokens.h>
29 
30 namespace tpie {
31 
32 namespace pipelining {
33 
35 public:
36  virtual void init_node(node & r) = 0;
37  virtual ~factory_init_hook() {
38  }
39 };
40 
42  enum type {
43  none,
44  push,
45  pull
46  };
47 };
48 
73 class factory_base {
74 public:
75  factory_base() : m_amount(0), m_set(false), m_destinationKind(destination_kind::none) {
76  }
77 
78  factory_base(const factory_base & other) = delete;
79  factory_base(factory_base &&) = default;
80  factory_base & operator=(const factory_base & other) = delete;
81  factory_base & operator=(factory_base &&) = default;
82 
89  inline void memory(double amount) {
90  m_amount = amount;
91  m_set = true;
92  }
93 
101  inline double memory() const {
102  return m_amount;
103  }
104 
112  m_hooks.push_back(hook);
113  }
114 
118  void copy_hooks_to(factory_base & other) const {
119  for (size_t i = 0; i < m_hooks.size(); ++i) {
120  other.m_hooks.push_back(m_hooks[i]);
121  }
122  }
123 
134  inline void init_node(node & r) {
135  if (!m_name.empty()) {
136  r.set_name(m_name, m_namePriority);
137  }
138  if (!m_phaseName.empty()) {
139  r.set_phase_name(m_phaseName, m_phaseNamePriority);
140  }
141  if (!m_breadcrumbs.empty()) {
142  r.set_breadcrumb(m_breadcrumbs);
143  }
144  init_common(r);
145  }
146 
157  void init_sub_node(node & r) {
158  if (m_breadcrumbs.empty()) {
159  if (m_name.empty()) {
160  // no op
161  } else {
162  r.set_breadcrumb(m_name);
163  }
164  } else {
165  if (m_name.empty()) {
166  r.set_breadcrumb(m_breadcrumbs);
167  } else {
168  r.set_breadcrumb(m_breadcrumbs + " | " + m_name);
169  }
170  }
171  init_common(r);
172  }
173 
178  void add_default_edge(node & r, const node & dest) const {
179  add_default_edge(r, dest.get_token());
180  }
181 
186  void add_default_edge(node & r, const node_token & dest) const {
187  if (r.get_node_map()->find_authority()->out_degree(r.get_id()) > 0) return;
188  switch (m_destinationKind) {
189  case destination_kind::none:
190  break;
191  case destination_kind::push:
192  r.add_push_destination(dest);
193  break;
194  case destination_kind::pull:
195  r.add_pull_source(dest);
196  break;
197  }
198  }
199 
200  void add_node_set_edges(node & r) const {
201  bits::node_map::ptr m=r.get_node_map();
202  for (size_t i=0; i < m_add_to_set.size(); ++i) {
203  bits::node_map::ptr m2=m_add_to_set[i]->m_map;
204  if (m2 && m2 != m)
205  m2->union_set(m);
206  }
207  for (size_t i=0; i < m_add_relations.size(); ++i) {
208  bits::node_map::ptr m2=m_add_relations[i].first->m_map;
209  if (m2 && m2 != m)
210  m2->union_set(m);
211  }
212  m = m->find_authority();
213  for (size_t i=0; i < m_add_to_set.size(); ++i)
214  m_add_to_set[i]->m_map = m;
215  for (size_t i=0; i < m_add_relations.size(); ++i)
216  m_add_relations[i].first->m_map = m;
217 
218  for (size_t i=0; i < m_add_to_set.size(); ++i) {
219  node_set s=m_add_to_set[i];
220  for (size_t j=0; j < s->m_relations.size(); ++j)
221  m->add_relation(s->m_relations[j].first, r.get_id(), s->m_relations[j].second);
222  s->m_nodes.push_back(r.get_id());
223  }
224 
225  for (size_t i=0; i < m_add_relations.size(); ++i) {
226  node_set s=m_add_relations[i].first;
227  bits::node_relation relation = m_add_relations[i].second;
228  for (size_t j=0; j < s->m_nodes.size(); ++j)
229  m->add_relation(r.get_id(), s->m_nodes[j], relation);
230  s->m_relations.push_back(std::make_pair(r.get_id(), relation));
231  }
232  }
233 
234 
241  inline void name(const std::string & n, priority_type p) {
242  m_name = n;
243  m_namePriority = p;
244  }
245 
252  inline void phase_name(const std::string & n, priority_type p) {
253  m_phaseName = n;
254  m_phaseNamePriority = p;
255  }
256 
257 
264  inline void push_breadcrumb(const std::string & n) {
265  if (m_breadcrumbs.empty()) m_breadcrumbs = n;
266  else m_breadcrumbs = n + " | " + m_breadcrumbs;
267  }
268 
274  m_destinationKind = destination_kind::push;
275  }
276 
282  m_destinationKind = destination_kind::pull;
283  }
284 
285  void add_to_set(node_set s) {
286  if (s)
287  m_add_to_set.push_back(s);
288  }
289 
290  void add_dependencies(node_set s) {
291  if (s)
292  m_add_relations.push_back(std::make_pair(s,bits::no_forward_depends));
293  }
294 
295  void add_forwarding_dependencies(node_set s) {
296  if (s)
297  m_add_relations.push_back(std::make_pair(s,bits::depends));
298  }
299 
300  void forward(const std::string & key, any_noncopyable value) {
301  m_forwards.push_back({key, std::move(value)});
302  }
303 
304 private:
305  void init_common(node & r) {
306  if (m_set) r.set_memory_fraction(memory());
307 
308  for (size_t i = 0; i < m_hooks.size(); ++i) {
309  m_hooks[i]->init_node(r);
310  }
311 
312  auto nodeMap = r.get_node_map()->find_authority();
313 
314  for (auto &p : m_forwards) {
315  nodeMap->forward_from_pipe_base(r.get_id(), p.first, std::move(p.second));
316  }
317  }
318 
319  double m_amount;
320  bool m_set;
321  destination_kind::type m_destinationKind;
322  std::string m_name, m_phaseName;
323  std::string m_breadcrumbs;
324  priority_type m_namePriority, m_phaseNamePriority;
325  std::vector<factory_init_hook *> m_hooks;
326  std::vector<node_set> m_add_to_set;
327  std::vector<std::pair<node_set, bits::node_relation> > m_add_relations;
328  std::vector<std::pair<std::string, any_noncopyable> > m_forwards;
329 };
330 
331 } // namespace pipelining
332 
333 } // namespace tpie
334 
335 #endif // __TPIE_PIPELINING_FACTORY_BASE_H__
void set_destination_kind_push()
Used by pipe_base classes to indicate that the default actor edge is a push edge. ...
Definition: factory_base.h:273
void hook_initialization(factory_init_hook *hook)
Add a node initialization hook.
Definition: factory_base.h:111
void memory(double amount)
Set memory fraction for this node in the pipeline phase.
Definition: factory_base.h:89
void add_default_edge(node &r, const node &dest) const
Used by pipe_base classes to set a default actor edge for ordinary push/pull nodes.
Definition: factory_base.h:178
void set_phase_name(const std::string &name, priority_type priority=PRIORITY_USER)
Set this node's phase name.
void add_pull_source(const node_token &dest)
Called by implementers to declare a pull source.
bits::node_map::ptr get_node_map() const
Get the local node map, mapping node IDs to node pointers for all the nodes reachable from this one...
Definition: node.h:251
void add_default_edge(node &r, const node_token &dest) const
Used by pipe_base classes to set a default actor edge for ordinary push/pull nodes.
Definition: factory_base.h:186
Base class of all pipelining factories.
Definition: factory_base.h:73
void copy_hooks_to(factory_base &other) const
Copy the hooks that have been added to this factory to another.
Definition: factory_base.h:118
const node_token & get_token() const
Get the node_token that maps this node's ID to a pointer to this.
Definition: node.h:632
void init_node(node &r)
Initialize node constructed in a subclass.
Definition: factory_base.h:134
void phase_name(const std::string &n, priority_type p)
Set name for this phase.
Definition: factory_base.h:252
void set_breadcrumb(const std::string &breadcrumb)
Used internally when a pair_factory has a name set.
Definition: node.h:389
Base class of all nodes.
Definition: node.h:78
void add_push_destination(const node_token &dest)
Called by implementers to declare a push destination.
void name(const std::string &n, priority_type p)
Set name for this node.
Definition: factory_base.h:241
Pipeline tokens.
void set_name(const std::string &name, priority_type priority=PRIORITY_USER)
Set this node's name.
void init_sub_node(node &r)
Initialize node constructed in a subclass.
Definition: factory_base.h:157
double memory() const
Set memory fraction for this node in the pipeline phase.
Definition: factory_base.h:101
node_token::id_t get_id() const
Get the internal node ID of this node (mainly for debugging purposes).
Definition: node.h:259
void set_destination_kind_pull()
Used by pipe_base classes to indicate that the default actor edge is a pull edge. ...
Definition: factory_base.h:281
void push_breadcrumb(const std::string &n)
Set a prefix for the name of this node.
Definition: factory_base.h:264