test_pipegraph.cxx
Go to the documentation of this file.
1 /** This test exercises the basics of wire cell's pipe graph and
2  * doesn't otherwise depend on wire cell. All the nodes here resemble
3  * "real" ones but should otherwise not be considered for any other
4  * use. Real use with INodes may be done via Pgraph::Factory. See
5  * test_pipgraphwrappers.cxx.
6  */
7 
8 #include "WireCellPgraph/Graph.h"
9 
10 #include <iostream>
11 #include <sstream>
12 
13 using namespace WireCell;
14 using namespace std;
15 
16 class IdNode : public Pgraph::Node
17 {
18 public:
19  IdNode(const std::string& name, int id, size_t nin=0, size_t nout=0)
20  : m_name(name), m_id(id) {
21  using Pgraph::Port;
22  for (size_t ind=0; ind<nin; ++ind) {
23  m_ports[Port::input].push_back(
24  Pgraph::Port(this, Pgraph::Port::input, "int"));
25  }
26  for (size_t ind=0; ind<nout; ++ind) {
27  m_ports[Port::output].push_back(
28  Pgraph::Port(this, Pgraph::Port::output, "int"));
29  }
30  }
31  int id() { return m_id; }
32 
33  virtual std::string ident() {
34  stringstream ss;
35  ss << m_name << "[" << m_id << "]";
36  return ss.str();
37  }
38  std::ostream& msg(const std::string s) {
39  std::cerr << ident() << ":\t" << s;
40  return std::cerr;
41  }
42 
43  virtual bool ready() {
44  using Pgraph::Port;
45  for (auto& p : m_ports[Port::input]) {
46  if (p.empty()) return false;
47  }
48  return true;
49  }
50 
51 
52 private:
54  int m_id;
55 };
56 class Source : public IdNode {
57 public:
58  Source(int id, int beg, int end)
59  : IdNode("src", id, 0, 1), m_num(beg), m_end(end) {}
60  virtual ~Source() {}
61  virtual bool ready() {
62  return m_num < m_end;
63  }
64  virtual bool operator()() {
65  if (m_num >= m_end) {
66  msg("dry\n");
67  return false;
68  }
69  msg("make: ") << m_num << std::endl;
70  Pgraph::Data d = m_num;
71  oport().put(d);
72  ++m_num;
73  return true;
74  }
75 private:
76  int m_num, m_end;
77 };
78 class Sink: public IdNode {
79 public:
80  Sink(int id) : IdNode("dst", id, 1, 0) {}
81  virtual ~Sink() {}
82  virtual bool operator()() {
83  if (iport().empty()) { return false; }
84  int d = boost::any_cast<int>(iport().get());
85  msg("sink: ") << d << std::endl;
86  return true;
87  }
88 };
89 class Njoin: public IdNode {
90 public:
91  Njoin(int id, int n) : IdNode("joi", id, n, 1) {}
92  virtual bool ready() {
93  auto& ip = input_ports();
94  for (size_t ind=0; ind<ip.size(); ++ind) {
95  auto& p = ip[ind];
96  if (p.empty()) {
97  //msg("port empty: ") << ind << std::endl;
98  return false;
99  }
100  }
101  return true;
102  }
103  virtual bool operator()() {
104  Pgraph::Queue outv;
105  auto& o = msg("join: ");
106  for (auto p : input_ports()) {
107  if (p.empty()) {
108  continue;
109  }
110  Pgraph::Data d = p.get();
111  int n = boost::any_cast<int>(d);
112  o << n << " ";
113  outv.push_back(d);
114  }
115  o << std::endl;
116 
117  if (outv.empty()) {
118  return false;
119  }
120 
121  Pgraph::Data out = outv;
122  oport().put(out);
123  return true;
124  }
125 };
126 class SplitQueueBuffer : public IdNode {
127 public:
128  SplitQueueBuffer(int id) : IdNode("sqb", id, 1, 1) {}
129  virtual bool read() {
130  if (!m_buf.empty()) {
131  return true;
132  }
133  return IdNode::ready();
134  }
135  virtual bool operator()() {
136  if (m_buf.empty()) {
137  if (iport().empty()) {
138  return false;
139  }
140  m_buf = boost::any_cast<Pgraph::Queue>(iport().get());
141  }
142  if (m_buf.empty()) {
143  return false;
144  }
145  auto d = m_buf.front();
146  m_buf.pop_front();
147  oport().put(d);
148  return true;
149  }
150 private:
152 };
153 
154 class Nfan : public IdNode {
155 public:
156  Nfan(int id, int n) : IdNode("fan", id, 1, n) {}
157  virtual bool operator()() {
158  if (iport().empty()) {
159  return false;
160  }
161  auto obj = iport().get();
162  int d = boost::any_cast<int>(obj);
163  msg("nfan: ") << d << std::endl;
164  for (auto p : output_ports()) {
165  p.put(obj);
166  }
167  return true;
168  }
169 };
170 class Func : public IdNode
171 {
172 public:
173  Func(int id) : IdNode("fun", id, 1, 1) {}
174  virtual bool operator()() {
175  if (iport().empty()) {
176  return false;
177  }
178  Pgraph::Data out = iport().get();
179  int d = boost::any_cast<int>(out);
180  msg("func: ") << d << std::endl;
181  oport().put(out);
182  return true;
183  }
184 };
185 
186 // also: N->M: hydra
187 
188 
189 int main() {
190  using Pgraph::Node;
191  using Pgraph::Graph;
192 
193  int count = 0;
194  auto src1 = new Source(count++, 0,4);
195  auto src2 = new Source(count++, 10,14);
196  auto dst1 = new Sink(count++);
197  auto dst2 = new Sink(count++);
198  auto fun1 = new Func(count++);
199  auto fun2 = new Func(count++);
200  auto fun3 = new Func(count++);
201  auto fan1 = new Nfan(count++, 2);
202  auto joi1 = new Njoin(count++, 2);
203  auto sqb1 = new SplitQueueBuffer(count++);
204 
205 
206  Graph g;
207  g.connect(src1,fun1);
208  g.connect(fun1,fan1);
209  g.connect(fan1,dst1);
210  g.connect(fan1,fun2,1);
211  g.connect(fun2,joi1);
212  g.connect(src2,fun3);
213  g.connect(fun3,joi1,0,1);
214  g.connect(joi1,sqb1);
215  g.connect(sqb1,dst2);
216 
217  auto sorted = g.sort_kahn();
218  cout << "Sorted to " << sorted.size() << " nodes\n";
219 
220  for (size_t ind=0; ind<sorted.size(); ++ind) {
221  IdNode* idn = dynamic_cast<IdNode*>(sorted[ind]);
222  idn->msg("at index ") << ind << endl;
223  }
224  cout << "Executing:\n";
225 
226  g.execute();
227 
228 }
static QCString name
Definition: declinfo.cpp:673
virtual bool operator()()
Func(int id)
virtual bool operator()()
void msg(const char *fmt,...)
Definition: message.cpp:107
QMapNodeBase Node
Definition: qmap.cpp:41
std::string string
Definition: nybbler.cc:12
Sink(int id)
std::deque< Data > Queue
Definition: Port.h:24
virtual ~Source()
STL namespace.
virtual std::string ident()
static const double g
Definition: Units.h:145
Nfan(int id, int n)
decltype(auto) constexpr end(T &&obj)
ADL-aware version of std::end.
Definition: StdUtils.h:72
virtual bool operator()()
virtual bool ready()
static int input(void)
Definition: code.cpp:15695
virtual ~Sink()
virtual bool read()
int main()
std::string m_name
Definition: Main.h:22
p
Definition: test.py:223
boost::any Data
Definition: Port.h:19
virtual bool operator()()
boost::adjacency_list< boost::vecS, boost::vecS, boost::bidirectionalS, VertexData, boost::property< boost::edge_weight_t, double, EdgeData > > Graph
define the boost-graph
virtual bool operator()()
Njoin(int id, int n)
Source(int id, int beg, int end)
virtual bool ready()
std::ostream & msg(const std::string s)
IdNode(const std::string &name, int id, size_t nin=0, size_t nout=0)
virtual bool operator()()
Pgraph::Queue m_buf
std::size_t n
Definition: format.h:3399
virtual bool ready()
static QCString * s
Definition: config.cpp:1042
decltype(auto) constexpr empty(T &&obj)
ADL-aware version of std::empty.
Definition: StdUtils.h:92
QTextStream & endl(QTextStream &s)