LLVM API Documentation

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Graph.h
Go to the documentation of this file.
1 //===-------------------- Graph.h - PBQP Graph ------------------*- C++ -*-===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // PBQP Graph class.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 
15 #ifndef LLVM_CODEGEN_PBQP_GRAPH_H
16 #define LLVM_CODEGEN_PBQP_GRAPH_H
17 
18 #include "Math.h"
19 #include "llvm/ADT/ilist.h"
20 #include "llvm/ADT/ilist_node.h"
21 #include <list>
22 #include <map>
23 #include <set>
24 
25 namespace PBQP {
26 
27  /// PBQP Graph class.
28  /// Instances of this class describe PBQP problems.
29  class Graph {
30  public:
31 
32  typedef unsigned NodeId;
33  typedef unsigned EdgeId;
34 
35  private:
36 
37  typedef std::set<NodeId> AdjEdgeList;
38 
39  public:
40 
41  typedef AdjEdgeList::iterator AdjEdgeItr;
42 
43  private:
44 
45  class NodeEntry {
46  private:
47  Vector costs;
48  AdjEdgeList adjEdges;
49  void *data;
50  NodeEntry() : costs(0, 0) {}
51  public:
52  NodeEntry(const Vector &costs) : costs(costs), data(0) {}
53  Vector& getCosts() { return costs; }
54  const Vector& getCosts() const { return costs; }
55  unsigned getDegree() const { return adjEdges.size(); }
56  AdjEdgeItr edgesBegin() { return adjEdges.begin(); }
57  AdjEdgeItr edgesEnd() { return adjEdges.end(); }
59  return adjEdges.insert(adjEdges.end(), e);
60  }
61  void removeEdge(AdjEdgeItr ae) {
62  adjEdges.erase(ae);
63  }
64  void setData(void *data) { this->data = data; }
65  void* getData() { return data; }
66  };
67 
68  class EdgeEntry {
69  private:
70  NodeId node1, node2;
71  Matrix costs;
72  AdjEdgeItr node1AEItr, node2AEItr;
73  void *data;
74  EdgeEntry() : costs(0, 0, 0), data(0) {}
75  public:
76  EdgeEntry(NodeId node1, NodeId node2, const Matrix &costs)
77  : node1(node1), node2(node2), costs(costs) {}
78  NodeId getNode1() const { return node1; }
79  NodeId getNode2() const { return node2; }
80  Matrix& getCosts() { return costs; }
81  const Matrix& getCosts() const { return costs; }
82  void setNode1AEItr(AdjEdgeItr ae) { node1AEItr = ae; }
83  AdjEdgeItr getNode1AEItr() { return node1AEItr; }
84  void setNode2AEItr(AdjEdgeItr ae) { node2AEItr = ae; }
85  AdjEdgeItr getNode2AEItr() { return node2AEItr; }
86  void setData(void *data) { this->data = data; }
87  void *getData() { return data; }
88  };
89 
90  // ----- MEMBERS -----
91 
92  typedef std::vector<NodeEntry> NodeVector;
93  typedef std::vector<NodeId> FreeNodeVector;
94  NodeVector nodes;
95  FreeNodeVector freeNodes;
96 
97  typedef std::vector<EdgeEntry> EdgeVector;
98  typedef std::vector<EdgeId> FreeEdgeVector;
99  EdgeVector edges;
100  FreeEdgeVector freeEdges;
101 
102  // ----- INTERNAL METHODS -----
103 
104  NodeEntry& getNode(NodeId nId) { return nodes[nId]; }
105  const NodeEntry& getNode(NodeId nId) const { return nodes[nId]; }
106 
107  EdgeEntry& getEdge(EdgeId eId) { return edges[eId]; }
108  const EdgeEntry& getEdge(EdgeId eId) const { return edges[eId]; }
109 
110  NodeId addConstructedNode(const NodeEntry &n) {
111  NodeId nodeId = 0;
112  if (!freeNodes.empty()) {
113  nodeId = freeNodes.back();
114  freeNodes.pop_back();
115  nodes[nodeId] = n;
116  } else {
117  nodeId = nodes.size();
118  nodes.push_back(n);
119  }
120  return nodeId;
121  }
122 
123  EdgeId addConstructedEdge(const EdgeEntry &e) {
124  assert(findEdge(e.getNode1(), e.getNode2()) == invalidEdgeId() &&
125  "Attempt to add duplicate edge.");
126  EdgeId edgeId = 0;
127  if (!freeEdges.empty()) {
128  edgeId = freeEdges.back();
129  freeEdges.pop_back();
130  edges[edgeId] = e;
131  } else {
132  edgeId = edges.size();
133  edges.push_back(e);
134  }
135 
136  EdgeEntry &ne = getEdge(edgeId);
137  NodeEntry &n1 = getNode(ne.getNode1());
138  NodeEntry &n2 = getNode(ne.getNode2());
139 
140  // Sanity check on matrix dimensions:
141  assert((n1.getCosts().getLength() == ne.getCosts().getRows()) &&
142  (n2.getCosts().getLength() == ne.getCosts().getCols()) &&
143  "Edge cost dimensions do not match node costs dimensions.");
144 
145  ne.setNode1AEItr(n1.addEdge(edgeId));
146  ne.setNode2AEItr(n2.addEdge(edgeId));
147  return edgeId;
148  }
149 
150  Graph(const Graph &other) {}
151  void operator=(const Graph &other) {}
152 
153  public:
154 
155  class NodeItr {
156  public:
157  NodeItr(NodeId nodeId, const Graph &g)
158  : nodeId(nodeId), endNodeId(g.nodes.size()), freeNodes(g.freeNodes) {
159  this->nodeId = findNextInUse(nodeId); // Move to the first in-use nodeId
160  }
161 
162  bool operator==(const NodeItr& n) const { return nodeId == n.nodeId; }
163  bool operator!=(const NodeItr& n) const { return !(*this == n); }
164  NodeItr& operator++() { nodeId = findNextInUse(++nodeId); return *this; }
165  NodeId operator*() const { return nodeId; }
166 
167  private:
168  NodeId findNextInUse(NodeId n) const {
169  while (n < endNodeId &&
170  std::find(freeNodes.begin(), freeNodes.end(), n) !=
171  freeNodes.end()) {
172  ++n;
173  }
174  return n;
175  }
176 
177  NodeId nodeId, endNodeId;
178  const FreeNodeVector& freeNodes;
179  };
180 
181  class EdgeItr {
182  public:
183  EdgeItr(EdgeId edgeId, const Graph &g)
184  : edgeId(edgeId), endEdgeId(g.edges.size()), freeEdges(g.freeEdges) {
185  this->edgeId = findNextInUse(edgeId); // Move to the first in-use edgeId
186  }
187 
188  bool operator==(const EdgeItr& n) const { return edgeId == n.edgeId; }
189  bool operator!=(const EdgeItr& n) const { return !(*this == n); }
190  EdgeItr& operator++() { edgeId = findNextInUse(++edgeId); return *this; }
191  EdgeId operator*() const { return edgeId; }
192 
193  private:
194  EdgeId findNextInUse(EdgeId n) const {
195  while (n < endEdgeId &&
196  std::find(freeEdges.begin(), freeEdges.end(), n) !=
197  freeEdges.end()) {
198  ++n;
199  }
200  return n;
201  }
202 
203  EdgeId edgeId, endEdgeId;
204  const FreeEdgeVector& freeEdges;
205  };
206 
207  /// \brief Construct an empty PBQP graph.
208  Graph() {}
209 
210  /// \brief Add a node with the given costs.
211  /// @param costs Cost vector for the new node.
212  /// @return Node iterator for the added node.
213  NodeId addNode(const Vector &costs) {
214  return addConstructedNode(NodeEntry(costs));
215  }
216 
217  /// \brief Add an edge between the given nodes with the given costs.
218  /// @param n1Id First node.
219  /// @param n2Id Second node.
220  /// @return Edge iterator for the added edge.
221  EdgeId addEdge(NodeId n1Id, NodeId n2Id, const Matrix &costs) {
222  assert(getNodeCosts(n1Id).getLength() == costs.getRows() &&
223  getNodeCosts(n2Id).getLength() == costs.getCols() &&
224  "Matrix dimensions mismatch.");
225  return addConstructedEdge(EdgeEntry(n1Id, n2Id, costs));
226  }
227 
228  /// \brief Get the number of nodes in the graph.
229  /// @return Number of nodes in the graph.
230  unsigned getNumNodes() const { return nodes.size() - freeNodes.size(); }
231 
232  /// \brief Get the number of edges in the graph.
233  /// @return Number of edges in the graph.
234  unsigned getNumEdges() const { return edges.size() - freeEdges.size(); }
235 
236  /// \brief Get a node's cost vector.
237  /// @param nId Node id.
238  /// @return Node cost vector.
239  Vector& getNodeCosts(NodeId nId) { return getNode(nId).getCosts(); }
240 
241  /// \brief Get a node's cost vector (const version).
242  /// @param nId Node id.
243  /// @return Node cost vector.
244  const Vector& getNodeCosts(NodeId nId) const {
245  return getNode(nId).getCosts();
246  }
247 
248  /// \brief Set a node's data pointer.
249  /// @param nId Node id.
250  /// @param data Pointer to node data.
251  ///
252  /// Typically used by a PBQP solver to attach data to aid in solution.
253  void setNodeData(NodeId nId, void *data) { getNode(nId).setData(data); }
254 
255  /// \brief Get the node's data pointer.
256  /// @param nId Node id.
257  /// @return Pointer to node data.
258  void* getNodeData(NodeId nId) { return getNode(nId).getData(); }
259 
260  /// \brief Get an edge's cost matrix.
261  /// @param eId Edge id.
262  /// @return Edge cost matrix.
263  Matrix& getEdgeCosts(EdgeId eId) { return getEdge(eId).getCosts(); }
264 
265  /// \brief Get an edge's cost matrix (const version).
266  /// @param eId Edge id.
267  /// @return Edge cost matrix.
268  const Matrix& getEdgeCosts(EdgeId eId) const {
269  return getEdge(eId).getCosts();
270  }
271 
272  /// \brief Set an edge's data pointer.
273  /// @param eId Edge id.
274  /// @param data Pointer to edge data.
275  ///
276  /// Typically used by a PBQP solver to attach data to aid in solution.
277  void setEdgeData(EdgeId eId, void *data) { getEdge(eId).setData(data); }
278 
279  /// \brief Get an edge's data pointer.
280  /// @param eId Edge id.
281  /// @return Pointer to edge data.
282  void* getEdgeData(EdgeId eId) { return getEdge(eId).getData(); }
283 
284  /// \brief Get a node's degree.
285  /// @param nId Node id.
286  /// @return The degree of the node.
287  unsigned getNodeDegree(NodeId nId) const {
288  return getNode(nId).getDegree();
289  }
290 
291  /// \brief Begin iterator for node set.
292  NodeItr nodesBegin() const { return NodeItr(0, *this); }
293 
294  /// \brief End iterator for node set.
295  NodeItr nodesEnd() const { return NodeItr(nodes.size(), *this); }
296 
297  /// \brief Begin iterator for edge set.
298  EdgeItr edgesBegin() const { return EdgeItr(0, *this); }
299 
300  /// \brief End iterator for edge set.
301  EdgeItr edgesEnd() const { return EdgeItr(edges.size(), *this); }
302 
303  /// \brief Get begin iterator for adjacent edge set.
304  /// @param nId Node id.
305  /// @return Begin iterator for the set of edges connected to the given node.
307  return getNode(nId).edgesBegin();
308  }
309 
310  /// \brief Get end iterator for adjacent edge set.
311  /// @param nId Node id.
312  /// @return End iterator for the set of edges connected to the given node.
314  return getNode(nId).edgesEnd();
315  }
316 
317  /// \brief Get the first node connected to this edge.
318  /// @param eId Edge id.
319  /// @return The first node connected to the given edge.
321  return getEdge(eId).getNode1();
322  }
323 
324  /// \brief Get the second node connected to this edge.
325  /// @param eId Edge id.
326  /// @return The second node connected to the given edge.
328  return getEdge(eId).getNode2();
329  }
330 
331  /// \brief Get the "other" node connected to this edge.
332  /// @param eId Edge id.
333  /// @param nId Node id for the "given" node.
334  /// @return The iterator for the "other" node connected to this edge.
336  EdgeEntry &e = getEdge(eId);
337  if (e.getNode1() == nId) {
338  return e.getNode2();
339  } // else
340  return e.getNode1();
341  }
342 
344  return std::numeric_limits<EdgeId>::max();
345  }
346 
347  /// \brief Get the edge connecting two nodes.
348  /// @param n1Id First node id.
349  /// @param n2Id Second node id.
350  /// @return An id for edge (n1Id, n2Id) if such an edge exists,
351  /// otherwise returns an invalid edge id.
352  EdgeId findEdge(NodeId n1Id, NodeId n2Id) {
353  for (AdjEdgeItr aeItr = adjEdgesBegin(n1Id), aeEnd = adjEdgesEnd(n1Id);
354  aeItr != aeEnd; ++aeItr) {
355  if ((getEdgeNode1(*aeItr) == n2Id) ||
356  (getEdgeNode2(*aeItr) == n2Id)) {
357  return *aeItr;
358  }
359  }
360  return invalidEdgeId();
361  }
362 
363  /// \brief Remove a node from the graph.
364  /// @param nId Node id.
365  void removeNode(NodeId nId) {
366  NodeEntry &n = getNode(nId);
367  for (AdjEdgeItr itr = n.edgesBegin(), end = n.edgesEnd(); itr != end; ++itr) {
368  EdgeId eId = *itr;
369  removeEdge(eId);
370  }
371  freeNodes.push_back(nId);
372  }
373 
374  /// \brief Remove an edge from the graph.
375  /// @param eId Edge id.
376  void removeEdge(EdgeId eId) {
377  EdgeEntry &e = getEdge(eId);
378  NodeEntry &n1 = getNode(e.getNode1());
379  NodeEntry &n2 = getNode(e.getNode2());
380  n1.removeEdge(e.getNode1AEItr());
381  n2.removeEdge(e.getNode2AEItr());
382  freeEdges.push_back(eId);
383  }
384 
385  /// \brief Remove all nodes and edges from the graph.
386  void clear() {
387  nodes.clear();
388  freeNodes.clear();
389  edges.clear();
390  freeEdges.clear();
391  }
392 
393  /// \brief Dump a graph to an output stream.
394  template <typename OStream>
395  void dump(OStream &os) {
396  os << getNumNodes() << " " << getNumEdges() << "\n";
397 
398  for (NodeItr nodeItr = nodesBegin(), nodeEnd = nodesEnd();
399  nodeItr != nodeEnd; ++nodeItr) {
400  const Vector& v = getNodeCosts(*nodeItr);
401  os << "\n" << v.getLength() << "\n";
402  assert(v.getLength() != 0 && "Empty vector in graph.");
403  os << v[0];
404  for (unsigned i = 1; i < v.getLength(); ++i) {
405  os << " " << v[i];
406  }
407  os << "\n";
408  }
409 
410  for (EdgeItr edgeItr = edgesBegin(), edgeEnd = edgesEnd();
411  edgeItr != edgeEnd; ++edgeItr) {
412  NodeId n1 = getEdgeNode1(*edgeItr);
413  NodeId n2 = getEdgeNode2(*edgeItr);
414  assert(n1 != n2 && "PBQP graphs shound not have self-edges.");
415  const Matrix& m = getEdgeCosts(*edgeItr);
416  os << "\n" << n1 << " " << n2 << "\n"
417  << m.getRows() << " " << m.getCols() << "\n";
418  assert(m.getRows() != 0 && "No rows in matrix.");
419  assert(m.getCols() != 0 && "No cols in matrix.");
420  for (unsigned i = 0; i < m.getRows(); ++i) {
421  os << m[i][0];
422  for (unsigned j = 1; j < m.getCols(); ++j) {
423  os << " " << m[i][j];
424  }
425  os << "\n";
426  }
427  }
428  }
429 
430  /// \brief Print a representation of this graph in DOT format.
431  /// @param os Output stream to print on.
432  template <typename OStream>
433  void printDot(OStream &os) {
434 
435  os << "graph {\n";
436 
437  for (NodeItr nodeItr = nodesBegin(), nodeEnd = nodesEnd();
438  nodeItr != nodeEnd; ++nodeItr) {
439 
440  os << " node" << nodeItr << " [ label=\""
441  << nodeItr << ": " << getNodeCosts(*nodeItr) << "\" ]\n";
442  }
443 
444  os << " edge [ len=" << getNumNodes() << " ]\n";
445 
446  for (EdgeItr edgeItr = edgesBegin(), edgeEnd = edgesEnd();
447  edgeItr != edgeEnd; ++edgeItr) {
448 
449  os << " node" << getEdgeNode1(*edgeItr)
450  << " -- node" << getEdgeNode2(*edgeItr)
451  << " [ label=\"";
452 
453  const Matrix &edgeCosts = getEdgeCosts(*edgeItr);
454 
455  for (unsigned i = 0; i < edgeCosts.getRows(); ++i) {
456  os << edgeCosts.getRowAsVector(i) << "\\n";
457  }
458  os << "\" ]\n";
459  }
460  os << "}\n";
461  }
462 
463  };
464 
465 // void Graph::copyFrom(const Graph &other) {
466 // std::map<Graph::ConstNodeItr, Graph::NodeItr,
467 // NodeItrComparator> nodeMap;
468 
469 // for (Graph::ConstNodeItr nItr = other.nodesBegin(),
470 // nEnd = other.nodesEnd();
471 // nItr != nEnd; ++nItr) {
472 // nodeMap[nItr] = addNode(other.getNodeCosts(nItr));
473 // }
474 // }
475 
476 }
477 
478 #endif // LLVM_CODEGEN_PBQP_GRAPH_HPP
const_iterator end(StringRef path)
Get end iterator over path.
Definition: Path.cpp:181
EdgeId invalidEdgeId() const
Definition: Graph.h:343
const Matrix & getEdgeCosts(EdgeId eId) const
Get an edge's cost matrix (const version).
Definition: Graph.h:268
Vector & getNodeCosts(NodeId nId)
Get a node's cost vector.
Definition: Graph.h:239
NodeItr nodesEnd() const
End iterator for node set.
Definition: Graph.h:295
NodeId getEdgeNode1(EdgeId eId)
Get the first node connected to this edge.
Definition: Graph.h:320
unsigned EdgeId
Definition: Graph.h:33
bool operator!=(const NodeItr &n) const
Definition: Graph.h:163
AdjEdgeList::iterator AdjEdgeItr
Definition: Graph.h:41
unsigned getLength() const
Return the length of the vector.
Definition: Math.h:55
bool operator==(const EdgeItr &n) const
Definition: Graph.h:188
unsigned getNodeDegree(NodeId nId) const
Get a node's degree.
Definition: Graph.h:287
EdgeItr edgesBegin() const
Begin iterator for edge set.
Definition: Graph.h:298
Live Register Matrix
NodeId addNode(const Vector &costs)
Add a node with the given costs.
Definition: Graph.h:213
AdjEdgeItr adjEdgesEnd(NodeId nId)
Get end iterator for adjacent edge set.
Definition: Graph.h:313
void removeEdge(EdgeId eId)
Remove an edge from the graph.
Definition: Graph.h:376
Graph()
Construct an empty PBQP graph.
Definition: Graph.h:208
unsigned getRows() const
Return the number of rows in this matrix.
Definition: Math.h:146
void removeNode(NodeId nId)
Remove a node from the graph.
Definition: Graph.h:365
EdgeId findEdge(NodeId n1Id, NodeId n2Id)
Get the edge connecting two nodes.
Definition: Graph.h:352
NodeItr(NodeId nodeId, const Graph &g)
Definition: Graph.h:157
const Vector & getNodeCosts(NodeId nId) const
Get a node's cost vector (const version).
Definition: Graph.h:244
NodeItr & operator++()
Definition: Graph.h:164
NodeId operator*() const
Definition: Graph.h:165
NodeId getEdgeNode2(EdgeId eId)
Get the second node connected to this edge.
Definition: Graph.h:327
void setNodeData(NodeId nId, void *data)
Set a node's data pointer.
Definition: Graph.h:253
void clear()
Remove all nodes and edges from the graph.
Definition: Graph.h:386
void printDot(OStream &os)
Print a representation of this graph in DOT format.
Definition: Graph.h:433
EdgeItr(EdgeId edgeId, const Graph &g)
Definition: Graph.h:183
unsigned getNumNodes() const
Get the number of nodes in the graph.
Definition: Graph.h:230
Vector getRowAsVector(unsigned r) const
Returns the given row as a vector.
Definition: Math.h:164
NodeId getEdgeOtherNode(EdgeId eId, NodeId nId)
Get the "other" node connected to this edge.
Definition: Graph.h:335
AdjEdgeItr adjEdgesBegin(NodeId nId)
Get begin iterator for adjacent edge set.
Definition: Graph.h:306
Matrix & getEdgeCosts(EdgeId eId)
Get an edge's cost matrix.
Definition: Graph.h:263
EdgeItr edgesEnd() const
End iterator for edge set.
Definition: Graph.h:301
bool operator==(const NodeItr &n) const
Definition: Graph.h:162
void dump(OStream &os)
Dump a graph to an output stream.
Definition: Graph.h:395
bool operator!=(const EdgeItr &n) const
Definition: Graph.h:189
void * getEdgeData(EdgeId eId)
Get an edge's data pointer.
Definition: Graph.h:282
unsigned getNumEdges() const
Get the number of edges in the graph.
Definition: Graph.h:234
EdgeItr & operator++()
Definition: Graph.h:190
EdgeId addEdge(NodeId n1Id, NodeId n2Id, const Matrix &costs)
Add an edge between the given nodes with the given costs.
Definition: Graph.h:221
unsigned NodeId
Definition: Graph.h:32
void setEdgeData(EdgeId eId, void *data)
Set an edge's data pointer.
Definition: Graph.h:277
NodeItr nodesBegin() const
Begin iterator for node set.
Definition: Graph.h:292
PBQP Vector class.
Definition: Math.h:22
unsigned getCols() const
Return the number of cols in this matrix.
Definition: Math.h:149
void * getNodeData(NodeId nId)
Get the node's data pointer.
Definition: Graph.h:258
PBQP Matrix class.
Definition: Math.h:112
EdgeId operator*() const
Definition: Graph.h:191