CGRA-ME
GraphAlgorithmHelpers.h
Go to the documentation of this file.
1 /*******************************************************************************
2  * The software programs comprising "CGRA-ME" and the documentation provided
3  * with them are copyright by its authors and the University of Toronto. Only
4  * non-commercial, not-for-profit use of this software is permitted without ex-
5  * plicit permission. This software is provided "as is" with no warranties or
6  * guarantees of support. See the LICENCE for more details. You should have re-
7  * ceived a copy of the full licence along with this software. If not, see
8  * <http://cgra-me.ece.utoronto.ca/license/>.
9  ******************************************************************************/
10 
11 
12 #ifndef __IMPL_GRAPH_ALGORITHM_HELPERS_H__
13 #define __IMPL_GRAPH_ALGORITHM_HELPERS_H__
14 
16 
17 #include <set>
18 #include <map>
19 #include <iostream>
20 
21 template<typename VertexID>
22 auto findSingleVertex(VertexID v) {
23  return returnsIfEqualTo(std::move(v));
24 }
25 
26 template<typename VertexSet, typename VertexID>
27 auto findVertexInSet(const VertexSet& v_set, VertexID& vertex_found) {
28  return [&](const auto& v) {
29  if (v_set.find(v) != v_set.end()) {
30  vertex_found = v;
31  return true;
32  } else {
33  return false;
34  }
35  };
36 }
37 
38 inline auto visitAllVertices() { return AlwaysFalse{}; }
39 inline auto acceptAllPaths() { return AlwaysTrue{}; }
40 
48 template<typename VertexID>
50 public:
55  void onExamine(const VertexID&) { }
56 
60  void onExamineEdge(const VertexID&, const VertexID&) { }
61 
65  bool shouldIgnore(const VertexID&) { return false; }
66 
70  bool shouldIgnoreEdge(const VertexID&, const VertexID&) { return false; }
71 
78  void onSkipped(const VertexID&) { }
79 
88  void onSkippedEdge(const VertexID&, const VertexID&) { }
89 
93  void onWaveEnd() { }
94 
101  bool shouldStop() { return false; }
102 };
103 
109 template<typename Visitor>
111 public:
112  using VisitorPtr = std::remove_reference_t<Visitor>*;
114 
115  ForwardingVisitor(VisitorPtr visitor) : ref(visitor) { }
116 
117  ForwardingVisitor(const ForwardingVisitor&) = default;
118  ForwardingVisitor& operator=(const ForwardingVisitor&) = default;
121 
122  template<typename VertexID>
123  void onExamine(const VertexID& v) { ref->onExamine(v); }
124 
125  template<typename VertexID1, typename VertexID2>
126  void onExamineEdge(const VertexID1& v1, const VertexID2& v2) { ref->onExamineEdge(v1, v2); }
127 
128  template<typename VertexID>
129  bool shouldIgnore(const VertexID& v) { return ref->shouldIgnore(v); }
130 
131  template<typename VertexID1, typename VertexID2>
132  bool shouldIgnoreEdge(const VertexID1& v1, const VertexID2& v2) { return ref->shouldIgnoreEdge(v1, v2); }
133 
134  template<typename VertexID>
135  void onSkipped(const VertexID& v) { ref->onSkipped(v); }
136 
137  template<typename VertexID1, typename VertexID2>
138  void onSkippedEdge(const VertexID1& v1, const VertexID2& v2) { ref->onSkippedEdge(v1, v2); }
139 };
140 
141 template<
142  typename VertexID,
143  typename Base = DoNothingGraphVisitor<VertexID>,
144  typename NodeSet = std::set<VertexID>
145 >
146 struct IgnoreVertexSetVisitor : Base {
148 
149  template<typename ARG1 = NodeSet, typename... Args>
150  IgnoreVertexSetVisitor(ARG1&& arg1, Args&&... args)
151  : nodes_to_ignore(std::forward<ARG1>(arg1), std::forward<Args>(args)...)
152  { }
153 
154  bool shouldIgnore(const VertexID& v) {
155  return nodes_to_ignore.find(v) != end(nodes_to_ignore);
156  }
157 };
158 
159 template<
160  typename VertexID,
161  typename Base = DoNothingGraphVisitor<VertexID>,
162  typename EdgeSet = std::set<std::pair<VertexID, VertexID>>
163 >
164 struct IgnoreEdgeSetVisitor : Base {
166 
167  template<typename ARG1 = EdgeSet, typename... Args>
168  IgnoreEdgeSetVisitor(ARG1&& arg1, Args&&... args)
169  : edges_to_ignore(std::forward<ARG1>(arg1), std::forward<Args>(args)...)
170  { }
171 
172  bool shouldIgnoreEdge(const VertexID& v1, const VertexID& v2) {
173  return edges_to_ignore.find(std::make_pair(v1, v2)) != end(edges_to_ignore);
174  }
175 };
176 
180 template<typename VertexID, typename Base = DoNothingGraphVisitor<VertexID>, typename OStream = std::ostream>
181 struct DebugVisitor : Base {
182  OStream* debug_stream;
184 
185  void onExamine(const VertexID& v) {
186  Base::onExamine(v);
187  if (debug_stream) { *debug_stream << " explore: " << v << '\n'; }
188  }
189 
190  void onSkipped(const VertexID& v) {
191  Base::onSkipped(v);
192  if (debug_stream) { *debug_stream << " skipped: " << v << '\n'; }
193  }
194 
195  void onExamineEdge(const VertexID& source, const VertexID& target) {
196  Base::onExamineEdge(source, target);
197  if (debug_stream) { *debug_stream << " edge: " << source << " -> " << target << '\n'; }
198  }
199 
200  void onSkippedEdge(const VertexID& source, const VertexID& target) {
201  Base::onSkippedEdge(source, target);
202  if (debug_stream) { *debug_stream << " skipped edge: " << source << " -> " << target << '\n'; }
203  }
204 
205  void onWaveEnd() {
206  Base::onWaveEnd();
207  if (debug_stream) { *debug_stream << "--- wave ended ---\n"; }
208  }
209 };
210 
214 template<typename VertexID, typename Base = DoNothingGraphVisitor<VertexID>>
215 struct EventRecordingVisitor : Base {
216  struct Event {
217  enum Type {
223  };
225  VertexID v1, v2;
226 
227  friend std::ostream& operator<<(std::ostream& os, const Type& et) {
228  switch (et) {
229  case onExamine: return os << "onExamine";
230  case onSkipped: return os << "onSkipped";
231  case onExamineEdge: return os << "onExamineEdge";
232  case onSkippedEdge: return os << "onSkippedEdge";
233  case onWaveEnd: return os << "onWaveEnd";
234  default: return os << "Unimplemented Event::Type";
235  }
236  }
237 
238  friend std::ostream& operator<<(std::ostream& os, const Event& e) {
239  os << "{ " << e.type;
240  switch (e.type) {
241  case onExamine:
242  case onSkipped: return os << ": " << e.v1 << " }";
243  case onExamineEdge:
244  case onSkippedEdge: return os << ": " << e.v1 << " -> " << e.v2 << " }";
245  case onWaveEnd:
246  default: return os << " }";
247  }
248  }
249  };
250 
251  std::vector<Event> examine_order = {};
252 
253  EventRecordingVisitor() = default;
254  EventRecordingVisitor(Base b) : Base(std::move(b)) {}
255 
256  void onExamine(const VertexID& v) {
257  Base::onExamine(v);
258  examine_order.push_back({Event::onExamine, v, {}});
259  }
260 
261  void onSkipped(const VertexID& v) {
262  Base::onSkipped(v);
263  examine_order.push_back({Event::onSkipped, v, {}});
264  }
265 
266  void onExamineEdge(const VertexID& source, const VertexID& target) {
267  Base::onExamineEdge(source, target);
268  examine_order.push_back({Event::onExamineEdge, source, target});
269  }
270 
271  void onSkippedEdge(const VertexID& source, const VertexID& target) {
272  Base::onSkippedEdge(source, target);
273  examine_order.push_back({Event::onSkippedEdge, source, target});
274  }
275 
276  void onWaveEnd() {
277  Base::onWaveEnd();
278  examine_order.push_back({Event::onWaveEnd, {} , {}});
279  }
280 };
281 
287  using VertexID = std::string;
288  std::map<std::string, std::vector<VertexID>> fanout_lists = {};
289 
290  VertexID insert(std::string name) {
291  fanout_lists[name]; return name;
292  }
293 
294  VertexID insert(VertexID fanin, std::string name) {
295  auto vid = insert(name);
296  link(fanin, vid);
297  return vid;
298  }
299 
300  template<typename VertexIDList = std::initializer_list<VertexID>>
301  VertexID insertMultiFanin(const VertexIDList& fanins, std::string name) {
302  auto vid = insert(name);
303  for (const auto& fanin : fanins) {
304  link(fanin, vid);
305  }
306  return vid;
307  }
308 
309  void link(const VertexID& source, const VertexID& target) {
310  fanout_lists.at(source).push_back(target);
311  }
312 
313  auto& fanout(const VertexID& ndesc) const {
314  return fanout_lists.at(ndesc);
315  }
316 };
317 
326 template<typename VertexID, typename Data>
328  Data* data;
329 
330  using VertexList = std::decay_t<decltype(std::declval<Data>().at(std::declval<VertexID>()).fanin)>;
332 
337 
338  const auto& fanout(const VertexID& v) {
339  const auto search_result = data->find(v);
340  if (search_result == end(*data)) return empty_list;
341  else return search_result->second.fanin;
342  }
343 };
344 
345 template<typename VertexID, typename Data>
348 }
349 
350 #endif /* __IMPL_GRAPH_ALGORITHM_HELPERS_H__ */
DebugVisitor
Definition: GraphAlgorithmHelpers.h:181
DebugVisitor::onExamineEdge
void onExamineEdge(const VertexID &source, const VertexID &target)
Definition: GraphAlgorithmHelpers.h:195
StringIDGraph::fanout
auto & fanout(const VertexID &ndesc) const
Definition: GraphAlgorithmHelpers.h:313
EventRecordingVisitor::Event::onExamineEdge
@ onExamineEdge
Definition: GraphAlgorithmHelpers.h:220
ForwardingVisitor
Definition: GraphAlgorithmHelpers.h:110
EventRecordingVisitor::Event::operator<<
friend std::ostream & operator<<(std::ostream &os, const Event &e)
Definition: GraphAlgorithmHelpers.h:238
EventRecordingVisitor::Event::onSkipped
@ onSkipped
Definition: GraphAlgorithmHelpers.h:219
EventRecordingVisitor::Event::type
Type type
Definition: GraphAlgorithmHelpers.h:224
IgnoreVertexSetVisitor::shouldIgnore
bool shouldIgnore(const VertexID &v)
Definition: GraphAlgorithmHelpers.h:154
EventRecordingVisitor::Event::Type
Type
Definition: GraphAlgorithmHelpers.h:217
EventRecordingVisitor::Event::v1
VertexID v1
Definition: GraphAlgorithmHelpers.h:225
ForwardingVisitor::shouldIgnore
bool shouldIgnore(const VertexID &v)
Definition: GraphAlgorithmHelpers.h:129
StringIDGraph::link
void link(const VertexID &source, const VertexID &target)
Definition: GraphAlgorithmHelpers.h:309
AlwaysTrue
Definition: Functional.h:92
DebugVisitor::DebugVisitor
DebugVisitor(OStream *debug_stream=nullptr)
Definition: GraphAlgorithmHelpers.h:183
DoNothingGraphVisitor::onWaveEnd
void onWaveEnd()
Definition: GraphAlgorithmHelpers.h:93
ForwardingVisitor::shouldIgnoreEdge
bool shouldIgnoreEdge(const VertexID1 &v1, const VertexID2 &v2)
Definition: GraphAlgorithmHelpers.h:132
EventRecordingVisitor::Event::onWaveEnd
@ onWaveEnd
Definition: GraphAlgorithmHelpers.h:222
EventRecordingVisitor::Event::onSkippedEdge
@ onSkippedEdge
Definition: GraphAlgorithmHelpers.h:221
IgnoreVertexSetVisitor
Definition: GraphAlgorithmHelpers.h:146
returnsIfEqualTo
auto returnsIfEqualTo(T t)
Definition: Functional.h:108
DoNothingGraphVisitor::shouldIgnore
bool shouldIgnore(const VertexID &)
Definition: GraphAlgorithmHelpers.h:65
IgnoreVertexSetVisitor::IgnoreVertexSetVisitor
IgnoreVertexSetVisitor(ARG1 &&arg1, Args &&... args)
Definition: GraphAlgorithmHelpers.h:150
visitAllVertices
auto visitAllVertices()
Definition: GraphAlgorithmHelpers.h:38
DebugVisitor::debug_stream
OStream * debug_stream
Definition: GraphAlgorithmHelpers.h:182
ReversedGraphFromFaninLists::empty_list
VertexList empty_list
Definition: GraphAlgorithmHelpers.h:331
IgnoreEdgeSetVisitor::shouldIgnoreEdge
bool shouldIgnoreEdge(const VertexID &v1, const VertexID &v2)
Definition: GraphAlgorithmHelpers.h:172
ForwardingVisitor::VisitorPtr
std::remove_reference_t< Visitor > * VisitorPtr
Definition: GraphAlgorithmHelpers.h:112
IgnoreVertexSetVisitor::nodes_to_ignore
NodeSet nodes_to_ignore
Definition: GraphAlgorithmHelpers.h:147
EventRecordingVisitor::Event::onExamine
@ onExamine
Definition: GraphAlgorithmHelpers.h:218
DoNothingGraphVisitor::onExamine
void onExamine(const VertexID &)
Definition: GraphAlgorithmHelpers.h:55
StringIDGraph::insertMultiFanin
VertexID insertMultiFanin(const VertexIDList &fanins, std::string name)
Definition: GraphAlgorithmHelpers.h:301
DoNothingGraphVisitor::onExamineEdge
void onExamineEdge(const VertexID &, const VertexID &)
Definition: GraphAlgorithmHelpers.h:60
findSingleVertex
auto findSingleVertex(VertexID v)
Definition: GraphAlgorithmHelpers.h:22
StringIDGraph::insert
VertexID insert(VertexID fanin, std::string name)
Definition: GraphAlgorithmHelpers.h:294
EventRecordingVisitor::Event::operator<<
friend std::ostream & operator<<(std::ostream &os, const Type &et)
Definition: GraphAlgorithmHelpers.h:227
acceptAllPaths
auto acceptAllPaths()
Definition: GraphAlgorithmHelpers.h:39
DoNothingGraphVisitor::shouldIgnoreEdge
bool shouldIgnoreEdge(const VertexID &, const VertexID &)
Definition: GraphAlgorithmHelpers.h:70
DebugVisitor::onExamine
void onExamine(const VertexID &v)
Definition: GraphAlgorithmHelpers.h:185
ForwardingVisitor::onExamine
void onExamine(const VertexID &v)
Definition: GraphAlgorithmHelpers.h:123
EventRecordingVisitor::EventRecordingVisitor
EventRecordingVisitor(Base b)
Definition: GraphAlgorithmHelpers.h:254
IgnoreEdgeSetVisitor::edges_to_ignore
EdgeSet edges_to_ignore
Definition: GraphAlgorithmHelpers.h:165
Functional.h
EventRecordingVisitor::EventRecordingVisitor
EventRecordingVisitor()=default
DebugVisitor::onSkipped
void onSkipped(const VertexID &v)
Definition: GraphAlgorithmHelpers.h:190
DoNothingGraphVisitor::onSkippedEdge
void onSkippedEdge(const VertexID &, const VertexID &)
Definition: GraphAlgorithmHelpers.h:88
ReversedGraphFromFaninLists::operator=
ReversedGraphFromFaninLists & operator=(const ReversedGraphFromFaninLists &)=default
StringIDGraph::VertexID
std::string VertexID
Definition: GraphAlgorithmHelpers.h:287
ReversedGraphFromFaninLists
Definition: GraphAlgorithmHelpers.h:327
EventRecordingVisitor::onWaveEnd
void onWaveEnd()
Definition: GraphAlgorithmHelpers.h:276
EventRecordingVisitor::onSkipped
void onSkipped(const VertexID &v)
Definition: GraphAlgorithmHelpers.h:261
StringIDGraph::insert
VertexID insert(std::string name)
Definition: GraphAlgorithmHelpers.h:290
EventRecordingVisitor::examine_order
std::vector< Event > examine_order
Definition: GraphAlgorithmHelpers.h:251
EventRecordingVisitor::onExamineEdge
void onExamineEdge(const VertexID &source, const VertexID &target)
Definition: GraphAlgorithmHelpers.h:266
EventRecordingVisitor::onSkippedEdge
void onSkippedEdge(const VertexID &source, const VertexID &target)
Definition: GraphAlgorithmHelpers.h:271
ReversedGraphFromFaninLists::data
Data * data
Definition: GraphAlgorithmHelpers.h:328
ForwardingVisitor::onSkippedEdge
void onSkippedEdge(const VertexID1 &v1, const VertexID2 &v2)
Definition: GraphAlgorithmHelpers.h:138
DebugVisitor::onSkippedEdge
void onSkippedEdge(const VertexID &source, const VertexID &target)
Definition: GraphAlgorithmHelpers.h:200
DoNothingGraphVisitor
Definition: GraphAlgorithmHelpers.h:49
end
auto end(const SingleItemImmutableSet< VertexID > &siis)
Definition: Collections.h:138
IgnoreEdgeSetVisitor
Definition: GraphAlgorithmHelpers.h:164
ReversedGraphFromFaninLists::ReversedGraphFromFaninLists
ReversedGraphFromFaninLists(const ReversedGraphFromFaninLists &)=default
ReversedGraphFromFaninLists::VertexList
std::decay_t< decltype(std::declval< Data >().at(std::declval< VertexID >()).fanin)> VertexList
Definition: GraphAlgorithmHelpers.h:330
StringIDGraph
Definition: GraphAlgorithmHelpers.h:286
DoNothingGraphVisitor::shouldStop
bool shouldStop()
Definition: GraphAlgorithmHelpers.h:101
ForwardingVisitor::ref
VisitorPtr ref
Definition: GraphAlgorithmHelpers.h:113
EventRecordingVisitor
Definition: GraphAlgorithmHelpers.h:215
StringIDGraph::fanout_lists
std::map< std::string, std::vector< VertexID > > fanout_lists
Definition: GraphAlgorithmHelpers.h:288
findVertexInSet
auto findVertexInSet(const VertexSet &v_set, VertexID &vertex_found)
Definition: GraphAlgorithmHelpers.h:27
DoNothingGraphVisitor::onSkipped
void onSkipped(const VertexID &)
Definition: GraphAlgorithmHelpers.h:78
DebugVisitor::onWaveEnd
void onWaveEnd()
Definition: GraphAlgorithmHelpers.h:205
IgnoreEdgeSetVisitor::IgnoreEdgeSetVisitor
IgnoreEdgeSetVisitor(ARG1 &&arg1, Args &&... args)
Definition: GraphAlgorithmHelpers.h:168
EventRecordingVisitor::Event
Definition: GraphAlgorithmHelpers.h:216
makeReversedGraphFromFaninLists
auto makeReversedGraphFromFaninLists(Data *data)
Definition: GraphAlgorithmHelpers.h:346
AlwaysFalse
Definition: Functional.h:87
ForwardingVisitor::operator=
ForwardingVisitor & operator=(const ForwardingVisitor &)=default
EventRecordingVisitor::Event::v2
VertexID v2
Definition: GraphAlgorithmHelpers.h:225
ForwardingVisitor::onSkipped
void onSkipped(const VertexID &v)
Definition: GraphAlgorithmHelpers.h:135
ReversedGraphFromFaninLists::fanout
const auto & fanout(const VertexID &v)
Definition: GraphAlgorithmHelpers.h:338
EventRecordingVisitor::onExamine
void onExamine(const VertexID &v)
Definition: GraphAlgorithmHelpers.h:256
ForwardingVisitor::ForwardingVisitor
ForwardingVisitor(VisitorPtr visitor)
Definition: GraphAlgorithmHelpers.h:115
ForwardingVisitor::onExamineEdge
void onExamineEdge(const VertexID1 &v1, const VertexID2 &v2)
Definition: GraphAlgorithmHelpers.h:126