CGRA-ME
ConfigGraph.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 #ifndef CONFIG_GRAPH_H___
12 #define CONFIG_GRAPH_H___
13 
14 #include <CGRA/ConfigStore.h>
16 
17 #include <iomanip>
18 #include <iostream>
19 #include <map>
20 #include <string>
21 
26 inline auto printDotID(std::ostream& os, const std::string& id) -> std::ostream& {
27  // handle some edge cases, and keywords
28  if ( id.empty() || id == "."
29  || id == "node" || id == "edge" || id == "graph"
30  || id == "digraph" || id == "subgraph" || id == "strict") {
31  return os << '"' << id << '"';
32  }
33 
34  // just alphanum+underscore, not starting with digit
35  if (std::all_of(id.begin(), id.end(), [&](const auto& c){
36  return std::isalnum(c) || c == '_';
37  }) && not std::isdigit(*id.begin())) {
38  return os << id;
39  }
40 
41  // The general case. Escapes quotes.
42  os << '"';
43  for (std::ptrdiff_t i = 0; i != (std::ptrdiff_t)id.size(); ++i) {
44  if (id[i] == '"') os << '\\';
45  os << id[i];
46  }
47  return os << '"';
48 }
49 
50 /* A helper class for printing string-convertable objects as DOT IDs.
51  * see dotIDPrinter(T&) below */
52 template<typename T>
53 struct DotIDPrinter {
55  friend auto operator<<(std::ostream& os, const DotIDPrinter& rhs) -> std::ostream& {
56  return printDotID(os, *rhs.value_ptr);
57  }
58 };
59 
66 template<typename T>
67 auto dotIDPrinter(T& t) -> DotIDPrinter<T> { return {&t}; }
68 
72 class ConfigGraph {
73 public:
74  struct VertexID;
75  struct EdgeID;
76 
77  // used in constructor (hack for compilers/stdlibs with explicit tuple constructors)
78  struct NameNameConfigStore { std::string name1, name2; ConfigStore cs; };
79 
90  template<
91  typename VertexList = std::vector<std::pair<std::string,ConfigStore>>,
92  typename EdgeList = std::vector<NameNameConfigStore>
93  >
95  std::string graph_name_ = {}, ConfigStore graph_attributes_ = {},
96  VertexList vertices_ = {}, EdgeList edges_ = {}
97  )
98  : graph_name(std::move(graph_name_))
99  , graph_attributes(std::move(graph_attributes_))
100  {
101  for (const auto& v : vertices_) { insert(std::move(v.first), std::move(v.second)); }
102  for (const auto& e : edges_) { link(insert(std::move(e.name1)).first,
103  insert(std::move(e.name2)).first, std::move(e.cs)); }
104  }
105 
109  const ConfigStore& graphAttributes() const& { return graph_attributes; }
110  void setGraphAttributes(ConfigStore&& attrs) { graph_attributes = std::move(attrs); }
111  void setGraphAttributes(const ConfigStore& attrs) { graph_attributes = attrs; }
112 
116  const std::string& graphName() const& { return graph_name; }
117  void setGraphName(const std::string& s) { graph_name = s; }
118  void setGraphName(std::string&& s) { graph_name = std::move(s); }
119 
123  const std::string& name(const VertexID& v) const { return v.id; }
124 
128  const ConfigStore& attributes(const VertexID& v) const { return vertices.at(v); }
129  const ConfigStore& attributes(const EdgeID& e) const { return edges.at(e); }
130 
134  const VertexID& target(const EdgeID& e) const { return e.target; }
135  const VertexID& source(const EdgeID& e) const { return e.source; }
136  VertexID target(EdgeID&& e) const { return std::move(e.target); }
137  VertexID source(EdgeID&& e) const { return std::move(e.source); }
138 
142  auto allNodes() const { return make_first_of_pair_range(vertices); }
143 
148  auto outEdges(const VertexID& v) const {
150  }
151 
156  auto fanout(const VertexID& v) const {
157  std::vector<VertexID> result;
158  for (const auto& e : outEdges(v)) { result.push_back(e.target); }
159  return result;
160  }
161 
173  std::pair<VertexID,bool> insert(std::string name, ConfigStore vertex_attrs = {}) {
174  auto vid = VertexID{ name };
175  auto it_and_is_new = vertices.insert({vid, {}});
176  if (it_and_is_new.second) {
177  it_and_is_new.first->second = std::move(vertex_attrs);
178  } else {
179  set_all(it_and_is_new.first->second, std::move(vertex_attrs));
180  }
181  return {vid,true};
182  }
183 
191  decltype(EdgeID::id) edge_count = 0;
192  for (const auto& fo : fanout(source)) {
193  if (fo == target) { edge_count += 1; }
194  }
195  auto edge_id = EdgeID{ source, std::move(target), edge_count };
196  out_edges.emplace(std::move(source), edge_id);
197  edges.emplace(edge_id, std::move(edge_attrs));
198  return edge_id;
199  }
200 
205  std::ostream& printDot(std::ostream& os) const {
206  const auto print_attribute_list = [](auto& os, const auto& attrs) -> auto& {
207  if (attrs.empty()) { return os; }
208  os << " [";
209  bool first_iter = true;
210  for (const auto& kv : attrs) {
211  if (not first_iter) { os << ", "; }
212  printDotID(os,kv.first) << "="; printDotID(os,kv.second);
213  first_iter = false;
214  }
215  return os << "]";
216  };
217 
218  os << "digraph " << dotIDPrinter(graph_name) << " {\n";
219  if (not graph_attributes.empty()) {
220  os << " graph"; print_attribute_list(os,graph_attributes) << ";\n";
221  }
222 
223  for (const auto& v : allNodes()) {
224  os << " "; printDotID(os,name(v));
225  print_attribute_list(os,attributes(v)) << ";\n";
226  }
227 
228  for (const auto& v : allNodes()) {
229  for (const auto& e : outEdges(v)) {
230  os << " "; printDotID(os,name(source(e))) << " -> "; printDotID(os,name(target(e)));
231  print_attribute_list(os,attributes(e)) << ";\n";
232  }
233  }
234  return os << '}';
235  }
236 
237  friend std::ostream& operator<<(std::ostream& os, const ConfigGraph& cs) { return cs.printDot(os); }
238  friend bool operator==(const ConfigGraph& lhs, const ConfigGraph& rhs);
239 
240  bool empty() const { return vertices.empty(); }
241  std::ptrdiff_t numVertices() const { return vertices.size(); }
242  std::ptrdiff_t numEdges() const { return edges.size(); }
243 
247 
248  struct VertexID {
249  bool operator<(const VertexID& rhs) const {
250  return std::tie(this->id) < std::tie(rhs.id);
251  }
252  bool operator==(const VertexID& rhs) const {
253  return std::tie(this->id) == std::tie(rhs.id);
254  }
255  friend std::ostream& operator<<(std::ostream& os, const VertexID& v) {
256  return os << v.id;
257  }
258  private:
259  VertexID(std::string id_) : id(std::move(id_)) { }
260  friend ConfigGraph;
261  std::string id;
262  };
263 
264  struct EdgeID {
265  bool operator<(const EdgeID& rhs) const {
266  return std::tie(this->source, this->target, this->id)
267  < std::tie( rhs.source, rhs.target, rhs.id);
268  }
269  bool operator==(const EdgeID& rhs) const {
270  return std::tie(this->source, this->target, this->id)
271  == std::tie( rhs.source, rhs.target, rhs.id);
272  }
273  friend std::ostream& operator<<(std::ostream& os, const EdgeID& e) {
274  return os << e.source << "-" << e.id << "->" << e.target;
275  }
276  private:
278  : source(std::move(source)), target(std::move(target)), id(id)
279  { }
280  friend ConfigGraph;
282  };
283 
284 private:
285  std::string graph_name;
287 
288  std::map<VertexID,ConfigStore> vertices = {};
289  std::multimap<VertexID,EdgeID> out_edges = {};
290  std::map<EdgeID,ConfigStore> edges = {};
291 
292  friend bool operator==(const ConfigGraph& lhs, const ConfigGraph& rhs) {
293  return std::tie(lhs.graph_name, lhs.graph_attributes, lhs.vertices, lhs.out_edges, lhs.edges)
294  == std::tie(rhs.graph_name, rhs.graph_attributes, rhs.vertices, rhs.out_edges, rhs.edges);
295  }
296 };
297 
298 #endif /* CONFIG_GRAPH_H___ */
ConfigGraph::fanout
auto fanout(const VertexID &v) const
Definition: ConfigGraph.h:156
ConfigGraph::allNodes
auto allNodes() const
Definition: ConfigGraph.h:142
ConfigGraph::attributes
const ConfigStore & attributes(const VertexID &v) const
Definition: ConfigGraph.h:128
DotIDPrinter::operator<<
friend auto operator<<(std::ostream &os, const DotIDPrinter &rhs) -> std::ostream &
Definition: ConfigGraph.h:55
ConfigGraph::EdgeID::operator<<
friend std::ostream & operator<<(std::ostream &os, const EdgeID &e)
Definition: ConfigGraph.h:273
begin
auto begin(const SingleItemImmutableSet< VertexID > &siis)
Definition: Collections.h:137
printDotID
auto printDotID(std::ostream &os, const std::string &id) -> std::ostream &
Definition: ConfigGraph.h:26
ConfigGraph::ConfigGraph
ConfigGraph(std::string graph_name_={}, ConfigStore graph_attributes_={}, VertexList vertices_={}, EdgeList edges_={})
Definition: ConfigGraph.h:94
ConfigStore.h
make_second_of_pair_range
tuple_get_range< 1, Range > make_second_of_pair_range(Range &&r)
Definition: Collections.h:106
ConfigGraph::graph_name
std::string graph_name
Definition: ConfigGraph.h:285
ConfigGraph
Definition: ConfigGraph.h:72
ConfigStore
Definition: ConfigStore.h:76
make_first_of_pair_range
tuple_get_range< 0, Range > make_first_of_pair_range(Range &&r)
Definition: Collections.h:111
ConfigGraph::outEdges
auto outEdges(const VertexID &v) const
Definition: ConfigGraph.h:148
ConfigGraph::NameNameConfigStore
Definition: ConfigGraph.h:78
ConfigGraph::NameNameConfigStore::cs
ConfigStore cs
Definition: ConfigGraph.h:78
ConfigGraph::setGraphAttributes
void setGraphAttributes(const ConfigStore &attrs)
Definition: ConfigGraph.h:111
dotIDPrinter
auto dotIDPrinter(T &t) -> DotIDPrinter< T >
Definition: ConfigGraph.h:67
ConfigGraph::EdgeID::operator<
bool operator<(const EdgeID &rhs) const
Definition: ConfigGraph.h:265
ConfigGraph::graph_attributes
ConfigStore graph_attributes
Definition: ConfigGraph.h:286
ConfigGraph::name
const std::string & name(const VertexID &v) const
Definition: ConfigGraph.h:123
ConfigGraph::VertexID::VertexID
VertexID(std::string id_)
Definition: ConfigGraph.h:259
ConfigStore::empty
bool empty() const
Definition: ConfigStore.h:215
make_iterator_range
auto make_iterator_range(BIter &&b, EIter &&e)
Definition: Collections.h:48
EdgeList
std::multimap< MRRG::NodeDescriptor, MRRG::NodeDescriptor > EdgeList
Definition: PerfEngine.h:26
ConfigGraph::EdgeID::ConfigGraph
friend ConfigGraph
Definition: ConfigGraph.h:280
ConfigGraph::EdgeID::id
int id
Definition: ConfigGraph.h:281
ConfigGraph::graphAttributes
const ConfigStore & graphAttributes() const &
Definition: ConfigGraph.h:109
ConfigGraph::attributes
const ConfigStore & attributes(const EdgeID &e) const
Definition: ConfigGraph.h:129
ConfigGraph::setGraphAttributes
void setGraphAttributes(ConfigStore &&attrs)
Definition: ConfigGraph.h:110
ConfigGraph::insert
std::pair< VertexID, bool > insert(std::string name, ConfigStore vertex_attrs={})
Definition: ConfigGraph.h:173
ConfigGraph::EdgeID::target
VertexID target
Definition: ConfigGraph.h:281
ConfigGraph::link
EdgeID link(VertexID source, VertexID target, ConfigStore edge_attrs={})
Definition: ConfigGraph.h:190
ConfigGraph::EdgeID::source
VertexID source
Definition: ConfigGraph.h:281
ConfigGraph::vertices
std::map< VertexID, ConfigStore > vertices
Definition: ConfigGraph.h:288
DotIDPrinter
Definition: ConfigGraph.h:53
ConfigGraph::EdgeID::EdgeID
EdgeID(VertexID source, VertexID target, int id)
Definition: ConfigGraph.h:277
ConfigGraph::numVertices
std::ptrdiff_t numVertices() const
Definition: ConfigGraph.h:241
Collections.h
end
auto end(const SingleItemImmutableSet< VertexID > &siis)
Definition: Collections.h:138
ConfigGraph::source
const VertexID & source(const EdgeID &e) const
Definition: ConfigGraph.h:135
ConfigGraph::VertexID::ConfigGraph
friend ConfigGraph
Definition: ConfigGraph.h:260
set_all
ConfigStore & set_all(ConfigStore &into, const ConfigStore &from)
Definition: ConfigStore.h:252
ConfigGraph::NameNameConfigStore::name1
std::string name1
Definition: ConfigGraph.h:78
ConfigGraph::target
const VertexID & target(const EdgeID &e) const
Definition: ConfigGraph.h:134
ConfigGraph::VertexID::operator<<
friend std::ostream & operator<<(std::ostream &os, const VertexID &v)
Definition: ConfigGraph.h:255
ConfigGraph::empty
bool empty() const
Definition: ConfigGraph.h:240
ConfigGraph::graphName
const std::string & graphName() const &
Definition: ConfigGraph.h:116
ConfigGraph::EdgeID::operator==
bool operator==(const EdgeID &rhs) const
Definition: ConfigGraph.h:269
ConfigGraph::printDot
std::ostream & printDot(std::ostream &os) const
Definition: ConfigGraph.h:205
ConfigGraph::VertexID::operator<
bool operator<(const VertexID &rhs) const
Definition: ConfigGraph.h:249
ConfigGraph::VertexID
Definition: ConfigGraph.h:248
ConfigGraph::operator==
friend bool operator==(const ConfigGraph &lhs, const ConfigGraph &rhs)
ConfigGraph::edges
std::map< EdgeID, ConfigStore > edges
Definition: ConfigGraph.h:290
ConfigGraph::VertexID::operator==
bool operator==(const VertexID &rhs) const
Definition: ConfigGraph.h:252
ConfigGraph::out_edges
std::multimap< VertexID, EdgeID > out_edges
Definition: ConfigGraph.h:289
ConfigGraph::setGraphName
void setGraphName(std::string &&s)
Definition: ConfigGraph.h:118
ConfigGraph::numEdges
std::ptrdiff_t numEdges() const
Definition: ConfigGraph.h:242
ConfigGraph::VertexID::id
std::string id
Definition: ConfigGraph.h:261
ConfigGraph::NameNameConfigStore::name2
std::string name2
Definition: ConfigGraph.h:78
ConfigGraph::operator<<
friend std::ostream & operator<<(std::ostream &os, const ConfigGraph &cs)
Definition: ConfigGraph.h:237
ConfigGraph::target
VertexID target(EdgeID &&e) const
Definition: ConfigGraph.h:136
ConfigGraph::EdgeID
Definition: ConfigGraph.h:264
DotIDPrinter::value_ptr
T * value_ptr
Definition: ConfigGraph.h:54
ConfigGraph::setGraphName
void setGraphName(const std::string &s)
Definition: ConfigGraph.h:117
ConfigGraph::source
VertexID source(EdgeID &&e) const
Definition: ConfigGraph.h:137