16 #ifndef LLVM_CODEGEN_PBQP_HEURISTICSOLVER_H
17 #define LLVM_CODEGEN_PBQP_HEURISTICSOLVER_H
36 template <
typename HImpl>
40 typedef typename HImpl::NodeData HeuristicNodeData;
41 typedef typename HImpl::EdgeData HeuristicEdgeData;
43 typedef std::list<Graph::EdgeId> SolverEdges;
54 NodeData() : solverDegree(0) {}
60 return solverEdges.insert(solverEdges.end(), eId);
65 solverEdges.erase(seItr);
71 void clearSolverEdges() {
78 unsigned solverDegree;
79 SolverEdges solverEdges;
84 HeuristicEdgeData& getHeuristicData() {
return hData; }
87 this->n1SolverEdgeItr = n1SolverEdgeItr;
90 SolverEdgeItr getN1SolverEdgeItr() {
return n1SolverEdgeItr; }
93 this->n2SolverEdgeItr = n2SolverEdgeItr;
96 SolverEdgeItr getN2SolverEdgeItr() {
return n2SolverEdgeItr; }
100 HeuristicEdgeData hData;
107 std::vector<Graph::NodeId> stack;
109 typedef std::list<NodeData> NodeDataList;
110 NodeDataList nodeDataList;
112 typedef std::list<EdgeData> EdgeDataList;
113 EdgeDataList edgeDataList;
131 return getSolverNodeData(nId).getHeuristicData();
138 return getSolverEdgeData(eId).getHeuristicData();
147 return getSolverNodeData(nId).solverEdgesBegin();
156 return getSolverNodeData(nId).solverEdgesEnd();
165 EdgeData &eData = getSolverEdgeData(eId);
166 NodeData &n1Data = getSolverNodeData(g.
getEdgeNode1(eId)),
169 n1Data.removeSolverEdge(eData.getN1SolverEdgeItr());
170 n2Data.removeSolverEdge(eData.getN2SolverEdgeItr());
193 getSolverNodeData(nId).clearSolverEdges();
194 stack.push_back(nId);
201 return getSolverNodeData(nId).getSolverDegree();
212 aeItr != aeEnd; ++aeItr) {
215 getSolverNodeData(anId).addSolverEdge(eId);
225 "R0 applied to node with degree != 0.");
238 NodeData &nd = getSolverNodeData(xnId);
239 assert(nd.getSolverDegree() == 1 &&
240 "R1 applied to node with degree != 1.");
251 for (
unsigned j = 0; j < yCosts.
getLength(); ++j) {
252 PBQPNum min = eCosts[0][j] + xCosts[0];
253 for (
unsigned i = 1; i < xCosts.getLength(); ++i) {
254 PBQPNum c = eCosts[i][j] + xCosts[i];
260 h.handleRemoveEdge(eId, ynId);
264 for (
unsigned i = 0; i < yCosts.
getLength(); ++i) {
265 PBQPNum min = eCosts[i][0] + xCosts[0];
266 for (
unsigned j = 1; j < xCosts.getLength(); ++j) {
267 PBQPNum c = eCosts[i][j] + xCosts[j];
273 h.handleRemoveEdge(eId, ynId);
276 assert(nd.getSolverDegree() == 0 &&
277 "Degree 1 with edge removed should be 0.");
288 "R2 applied to node with degree != 2.");
290 NodeData &nd = getSolverNodeData(xnId);
303 const Matrix *yxeCosts = flipEdge1 ?
307 const Matrix *zxeCosts = flipEdge2 ?
317 for (
unsigned i = 0; i < yLen; ++i) {
318 for (
unsigned j = 0; j < zLen; ++j) {
319 PBQPNum min = (*yxeCosts)[i][0] + (*zxeCosts)[j][0] + xCosts[0];
320 for (
unsigned k = 1; k < xLen; ++k) {
321 PBQPNum c = (*yxeCosts)[i][k] + (*zxeCosts)[j][k] + xCosts[k];
337 bool addedEdge =
false;
340 yzeId = g.
addEdge(ynId, znId, delta);
344 h.preUpdateEdgeCosts(yzeId);
352 bool nullCostEdge = tryNormaliseEdgeMatrix(yzeId);
356 h.postUpdateEdgeCosts(yzeId);
364 h.handleRemoveEdge(yzeId, ynId);
365 h.handleRemoveEdge(yzeId, znId);
369 }
else if (addedEdge) {
372 edgeDataList.push_back(EdgeData());
374 addSolverEdge(yzeId);
375 h.handleAddEdge(yzeId);
378 h.handleRemoveEdge(yxeId, ynId);
380 h.handleRemoveEdge(zxeId, znId);
395 return *
static_cast<NodeData*
>(g.
getNodeData(nId));
399 return *
static_cast<EdgeData*
>(g.
getEdgeData(eId));
403 EdgeData &eData = getSolverEdgeData(eId);
404 NodeData &n1Data = getSolverNodeData(g.
getEdgeNode1(eId)),
407 eData.setN1SolverEdgeItr(n1Data.addSolverEdge(eId));
408 eData.setN2SolverEdgeItr(n2Data.addSolverEdge(eId));
412 if (h.solverRunSimplify()) {
418 nItr != nEnd; ++nItr) {
419 nodeDataList.push_back(NodeData());
425 eItr != eEnd; ++eItr) {
426 edgeDataList.push_back(EdgeData());
428 addSolverEdge(*eItr);
433 disconnectTrivialNodes();
434 eliminateIndependentEdges();
438 void disconnectTrivialNodes() {
439 unsigned numDisconnected = 0;
442 nItr != nEnd; ++nItr) {
448 std::vector<Graph::EdgeId> edgesToRemove;
452 aeItr != aeEnd; ++aeItr) {
467 edgesToRemove.push_back(eId);
470 if (!edgesToRemove.empty())
473 while (!edgesToRemove.empty()) {
475 edgesToRemove.pop_back();
481 void eliminateIndependentEdges() {
482 std::vector<Graph::EdgeId> edgesToProcess;
483 unsigned numEliminated = 0;
486 eItr != eEnd; ++eItr) {
487 edgesToProcess.push_back(*eItr);
490 while (!edgesToProcess.empty()) {
491 if (tryToEliminateEdge(edgesToProcess.back()))
493 edgesToProcess.pop_back();
498 if (tryNormaliseEdgeMatrix(eId)) {
507 const PBQPNum infinity = std::numeric_limits<PBQPNum>::infinity();
513 for (
unsigned r = 0; r < edgeCosts.getRows(); ++r) {
516 for (
unsigned c = 0; c < edgeCosts.getCols(); ++c) {
517 if (vCosts[c] != infinity && edgeCosts[r][c] < rowMin)
518 rowMin = edgeCosts[r][c];
523 if (rowMin != infinity) {
524 edgeCosts.subFromRow(r, rowMin);
527 edgeCosts.setRow(r, 0);
531 for (
unsigned c = 0; c < edgeCosts.getCols(); ++c) {
534 for (
unsigned r = 0; r < edgeCosts.getRows(); ++r) {
535 if (uCosts[r] != infinity && edgeCosts[r][c] < colMin)
536 colMin = edgeCosts[r][c];
541 if (colMin != infinity) {
542 edgeCosts.subFromCol(c, colMin);
545 edgeCosts.setCol(c, 0);
549 return edgeCosts.isZero();
552 void backpropagate() {
553 while (!stack.empty()) {
561 NodeData &nodeData = getSolverNodeData(nId);
566 for (
SolverEdgeItr solvedEdgeItr = nodeData.solverEdgesBegin(),
567 solvedEdgeEnd = nodeData.solverEdgesEnd();
568 solvedEdgeItr != solvedEdgeEnd; ++solvedEdgeItr) {
576 v += edgeCosts.getColAsVector(adjSolution);
581 v += edgeCosts.getRowAsVector(adjSolution);
591 nodeDataList.clear();
592 edgeDataList.clear();
607 template <
typename HImpl>
618 #endif // LLVM_CODEGEN_PBQP_HEURISTICSOLVER_H
void recordR0()
Records a reduction via the R0 rule. Should be called from the solver only.
EdgeId invalidEdgeId() const
Vector & getNodeCosts(NodeId nId)
Get a node's cost vector.
NodeItr nodesEnd() const
End iterator for node set.
NodeId getEdgeNode1(EdgeId eId)
Get the first node connected to this edge.
void recordR1()
Records a reduction via the R1 rule. Should be called from the solver only.
HeuristicNodeData & getHeuristicNodeData(Graph::NodeId nId)
Get the heuristic data attached to the given node.
AdjEdgeList::iterator AdjEdgeItr
void recordRN()
Records a reduction via the RN rule. Should be called from the solver only.
unsigned getLength() const
Return the length of the vector.
EdgeItr edgesBegin() const
Begin iterator for edge set.
SolverEdgeItr solverEdgesBegin(Graph::NodeId nId)
Begin iterator for the set of edges adjacent to the given node in the solver graph.
HeuristicSolverImpl(Graph &g)
Construct a heuristic solver implementation to solve the given graph.
AdjEdgeItr adjEdgesEnd(NodeId nId)
Get end iterator for adjacent edge set.
void removeEdge(EdgeId eId)
Remove an edge from the graph.
unsigned getRows() const
Return the number of rows in this matrix.
unsigned getSelection(Graph::NodeId nodeId) const
Get a node's selection.
EdgeId findEdge(NodeId n1Id, NodeId n2Id)
Get the edge connecting two nodes.
static Solution solve(Graph &g)
NodeId getEdgeNode2(EdgeId eId)
Get the second node connected to this edge.
SolverEdges::iterator SolverEdgeItr
Iterator type for edges in the solver graph.
void recordRN()
Record an application of the RN rule.
void setNodeData(NodeId nId, void *data)
Set a node's data pointer.
unsigned getSolverDegree(Graph::NodeId nId)
Returns the solver degree of the given node.
Vector getRowAsVector(unsigned r) const
Returns the given row as a vector.
NodeId getEdgeOtherNode(EdgeId eId, NodeId nId)
Get the "other" node connected to this edge.
void setSelection(Graph::NodeId nodeId, unsigned selection)
Set the selection for a given node.
SolverEdgeItr solverEdgesEnd(Graph::NodeId nId)
End iterator for the set of edges adjacent to the given node in the solver graph. ...
void pushToStack(Graph::NodeId nId)
Add to the end of the stack.
AdjEdgeItr adjEdgesBegin(NodeId nId)
Get begin iterator for adjacent edge set.
void applyR0(Graph::NodeId nId)
Apply rule R0.
HeuristicEdgeData & getHeuristicEdgeData(Graph::EdgeId eId)
Get the heuristic data attached to the given edge.
void removeSolverEdge(Graph::EdgeId eId)
Remove a node from the solver graph.
Matrix & getEdgeCosts(EdgeId eId)
Get an edge's cost matrix.
EdgeItr edgesEnd() const
End iterator for edge set.
Heuristic PBQP solver implementation.
void setSolution(const Graph::NodeId &nId, unsigned selection)
Set the solution of the given node.
Represents a solution to a PBQP problem.
void * getEdgeData(EdgeId eId)
Get an edge's data pointer.
PBQP heuristic solver class.
EdgeId addEdge(NodeId n1Id, NodeId n2Id, const Matrix &costs)
Add an edge between the given nodes with the given costs.
void setEdgeData(EdgeId eId, void *data)
Set an edge's data pointer.
void applyR2(Graph::NodeId xnId)
Apply rule R2.
NodeItr nodesBegin() const
Begin iterator for node set.
Matrix transpose() const
Matrix transpose.
Graph & getGraph()
Get the graph being solved by this solver.
void * getNodeData(NodeId nId)
Get the node's data pointer.
void recordR2()
Records a reduction via the R2 rule. Should be called from the solver only.
void applyR1(Graph::NodeId xnId)
Apply rule R1.
Solution computeSolution()
Compute a solution to the PBQP problem instance with which this heuristic solver was constructed...
Vector getColAsVector(unsigned c) const
Returns the given column as a vector.