decrease the time required to find an elimination order

This commit is contained in:
Tiago Gomes 2012-05-17 17:29:31 +01:00
parent cf9a7f1413
commit 16cb48fea4
3 changed files with 109 additions and 135 deletions

View File

@ -54,16 +54,20 @@ VarIds
ElimGraph::getEliminatingOrder (const VarIds& exclude) ElimGraph::getEliminatingOrder (const VarIds& exclude)
{ {
VarIds elimOrder; VarIds elimOrder;
marked_.resize (nodes_.size(), false); unmarked_.reserve (nodes_.size());
for (unsigned i = 0; i < exclude.size(); i++) { for (unsigned i = 0; i < nodes_.size(); i++) {
assert (getEgNode (exclude[i])); if (Util::contains (exclude, nodes_[i]->varId()) == false) {
EgNode* node = getEgNode (exclude[i]); unmarked_.insert (nodes_[i]);
marked_[*node] = true; }
} }
unsigned nVarsToEliminate = nodes_.size() - exclude.size(); unsigned nVarsToEliminate = nodes_.size() - exclude.size();
for (unsigned i = 0; i < nVarsToEliminate; i++) { for (unsigned i = 0; i < nVarsToEliminate; i++) {
EgNode* node = getLowestCostNode(); EgNode* node = getLowestCostNode();
marked_[*node] = true; unmarked_.remove (node);
const EGNeighs& neighs = node->neighbors();
for (unsigned j = 0; j < neighs.size(); j++) {
neighs[j]->removeNeighbor (node);
}
elimOrder.push_back (node->varId()); elimOrder.push_back (node->varId());
connectAllNeighbors (node); connectAllNeighbors (node);
} }
@ -77,7 +81,7 @@ ElimGraph::print (void) const
{ {
for (unsigned i = 0; i < nodes_.size(); i++) { for (unsigned i = 0; i < nodes_.size(); i++) {
cout << "node " << nodes_[i]->label() << " neighs:" ; cout << "node " << nodes_[i]->label() << " neighs:" ;
vector<EgNode*> neighs = nodes_[i]->neighbors(); EGNeighs neighs = nodes_[i]->neighbors();
for (unsigned j = 0; j < neighs.size(); j++) { for (unsigned j = 0; j < neighs.size(); j++) {
cout << " " << neighs[j]->label(); cout << " " << neighs[j]->label();
} }
@ -120,7 +124,7 @@ ElimGraph::exportToGraphViz (
} }
for (unsigned i = 0; i < nodes_.size(); i++) { for (unsigned i = 0; i < nodes_.size(); i++) {
vector<EgNode*> neighs = nodes_[i]->neighbors(); EGNeighs neighs = nodes_[i]->neighbors();
for (unsigned j = 0; j < neighs.size(); j++) { for (unsigned j = 0; j < neighs.size(); j++) {
out << '"' << nodes_[i]->label() << '"' << " -- " ; out << '"' << nodes_[i]->label() << '"' << " -- " ;
out << '"' << neighs[j]->label() << '"' << endl; out << '"' << neighs[j]->label() << '"' << endl;
@ -171,118 +175,44 @@ ElimGraph::getLowestCostNode (void) const
{ {
EgNode* bestNode = 0; EgNode* bestNode = 0;
unsigned minCost = std::numeric_limits<unsigned>::max(); unsigned minCost = std::numeric_limits<unsigned>::max();
for (unsigned i = 0; i < nodes_.size(); i++) {
if (marked_[i]) continue;
unsigned cost = 0; unsigned cost = 0;
EGNeighs::const_iterator it;
switch (elimHeuristic) { switch (elimHeuristic) {
case MIN_NEIGHBORS: case MIN_NEIGHBORS: {
cost = getNeighborsCost (nodes_[i]); for (it = unmarked_.begin(); it != unmarked_.end(); ++ it) {
cost = getNeighborsCost (*it);
if (cost < minCost) {
bestNode = *it;
minCost = cost;
}
}}
break; break;
case MIN_WEIGHT: case MIN_WEIGHT:
cost = getWeightCost (nodes_[i]); //cost = getWeightCost (unmarked_[i]);
break; break;
case MIN_FILL: case MIN_FILL:
cost = getFillCost (nodes_[i]); //cost = getFillCost (unmarked_[i]);
break; break;
case WEIGHTED_MIN_FILL: case WEIGHTED_MIN_FILL:
cost = getWeightedFillCost (nodes_[i]); //cost = getWeightedFillCost (unmarked_[i]);
break; break;
default: default:
assert (false); assert (false);
} }
if (cost < minCost) {
bestNode = nodes_[i];
minCost = cost;
}
}
assert (bestNode); assert (bestNode);
return bestNode; return bestNode;
} }
unsigned
ElimGraph::getNeighborsCost (const EgNode* n) const
{
unsigned cost = 0;
const vector<EgNode*>& neighs = n->neighbors();
for (unsigned i = 0; i < neighs.size(); i++) {
if (marked_[*neighs[i]] == false) {
cost ++;
}
}
return cost;
}
unsigned
ElimGraph::getWeightCost (const EgNode* n) const
{
unsigned cost = 1;
const vector<EgNode*>& neighs = n->neighbors();
for (unsigned i = 0; i < neighs.size(); i++) {
if (marked_[*neighs[i]] == false) {
cost *= neighs[i]->range();
}
}
return cost;
}
unsigned
ElimGraph::getFillCost (const EgNode* n) const
{
unsigned cost = 0;
const vector<EgNode*>& neighs = n->neighbors();
if (neighs.size() > 0) {
for (unsigned i = 0; i < neighs.size() - 1; i++) {
if (marked_[*neighs[i]] == true) continue;
for (unsigned j = i+1; j < neighs.size(); j++) {
if (marked_[*neighs[j]] == true) continue;
if (!neighbors (neighs[i], neighs[j])) {
cost ++;
}
}
}
}
return cost;
}
unsigned
ElimGraph::getWeightedFillCost (const EgNode* n) const
{
unsigned cost = 0;
const vector<EgNode*>& neighs = n->neighbors();
if (neighs.size() > 0) {
for (unsigned i = 0; i < neighs.size() - 1; i++) {
if (marked_[*neighs[i]] == true) continue;
for (unsigned j = i+1; j < neighs.size(); j++) {
if (marked_[*neighs[j]] == true) continue;
if (!neighbors (neighs[i], neighs[j])) {
cost += neighs[i]->range() * neighs[j]->range();
}
}
}
}
return cost;
}
void void
ElimGraph::connectAllNeighbors (const EgNode* n) ElimGraph::connectAllNeighbors (const EgNode* n)
{ {
const vector<EgNode*>& neighs = n->neighbors(); const EGNeighs& neighs = n->neighbors();
if (neighs.size() > 0) { if (neighs.size() > 0) {
for (unsigned i = 0; i < neighs.size() - 1; i++) { for (unsigned i = 0; i < neighs.size() - 1; i++) {
if (marked_[*neighs[i]] == true) continue;
for (unsigned j = i+1; j < neighs.size(); j++) { for (unsigned j = i+1; j < neighs.size(); j++) {
if (marked_[*neighs[j]] == true) continue; if ( ! neighbors (neighs[i], neighs[j])) {
if (!neighbors (neighs[i], neighs[j])) {
addEdge (neighs[i], neighs[j]); addEdge (neighs[i], neighs[j]);
} }
} }
@ -290,17 +220,3 @@ ElimGraph::connectAllNeighbors (const EgNode* n)
} }
} }
bool
ElimGraph::neighbors (const EgNode* n1, const EgNode* n2) const
{
const vector<EgNode*>& neighs = n1->neighbors();
for (unsigned i = 0; i < neighs.size(); i++) {
if (neighs[i] == n2) {
return true;
}
}
return false;
}

View File

@ -4,8 +4,10 @@
#include "unordered_map" #include "unordered_map"
#include "FactorGraph.h" #include "FactorGraph.h"
#include "TinySet.h"
#include "Horus.h" #include "Horus.h"
using namespace std; using namespace std;
enum ElimHeuristic enum ElimHeuristic
@ -17,17 +19,26 @@ enum ElimHeuristic
}; };
class EgNode;
typedef TinySet<EgNode*> EGNeighs;
class EgNode : public Var class EgNode : public Var
{ {
public: public:
EgNode (VarId vid, unsigned range) : Var (vid, range) { } EgNode (VarId vid, unsigned range) : Var (vid, range) { }
void addNeighbor (EgNode* n) { neighs_.push_back (n); } void addNeighbor (EgNode* n) { neighs_.insert (n); }
const vector<EgNode*>& neighbors (void) const { return neighs_; } void removeNeighbor (EgNode* n) { neighs_.remove (n); }
bool isNeighbor (EgNode* n) const { return neighs_.contains (n); }
const EGNeighs& neighbors (void) const { return neighs_; }
private: private:
vector<EgNode*> neighs_; EGNeighs neighs_;
}; };
@ -58,25 +69,68 @@ class ElimGraph
n2->addNeighbor (n1); n2->addNeighbor (n1);
} }
unsigned getNeighborsCost (const EgNode* n) const
{
return n->neighbors().size();
}
unsigned getWeightCost (const EgNode* n) const
{
unsigned cost = 1;
const EGNeighs& neighs = n->neighbors();
for (unsigned i = 0; i < neighs.size(); i++) {
cost *= neighs[i]->range();
}
return cost;
}
unsigned getFillCost (const EgNode* n) const
{
unsigned cost = 0;
const EGNeighs& neighs = n->neighbors();
if (neighs.size() > 0) {
for (unsigned i = 0; i < neighs.size() - 1; i++) {
for (unsigned j = i + 1; j < neighs.size(); j++) {
if ( ! neighbors (neighs[i], neighs[j])) {
cost ++;
}
}
}
}
return cost;
}
unsigned getWeightedFillCost (const EgNode* n) const
{
unsigned cost = 0;
const EGNeighs& neighs = n->neighbors();
if (neighs.size() > 0) {
for (unsigned i = 0; i < neighs.size() - 1; i++) {
for (unsigned j = i+1; j < neighs.size(); j++) {
if ( ! neighbors (neighs[i], neighs[j])) {
cost += neighs[i]->range() * neighs[j]->range();
}
}
}
}
return cost;
}
bool neighbors (EgNode* n1, EgNode* n2) const
{
return n1->isNeighbor (n2);
}
void addNode (EgNode*); void addNode (EgNode*);
EgNode* getEgNode (VarId) const; EgNode* getEgNode (VarId) const;
EgNode* getLowestCostNode (void) const; EgNode* getLowestCostNode (void) const;
unsigned getNeighborsCost (const EgNode*) const;
unsigned getWeightCost (const EgNode*) const;
unsigned getFillCost (const EgNode*) const;
unsigned getWeightedFillCost (const EgNode*) const;
void connectAllNeighbors (const EgNode*); void connectAllNeighbors (const EgNode*);
bool neighbors (const EgNode*, const EgNode*) const;
vector<EgNode*> nodes_; vector<EgNode*> nodes_;
vector<bool> marked_; TinySet<EgNode*> unmarked_;
unordered_map<VarId, EgNode*> varMap_; unordered_map<VarId, EgNode*> varMap_;
}; };

View File

@ -5,4 +5,8 @@
- Consider using hashs instead of vectors of colors to calculate the groups in - Consider using hashs instead of vectors of colors to calculate the groups in
counting bp counting bp
- use more psize_t instead of unsigned for looping through params - use more psize_t instead of unsigned for looping through params
- Find a way to decrease the time required to find an
elimination order for variable elimination
- Add a sequential elimination heuristic