nur/pkgs/ieda/remove_format.patch

3078 lines
114 KiB
Diff
Raw Normal View History

2024-02-04 04:25:22 +00:00
diff --git a/src/third_party/salt/CHANGELOG.md b/src/third_party/salt/CHANGELOG.md
index 5408be85..33992341 100644
--- a/src/third_party/salt/CHANGELOG.md
+++ b/src/third_party/salt/CHANGELOG.md
@@ -149,8 +149,4 @@ diff -r ./base/net.h {ORIGIN REPOSITORY}/src/salt/base/net.h
> void Write(const string& prefix, bool withNetInfo = true) const;
>
> friend ostream& operator<<(ostream& os, const Net& net) { net.Write(os); return os; }
-```
-
-### Rename variable
-
-Changing some variable names and function names for the uniform naming convention does not change the code logic
\ No newline at end of file
+```
\ No newline at end of file
diff --git a/src/third_party/salt/base/eval.cpp b/src/third_party/salt/base/eval.cpp
index 1cf554b4..b1f8cc5e 100644
--- a/src/third_party/salt/base/eval.cpp
+++ b/src/third_party/salt/base/eval.cpp
@@ -7,7 +7,7 @@ namespace salt {
void WireLengthEvalBase::Update(const Tree& tree) {
wireLength = 0;
- tree.postOrder([&](const shared_ptr<TreeNode>& node) {
+ tree.PostOrder([&](const shared_ptr<TreeNode>& node) {
if (node->parent) {
wireLength += node->WireToParent();
}
@@ -60,7 +60,7 @@ void ElmoreDelayEval::Update(double rd, Tree& tree, bool normalize) {
maxDelay = avgDelay = maxNorDelay = avgNorDelay = 0;
auto delay = GetDelay(rd, tree, numNodes); // delay for all tree nodes
- tree.preOrder([&](const shared_ptr<TreeNode>& node) {
+ tree.PreOrder([&](const shared_ptr<TreeNode>& node) {
if (!node->pin || node == tree.source) return;
maxDelay = max(maxDelay, delay[node->id]);
avgDelay += delay[node->id];
@@ -70,7 +70,7 @@ void ElmoreDelayEval::Update(double rd, Tree& tree, bool normalize) {
if (!normalize) return;
auto lb = GetDelayLB(rd, tree); // delay lb for all pins, 0 is source
- // tree.preOrder([&](const shared_ptr<TreeNode>& node){
+ // tree.PreOrder([&](const shared_ptr<TreeNode>& node){
// if(!node->pin || node == tree.source) return;
// double norDelay = delay[node->id] / lb[node->id];
// maxNorDelay = max(maxNorDelay, norDelay);
@@ -85,7 +85,7 @@ void ElmoreDelayEval::Update(double rd, Tree& tree, bool normalize) {
vector<double> ElmoreDelayEval::GetDelay(double rd, const Tree& tree, int numNode) {
// get node cap by post-order traversal
vector<double> cap(numNode, 0);
- tree.postOrder([&](const shared_ptr<TreeNode>& node) {
+ tree.PostOrder([&](const shared_ptr<TreeNode>& node) {
if (node->pin && node != tree.source) cap[node->id] = node->pin->cap;
for (auto c : node->children) {
cap[node->id] += cap[c->id];
@@ -95,7 +95,7 @@ vector<double> ElmoreDelayEval::GetDelay(double rd, const Tree& tree, int numNod
// get delay by post-order traversal
vector<double> delay(numNode, 0);
- tree.preOrder([&](const shared_ptr<TreeNode>& node) {
+ tree.PreOrder([&](const shared_ptr<TreeNode>& node) {
if (node == tree.source)
delay[node->id] = rd * cap[node->id];
else {
diff --git a/src/third_party/salt/base/flute.cpp b/src/third_party/salt/base/flute.cpp
index 31672f46..f83f637f 100644
--- a/src/third_party/salt/base/flute.cpp
+++ b/src/third_party/salt/base/flute.cpp
@@ -14,8 +14,8 @@ void salt::FluteBuilder::Run(const salt::Net& net, salt::Tree& saltTree) {
}
// Obtain flute tree
- Flute::Tree flute_tree;
- flute_tree.branch = nullptr;
+ Flute::Tree fluteTree;
+ fluteTree.branch = nullptr;
int d = net.pins.size();
assert(d <= MAXD);
int x[MAXD], y[MAXD];
@@ -23,17 +23,17 @@ void salt::FluteBuilder::Run(const salt::Net& net, salt::Tree& saltTree) {
x[i] = net.pins[i]->loc.x;
y[i] = net.pins[i]->loc.y;
}
- if (flute_tree.branch) free(flute_tree.branch); // is it complete for mem leak?
- flute_tree = Flute::flute(d, x, y, FLUTE_ACCURACY);
+ if (fluteTree.branch) free(fluteTree.branch); // is it complete for mem leak?
+ fluteTree = Flute::flute(d, x, y, FLUTE_ACCURACY);
// Build adjacency list
unordered_map<pair<DTYPE, DTYPE>, shared_ptr<salt::TreeNode>, boost::hash<pair<DTYPE, DTYPE>>> key2node;
for (auto p : net.pins) {
key2node[{p->loc.x, p->loc.y}] = make_shared<salt::TreeNode>(p);
}
- auto& t = flute_tree;
+ auto& t = fluteTree;
- auto find_or_create = [&](DTYPE x, DTYPE y) {
+ auto FindOrCreate = [&](DTYPE x, DTYPE y) {
auto it = key2node.find({x, y});
if (it == key2node.end()) {
shared_ptr<salt::TreeNode> node = make_shared<salt::TreeNode>(x, y);
@@ -47,8 +47,8 @@ void salt::FluteBuilder::Run(const salt::Net& net, salt::Tree& saltTree) {
int j = t.branch[i].n;
if (t.branch[i].x == t.branch[j].x && t.branch[i].y == t.branch[j].y) continue;
// any more duplicate?
- shared_ptr<salt::TreeNode> n1 = find_or_create(t.branch[i].x, t.branch[i].y);
- shared_ptr<salt::TreeNode> n2 = find_or_create(t.branch[j].x, t.branch[j].y);
+ shared_ptr<salt::TreeNode> n1 = FindOrCreate(t.branch[i].x, t.branch[i].y);
+ shared_ptr<salt::TreeNode> n2 = FindOrCreate(t.branch[j].x, t.branch[j].y);
// printlog(LOG_INFO, "%d - %d\n", n1->pin?n1->pin->id:-1, n2->pin?n2->pin->id:-1);
n1->children.push_back(n2);
n2->children.push_back(n1);
@@ -59,5 +59,5 @@ void salt::FluteBuilder::Run(const salt::Net& net, salt::Tree& saltTree) {
saltTree.SetParentFromUndirectedAdjList();
saltTree.net = &net;
- free(flute_tree.branch);
+ free(fluteTree.branch);
}
\ No newline at end of file
diff --git a/src/third_party/salt/base/mst.cpp b/src/third_party/salt/base/mst.cpp
index 8a2ac098..48fe9352 100644
--- a/src/third_party/salt/base/mst.cpp
+++ b/src/third_party/salt/base/mst.cpp
@@ -68,7 +68,7 @@ void MstBuilder::RunPrimAlg(const Net& net, const vector<vector<int>>& adjLists,
}
for (int i = 0; i < numPins; ++i) {
if (prefixes[i] >= 0) {
- TreeNode::setParent(nodes[i], nodes[prefixes[i]]);
+ TreeNode::SetParent(nodes[i], nodes[prefixes[i]]);
}
}
tree.source = nodes[0];
diff --git a/src/third_party/salt/base/net.cpp b/src/third_party/salt/base/net.cpp
index ce852e22..246d2f23 100644
--- a/src/third_party/salt/base/net.cpp
+++ b/src/third_party/salt/base/net.cpp
@@ -39,7 +39,7 @@ bool Net::Read(istream& is) {
istringstream iss(buf);
iss >> id >> name >> numPin >> option;
assert(numPin > 0);
- with_cap = (option == "-cap");
+ withCap = (option == "-cap");
// pins
int i;
@@ -48,7 +48,7 @@ bool Net::Read(istream& is) {
pins.resize(numPin);
for (auto& pin : pins) {
is >> i >> x >> y;
- if (with_cap) is >> c;
+ if (withCap) is >> c;
pin = make_shared<Pin>(x, y, i, c);
}
@@ -67,7 +67,7 @@ void Net::Read(const string& fileName) {
string Net::GetHeader() const {
string header = to_string(id) + " " + name + " " + to_string(pins.size());
// string header = name + " " + to_string(pins.size());
- if (with_cap) header += " -cap";
+ if (withCap) header += " -cap";
return header;
}
@@ -78,7 +78,7 @@ void Net::Write(ostream& os) const {
// pins
for (const auto& pin : pins) {
os << pin->id << " " << pin->loc.x << " " << pin->loc.y;
- if (with_cap) os << " " << pin->cap;
+ if (withCap) os << " " << pin->cap;
os << endl;
}
}
diff --git a/src/third_party/salt/base/net.h b/src/third_party/salt/base/net.h
index 3869359e..968eb8e2 100644
--- a/src/third_party/salt/base/net.h
+++ b/src/third_party/salt/base/net.h
@@ -6,19 +6,21 @@
#include "salt/utils/utils.h"
+using namespace std;
+
// #define DTYPE int // same as flute.h, will overwrite it
typedef int DTYPE;
namespace salt {
-using namespace std;
+
using Point = utils::PointT<DTYPE>;
using Box = utils::BoxT<DTYPE>;
class Pin
{
public:
- Point loc;
int id; // 0 for source, should be in range [0, pin_num) for a net
+ Point loc;
double cap;
Pin(const Point& l, int i = -1, double c = 0.0) : loc(l), id(i), cap(c) {}
@@ -33,7 +35,7 @@ class Net
public:
int id;
string name;
- bool with_cap = false;
+ bool withCap = false;
vector<shared_ptr<Pin>> pins; // source is always the first one
@@ -42,7 +44,7 @@ class Net
this->id = id;
this->name = name;
this->pins = pins;
- this->with_cap = true;
+ this->withCap = true;
}
void RanInit(int i, int numPin, DTYPE width = 100, DTYPE height = 100); // random initialization
diff --git a/src/third_party/salt/base/rsa.cpp b/src/third_party/salt/base/rsa.cpp
index 8461cbbe..b76f4345 100644
--- a/src/third_party/salt/base/rsa.cpp
+++ b/src/third_party/salt/base/rsa.cpp
@@ -5,255 +5,227 @@
namespace salt {
-constexpr double kPI = 3.14159265358979323846; /* pi */
-
-void RSABase::ReplaceRootChildren(Tree& tree)
-{
- const Net* old_net = tree.net;
-
- // create tmp_net and fake_pins
- Net tmp_net = *old_net;
- tmp_net.pins.clear();
- unordered_map<shared_ptr<Pin>, shared_ptr<TreeNode>> pin_to_old_node;
- tmp_net.pins.push_back(tree.source->pin);
- unordered_set<shared_ptr<Pin>> fake_pins;
- pin_to_old_node[tree.source->pin] = tree.source;
- for (auto c : tree.source->children) { // only contains the direct children of tree.source
- shared_ptr<Pin> pin = c->pin;
- if (!pin) {
- pin = make_shared<Pin>(c->loc);
- fake_pins.insert(pin);
- }
- tmp_net.pins.push_back(pin);
- pin_to_old_node[pin] = c;
- }
- tree.source->children.clear(); // free them...
-
- // get rsa and graft the old subtrees to it
- Run(tmp_net, tree);
- tree.postOrder([&](const shared_ptr<TreeNode>& node) {
- if (node->pin) {
- auto old_node = pin_to_old_node[node->pin];
- if (fake_pins.find(node->pin) != fake_pins.end())
- node->pin = nullptr;
- if (node->parent)
- for (auto c : old_node->children)
- TreeNode::setParent(c, node);
+constexpr double PI_VALUE = 3.14159265358979323846; /* pi */
+
+void RsaBase::ReplaceRootChildren(Tree& tree) {
+ const Net* oldNet = tree.net;
+
+ // create tmpNet and fakePins
+ Net tmpNet = *oldNet;
+ tmpNet.pins.clear();
+ unordered_map<shared_ptr<Pin>, shared_ptr<TreeNode>> pinToOldNode;
+ tmpNet.pins.push_back(tree.source->pin);
+ unordered_set<shared_ptr<Pin>> fakePins;
+ pinToOldNode[tree.source->pin] = tree.source;
+ for (auto c : tree.source->children) { // only contains the direct children of tree.source
+ shared_ptr<Pin> pin = c->pin;
+ if (!pin) {
+ pin = make_shared<Pin>(c->loc);
+ fakePins.insert(pin);
+ }
+ tmpNet.pins.push_back(pin);
+ pinToOldNode[pin] = c;
}
- });
- tree.net = old_net;
- tree.RemoveTopoRedundantSteiner();
+ tree.source->children.clear(); // free them...
+
+ // get rsa and graft the old subtrees to it
+ Run(tmpNet, tree);
+ tree.PostOrder([&](const shared_ptr<TreeNode>& node) {
+ if (node->pin) {
+ auto oldNode = pinToOldNode[node->pin];
+ if (fakePins.find(node->pin) != fakePins.end()) node->pin = nullptr;
+ if (node->parent)
+ for (auto c : oldNode->children) TreeNode::SetParent(c, node);
+ }
+ });
+ tree.net = oldNet;
+ tree.RemoveTopoRedundantSteiner();
}
-DTYPE RSABase::MaxOvlp(DTYPE z1, DTYPE z2)
-{
- if (z1 >= 0 && z2 >= 0)
- return min(z1, z2);
- else if (z1 <= 0 && z2 <= 0)
- return max(z1, z2);
- else
- return 0;
+DTYPE RsaBase::MaxOvlp(DTYPE z1, DTYPE z2) {
+ if (z1 >= 0 && z2 >= 0)
+ return min(z1, z2);
+ else if (z1 <= 0 && z2 <= 0)
+ return max(z1, z2);
+ else
+ return 0;
}
-void RsaBuilder::Run(const Net& net, Tree& tree)
-{
- // Shift all pins to make source (0,0)
- auto ori_src_loc = net.source()->loc;
- for (auto& p : net.pins)
- p->loc -= ori_src_loc;
-
- // Init inner_nodes with all sinks
- for (auto p : net.pins)
- if (p->IsSink())
- inner_nodes.insert(new InnerNode(make_shared<TreeNode>(p)));
-
- // Process a inner node in each iteration
- while (!inner_nodes.empty()) {
- if ((*inner_nodes.begin())->dist == 0)
- break; // TODO: clear
- shared_ptr<TreeNode> node = (*inner_nodes.begin())->tn;
- auto for_delete = *inner_nodes.begin();
- inner_nodes.erase(inner_nodes.begin());
- if (!node->pin) { // steiner node
- assert(node->children.size() == 2);
- if (node->children[0])
- RemoveAnOuterNode(node->children[0], true, false);
- if (node->children[1])
- RemoveAnOuterNode(node->children[1], false, true);
- node->children[0]->parent = node;
- node->children[1]->parent = node;
- } else { // pin node
- TryDominating(node);
+void RsaBuilder::Run(const Net& net, Tree& tree) {
+ // Shift all pins to make source (0,0)
+ auto oriSrcLoc = net.source()->loc;
+ for (auto& p : net.pins) p->loc -= oriSrcLoc;
+
+ // Init innerNodes with all sinks
+ for (auto p : net.pins)
+ if (p->IsSink()) innerNodes.insert(new InnerNode(make_shared<TreeNode>(p)));
+
+ // Process a inner node in each iteration
+ while (!innerNodes.empty()) {
+ if ((*innerNodes.begin())->dist == 0) break; // TODO: clear
+ shared_ptr<TreeNode> node = (*innerNodes.begin())->tn;
+ auto forDelete = *innerNodes.begin();
+ innerNodes.erase(innerNodes.begin());
+ if (!node->pin) { // steiner node
+ assert(node->children.size() == 2);
+ if (node->children[0]) RemoveAnOuterNode(node->children[0], true, false);
+ if (node->children[1]) RemoveAnOuterNode(node->children[1], false, true);
+ node->children[0]->parent = node;
+ node->children[1]->parent = node;
+ } else { // pin node
+ TryDominating(node);
+ }
+ delete forDelete;
+ AddAnOuterNode(node);
}
- delete for_delete;
- AddAnOuterNode(node);
- }
- // connet the remaining outer_nodes to the source
- tree.source = make_shared<TreeNode>(net.source());
- for (const auto& on : outer_nodes)
- TreeNode::setParent(on.second.cur, tree.source);
- tree.net = &net;
+ // connet the remaining outerNodes to the source
+ tree.source = make_shared<TreeNode>(net.source());
+ for (const auto& on : outerNodes) TreeNode::SetParent(on.second.cur, tree.source);
+ tree.net = &net;
- // shift all pins back
- for (auto& p : net.pins)
- p->loc += ori_src_loc;
- tree.preOrder([&](const shared_ptr<TreeNode>& node) { node->loc += ori_src_loc; });
+ // shift all pins back
+ for (auto& p : net.pins) p->loc += oriSrcLoc;
+ tree.PreOrder([&](const shared_ptr<TreeNode>& node) { node->loc += oriSrcLoc; });
- // clear
- for (auto in : inner_nodes)
- delete in;
- inner_nodes.clear();
- outer_nodes.clear();
+ // clear
+ for (auto in : innerNodes) delete in;
+ innerNodes.clear();
+ outerNodes.clear();
}
-map<double, OuterNode>::iterator RsaBuilder::NextOuterNode(const map<double, OuterNode>::iterator& it)
-{
- auto res = next(it);
- if (res != outer_nodes.end())
- return res;
- else
- return outer_nodes.begin();
+map<double, OuterNode>::iterator RsaBuilder::NextOuterNode(const map<double, OuterNode>::iterator& it) {
+ auto res = next(it);
+ if (res != outerNodes.end())
+ return res;
+ else
+ return outerNodes.begin();
}
-map<double, OuterNode>::iterator RsaBuilder::PrevOuterNode(const map<double, OuterNode>::iterator& it)
-{
- if (it != outer_nodes.begin())
- return prev(it);
- else
- return prev(outer_nodes.end());
+map<double, OuterNode>::iterator RsaBuilder::PrevOuterNode(const map<double, OuterNode>::iterator& it) {
+ if (it != outerNodes.begin())
+ return prev(it);
+ else
+ return prev(outerNodes.end());
}
-bool RsaBuilder::TryMaxOvlpSteinerNode(OuterNode& left, OuterNode& right)
-{
- double rl_ang = atan2(right.cur->loc.y, right.cur->loc.x) - atan2(left.cur->loc.y, left.cur->loc.x);
- // if (rl_ang>-kPI && rl_ang<0) return false; // there is smaller arc
- DTYPE new_x, new_y;
- if ((rl_ang > -kPI && rl_ang < 0) || rl_ang > kPI) { // large arc
- new_x = 0;
- new_y = 0;
- } else {
- new_x = MaxOvlp(left.cur->loc.x, right.cur->loc.x);
- new_y = MaxOvlp(left.cur->loc.y, right.cur->loc.y);
- }
- // if (new_x==0 && new_y==0) return false; // non-neighboring quadrant
- auto tn = make_shared<TreeNode>(new_x, new_y);
- tn->children = {left.cur, right.cur};
- auto in = new InnerNode(tn);
- left.right_parent = in;
- right.left_parent = in;
- inner_nodes.insert(in);
- // cout << "add a tmp steiner point" << endl;
- // tn->Print(0,true);
- return true;
+bool RsaBuilder::TryMaxOvlpSteinerNode(OuterNode& left, OuterNode& right) {
+ double rlAng = atan2(right.cur->loc.y, right.cur->loc.x) - atan2(left.cur->loc.y, left.cur->loc.x);
+ // if (rlAng>-PI_VALUE && rlAng<0) return false; // there is smaller arc
+ DTYPE newX, newY;
+ if ((rlAng > -PI_VALUE && rlAng < 0) || rlAng > PI_VALUE) { // large arc
+ newX = 0;
+ newY = 0;
+ } else {
+ newX = MaxOvlp(left.cur->loc.x, right.cur->loc.x);
+ newY = MaxOvlp(left.cur->loc.y, right.cur->loc.y);
+ }
+ // if (newX==0 && newY==0) return false; // non-neighboring quadrant
+ auto tn = make_shared<TreeNode>(newX, newY);
+ tn->children = {left.cur, right.cur};
+ auto in = new InnerNode(tn);
+ left.rightP = in;
+ right.leftP = in;
+ innerNodes.insert(in);
+ // cout << "add a tmp steiner point" << endl;
+ // tn->Print(0,true);
+ return true;
}
-void RsaBuilder::RemoveAnOuterNode(const shared_ptr<TreeNode>& node, bool del_left, bool del_right)
-{
- auto outer_cur = outer_nodes.find(OuterNodeKey(node));
- assert(outer_cur != outer_nodes.end());
- InnerNode *inner_left = outer_cur->second.left_parent, *inner_right = outer_cur->second.right_parent;
- auto outer_left = outer_nodes.end(), outer_right = outer_nodes.end();
- if (inner_left != nullptr) {
- outer_left = PrevOuterNode(outer_cur);
- assert(outer_left->second.cur == inner_left->tn->children[0]);
- assert(outer_cur->second.cur == inner_left->tn->children[1]);
- inner_nodes.erase(inner_left);
- if (del_left)
- delete inner_left; // inner parent become invalid now
- outer_left->second.right_parent = nullptr;
- }
- if (inner_right != nullptr) {
- outer_right = NextOuterNode(outer_cur);
- assert(outer_cur->second.cur == inner_right->tn->children[0]);
- assert(outer_right->second.cur == inner_right->tn->children[1]);
- inner_nodes.erase(inner_right);
- if (del_right)
- delete inner_right; // inner parent become invalid now
- outer_right->second.left_parent = nullptr;
- }
- // delete outer_cur->second.first; // outer child should be kept
- outer_nodes.erase(outer_cur);
- if (del_left && del_right && outer_right != outer_nodes.end() && outer_left != outer_nodes.end() && outer_left != outer_right) {
- TryMaxOvlpSteinerNode(outer_left->second, outer_right->second);
- }
+void RsaBuilder::RemoveAnOuterNode(const shared_ptr<TreeNode>& node, bool delL, bool delR) {
+ auto outerCur = outerNodes.find(OuterNodeKey(node));
+ assert(outerCur != outerNodes.end());
+ InnerNode *innerL = outerCur->second.leftP, *innerR = outerCur->second.rightP;
+ auto outerL = outerNodes.end(), outerR = outerNodes.end();
+ if (innerL != nullptr) {
+ outerL = PrevOuterNode(outerCur);
+ assert(outerL->second.cur == innerL->tn->children[0]);
+ assert(outerCur->second.cur == innerL->tn->children[1]);
+ innerNodes.erase(innerL);
+ if (delL) delete innerL; // inner parent become invalid now
+ outerL->second.rightP = nullptr;
+ }
+ if (innerR != nullptr) {
+ outerR = NextOuterNode(outerCur);
+ assert(outerCur->second.cur == innerR->tn->children[0]);
+ assert(outerR->second.cur == innerR->tn->children[1]);
+ innerNodes.erase(innerR);
+ if (delR) delete innerR; // inner parent become invalid now
+ outerR->second.leftP = nullptr;
+ }
+ // delete outerCur->second.first; // outer child should be kept
+ outerNodes.erase(outerCur);
+ if (delL && delR && outerR != outerNodes.end() && outerL != outerNodes.end() && outerL != outerR) {
+ TryMaxOvlpSteinerNode(outerL->second, outerR->second);
+ }
}
// p dominates c
-inline bool Dominate(const Point& p, const Point& c)
-{
- return ((p.x >= 0 && c.x >= 0 && p.x <= c.x) || (p.x <= 0 && c.x <= 0 && p.x >= c.x)) // x
- && ((p.y >= 0 && c.y >= 0 && p.y <= c.y) || (p.y <= 0 && c.y <= 0 && p.y >= c.y)); // y
+inline bool Dominate(const Point& p, const Point& c) {
+ return ((p.x >= 0 && c.x >= 0 && p.x <= c.x) || (p.x <= 0 && c.x <= 0 && p.x >= c.x)) // x
+ && ((p.y >= 0 && c.y >= 0 && p.y <= c.y) || (p.y <= 0 && c.y <= 0 && p.y >= c.y)); // y
}
-bool RsaBuilder::TryDominatingOneSide(OuterNode& p, OuterNode& c)
-{
- if (!Dominate(p.cur->loc, c.cur->loc))
- return false;
- TreeNode::setParent(c.cur, p.cur);
- RemoveAnOuterNode(c.cur);
- return true;
+bool RsaBuilder::TryDominatingOneSide(OuterNode& p, OuterNode& c) {
+ if (!Dominate(p.cur->loc, c.cur->loc)) return false;
+ TreeNode::SetParent(c.cur, p.cur);
+ RemoveAnOuterNode(c.cur);
+ return true;
}
-void RsaBuilder::TryDominating(const shared_ptr<TreeNode>& node)
-{
- OuterNode outer_cur(node);
- if (outer_nodes.empty())
- return;
- else if (outer_nodes.size() == 1) {
- TryDominatingOneSide(outer_cur, outer_nodes.begin()->second);
- return;
- }
- // get outer_right & outer_left
- auto outer_right = outer_nodes.upper_bound(OuterNodeKey(node));
- if (outer_right == outer_nodes.end())
- outer_right = outer_nodes.begin();
- auto outer_left = PrevOuterNode(outer_right);
- assert(outer_left != outer_nodes.end() && outer_right != outer_nodes.end());
- assert(outer_left->second.right_parent == outer_right->second.left_parent);
- // try dominating twice
- TryDominatingOneSide(outer_cur, outer_left->second);
- TryDominatingOneSide(outer_cur, outer_right->second);
+void RsaBuilder::TryDominating(const shared_ptr<TreeNode>& node) {
+ OuterNode outerCur(node);
+ if (outerNodes.empty())
+ return;
+ else if (outerNodes.size() == 1) {
+ TryDominatingOneSide(outerCur, outerNodes.begin()->second);
+ return;
+ }
+ // get outerR & outerL
+ auto outerR = outerNodes.upper_bound(OuterNodeKey(node));
+ if (outerR == outerNodes.end()) outerR = outerNodes.begin();
+ auto outerL = PrevOuterNode(outerR);
+ assert(outerL != outerNodes.end() && outerR != outerNodes.end());
+ assert(outerL->second.rightP == outerR->second.leftP);
+ // try dominating twice
+ TryDominatingOneSide(outerCur, outerL->second);
+ TryDominatingOneSide(outerCur, outerR->second);
}
// suppose no case of [node = min(node, an outer node)]
-void RsaBuilder::AddAnOuterNode(const shared_ptr<TreeNode>& node)
-{
- OuterNode outer_cur(node);
- if (!outer_nodes.empty()) {
- // get outer_right & outer_left
- auto outer_right = outer_nodes.upper_bound(OuterNodeKey(node));
- if (outer_right == outer_nodes.end())
- outer_right = outer_nodes.begin();
- auto outer_left = PrevOuterNode(outer_right);
- assert(outer_left != outer_nodes.end() && outer_right != outer_nodes.end());
- assert(outer_left->second.right_parent == outer_right->second.left_parent);
- // delete parent(outer_right, outer_left)
- if (outer_left->second.right_parent) {
- inner_nodes.erase(outer_left->second.right_parent);
- delete outer_left->second.right_parent; // inner parent become invalid now
+void RsaBuilder::AddAnOuterNode(const shared_ptr<TreeNode>& node) {
+ OuterNode outerCur(node);
+ if (!outerNodes.empty()) {
+ // get outerR & outerL
+ auto outerR = outerNodes.upper_bound(OuterNodeKey(node));
+ if (outerR == outerNodes.end()) outerR = outerNodes.begin();
+ auto outerL = PrevOuterNode(outerR);
+ assert(outerL != outerNodes.end() && outerR != outerNodes.end());
+ assert(outerL->second.rightP == outerR->second.leftP);
+ // delete parent(outerR, outerL)
+ if (outerL->second.rightP) {
+ innerNodes.erase(outerL->second.rightP);
+ delete outerL->second.rightP; // inner parent become invalid now
+ }
+ // add two parents
+ TryMaxOvlpSteinerNode(outerL->second, outerCur);
+ TryMaxOvlpSteinerNode(outerCur, outerR->second);
}
- // add two parents
- TryMaxOvlpSteinerNode(outer_left->second, outer_cur);
- TryMaxOvlpSteinerNode(outer_cur, outer_right->second);
- }
- outer_nodes.insert({OuterNodeKey(node), outer_cur});
+ outerNodes.insert({OuterNodeKey(node), outerCur});
}
-void RsaBuilder::PrintInnerNodes()
-{
- cout << "Inner nodes (# = " << inner_nodes.size() << ")" << endl;
- for (auto in : inner_nodes) {
- cout << in->tn;
- }
+void RsaBuilder::PrintInnerNodes() {
+ cout << "Inner nodes (# = " << innerNodes.size() << ")" << endl;
+ for (auto in : innerNodes) {
+ cout << in->tn;
+ }
}
-void RsaBuilder::PrintOuterNodes()
-{
- cout << "Outer nodes (# = " << outer_nodes.size() << ")" << endl;
- for (auto on : outer_nodes) {
- cout << on.second.cur;
- }
+void RsaBuilder::PrintOuterNodes() {
+ cout << "Outer nodes (# = " << outerNodes.size() << ")" << endl;
+ for (auto on : outerNodes) {
+ cout << on.second.cur;
+ }
}
} // namespace salt
\ No newline at end of file
diff --git a/src/third_party/salt/base/rsa.h b/src/third_party/salt/base/rsa.h
index 172829fa..2266ae0a 100644
--- a/src/third_party/salt/base/rsa.h
+++ b/src/third_party/salt/base/rsa.h
@@ -1,91 +1,85 @@
#pragma once
+#include "tree.h"
+
#include <cmath>
#include <map>
#include <set>
-#include "tree.h"
-
namespace salt {
-class RSABase
-{
- public:
- void ReplaceRootChildren(Tree& tree);
- virtual void Run(const Net& net, Tree& tree) = 0;
+class RsaBase {
+public:
+ void ReplaceRootChildren(Tree& tree);
+ virtual void Run(const Net& net, Tree& tree) = 0;
- protected:
- DTYPE MaxOvlp(DTYPE z1, DTYPE z2);
+protected:
+ DTYPE MaxOvlp(DTYPE z1, DTYPE z2);
};
// Inner Node: an inner node alway has two child (outer) nodes
// tn->children[0]: smaller angle, clockwise, left
// tn->children[1]: larger angle, counter clockwise, right
-class InnerNode
-{
- public:
- unsigned id;
- shared_ptr<TreeNode> tn;
- DTYPE dist;
- double angle; // [-pi, pi]
- InnerNode(const shared_ptr<TreeNode>& treeNode) : tn(treeNode), dist(abs(tn->loc.x) + abs(tn->loc.y)), angle(atan2(tn->loc.y, tn->loc.x))
- {
- static unsigned gid = 0;
- id = gid++;
- } // use id instead of pointer to make it deterministic
+class InnerNode {
+public:
+ unsigned id;
+ shared_ptr<TreeNode> tn;
+ DTYPE dist;
+ double angle; // [-pi, pi]
+ InnerNode(const shared_ptr<TreeNode>& treeNode)
+ : tn(treeNode), dist(abs(tn->loc.x) + abs(tn->loc.y)), angle(atan2(tn->loc.y, tn->loc.x)) {
+ static unsigned gid = 0;
+ id = gid++;
+ } // use id instead of pointer to make it deterministic
};
-class CompInnerNode
-{
- public:
- bool operator()(const InnerNode* a, const InnerNode* b)
- {
- return a->dist > b->dist || // prefer fathest one
- (a->dist == b->dist
- && (a->angle > b->angle || // prefer single direction
- (a->angle == b->angle && a->id > b->id))); // distinguish two nodes with same loc (not touched normally)
- }
+class CompInnerNode {
+public:
+ bool operator()(const InnerNode* a, const InnerNode* b) {
+ return a->dist > b->dist || // prefer fathest one
+ (a->dist == b->dist && (a->angle > b->angle || // prefer single direction
+ (a->angle == b->angle &&
+ a->id > b->id))); // distinguish two nodes with same loc (not touched normally)
+ }
};
// Outer Node: an outer node has one or two parent (inner) nodes
-class OuterNode
-{
- public:
- shared_ptr<TreeNode> cur; // itself
- InnerNode *left_parent, *right_parent; // left parent, right parent
- OuterNode(const shared_ptr<TreeNode>& c, InnerNode* l = nullptr, InnerNode* r = nullptr) : cur(c), left_parent(l), right_parent(r) {}
+class OuterNode {
+public:
+ shared_ptr<TreeNode> cur; // itself
+ InnerNode *leftP, *rightP; // left parent, right parent
+ OuterNode(const shared_ptr<TreeNode>& c, InnerNode* l = nullptr, InnerNode* r = nullptr) : cur(c), leftP(l), rightP(r) {}
};
// RSA Builder
-class RsaBuilder : public RSABase
-{
- public:
- void Run(const Net& net, Tree& tree);
+class RsaBuilder : public RsaBase {
+public:
+ void Run(const Net& net, Tree& tree);
- private:
- // inner nodes
- set<InnerNode*, CompInnerNode> inner_nodes;
+private:
+ // inner nodes
+ set<InnerNode*, CompInnerNode> innerNodes;
- // outer nodes
- map<double, OuterNode> outer_nodes;
- // the unique key is always guaranteed, better for query/find by key
- inline double OuterNodeKey(const shared_ptr<TreeNode>& tn) { return atan2(tn->loc.y, tn->loc.x); }
- // larger angle, counter clockwise, right
- map<double, OuterNode>::iterator NextOuterNode(const map<double, OuterNode>::iterator& it);
- // smaller angle, clockwise, left
- map<double, OuterNode>::iterator PrevOuterNode(const map<double, OuterNode>::iterator& it);
+ // outer nodes
+ map<double, OuterNode> outerNodes;
+ // the unique key is always guaranteed, better for query/find by key
+ inline double OuterNodeKey(const shared_ptr<TreeNode>& tn) { return atan2(tn->loc.y, tn->loc.x); }
+ // larger angle, counter clockwise, right
+ map<double, OuterNode>::iterator NextOuterNode(const map<double, OuterNode>::iterator& it);
+ // smaller angle, clockwise, left
+ map<double, OuterNode>::iterator PrevOuterNode(const map<double, OuterNode>::iterator& it);
- // remove an outer node
- bool TryMaxOvlpSteinerNode(OuterNode& left, OuterNode& right); // maximize the overlapping
- void RemoveAnOuterNode(const shared_ptr<TreeNode>& node, bool del_left = true, bool del_right = true);
+ // remove an outer node
+ bool TryMaxOvlpSteinerNode(OuterNode& left, OuterNode& right); // maximize the overlapping
+ void RemoveAnOuterNode(const shared_ptr<TreeNode>& node, bool delL = true, bool delR = true);
- // add an outer node
- bool TryDominatingOneSide(OuterNode& p, OuterNode& c);
- void TryDominating(const shared_ptr<TreeNode>& node);
- void AddAnOuterNode(const shared_ptr<TreeNode>& node);
+ // add an outer node
+ bool TryDominatingOneSide(OuterNode& p, OuterNode& c);
+ void TryDominating(const shared_ptr<TreeNode>& node);
+ void AddAnOuterNode(const shared_ptr<TreeNode>& node);
- // for debug
- void PrintInnerNodes();
- void PrintOuterNodes();
+ // for debug
+ void PrintInnerNodes();
+ void PrintOuterNodes();
};
} // namespace salt
\ No newline at end of file
diff --git a/src/third_party/salt/base/tree.cpp b/src/third_party/salt/base/tree.cpp
index a8648297..0fa5f8a3 100644
--- a/src/third_party/salt/base/tree.cpp
+++ b/src/third_party/salt/base/tree.cpp
@@ -6,349 +6,310 @@
namespace salt {
-void TreeNode::PrintSingle(ostream& os) const
-{
- os << "Node " << id << ": " << loc << (pin ? ", pin" : "") << ", " << children.size() << " children";
+void TreeNode::PrintSingle(ostream& os) const {
+ os << "Node " << id << ": " << loc << (pin ? ", pin" : "") << ", " << children.size() << " children";
}
-void TreeNode::PrintRecursiveHelp(ostream& os, vector<bool>& prefix) const
-{
- for (auto pre : prefix)
- os << (pre ? " |" : " ");
- if (!prefix.empty())
- os << "-> ";
- PrintSingle(os);
- os << endl;
- if (children.size() > 0) {
- prefix.push_back(true);
- for (size_t i = 0; i < children.size() - 1; ++i) {
- if (children[i])
- children[i]->PrintRecursiveHelp(os, prefix);
- else
- os << "<null>" << endl;
+void TreeNode::PrintRecursiveHelp(ostream& os, vector<bool>& prefix) const {
+ for (auto pre : prefix) os << (pre ? " |" : " ");
+ if (!prefix.empty()) os << "-> ";
+ PrintSingle(os);
+ os << endl;
+ if (children.size() > 0) {
+ prefix.push_back(true);
+ for (size_t i = 0; i < children.size() - 1; ++i) {
+ if (children[i])
+ children[i]->PrintRecursiveHelp(os, prefix);
+ else
+ os << "<null>" << endl;
+ }
+ prefix.back() = false;
+ children.back()->PrintRecursiveHelp(os, prefix);
+ prefix.pop_back();
}
- prefix.back() = false;
- children.back()->PrintRecursiveHelp(os, prefix);
- prefix.pop_back();
- }
}
-void TreeNode::PrintRecursive(ostream& os) const
-{
- vector<bool> prefix; // prefix indicates whether an ancestor is a last child or not
- PrintRecursiveHelp(os, prefix);
+void TreeNode::PrintRecursive(ostream& os) const {
+ vector<bool> prefix; // prefix indicates whether an ancestor is a last child or not
+ PrintRecursiveHelp(os, prefix);
}
-void TreeNode::setParent(const shared_ptr<TreeNode>& childNode, const shared_ptr<TreeNode>& parentNode)
-{
- childNode->parent = parentNode;
- parentNode->children.push_back(childNode);
+void TreeNode::SetParent(const shared_ptr<TreeNode>& childNode, const shared_ptr<TreeNode>& parentNode) {
+ childNode->parent = parentNode;
+ parentNode->children.push_back(childNode);
}
-void TreeNode::resetParent(const shared_ptr<TreeNode>& node)
-{
- assert(node->parent);
+void TreeNode::ResetParent(const shared_ptr<TreeNode>& node) {
+ assert(node->parent);
- auto& n = node->parent->children;
- auto it = find(n.begin(), n.end(), node);
- assert(it != n.end());
- *it = n.back();
- n.pop_back();
+ auto& n = node->parent->children;
+ auto it = find(n.begin(), n.end(), node);
+ assert(it != n.end());
+ *it = n.back();
+ n.pop_back();
- node->parent.reset();
+ node->parent.reset();
}
-void TreeNode::reroot(const shared_ptr<TreeNode>& node)
-{
- if (node->parent) {
- reroot(node->parent);
- auto old_parent = node->parent;
- TreeNode::resetParent(node);
- TreeNode::setParent(old_parent, node);
- }
+void TreeNode::Reroot(const shared_ptr<TreeNode>& node) {
+ if (node->parent) {
+ Reroot(node->parent);
+ auto oldParent = node->parent;
+ TreeNode::ResetParent(node);
+ TreeNode::SetParent(oldParent, node);
+ }
}
-bool TreeNode::isAncestor(const shared_ptr<TreeNode>& ancestor, const shared_ptr<TreeNode>& descendant)
-{
- auto tmp = descendant;
- do {
- if (tmp == ancestor) {
- return true;
- }
- tmp = tmp->parent;
- } while (tmp);
- return false;
+bool TreeNode::IsAncestor(const shared_ptr<TreeNode>& ancestor, const shared_ptr<TreeNode>& descendant) {
+ auto tmp = descendant;
+ do {
+ if (tmp == ancestor) {
+ return true;
+ }
+ tmp = tmp->parent;
+ } while (tmp);
+ return false;
}
-void TreeNode::preOrder(const shared_ptr<TreeNode>& node, const function<void(const shared_ptr<TreeNode>&)>& visit)
-{
- visit(node);
- for (auto c : node->children)
- preOrder(c, visit);
+void TreeNode::PreOrder(const shared_ptr<TreeNode>& node, const function<void(const shared_ptr<TreeNode>&)>& visit) {
+ visit(node);
+ for (auto c : node->children) PreOrder(c, visit);
}
-void TreeNode::postOrder(const shared_ptr<TreeNode>& node, const function<void(const shared_ptr<TreeNode>&)>& visit)
-{
- for (auto c : node->children)
- postOrder(c, visit);
- visit(node);
+void TreeNode::PostOrder(const shared_ptr<TreeNode>& node, const function<void(const shared_ptr<TreeNode>&)>& visit) {
+ for (auto c : node->children) PostOrder(c, visit);
+ visit(node);
}
-void TreeNode::postOrderCopy(const shared_ptr<TreeNode>& node, const function<void(const shared_ptr<TreeNode>&)>& visit)
-{
- auto tmp = node->children;
- for (auto c : tmp)
- postOrderCopy(c, visit);
- visit(node);
+void TreeNode::PostOrderCopy(const shared_ptr<TreeNode>& node, const function<void(const shared_ptr<TreeNode>&)>& visit) {
+ auto tmp = node->children;
+ for (auto c : tmp) PostOrderCopy(c, visit);
+ visit(node);
}
-void Tree::Reset(bool freeTreeNodes)
-{
- if (freeTreeNodes) {
- postOrder([](const shared_ptr<TreeNode>& node) { node->children.clear(); });
- }
- source.reset();
- net = nullptr;
+void Tree::Reset(bool freeTreeNodes) {
+ if (freeTreeNodes) {
+ PostOrder([](const shared_ptr<TreeNode>& node) { node->children.clear(); });
+ }
+ source.reset();
+ net = nullptr;
}
-void Tree::Read(istream& is)
-{
- Net* p_net = new Net;
-
- // header
- string buf, option;
- int num_pin = 0;
- while (is >> buf && buf != "Tree")
- ;
- assert(buf == "Tree");
- getline(is, buf);
- istringstream iss(buf);
- iss >> p_net->id >> p_net->name >> num_pin >> option;
- assert(num_pin > 0);
- p_net->with_cap = (option == "-cap");
-
- // pins
- int i, parent_idx;
- DTYPE x, y;
- double c = 0.0;
- p_net->pins.resize(num_pin);
- vector<int> parent_idxs;
- vector<shared_ptr<TreeNode>> tree_nodes;
- for (auto& pin : p_net->pins) {
- is >> i >> x >> y >> parent_idx;
- assert(i == tree_nodes.size());
- if (p_net->with_cap)
- is >> c;
- pin = make_shared<Pin>(x, y, i, c);
- tree_nodes.push_back(make_shared<TreeNode>(x, y, pin, i));
- parent_idxs.push_back(parent_idx);
- }
- assert(tree_nodes.size() == num_pin);
-
- // non-pin nodes
- getline(is, buf); // consume eol
- streampos pos;
- while (true) {
- pos = is.tellg();
+void Tree::Read(istream& is) {
+ Net* pNet = new Net;
+
+ // header
+ string buf, option;
+ int numPin = 0;
+ while (is >> buf && buf != "Tree")
+ ;
+ assert(buf == "Tree");
getline(is, buf);
- istringstream iss2(buf);
- iss2 >> i >> x >> y >> parent_idx;
- if (iss2.fail())
- break;
- assert(i == tree_nodes.size());
- tree_nodes.push_back(make_shared<TreeNode>(x, y, nullptr, i));
- parent_idxs.push_back(parent_idx);
- }
- is.seekg(pos); // go back
-
- // parents
- for (unsigned i = 0; i < tree_nodes.size(); ++i) {
- parent_idx = parent_idxs[i];
- if (parent_idx >= 0) {
- assert(parent_idx < tree_nodes.size());
- salt::TreeNode::setParent(tree_nodes[i], tree_nodes[parent_idx]);
- } else {
- assert(parent_idx == -1);
- source = tree_nodes[i];
+ istringstream iss(buf);
+ iss >> pNet->id >> pNet->name >> numPin >> option;
+ assert(numPin > 0);
+ pNet->withCap = (option == "-cap");
+
+ // pins
+ int i, parentIdx;
+ DTYPE x, y;
+ double c = 0.0;
+ pNet->pins.resize(numPin);
+ vector<int> parentIdxs;
+ vector<shared_ptr<TreeNode>> treeNodes;
+ for (auto& pin : pNet->pins) {
+ is >> i >> x >> y >> parentIdx;
+ assert(i == treeNodes.size());
+ if (pNet->withCap) is >> c;
+ pin = make_shared<Pin>(x, y, i, c);
+ treeNodes.push_back(make_shared<TreeNode>(x, y, pin, i));
+ parentIdxs.push_back(parentIdx);
+ }
+ assert(treeNodes.size() == numPin);
+
+ // non-pin nodes
+ getline(is, buf); // consume eol
+ streampos pos;
+ while (true) {
+ pos = is.tellg();
+ getline(is, buf);
+ istringstream iss2(buf);
+ iss2 >> i >> x >> y >> parentIdx;
+ if (iss2.fail()) break;
+ assert(i == treeNodes.size());
+ treeNodes.push_back(make_shared<TreeNode>(x, y, nullptr, i));
+ parentIdxs.push_back(parentIdx);
+ }
+ is.seekg(pos); // go back
+
+ // parents
+ for (unsigned i = 0; i < treeNodes.size(); ++i) {
+ parentIdx = parentIdxs[i];
+ if (parentIdx >= 0) {
+ assert(parentIdx < treeNodes.size());
+ salt::TreeNode::SetParent(treeNodes[i], treeNodes[parentIdx]);
+ } else {
+ assert(parentIdx == -1);
+ source = treeNodes[i];
+ }
}
- }
- net = p_net;
- // TODO: check dangling nodes
+ net = pNet;
+ // TODO: check dangling nodes
}
-void Tree::Read(const string& file_name)
-{
- ifstream is(file_name);
- if (is.fail()) {
- cout << "ERROR: Cannot open file " << file_name << endl;
- exit(1);
- }
- Read(is);
+void Tree::Read(const string& fileName) {
+ ifstream is(fileName);
+ if (is.fail()) {
+ cout << "ERROR: Cannot open file " << fileName << endl;
+ exit(1);
+ }
+ Read(is);
}
-void Tree::Write(ostream& os)
-{
- // header
- os << "Tree " << net->GetHeader() << endl;
-
- // nodes
- // Note: source pin may not be covered in some intermediate state
- int num_nodes = UpdateId();
- auto nodes = ObtainNodes();
- vector<shared_ptr<TreeNode>> sorted_nodes(num_nodes, nullptr); // bucket sort
- for (auto node : nodes) {
- sorted_nodes[node->id] = node;
- }
- for (auto node : sorted_nodes) {
- if (!node)
- continue;
- int parentId = node->parent ? node->parent->id : -1;
- os << node->id << " " << node->loc.x << " " << node->loc.y << " " << parentId;
- if (net->with_cap && node->pin)
- os << " " << node->pin->cap;
- os << endl;
- }
+void Tree::Write(ostream& os) {
+ // header
+ os << "Tree " << net->GetHeader() << endl;
+
+ // nodes
+ // Note: source pin may not be covered in some intermediate state
+ int numNodes = UpdateId();
+ auto nodes = ObtainNodes();
+ vector<shared_ptr<TreeNode>> sortedNodes(numNodes, nullptr); // bucket sort
+ for (auto node : nodes) {
+ sortedNodes[node->id] = node;
+ }
+ for (auto node : sortedNodes) {
+ if (!node) continue;
+ int parentId = node->parent ? node->parent->id : -1;
+ os << node->id << " " << node->loc.x << " " << node->loc.y << " " << parentId;
+ if (net->withCap && node->pin) os << " " << node->pin->cap;
+ os << endl;
+ }
}
-void Tree::Write(const string& prefix, bool with_net_info)
-{
- ofstream ofs(prefix + (with_net_info ? ("_" + net->name) : "") + ".tree");
- Write(ofs);
- ofs.close();
+void Tree::Write(const string& prefix, bool withNetInfo) {
+ ofstream ofs(prefix + (withNetInfo ? ("_" + net->name) : "") + ".tree");
+ Write(ofs);
+ ofs.close();
}
-void Tree::Print(ostream& os) const
-{
- os << "Tree ";
- if (net)
- os << net->id << ": #pins=" << net->pins.size() << endl;
- else
- os << "<no_net_associated>" << endl;
- if (source)
- source->PrintRecursive(os);
- else
- os << "<null>" << endl;
+void Tree::Print(ostream& os) const {
+ os << "Tree ";
+ if (net)
+ os << net->id << ": #pins=" << net->pins.size() << endl;
+ else
+ os << "<no_net_associated>" << endl;
+ if (source)
+ source->PrintRecursive(os);
+ else
+ os << "<null>" << endl;
}
-int Tree::UpdateId()
-{
- int num_node = net->pins.size();
- preOrder([&](const shared_ptr<TreeNode>& node) {
- if (node->pin) {
- assert(node->pin->id < net->pins.size());
- node->id = node->pin->id;
- } else
- node->id = num_node++;
- });
- return num_node;
+int Tree::UpdateId() {
+ int numNode = net->pins.size();
+ PreOrder([&](const shared_ptr<TreeNode>& node) {
+ if (node->pin) {
+ assert(node->pin->id < net->pins.size());
+ node->id = node->pin->id;
+ } else
+ node->id = numNode++;
+ });
+ return numNode;
}
-vector<shared_ptr<TreeNode>> Tree::ObtainNodes() const
-{
- vector<shared_ptr<TreeNode>> nodes;
- preOrder([&](const shared_ptr<TreeNode>& node) { nodes.push_back(node); });
- return nodes;
+vector<shared_ptr<TreeNode>> Tree::ObtainNodes() const {
+ vector<shared_ptr<TreeNode>> nodes;
+ PreOrder([&](const shared_ptr<TreeNode>& node) { nodes.push_back(node); });
+ return nodes;
}
-void Tree::SetParentFromChildren()
-{
- preOrder([](const shared_ptr<TreeNode>& node) {
- for (auto& c : node->children) {
- c->parent = node;
- }
- });
+void Tree::SetParentFromChildren() {
+ PreOrder([](const shared_ptr<TreeNode>& node) {
+ for (auto& c : node->children) {
+ c->parent = node;
+ }
+ });
}
-void Tree::SetParentFromUndirectedAdjList()
-{
- preOrder([](const shared_ptr<TreeNode>& node) {
- for (auto& c : node->children) {
- auto& n = c->children;
- auto it = find(n.begin(), n.end(), node);
- assert(it != n.end());
- *it = n.back();
- n.pop_back();
- c->parent = node;
- }
- });
+void Tree::SetParentFromUndirectedAdjList() {
+ PreOrder([](const shared_ptr<TreeNode>& node) {
+ for (auto& c : node->children) {
+ auto& n = c->children;
+ auto it = find(n.begin(), n.end(), node);
+ assert(it != n.end());
+ *it = n.back();
+ n.pop_back();
+ c->parent = node;
+ }
+ });
}
-void Tree::reroot()
-{
- TreeNode::reroot(source);
+void Tree::Reroot() {
+ TreeNode::Reroot(source);
}
-void Tree::QuickCheck()
-{
- int num_pin = net->pins.size(), num_checked = 0;
- vector<bool> pin_exist(num_pin, false);
- preOrder([&](const shared_ptr<TreeNode>& node) {
- if (!node) {
- cerr << "Error: empty node" << endl;
+void Tree::QuickCheck() {
+ int numPin = net->pins.size(), numChecked = 0;
+ vector<bool> pinExist(numPin, false);
+ PreOrder([&](const shared_ptr<TreeNode>& node) {
+ if (!node) {
+ cerr << "Error: empty node" << endl;
+ }
+ if (node->pin) {
+ auto id = node->pin->id;
+ if (!(id >= 0 && id < numPin && pinExist[id] == false)) {
+ cerr << "Error: Steiner node with incorrect id" << endl;
+ }
+ pinExist[id] = true;
+ ++numChecked;
+ }
+ for (auto& c : node->children) {
+ if (!c->parent || c->parent != node) {
+ cerr << "Error: inconsistent parent-child relationship" << endl;
+ }
+ }
+ });
+ if (numChecked != numPin) {
+ cerr << "Error: pin not covered" << endl;
}
- if (node->pin) {
- auto id = node->pin->id;
- if (!(id >= 0 && id < num_pin && pin_exist[id] == false)) {
- cerr << "Error: Steiner node with incorrect id" << endl;
- }
- pin_exist[id] = true;
- ++num_checked;
- }
- for (auto& c : node->children) {
- if (!c->parent || c->parent != node) {
- cerr << "Error: inconsistent parent-child relationship" << endl;
- }
- }
- });
- if (num_checked != num_pin) {
- cerr << "Error: pin not covered" << endl;
- }
}
-void Tree::RemovePhyRedundantSteiner()
-{
- postOrderCopy([](const shared_ptr<TreeNode>& node) {
- if (!node->parent || node->loc != node->parent->loc)
- return;
- if (node->pin) {
- if (node->parent->pin && node->parent->pin != node->pin)
- return;
- node->parent->pin = node->pin;
- }
- for (auto c : node->children)
- TreeNode::setParent(c, node->parent);
- TreeNode::resetParent(node);
- });
+void Tree::RemovePhyRedundantSteiner() {
+ PostOrderCopy([](const shared_ptr<TreeNode>& node) {
+ if (!node->parent || node->loc != node->parent->loc) return;
+ if (node->pin) {
+ if (node->parent->pin && node->parent->pin != node->pin) return;
+ node->parent->pin = node->pin;
+ }
+ for (auto c : node->children) TreeNode::SetParent(c, node->parent);
+ TreeNode::ResetParent(node);
+ });
}
-void Tree::RemoveTopoRedundantSteiner()
-{
- postOrderCopy([](const shared_ptr<TreeNode>& node) {
- // degree may change after post-order traversal of its children
- if (node->pin)
- return;
- if (node->children.empty()) {
- TreeNode::resetParent(node);
- } else if (node->children.size() == 1) {
- auto old_parent = node->parent, oldChild = node->children[0];
- TreeNode::resetParent(node);
- TreeNode::resetParent(oldChild);
- TreeNode::setParent(oldChild, old_parent);
- }
- });
+void Tree::RemoveTopoRedundantSteiner() {
+ PostOrderCopy([](const shared_ptr<TreeNode>& node) {
+ // degree may change after post-order traversal of its children
+ if (node->pin) return;
+ if (node->children.empty()) {
+ TreeNode::ResetParent(node);
+ } else if (node->children.size() == 1) {
+ auto oldParent = node->parent, oldChild = node->children[0];
+ TreeNode::ResetParent(node);
+ TreeNode::ResetParent(oldChild);
+ TreeNode::SetParent(oldChild, oldParent);
+ }
+ });
}
-void Tree::RemoveEmptyChildren()
-{
- preOrder([](const shared_ptr<TreeNode>& node) {
- int size = 0;
- for (int i = 0; i < node->children.size(); ++i) {
- if (node->children[i])
- node->children[size++] = node->children[i];
- }
- node->children.resize(size);
- });
+void Tree::RemoveEmptyChildren() {
+ PreOrder([](const shared_ptr<TreeNode>& node) {
+ int size = 0;
+ for (int i = 0; i < node->children.size(); ++i) {
+ if (node->children[i]) node->children[size++] = node->children[i];
+ }
+ node->children.resize(size);
+ });
}
} // namespace salt
\ No newline at end of file
diff --git a/src/third_party/salt/base/tree.h b/src/third_party/salt/base/tree.h
index 8fde2af2..f66880e7 100644
--- a/src/third_party/salt/base/tree.h
+++ b/src/third_party/salt/base/tree.h
@@ -1,132 +1,102 @@
#pragma once
-#include <functional>
-
#include "net.h"
+#include <functional>
+
namespace salt {
-class TreeNode
-{
- public:
- Point loc;
- shared_ptr<Pin> pin; // nullptr if it is not a pin
- int id;
- vector<shared_ptr<TreeNode>> children; // empty for leaf
- shared_ptr<TreeNode> parent; // nullptr for source
-
- // Constructors
- TreeNode(const Point& l = Point(), shared_ptr<Pin> p = nullptr, int i = -1) : loc(l), pin(p), id(i) {}
- TreeNode(DTYPE x, DTYPE y, shared_ptr<Pin> p = nullptr, int i = -1) : loc(x, y), pin(p), id(i) {}
- TreeNode(shared_ptr<Pin> p) : loc(p->loc), pin(p), id(p->id) {}
-
- // Accessors
- DTYPE WireToParent() const { return Dist(loc, parent->loc); }
- DTYPE WireToParentChecked() const { return parent ? WireToParent() : 0.0; }
-
- // Hunman-readable print
- void PrintSingle(ostream& os = cout) const;
- void PrintRecursiveHelp(ostream& os, vector<bool>& prefix) const; // hunman-readable print
- void PrintRecursive(ostream& os = cout) const;
- friend ostream& operator<<(ostream& os, const TreeNode& node)
- {
- node.PrintRecursive(os);
- return os;
- }
-
- // Set/reset/check parent/ancestor
- static void setParent(const shared_ptr<TreeNode>& childNode, const shared_ptr<TreeNode>& parentNode);
- static void resetParent(const shared_ptr<TreeNode>& node);
- static void reroot(const shared_ptr<TreeNode>& node);
- static bool isAncestor(const shared_ptr<TreeNode>& ancestor, const shared_ptr<TreeNode>& descendant);
-
- // Traverse
- static void preOrder(const shared_ptr<TreeNode>& node, const function<void(const shared_ptr<TreeNode>&)>& visit);
- static void postOrder(const shared_ptr<TreeNode>& node, const function<void(const shared_ptr<TreeNode>&)>& visit);
- static void postOrderCopy(const shared_ptr<TreeNode>& node, const function<void(const shared_ptr<TreeNode>&)>& visit);
+class TreeNode {
+public:
+ int id;
+ shared_ptr<Pin> pin; // nullptr if it is not a pin
+ Point loc;
+ vector<shared_ptr<TreeNode>> children; // empty for leaf
+ shared_ptr<TreeNode> parent; // nullptr for source
+
+ // Constructors
+ TreeNode(const Point& l = Point(), shared_ptr<Pin> p = nullptr, int i = -1) : loc(l), pin(p), id(i) {}
+ TreeNode(DTYPE x, DTYPE y, shared_ptr<Pin> p = nullptr, int i = -1) : loc(x, y), pin(p), id(i) {}
+ TreeNode(shared_ptr<Pin> p) : loc(p->loc), pin(p), id(p->id) {}
+
+ // Accessors
+ DTYPE WireToParent() const { return Dist(loc, parent->loc); }
+ DTYPE WireToParentChecked() const { return parent ? WireToParent() : 0.0; }
+
+ // Hunman-readable print
+ void PrintSingle(ostream& os = cout) const;
+ void PrintRecursiveHelp(ostream& os, vector<bool>& prefix) const; // hunman-readable print
+ void PrintRecursive(ostream& os = cout) const;
+ friend ostream& operator<<(ostream& os, const TreeNode& node) { node.PrintRecursive(os); return os; }
+
+ // Set/reset/check parent/ancestor
+ static void SetParent(const shared_ptr<TreeNode>& childNode, const shared_ptr<TreeNode>& parentNode);
+ static void ResetParent(const shared_ptr<TreeNode>& node);
+ static void Reroot(const shared_ptr<TreeNode>& node);
+ static bool IsAncestor(const shared_ptr<TreeNode>& ancestor, const shared_ptr<TreeNode>& descendant);
+
+ // Traverse
+ static void PreOrder(const shared_ptr<TreeNode>& node, const function<void(const shared_ptr<TreeNode>&)>& visit);
+ static void PostOrder(const shared_ptr<TreeNode>& node, const function<void(const shared_ptr<TreeNode>&)>& visit);
+ static void PostOrderCopy(const shared_ptr<TreeNode>& node, const function<void(const shared_ptr<TreeNode>&)>& visit);
};
-class Tree
-{
- public:
- shared_ptr<TreeNode> source;
- const Net* net;
-
- // Note: take care when using copy assign operator and copy constructor. use swap().
- Tree(const shared_ptr<TreeNode>& sourceNode = nullptr, const Net* associatedNet = nullptr) : source(sourceNode), net(associatedNet) {}
- void Reset(bool freeTreeNodes = true);
- ~Tree() { Reset(); }
-
- // File read/write
- // ------
- // Format:
- // Tree <net_id> <net_name> <pin_num> [-cap]
- // 0 x0 y0 -1 [cap0]
- // 1 x1 y1 parent_idx1 [cap1]
- // 2 x2 y2 parent_idx2 [cap2]
- // ...
- // k xk yk parent_idxk
- // ...
- // ------
- // Notes:
- // 1. Nodes with indexes [0, pin_num) are pins, others are Steiner
- // 2. Steiner nodes have no cap
- void Read(istream& is);
- void Read(const string& file_name);
- void Write(ostream& os); // TODO: const? but UpdateId
- void Write(const string& prefix, bool with_net_info = true);
-
- // Hunman-readable print
- void Print(ostream& os = cout) const;
- friend ostream& operator<<(ostream& os, const Tree& tree)
- {
- tree.Print(os);
- return os;
- }
-
- // Traverse
- void preOrder(const function<void(const shared_ptr<TreeNode>&)>& visit)
- {
- if (source)
- TreeNode::preOrder(source, visit);
- }
- void postOrder(const function<void(const shared_ptr<TreeNode>&)>& visit)
- {
- if (source)
- TreeNode::postOrder(source, visit);
- }
- void postOrderCopy(const function<void(const shared_ptr<TreeNode>&)>& visit)
- {
- if (source)
- TreeNode::postOrderCopy(source, visit);
- }
- void preOrder(const function<void(const shared_ptr<TreeNode>&)>& visit) const
- {
- if (source)
- TreeNode::preOrder(source, visit);
- }
- void postOrder(const function<void(const shared_ptr<TreeNode>&)>& visit) const
- {
- if (source)
- TreeNode::postOrder(source, visit);
- }
-
- // Flatten
- int UpdateId(); // update node ids to [0, nodeNum), return nodeNum
- vector<shared_ptr<TreeNode>> ObtainNodes() const;
-
- // Legalize parent-child relationship
- void SetParentFromChildren();
- void SetParentFromUndirectedAdjList();
- void reroot();
- void QuickCheck(); // check parent-child and pin coverage
-
- // Remove redundant Steiner nodes
- void RemovePhyRedundantSteiner(); // remove physically redudant ones (i.e., with the same locatoin of a pin)
- void RemoveTopoRedundantSteiner(); // remove topologically redudant ones (i.e., with 0/1 children)
-
- // Remove empty children
- void RemoveEmptyChildren();
+class Tree {
+public:
+ shared_ptr<TreeNode> source;
+ const Net* net;
+
+ // Note: take care when using copy assign operator and copy constructor. use swap().
+ Tree(const shared_ptr<TreeNode>& sourceNode = nullptr, const Net* associatedNet = nullptr) : source(sourceNode), net(associatedNet) {}
+ void Reset(bool freeTreeNodes = true);
+ ~Tree() { Reset(); }
+
+ // File read/write
+ // ------
+ // Format:
+ // Tree <net_id> <net_name> <pin_num> [-cap]
+ // 0 x0 y0 -1 [cap0]
+ // 1 x1 y1 parent_idx1 [cap1]
+ // 2 x2 y2 parent_idx2 [cap2]
+ // ...
+ // k xk yk parent_idxk
+ // ...
+ // ------
+ // Notes:
+ // 1. Nodes with indexes [0, pin_num) are pins, others are Steiner
+ // 2. Steiner nodes have no cap
+ void Read(istream& is);
+ void Read(const string& fileName);
+ void Write(ostream& os); // TODO: const? but UpdateId
+ void Write(const string& prefix, bool withNetInfo = true);
+
+ // Hunman-readable print
+ void Print(ostream& os = cout) const;
+ friend ostream& operator<<(ostream& os, const Tree& tree) { tree.Print(os); return os; }
+
+ // Traverse
+ void PreOrder(const function<void(const shared_ptr<TreeNode>&)>& visit) { if (source) TreeNode::PreOrder(source, visit); }
+ void PostOrder(const function<void(const shared_ptr<TreeNode>&)>& visit) { if (source) TreeNode::PostOrder(source, visit); }
+ void PostOrderCopy(const function<void(const shared_ptr<TreeNode>&)>& visit) { if (source) TreeNode::PostOrderCopy(source, visit); }
+ void PreOrder(const function<void(const shared_ptr<TreeNode>&)>& visit) const { if (source) TreeNode::PreOrder(source, visit); }
+ void PostOrder(const function<void(const shared_ptr<TreeNode>&)>& visit) const { if (source) TreeNode::PostOrder(source, visit); }
+
+ // Flatten
+ int UpdateId(); // update node ids to [0, nodeNum), return nodeNum
+ vector<shared_ptr<TreeNode>> ObtainNodes() const;
+
+ // Legalize parent-child relationship
+ void SetParentFromChildren();
+ void SetParentFromUndirectedAdjList();
+ void Reroot();
+ void QuickCheck(); // check parent-child and pin coverage
+
+ // Remove redundant Steiner nodes
+ void RemovePhyRedundantSteiner(); // remove physically redudant ones (i.e., with the same locatoin of a pin)
+ void RemoveTopoRedundantSteiner(); // remove topologically redudant ones (i.e., with 0/1 children)
+
+ // Remove empty children
+ void RemoveEmptyChildren();
};
} // namespace salt
\ No newline at end of file
diff --git a/src/third_party/salt/refine/cancel_intersect.cpp b/src/third_party/salt/refine/cancel_intersect.cpp
index f79b7b0e..1e17da44 100644
--- a/src/third_party/salt/refine/cancel_intersect.cpp
+++ b/src/third_party/salt/refine/cancel_intersect.cpp
@@ -96,16 +96,16 @@ void Cancel(array<shared_ptr<TreeNode>, 2> oric) {
auto rootN = oric[1 - minD]->parent;
shared_ptr<TreeNode> mergeN = nullptr;
for (int d = 0; d < 2; ++d) {
- TreeNode::resetParent(oric[d]);
+ TreeNode::ResetParent(oric[d]);
if (oric[d]->loc == cclosest[d]) mergeN = oric[d];
}
if (!mergeN) mergeN = make_shared<TreeNode>(cclosest[minD]);
- TreeNode::setParent(mergeN, rootN);
+ TreeNode::SetParent(mergeN, rootN);
for (int d = 0; d < 2; ++d)
- if (oric[d] != mergeN) TreeNode::setParent(oric[d], mergeN);
+ if (oric[d] != mergeN) TreeNode::SetParent(oric[d], mergeN);
}
-void Refine::cancelIntersect(Tree& tree) {
+void Refine::CancelIntersect(Tree& tree) {
bgi::rtree<RNode, bgi::linear<16>, bgi::indexable<RNode>, RNodeComp> rtree;
auto nodes = tree.ObtainNodes();
for (int i = 0; i < nodes.size(); ++i) {
diff --git a/src/third_party/salt/refine/flip.cpp b/src/third_party/salt/refine/flip.cpp
index 5dad3766..fca59b4c 100644
--- a/src/third_party/salt/refine/flip.cpp
+++ b/src/third_party/salt/refine/flip.cpp
@@ -27,10 +27,10 @@ void UpdateNode(const shared_ptr<TreeNode> node, // central node
const vector<array<DTYPE, 2>>& gains, // the gain of each child
int i, // current child
array<vector<DTYPE>, 4>& segs, // segments in each direction
- DTYPE acc_gain, // gain accumulated by now
+ DTYPE accGain, // gain accumulated by now
DTYPE& bestGain, // best gain
- vector<bool>& low_or_up, // each child edge is low or up
- vector<bool>& best_low_or_up // each child edge is low or up for best gain
+ vector<bool>& lowOrUp, // each child edge is low or up
+ vector<bool>& bestLowOrUp // each child edge is low or up for best gain
) {
if (i == node->children.size()) { // get to the end of enumeration
for (int j = 0; j < 4; ++j) {
@@ -38,49 +38,49 @@ void UpdateNode(const shared_ptr<TreeNode> node, // central node
DTYPE max = 0;
for (auto len : segs[j]) {
if (len > max) {
- acc_gain += max;
+ accGain += max;
max = len;
} else
- acc_gain += len;
+ accGain += len;
}
}
- if (acc_gain > bestGain) {
- bestGain = acc_gain;
- for (auto c : node->children) best_low_or_up[c->id] = low_or_up[c->id];
+ if (accGain > bestGain) {
+ bestGain = accGain;
+ for (auto c : node->children) bestLowOrUp[c->id] = lowOrUp[c->id];
}
} else if (align[i]) { // already consider, pass this child
- UpdateNode(node, align, gains, i + 1, segs, acc_gain, bestGain, low_or_up, best_low_or_up);
+ UpdateNode(node, align, gains, i + 1, segs, accGain, bestGain, lowOrUp, bestLowOrUp);
} else { // make a branch because this node-child edge can be L/U
int dir;
DTYPE dist;
bool low = true; // L/U
for (int j = 0; j < 2; ++j) {
GetDirId(node->children[i]->loc, node->loc, low, dir, dist);
- acc_gain += gains[i][j];
+ accGain += gains[i][j];
segs[dir].push_back(dist);
- low_or_up[node->children[i]->id] = low;
- UpdateNode(node, align, gains, i + 1, segs, acc_gain, bestGain, low_or_up, best_low_or_up);
- acc_gain -= gains[i][j];
+ lowOrUp[node->children[i]->id] = low;
+ UpdateNode(node, align, gains, i + 1, segs, accGain, bestGain, lowOrUp, bestLowOrUp);
+ accGain -= gains[i][j];
segs[dir].pop_back();
low = false; // L/U
}
}
}
-void UpdateSubTree(const shared_ptr<TreeNode> node, array<DTYPE, 2>& res, array<vector<bool>, 2>& best_low_or_up) {
+void UpdateSubTree(const shared_ptr<TreeNode> node, array<DTYPE, 2>& res, array<vector<bool>, 2>& bestLowOrUp) {
res = {0, 0}; // low, up
if (node->children.empty()) return;
// Calc gains of children
unsigned nc = node->children.size();
vector<array<DTYPE, 2>> gains(nc);
- for (unsigned i = 0; i < nc; ++i) UpdateSubTree(node->children[i], gains[i], best_low_or_up);
+ for (unsigned i = 0; i < nc; ++i) UpdateSubTree(node->children[i], gains[i], bestLowOrUp);
// Process aligned children
vector<bool> align(nc, false);
array<vector<DTYPE>, 4> segs;
- DTYPE acc_gain = 0;
- vector<bool> low_or_up(best_low_or_up[0].size());
+ DTYPE accGain = 0;
+ vector<bool> lowOrUp(bestLowOrUp[0].size());
for (unsigned i = 0; i < nc; ++i) {
Point &a = node->children[i]->loc, b = node->loc;
if (a.x == b.x || a.y == b.y) {
@@ -89,7 +89,7 @@ void UpdateSubTree(const shared_ptr<TreeNode> node, array<DTYPE, 2>& res, array<
GetDirId(a, node->loc, true, dir, dist);
segs[dir].push_back(dist);
align[i] = true; // no need for further processing
- acc_gain += gains[i][0];
+ accGain += gains[i][0];
}
}
@@ -101,12 +101,12 @@ void UpdateSubTree(const shared_ptr<TreeNode> node, array<DTYPE, 2>& res, array<
for (int j = 0; j < 2; ++j) {
GetDirId(node->parent->loc, node->loc, low, dir, dist);
segs[dir].push_back(dist);
- UpdateNode(node, align, gains, 0, segs, acc_gain, res[j], low_or_up, best_low_or_up[j]);
+ UpdateNode(node, align, gains, 0, segs, accGain, res[j], lowOrUp, bestLowOrUp[j]);
segs[dir].pop_back();
low = false; // L/U
}
} else // for source node, update res[0] only
- UpdateNode(node, align, gains, 0, segs, acc_gain, res[0], low_or_up, best_low_or_up[0]);
+ UpdateNode(node, align, gains, 0, segs, accGain, res[0], lowOrUp, bestLowOrUp[0]);
// cout<<*node->pin<<", low="<<res[0]<<", up="<<res[1]<<endl;
}
@@ -124,16 +124,16 @@ void AddNode(shared_ptr<TreeNode> c1, shared_ptr<TreeNode> c2, shared_ptr<TreeNo
if (c1->parent == c2) swap(c1, c2); // make sure (c1>=c2)
assert(c2->parent == c1 && c1->parent == p);
}
- TreeNode::resetParent(c1);
- TreeNode::setParent(c1, steiner);
- TreeNode::resetParent(c2);
- TreeNode::setParent(c2, steiner);
- TreeNode::setParent(steiner, p);
+ TreeNode::ResetParent(c1);
+ TreeNode::SetParent(c1, steiner);
+ TreeNode::ResetParent(c2);
+ TreeNode::SetParent(c2, steiner);
+ TreeNode::SetParent(steiner, p);
}
-int gDir[4] = {0, 0, 1, 1}; // down, up, left, right
+int dir2xy[4] = {0, 0, 1, 1}; // down, up, left, right
-void TraverseAndAddSteiner(const shared_ptr<TreeNode>& node, bool low, array<vector<bool>, 2>& best_low_or_up) {
+void TraverseAndAddSteiner(const shared_ptr<TreeNode>& node, bool low, array<vector<bool>, 2>& bestLowOrUp) {
// cout<<node->id<<(low?" low":" up")<<endl;
// node->Print(0,true);
if (node->children.empty()) return;
@@ -141,7 +141,7 @@ void TraverseAndAddSteiner(const shared_ptr<TreeNode>& node, bool low, array<vec
// go down first
int luid = low ? 0 : 1;
auto children_cpy = node->children; // it may be chagned later
- for (auto c : children_cpy) TraverseAndAddSteiner(c, best_low_or_up[luid][c->id], best_low_or_up);
+ for (auto c : children_cpy) TraverseAndAddSteiner(c, bestLowOrUp[luid][c->id], bestLowOrUp);
// get overlap info
array<vector<pair<int, shared_ptr<TreeNode>>>, 4> dist2node; // for four directions
@@ -153,12 +153,12 @@ void TraverseAndAddSteiner(const shared_ptr<TreeNode>& node, bool low, array<vec
}
for (auto c : node->children) {
if (c->id == -1) continue;
- GetDirId(c->loc, node->loc, best_low_or_up[luid][c->id], dir, dist);
+ GetDirId(c->loc, node->loc, bestLowOrUp[luid][c->id], dir, dist);
dist2node[dir].emplace_back(dist, c);
}
// add steiner point
- auto ori_parent = node->parent;
+ auto oriParent = node->parent;
for (dir = 0; dir < 4; ++dir) {
auto& cands = dist2node[dir];
if (cands.size() <= 1) continue;
@@ -171,7 +171,7 @@ void TraverseAndAddSteiner(const shared_ptr<TreeNode>& node, bool low, array<vec
auto out = cands[0].second;
for (int cid = 1; cid < cands.size(); ++cid) {
- int xy = gDir[dir];
+ int xy = dir2xy[dir];
Point p;
p[xy] = node->loc[xy];
p[1 - xy] = cands[cid].second->loc[1 - xy];
@@ -182,16 +182,16 @@ void TraverseAndAddSteiner(const shared_ptr<TreeNode>& node, bool low, array<vec
}
}
-void Refine::flip(Tree& tree) {
+void Refine::Flip(Tree& tree) {
WireLengthEvalBase cur(tree), pre;
do {
pre = cur;
array<DTYPE, 2> g; // low, up
- int num_node = tree.UpdateId();
- array<vector<bool>, 2> best_low_or_up = {vector<bool>(num_node), vector<bool>(num_node)};
- UpdateSubTree(tree.source, g, best_low_or_up);
- TraverseAndAddSteiner(tree.source, true, best_low_or_up);
+ int numNode = tree.UpdateId();
+ array<vector<bool>, 2> bestLowOrUp = {vector<bool>(numNode), vector<bool>(numNode)};
+ UpdateSubTree(tree.source, g, bestLowOrUp);
+ TraverseAndAddSteiner(tree.source, true, bestLowOrUp);
tree.RemovePhyRedundantSteiner();
cur.Update(tree);
} while (cur.wireLength < pre.wireLength);
diff --git a/src/third_party/salt/refine/refine.h b/src/third_party/salt/refine/refine.h
index 370e2cf9..c7a37e42 100644
--- a/src/third_party/salt/refine/refine.h
+++ b/src/third_party/salt/refine/refine.h
@@ -4,13 +4,12 @@
namespace salt {
-class Refine
-{
- public:
- static void cancelIntersect(Tree& tree);
- static void flip(Tree& tree);
- static void uShift(Tree& tree); // should be after flip to achieve good quality
- static void substitute(Tree& tree, double eps, bool useRTree = true);
+class Refine {
+public:
+ static void CancelIntersect(Tree& tree);
+ static void Flip(Tree& tree);
+ static void UShift(Tree& tree); // should be after Flip to achieve good quality
+ static void Substitute(Tree& tree, double eps, bool useRTree = true);
};
} // namespace salt
\ No newline at end of file
diff --git a/src/third_party/salt/refine/substitute.cpp b/src/third_party/salt/refine/substitute.cpp
index bb90fead..02083af4 100644
--- a/src/third_party/salt/refine/substitute.cpp
+++ b/src/third_party/salt/refine/substitute.cpp
@@ -1,12 +1,13 @@
+#include "refine.h"
+
+#include "salt/base/eval.h"
+#include "salt/base/mst.h"
+
#include <boost/geometry.hpp>
#include <boost/geometry/geometries/point.hpp>
#include <boost/geometry/geometries/segment.hpp>
#include <boost/geometry/index/rtree.hpp>
-#include "refine.h"
-#include "salt/base/eval.h"
-#include "salt/base/mst.h"
-
namespace salt {
namespace bg = boost::geometry;
@@ -17,216 +18,216 @@ using BSegment = bg::model::segment<BPoint>;
using BBox = bg::model::box<BPoint>;
using BPolygon = bg::model::polygon<BPoint>;
using RNode = pair<BBox, shared_ptr<TreeNode>>; // R-Tree node
-struct RNodeComp
-{
- bool operator()(const RNode& l, const RNode& r) const { return bg::equals(l.first, r.first) && l.second == r.second; }
+struct RNodeComp {
+ bool operator()(const RNode& l, const RNode& r) const {
+ return bg::equals(l.first, r.first) && l.second == r.second;
+ }
};
-void Refine::substitute(Tree& tree, double eps, bool useRTree)
-{
- bgi::rtree<RNode, bgi::rstar<8>, bgi::indexable<RNode>, RNodeComp> rtree;
- if (useRTree) {
- tree.postOrder([&](const shared_ptr<TreeNode>& n) {
- if (n->parent) {
- BBox s;
- bg::envelope(BSegment(BPoint(n->loc.x, n->loc.y), BPoint(n->parent->loc.x, n->parent->loc.y)), s);
- rtree.insert({s, n});
- }
- });
- }
- auto disconnect = [&](const shared_ptr<TreeNode>& n) {
+void Refine::Substitute(Tree& tree, double eps, bool useRTree) {
+ bgi::rtree<RNode, bgi::rstar<8>, bgi::indexable<RNode>, RNodeComp> rtree;
if (useRTree) {
- BBox s;
- bg::envelope(BSegment(BPoint(n->loc.x, n->loc.y), BPoint(n->parent->loc.x, n->parent->loc.y)), s);
- rtree.remove({s, n});
+ tree.PostOrder([&](const shared_ptr<TreeNode>& n) {
+ if (n->parent) {
+ BBox s;
+ bg::envelope(BSegment(BPoint(n->loc.x, n->loc.y), BPoint(n->parent->loc.x, n->parent->loc.y)), s);
+ rtree.insert({s, n});
+ }
+ });
}
- TreeNode::resetParent(n);
- };
- auto connect = [&](const shared_ptr<TreeNode>& n, const shared_ptr<TreeNode>& parent) {
- TreeNode::setParent(n, parent);
- if (useRTree) {
- BBox s;
- bg::envelope(BSegment(BPoint(n->loc.x, n->loc.y), BPoint(parent->loc.x, parent->loc.y)), s);
- rtree.insert({s, n});
- }
- };
- while (true) {
- // Get nearest neighbors
- tree.UpdateId();
- vector<shared_ptr<TreeNode>> nodes = tree.ObtainNodes(),
- ordered_nodes(nodes.size()); // note: all pins should be covered
- vector<Point> points(nodes.size());
- for (int i = 0; i < nodes.size(); ++i) {
- ordered_nodes[nodes[i]->id] = nodes[i];
- points[nodes[i]->id] = nodes[i]->loc; // TODO: move within bracket
- }
- nodes = ordered_nodes;
- vector<vector<int>> nearest_neighbors;
- if (!useRTree) {
- MstBuilder mst_builder;
- mst_builder.GetAllNearestNeighbors(points, nearest_neighbors);
- } else {
- nearest_neighbors.resize(nodes.size());
- for (auto n : nodes) {
- if (n->parent) {
- Point c = n->loc; // center
- DTYPE radius = n->WireToParent();
- // diamond is too slow...
- // BPolygon diamond;
- // diamond.outer().emplace_back(c.x - radius, c.y);
- // diamond.outer().emplace_back(c.x, c.y + radius);
- // diamond.outer().emplace_back(c.x + radius, c.y);
- // diamond.outer().emplace_back(c.x, c.y - radius);
- // diamond.outer().emplace_back(c.x - radius, c.y);
- BBox query_box{{c.x - radius, c.y - radius}, {c.x + radius, c.y + radius}};
- vector<RNode> cands;
- rtree.query(bgi::intersects(query_box), back_inserter(cands)); // TODO: change back_inserter
- for (const auto& cand : cands) {
- nearest_neighbors[n->id].push_back(cand.second->id);
- }
+ auto Disconnect = [&](const shared_ptr<TreeNode>& n) {
+ if (useRTree) {
+ BBox s;
+ bg::envelope(BSegment(BPoint(n->loc.x, n->loc.y), BPoint(n->parent->loc.x, n->parent->loc.y)), s);
+ rtree.remove({s, n});
}
- }
- }
-
- // Prune descendants in nearest neighbors
- vector<int> pre_order_idxes(nodes.size(), -1);
- int global_pre_order_idx = 0;
- function<void(const shared_ptr<TreeNode>&)> remove_descendants = [&](const shared_ptr<TreeNode>& node) {
- pre_order_idxes[node->id] = global_pre_order_idx++;
- for (auto child : node->children) {
- remove_descendants(child);
- }
- for (auto& neigh_idx : nearest_neighbors[node->id]) {
- int neigh_pre_order_idx = pre_order_idxes[neigh_idx];
- if (neigh_pre_order_idx != -1 && neigh_pre_order_idx >= pre_order_idxes[node->id]) {
- neigh_idx = -1; // -1 stands for "descendant"
+ TreeNode::ResetParent(n);
+ };
+ auto Connect = [&](const shared_ptr<TreeNode>& n, const shared_ptr<TreeNode>& parent) {
+ TreeNode::SetParent(n, parent);
+ if (useRTree) {
+ BBox s;
+ bg::envelope(BSegment(BPoint(n->loc.x, n->loc.y), BPoint(parent->loc.x, parent->loc.y)), s);
+ rtree.insert({s, n});
}
- }
};
- remove_descendants(tree.source);
+ while (true) {
+ // Get nearest neighbors
+ int num = tree.UpdateId();
+ vector<shared_ptr<TreeNode>> nodes = tree.ObtainNodes(),
+ orderedNodes(nodes.size()); // note: all pins should be covered
+ vector<Point> points(nodes.size());
+ for (int i = 0; i < nodes.size(); ++i) {
+ orderedNodes[nodes[i]->id] = nodes[i];
+ points[nodes[i]->id] = nodes[i]->loc; // TODO: move within bracket
+ }
+ nodes = orderedNodes;
+ vector<vector<int>> nearestNeighbors;
+ if (!useRTree) {
+ MstBuilder mstB;
+ mstB.GetAllNearestNeighbors(points, nearestNeighbors);
+ } else {
+ nearestNeighbors.resize(nodes.size());
+ for (auto n : nodes) {
+ if (n->parent) {
+ Point c = n->loc; // center
+ DTYPE radius = n->WireToParent();
+ // diamond is too slow...
+ // BPolygon diamond;
+ // diamond.outer().emplace_back(c.x - radius, c.y);
+ // diamond.outer().emplace_back(c.x, c.y + radius);
+ // diamond.outer().emplace_back(c.x + radius, c.y);
+ // diamond.outer().emplace_back(c.x, c.y - radius);
+ // diamond.outer().emplace_back(c.x - radius, c.y);
+ BBox queryBox{{c.x - radius, c.y - radius}, {c.x + radius, c.y + radius}};
+ vector<RNode> cands;
+ rtree.query(bgi::intersects(queryBox), back_inserter(cands)); // TODO: change back_inserter
+ for (const auto& cand : cands) {
+ nearestNeighbors[n->id].push_back(cand.second->id);
+ }
+ }
+ }
+ }
- // Init path lengths and subtree slacks
- vector<DTYPE> path_lengths(nodes.size());
- vector<DTYPE> slacks(nodes.size());
- auto update_path_lengths = [&](const shared_ptr<TreeNode>& node) {
- if (node->parent) {
- path_lengths[node->id] = path_lengths[node->parent->id] + node->WireToParent();
- } else {
- path_lengths[node->id] = 0;
- }
- };
- auto update_slacks = [&](const shared_ptr<TreeNode>& node) {
- if (node->children.empty()) {
- slacks[node->id] = Dist(node->loc, tree.source->loc) * (1 + eps) - path_lengths[node->id]; // floor here...
- } else {
- DTYPE min_slack = Dist(node->loc, tree.source->loc) * (1 + eps) - path_lengths[node->id];
- for (auto child : node->children) {
- min_slack = min(min_slack, slacks[child->id]);
+ // Prune descendants in nearest neighbors
+ vector<int> preOrderIdxes(nodes.size(), -1);
+ int globalPreOrderIdx = 0;
+ function<void(const shared_ptr<TreeNode>&)> removeDescendants = [&](const shared_ptr<TreeNode>& node) {
+ preOrderIdxes[node->id] = globalPreOrderIdx++;
+ for (auto child : node->children) {
+ removeDescendants(child);
+ }
+ for (auto& neighIdx : nearestNeighbors[node->id]) {
+ int neighPreOrderIdx = preOrderIdxes[neighIdx];
+ if (neighPreOrderIdx != -1 && neighPreOrderIdx >= preOrderIdxes[node->id]) {
+ neighIdx = -1; // -1 stands for "descendant"
+ }
+ }
+ };
+ removeDescendants(tree.source);
+
+ // Init path lengths and subtree slacks
+ vector<DTYPE> pathLengths(nodes.size());
+ vector<DTYPE> slacks(nodes.size());
+ auto UpdatePathLengths = [&](const shared_ptr<TreeNode>& node) {
+ if (node->parent) {
+ pathLengths[node->id] = pathLengths[node->parent->id] + node->WireToParent();
+ } else {
+ pathLengths[node->id] = 0;
+ }
+ };
+ auto UpdateSlacks = [&](const shared_ptr<TreeNode>& node) {
+ if (node->children.empty()) {
+ slacks[node->id] =
+ Dist(node->loc, tree.source->loc) * (1 + eps) - pathLengths[node->id]; // floor here...
+ } else {
+ DTYPE minSlack = Dist(node->loc, tree.source->loc) * (1 + eps) - pathLengths[node->id];
+ for (auto child : node->children) {
+ minSlack = min(minSlack, slacks[child->id]);
+ }
+ slacks[node->id] = minSlack;
+ }
+ };
+ tree.PreOrder(UpdatePathLengths);
+ tree.PostOrder(UpdateSlacks);
+
+ // Find legal candidate moves
+ using MoveT = tuple<DTYPE, shared_ptr<TreeNode>, shared_ptr<TreeNode>>;
+ vector<MoveT> candidateMoves; // <wireLengthDelta, node, newParent>
+ auto GetNearestPoint = [](const shared_ptr<TreeNode>& target, const shared_ptr<TreeNode>& neigh) {
+ Box box(neigh->loc, neigh->parent->loc);
+ box.Legalize();
+ return box.GetNearestPointTo(target->loc);
+ };
+ for (auto node : nodes) {
+ if (!(node->parent)) {
+ continue;
+ }
+ DTYPE bestWireLengthDelta = 0; // the negative, the better
+ shared_ptr<TreeNode> bestNewParent;
+ for (int neighIdx : nearestNeighbors[node->id]) {
+ if (neighIdx == -1 || !nodes[neighIdx]->parent) continue;
+ auto neigh = nodes[neighIdx];
+ auto neighParent = neigh->parent;
+ auto steinerPt = GetNearestPoint(node, neigh);
+ DTYPE wireLengthDelta = Dist(node->loc, steinerPt) - node->WireToParent();
+ if (wireLengthDelta < bestWireLengthDelta) { // has wire length improvement
+ DTYPE pathLengthDelta =
+ pathLengths[neighParent->id] + Dist(node->loc, neighParent->loc) - pathLengths[node->id];
+ if (pathLengthDelta <= slacks[node->id]) { // make path length under control
+ bestWireLengthDelta = wireLengthDelta;
+ bestNewParent = neigh;
+ }
+ }
+ }
+ if (bestNewParent) {
+ candidateMoves.emplace_back(bestWireLengthDelta, node, bestNewParent);
+ }
+ }
+ if (candidateMoves.empty()) {
+ break;
}
- slacks[node->id] = min_slack;
- }
- };
- tree.preOrder(update_path_lengths);
- tree.postOrder(update_slacks);
- // Find legal candidate moves
- using MoveT = tuple<DTYPE, shared_ptr<TreeNode>, shared_ptr<TreeNode>>;
- vector<MoveT> candidate_moves; // <wire_length_delta, node, newParent>
- auto get_nearest_point = [](const shared_ptr<TreeNode>& target, const shared_ptr<TreeNode>& neigh) {
- Box box(neigh->loc, neigh->parent->loc);
- box.Legalize();
- return box.GetNearestPointTo(target->loc);
- };
- for (auto node : nodes) {
- if (!(node->parent)) {
- continue;
- }
- DTYPE best_wire_length_delta = 0; // the negative, the better
- shared_ptr<TreeNode> best_new_parent;
- for (int neigh_idx : nearest_neighbors[node->id]) {
- if (neigh_idx == -1 || !nodes[neigh_idx]->parent)
- continue;
- auto neigh = nodes[neigh_idx];
- auto neigh_parent = neigh->parent;
- auto steiner_pt = get_nearest_point(node, neigh);
- DTYPE wire_length_delta = Dist(node->loc, steiner_pt) - node->WireToParent();
- if (wire_length_delta < best_wire_length_delta) { // has wire length improvement
- DTYPE path_length_delta = path_lengths[neigh_parent->id] + Dist(node->loc, neigh_parent->loc) - path_lengths[node->id];
- if (path_length_delta <= slacks[node->id]) { // make path length under control
- best_wire_length_delta = wire_length_delta;
- best_new_parent = neigh;
- }
+ // Try candidate moves in the order of descending wire length savings
+ // Note that earlier moves may influence the legality of later one
+ sort(candidateMoves.begin(), candidateMoves.end(), [](const MoveT& lhs, const MoveT& rhs){
+ return get<0>(lhs) < get<0>(rhs);
+ });
+ for (const auto& move : candidateMoves) {
+ auto node = get<1>(move), neigh = get<2>(move);
+ auto neighParent = neigh->parent;
+ // check due to earlier moves
+ if (TreeNode::IsAncestor(node, neighParent)) continue;
+ DTYPE pathLengthDelta =
+ pathLengths[neighParent->id] + Dist(node->loc, neighParent->loc) - pathLengths[node->id];
+ if (pathLengthDelta > slacks[node->id]) continue;
+ auto steinerPt = GetNearestPoint(node, neigh);
+ DTYPE wireLengthDelta = Dist(node->loc, steinerPt) - node->WireToParent();
+ if (wireLengthDelta >= 0) continue;
+ // break
+ Disconnect(node);
+ // reroot
+ if (steinerPt == neigh->loc) {
+ Connect(node, neigh);
+ } else if (steinerPt == neighParent->loc) {
+ Connect(node, neighParent);
+ } else {
+ auto steinerNode = make_shared<TreeNode>(steinerPt);
+ Connect(steinerNode, neighParent);
+ Disconnect(neigh);
+ Connect(neigh, steinerNode);
+ Connect(node, steinerNode);
+ // for later moves
+ steinerNode->id = nodes.size();
+ nodes.push_back(steinerNode);
+ pathLengths.push_back(pathLengths[neighParent->id] + steinerNode->WireToParent());
+ slacks.push_back(Dist(steinerNode->loc, tree.source->loc) * (1 + eps) - pathLengths.back());
+ }
+ // update slack for later moves: first subtree, then path to source
+ TreeNode::PreOrder(neighParent, UpdatePathLengths);
+ TreeNode::PostOrder(neighParent, UpdateSlacks);
+ auto tmp = neighParent;
+ while (tmp->parent) {
+ slacks[tmp->parent->id] = min(slacks[tmp->parent->id], slacks[tmp->id]);
+ tmp = tmp->parent;
+ }
}
- }
- if (best_new_parent) {
- candidate_moves.emplace_back(best_wire_length_delta, node, best_new_parent);
- }
- }
- if (candidate_moves.empty()) {
- break;
- }
- // Try candidate moves in the order of descending wire length savings
- // Note that earlier moves may influence the legality of later one
- sort(candidate_moves.begin(), candidate_moves.end(), [](const MoveT& lhs, const MoveT& rhs) { return get<0>(lhs) < get<0>(rhs); });
- for (const auto& move : candidate_moves) {
- auto node = get<1>(move), neigh = get<2>(move);
- auto neigh_parent = neigh->parent;
- // check due to earlier moves
- if (TreeNode::isAncestor(node, neigh_parent))
- continue;
- DTYPE path_length_delta = path_lengths[neigh_parent->id] + Dist(node->loc, neigh_parent->loc) - path_lengths[node->id];
- if (path_length_delta > slacks[node->id])
- continue;
- auto steiner_pt = get_nearest_point(node, neigh);
- DTYPE wire_length_delta = Dist(node->loc, steiner_pt) - node->WireToParent();
- if (wire_length_delta >= 0)
- continue;
- // break
- disconnect(node);
- // reroot
- if (steiner_pt == neigh->loc) {
- connect(node, neigh);
- } else if (steiner_pt == neigh_parent->loc) {
- connect(node, neigh_parent);
- } else {
- auto steiner_node = make_shared<TreeNode>(steiner_pt);
- connect(steiner_node, neigh_parent);
- disconnect(neigh);
- connect(neigh, steiner_node);
- connect(node, steiner_node);
- // for later moves
- steiner_node->id = nodes.size();
- nodes.push_back(steiner_node);
- path_lengths.push_back(path_lengths[neigh_parent->id] + steiner_node->WireToParent());
- slacks.push_back(Dist(steiner_node->loc, tree.source->loc) * (1 + eps) - path_lengths.back());
- }
- // update slack for later moves: first subtree, then path to source
- TreeNode::preOrder(neigh_parent, update_path_lengths);
- TreeNode::postOrder(neigh_parent, update_slacks);
- auto tmp = neigh_parent;
- while (tmp->parent) {
- slacks[tmp->parent->id] = min(slacks[tmp->parent->id], slacks[tmp->id]);
- tmp = tmp->parent;
- }
+ // Finalize
+ // tree.RemoveTopoRedundantSteiner();
+ tree.PostOrderCopy([&](const shared_ptr<TreeNode>& node) {
+ // degree may change after post-order traversal of its children
+ if (node->pin) return;
+ if (node->children.empty()) {
+ Disconnect(node);
+ } else if (node->children.size() == 1) {
+ auto oldParent = node->parent, oldChild = node->children[0];
+ Disconnect(node);
+ Disconnect(oldChild);
+ Connect(oldChild, oldParent);
+ }
+ });
}
-
- // Finalize
- // tree.RemoveTopoRedundantSteiner();
- tree.postOrderCopy([&](const shared_ptr<TreeNode>& node) {
- // degree may change after post-order traversal of its children
- if (node->pin)
- return;
- if (node->children.empty()) {
- disconnect(node);
- } else if (node->children.size() == 1) {
- auto old_parent = node->parent, old_child = node->children[0];
- disconnect(node);
- disconnect(old_child);
- connect(old_child, old_parent);
- }
- });
- }
}
} // namespace salt
\ No newline at end of file
diff --git a/src/third_party/salt/refine/u_shift.cpp b/src/third_party/salt/refine/u_shift.cpp
index b923661c..80f662ff 100644
--- a/src/third_party/salt/refine/u_shift.cpp
+++ b/src/third_party/salt/refine/u_shift.cpp
@@ -7,7 +7,7 @@ namespace salt {
// c pp -> root
// four Nodes: c - cur - p - pp -> root
// four points: out[0] - in[0] - in[1] - out[1]-> root
-void Refine::uShift(Tree& tree) {
+void Refine::UShift(Tree& tree) {
auto nodes = tree.ObtainNodes(); // fix the nodes considered (no deletion will happen)
for (auto cur : nodes) {
Point in[2], out[2];
@@ -35,9 +35,9 @@ void Refine::uShift(Tree& tree) {
for (int i = 0; i < 2; ++i) newP[i][d] = closer; // set pri dir
for (int i = 0; i < 2; ++i) newP[i][1 - d] = in[i][1 - d]; // set sec dir
- TreeNode::resetParent(c);
- TreeNode::resetParent(cur);
- TreeNode::resetParent(p);
+ TreeNode::ResetParent(c);
+ TreeNode::ResetParent(cur);
+ TreeNode::ResetParent(p);
// inS[0] inS[1]
// | |
// outS[0] - newS[0] - newS[1] - outS[1] -> root
@@ -50,13 +50,13 @@ void Refine::uShift(Tree& tree) {
else {
newS[i] = make_shared<TreeNode>(newP[i]);
if (i == 0)
- TreeNode::setParent(outS[i], newS[i]);
+ TreeNode::SetParent(outS[i], newS[i]);
else
- TreeNode::setParent(newS[i], outS[i]);
+ TreeNode::SetParent(newS[i], outS[i]);
}
- TreeNode::setParent(inS[i], newS[i]);
+ TreeNode::SetParent(inS[i], newS[i]);
}
- TreeNode::setParent(newS[0], newS[1]);
+ TreeNode::SetParent(newS[0], newS[1]);
}
}
diff --git a/src/third_party/salt/salt.cpp b/src/third_party/salt/salt.cpp
index 6e87682f..34d36d6e 100644
--- a/src/third_party/salt/salt.cpp
+++ b/src/third_party/salt/salt.cpp
@@ -6,92 +6,86 @@
namespace salt {
-void SaltInterface::Init(Tree& min_tree, shared_ptr<Pin> src_pin)
-{
- min_tree.UpdateId();
- auto mt_nodes = min_tree.ObtainNodes();
- sl_nodes.resize(mt_nodes.size());
- shortest_dists.resize(mt_nodes.size());
- cur_dists.resize(mt_nodes.size());
- for (auto mt_node : mt_nodes) {
- sl_nodes[mt_node->id] = make_shared<TreeNode>(mt_node->loc, mt_node->pin, mt_node->id);
- shortest_dists[mt_node->id] = Dist(mt_node->loc, src_pin->loc);
- cur_dists[mt_node->id] = numeric_limits<DTYPE>::max();
- }
- cur_dists[src_pin->id] = 0;
- sl_src = sl_nodes[src_pin->id];
+void SaltBase::Init(Tree& minTree, shared_ptr<Pin> srcP) {
+ minTree.UpdateId();
+ auto mtNodes = minTree.ObtainNodes();
+ slNodes.resize(mtNodes.size());
+ shortestDists.resize(mtNodes.size());
+ curDists.resize(mtNodes.size());
+ for (auto mtN : mtNodes) {
+ slNodes[mtN->id] = make_shared<TreeNode>(mtN->loc, mtN->pin, mtN->id);
+ shortestDists[mtN->id] = Dist(mtN->loc, srcP->loc);
+ curDists[mtN->id] = numeric_limits<DTYPE>::max();
+ }
+ curDists[srcP->id] = 0;
+ slSrc = slNodes[srcP->id];
}
-void SaltInterface::Finalize(const Net& net, Tree& tree)
-{
- for (auto n : sl_nodes)
- if (n->parent)
- sl_nodes[n->parent->id]->children.push_back(n);
- tree.source = sl_src;
- tree.net = &net;
+void SaltBase::Finalize(const Net& net, Tree& tree) {
+ for (auto n : slNodes)
+ if (n->parent) slNodes[n->parent->id]->children.push_back(n);
+ tree.source = slSrc;
+ tree.net = &net;
}
-void SaltBuilder::Run(const Net& net, Tree& tree, double eps, int refineLevel)
-{
- // SMT
- Tree smt;
- FluteBuilder flute_builder;
- flute_builder.Run(net, smt);
+void SaltBuilder::Run(const Net& net, Tree& tree, double eps, int refineLevel) {
+ // SMT
+ Tree smt;
+ FluteBuilder fluteB;
+ fluteB.Run(net, smt);
- // Refine SMT
- if (refineLevel >= 1) {
- Refine::flip(smt);
- Refine::uShift(smt);
- }
+ // Refine SMT
+ if (refineLevel >= 1) {
+ Refine::Flip(smt);
+ Refine::UShift(smt);
+ }
- // Init
- Init(smt, net.source());
+ // Init
+ Init(smt, net.source());
- // DFS
- DFS(smt.source, sl_src, eps);
- Finalize(net, tree);
- tree.RemoveTopoRedundantSteiner();
+ // DFS
+ DFS(smt.source, slSrc, eps);
+ Finalize(net, tree);
+ tree.RemoveTopoRedundantSteiner();
- // Connect breakpoints to source by RSA
- salt::RsaBuilder rsa_builder;
- rsa_builder.ReplaceRootChildren(tree);
+ // Connect breakpoints to source by RSA
+ salt::RsaBuilder rsaB;
+ rsaB.ReplaceRootChildren(tree);
- // Refine SALT
- if (refineLevel >= 1) {
- Refine::cancelIntersect(tree);
- Refine::flip(tree);
- Refine::uShift(tree);
- if (refineLevel >= 2) {
- Refine::substitute(tree, eps, refineLevel == 3);
+ // Refine SALT
+ if (refineLevel >= 1) {
+ Refine::CancelIntersect(tree);
+ Refine::Flip(tree);
+ Refine::UShift(tree);
+ if (refineLevel >= 2) {
+ Refine::Substitute(tree, eps, refineLevel == 3);
+ }
}
- }
}
-bool SaltBuilder::Relax(const shared_ptr<TreeNode>& u, const shared_ptr<TreeNode>& v)
-{
- DTYPE new_dist = cur_dists[u->id] + Dist(u->loc, v->loc);
- if (cur_dists[v->id] > new_dist) {
- cur_dists[v->id] = new_dist;
- v->parent = u;
- return true;
- } else if (cur_dists[v->id] == new_dist && Dist(u->loc, v->loc) < v->WireToParentChecked()) {
- v->parent = u;
- return true;
- } else
- return false;
+bool SaltBuilder::Relax(const shared_ptr<TreeNode>& u, const shared_ptr<TreeNode>& v) {
+ DTYPE newDist = curDists[u->id] + Dist(u->loc, v->loc);
+ if (curDists[v->id] > newDist) {
+ curDists[v->id] = newDist;
+ v->parent = u;
+ return true;
+ } else if (curDists[v->id] == newDist && Dist(u->loc, v->loc) < v->WireToParentChecked()) {
+ v->parent = u;
+ return true;
+ } else
+ return false;
}
-void SaltBuilder::DFS(const shared_ptr<TreeNode>& mst_node, const shared_ptr<TreeNode>& sl_node, double eps)
-{
- if (mst_node->pin && cur_dists[sl_node->id] > (1 + eps) * shortest_dists[sl_node->id]) {
- sl_node->parent = sl_src;
- cur_dists[sl_node->id] = shortest_dists[sl_node->id];
- }
- for (auto c : mst_node->children) {
- Relax(sl_node, sl_nodes[c->id]);
- DFS(c, sl_nodes[c->id], eps);
- Relax(sl_nodes[c->id], sl_node);
- }
+void SaltBuilder::DFS(const shared_ptr<TreeNode>& smtNode, const shared_ptr<TreeNode>& slNode, double eps) {
+ if (smtNode->pin && curDists[slNode->id] > (1 + eps) * shortestDists[slNode->id]) {
+ slNode->parent = slSrc;
+ curDists[slNode->id] = shortestDists[slNode->id];
+ }
+ for (auto c : smtNode->children) {
+ Relax(slNode, slNodes[c->id]);
+ DFS(c, slNodes[c->id], eps);
+ Relax(slNodes[c->id], slNode);
+ }
}
} // namespace salt
diff --git a/src/third_party/salt/salt.h b/src/third_party/salt/salt.h
index c4f38769..640e0401 100644
--- a/src/third_party/salt/salt.h
+++ b/src/third_party/salt/salt.h
@@ -4,28 +4,26 @@
namespace salt {
-class SaltInterface
-{
- protected:
- vector<shared_ptr<TreeNode>> sl_nodes; // nodes of the shallow-light tree
- vector<DTYPE> shortest_dists;
- vector<DTYPE> cur_dists;
- shared_ptr<TreeNode> sl_src; // source node of the shallow-light tree
+class SaltBase {
+protected:
+ vector<shared_ptr<TreeNode>> slNodes; // nodes of the shallow-light tree
+ vector<DTYPE> shortestDists;
+ vector<DTYPE> curDists;
+ shared_ptr<TreeNode> slSrc; // source node of the shallow-light tree
- void Init(Tree& min_tree, shared_ptr<Pin> src_pin); // tree of minimum weight
- void Finalize(const Net& net, Tree& tree);
- virtual bool Relax(const shared_ptr<TreeNode>& u, const shared_ptr<TreeNode>& v) = 0; // from u to v
- virtual void DFS(const shared_ptr<TreeNode>& mst_node, const shared_ptr<TreeNode>& sl_node, double eps) = 0;
+ void Init(Tree& minTree, shared_ptr<Pin> srcP); // tree of minimum weight
+ void Finalize(const Net& net, Tree& tree);
+ virtual bool Relax(const shared_ptr<TreeNode>& u, const shared_ptr<TreeNode>& v) = 0; // from u to v
+ virtual void DFS(const shared_ptr<TreeNode>& mstNode, const shared_ptr<TreeNode>& slNode, double eps) = 0;
};
-class SaltBuilder : public SaltInterface
-{
- public:
- void Run(const Net& net, Tree& tree, double eps, int refineLevel = 3);
+class SaltBuilder : public SaltBase {
+public:
+ void Run(const Net& net, Tree& tree, double eps, int refineLevel = 3);
- protected:
- bool Relax(const shared_ptr<TreeNode>& u, const shared_ptr<TreeNode>& v); // from u to v
- void DFS(const shared_ptr<TreeNode>& mst_node, const shared_ptr<TreeNode>& sl_node, double eps);
+protected:
+ bool Relax(const shared_ptr<TreeNode>& u, const shared_ptr<TreeNode>& v); // from u to v
+ void DFS(const shared_ptr<TreeNode>& mstNode, const shared_ptr<TreeNode>& slNode, double eps);
};
} // namespace salt
\ No newline at end of file
diff --git a/src/third_party/salt/utils/geo.h b/src/third_party/salt/utils/geo.h
index 19c5181f..fc0445a2 100644
--- a/src/third_party/salt/utils/geo.h
+++ b/src/third_party/salt/utils/geo.h
@@ -314,24 +314,24 @@ inline double L2Dist(const BoxT<T>& box1, const BoxT<T>& box2) {
// use BoxT instead of T & BoxT<T> to make it more general
template <typename BoxT>
void MergeRects(std::vector<BoxT>& boxes, int mergeDir) {
- int boundary_dir = 1 - mergeDir;
+ int boundaryDir = 1 - mergeDir;
std::sort(boxes.begin(), boxes.end(), [&](const BoxT& lhs, const BoxT& rhs) {
- return lhs[boundary_dir].low < rhs[boundary_dir].low ||
- (lhs[boundary_dir].low == rhs[boundary_dir].low && lhs[mergeDir].low < rhs[mergeDir].low);
+ return lhs[boundaryDir].low < rhs[boundaryDir].low ||
+ (lhs[boundaryDir].low == rhs[boundaryDir].low && lhs[mergeDir].low < rhs[mergeDir].low);
});
- std::vector<BoxT> merged_boxes;
- merged_boxes.push_back(boxes.front());
+ std::vector<BoxT> mergedBoxes;
+ mergedBoxes.push_back(boxes.front());
for (int i = 1; i < boxes.size(); ++i) {
- auto& last_box = merged_boxes.back();
- auto& sliced_box = boxes[i];
- if (sliced_box[boundary_dir] == last_box[boundary_dir] &&
- sliced_box[mergeDir].low <= last_box[mergeDir].high) { // aligned and intersected
- last_box[mergeDir] = last_box[mergeDir].UnionWith(sliced_box[mergeDir]);
+ auto& lastBox = mergedBoxes.back();
+ auto& slicedBox = boxes[i];
+ if (slicedBox[boundaryDir] == lastBox[boundaryDir] &&
+ slicedBox[mergeDir].low <= lastBox[mergeDir].high) { // aligned and intersected
+ lastBox[mergeDir] = lastBox[mergeDir].UnionWith(slicedBox[mergeDir]);
} else { // neither misaligned not seperated
- merged_boxes.push_back(sliced_box);
+ mergedBoxes.push_back(slicedBox);
}
}
- boxes = move(merged_boxes);
+ boxes = move(mergedBoxes);
}
// Slice polygons along sliceDir
@@ -339,40 +339,40 @@ void MergeRects(std::vector<BoxT>& boxes, int mergeDir) {
// assume no degenerated case
template <typename T>
void SlicePolygons(std::vector<BoxT<T>>& boxes, int sliceDir) {
- // Line sweep in sweep_dir = 1 - sliceDir
- // Suppose sliceDir = y and sweep_dir = x (sweep from left to right)
+ // Line sweep in sweepDir = 1 - sliceDir
+ // Suppose sliceDir = y and sweepDir = x (sweep from left to right)
// Not scalable impl (brute force interval query) but fast for small case
if (boxes.size() <= 1) return;
- // sort slice lines in sweep_dir
- int sweep_dir = 1 - sliceDir;
+ // sort slice lines in sweepDir
+ int sweepDir = 1 - sliceDir;
std::vector<T> locs;
for (const auto& box : boxes) {
- locs.push_back(box[sweep_dir].low);
- locs.push_back(box[sweep_dir].high);
+ locs.push_back(box[sweepDir].low);
+ locs.push_back(box[sweepDir].high);
}
std::sort(locs.begin(), locs.end());
locs.erase(std::unique(locs.begin(), locs.end()), locs.end());
// slice each box
- std::vector<BoxT<T>> sliced_boxes;
+ std::vector<BoxT<T>> slicedBoxes;
for (const auto& box : boxes) {
- BoxT<T> sliced_box = box;
- auto it_loc = std::lower_bound(locs.begin(), locs.end(), box[sweep_dir].low);
- auto it_end = std::upper_bound(it_loc, locs.end(), box[sweep_dir].high);
- while ((it_loc + 1) != it_end) {
- sliced_box[sweep_dir].Set(*it_loc, *(it_loc + 1));
- sliced_boxes.push_back(sliced_box);
- ++it_loc;
+ BoxT<T> slicedBox = box;
+ auto itLoc = std::lower_bound(locs.begin(), locs.end(), box[sweepDir].low);
+ auto itEnd = std::upper_bound(itLoc, locs.end(), box[sweepDir].high);
+ while ((itLoc + 1) != itEnd) {
+ slicedBox[sweepDir].Set(*itLoc, *(itLoc + 1));
+ slicedBoxes.push_back(slicedBox);
+ ++itLoc;
}
}
- boxes = move(sliced_boxes);
+ boxes = move(slicedBoxes);
// merge overlaped boxes along slice dir
MergeRects(boxes, sliceDir);
// stitch boxes along sweep dir
- MergeRects(boxes, sweep_dir);
+ MergeRects(boxes, sweepDir);
}
template <typename T>
diff --git a/src/third_party/salt/utils/prettyprint.h b/src/third_party/salt/utils/prettyprint.h
index 8acff997..191792f3 100644
--- a/src/third_party/salt/utils/prettyprint.h
+++ b/src/third_party/salt/utils/prettyprint.h
@@ -15,251 +15,219 @@
namespace utils {
-// SFINAE HasBeginEnd
+// SFINAE has_begin_end
template <typename T, typename = void>
-struct HasBeginEnd : std::false_type
-{
-};
+struct has_begin_end : std::false_type {};
template <typename T>
-struct HasBeginEnd<T, decltype((void) std::begin(std::declval<T>()), (void) std::end(std::declval<T>()))> : std::true_type
-{
-};
+struct has_begin_end<T, decltype((void)std::begin(std::declval<T>()), (void)std::end(std::declval<T>()))>
+ : std::true_type {};
// Holds the delimiter values for a specific character type
template <typename TChar>
-struct DelimitersValues
-{
- using char_type = TChar;
- const char_type* prefix;
- const char_type* delimiter;
- const char_type* postfix;
+struct delimiters_values {
+ using char_type = TChar;
+ const char_type *prefix;
+ const char_type *delimiter;
+ const char_type *postfix;
};
// Defines the delimiter values for a specific container and character type
template <typename T, typename TChar = char>
-struct Delimiters
-{
- using type = DelimitersValues<TChar>;
- static const type kValues;
+struct delimiters {
+ using type = delimiters_values<TChar>;
+ static const type values;
};
// Functor to print containers. You can use this directly if you want
-// to specificy a non-default Delimiters type. The printing logic can
+// to specificy a non-default delimiters type. The printing logic can
// be customized by specializing the nested template.
-template <typename T, typename TChar = char, typename TCharTraits = std::char_traits<TChar>, typename TDelimiters = Delimiters<T, TChar>>
-struct PrintContainerHelper
-{
- using delimiters_type = TDelimiters;
- using ostream_type = std::basic_ostream<TChar, TCharTraits>;
-
- template <typename U>
- struct Printer
- {
- static void printBody(const U& c, ostream_type& stream)
- {
- auto it = std::begin(c);
- const auto the_end = std::end(c);
-
- if (it != the_end) {
- for (;;) {
- stream << *it;
-
- if (++it == the_end)
- break;
-
- if (delimiters_type::values.delimiter != NULL)
- stream << delimiters_type::values.delimiter;
+template <typename T,
+ typename TChar = char,
+ typename TCharTraits = std::char_traits<TChar>,
+ typename TDelimiters = delimiters<T, TChar>>
+struct print_container_helper {
+ using delimiters_type = TDelimiters;
+ using ostream_type = std::basic_ostream<TChar, TCharTraits>;
+
+ template <typename U>
+ struct printer {
+ static void print_body(const U &c, ostream_type &stream) {
+ auto it = std::begin(c);
+ const auto the_end = std::end(c);
+
+ if (it != the_end) {
+ for (;;) {
+ stream << *it;
+
+ if (++it == the_end) break;
+
+ if (delimiters_type::values.delimiter != NULL) stream << delimiters_type::values.delimiter;
+ }
+ }
}
- }
- }
- };
+ };
- PrintContainerHelper(const T& container) : container_(container) {}
+ print_container_helper(const T &container) : container_(container) {}
- inline void operator()(ostream_type& stream) const
- {
- if (delimiters_type::values.prefix != NULL)
- stream << delimiters_type::values.prefix;
+ inline void operator()(ostream_type &stream) const {
+ if (delimiters_type::values.prefix != NULL) stream << delimiters_type::values.prefix;
- Printer<T>::printBody(container_, stream);
+ printer<T>::print_body(container_, stream);
- if (delimiters_type::values.postfix != NULL)
- stream << delimiters_type::values.postfix;
- }
+ if (delimiters_type::values.postfix != NULL) stream << delimiters_type::values.postfix;
+ }
- private:
- const T& container_;
+private:
+ const T &container_;
};
// Specialization for pairs
template <typename T, typename TChar, typename TCharTraits, typename TDelimiters>
template <typename T1, typename T2>
-struct PrintContainerHelper<T, TChar, TCharTraits, TDelimiters>::Printer<std::pair<T1, T2>>
-{
- using ostream_type = typename PrintContainerHelper<T, TChar, TCharTraits, TDelimiters>::ostream_type;
-
- static void printBody(const std::pair<T1, T2>& c, ostream_type& stream)
- {
- stream << c.first;
- if (PrintContainerHelper<T, TChar, TCharTraits, TDelimiters>::delimiters_type::values.delimiter != NULL)
- stream << PrintContainerHelper<T, TChar, TCharTraits, TDelimiters>::delimiters_type::values.delimiter;
- stream << c.second;
- }
+struct print_container_helper<T, TChar, TCharTraits, TDelimiters>::printer<std::pair<T1, T2>> {
+ using ostream_type = typename print_container_helper<T, TChar, TCharTraits, TDelimiters>::ostream_type;
+
+ static void print_body(const std::pair<T1, T2> &c, ostream_type &stream) {
+ stream << c.first;
+ if (print_container_helper<T, TChar, TCharTraits, TDelimiters>::delimiters_type::values.delimiter != NULL)
+ stream << print_container_helper<T, TChar, TCharTraits, TDelimiters>::delimiters_type::values.delimiter;
+ stream << c.second;
+ }
};
// Specialization for tuples
template <typename T, typename TChar, typename TCharTraits, typename TDelimiters>
template <typename... Args>
-struct PrintContainerHelper<T, TChar, TCharTraits, TDelimiters>::Printer<std::tuple<Args...>>
-{
- using ostream_type = typename PrintContainerHelper<T, TChar, TCharTraits, TDelimiters>::ostream_type;
- using element_type = std::tuple<Args...>;
+struct print_container_helper<T, TChar, TCharTraits, TDelimiters>::printer<std::tuple<Args...>> {
+ using ostream_type = typename print_container_helper<T, TChar, TCharTraits, TDelimiters>::ostream_type;
+ using element_type = std::tuple<Args...>;
- template <std::size_t I>
- struct Int
- {
- };
+ template <std::size_t I>
+ struct Int {};
- static void printBody(const element_type& c, ostream_type& stream) { tuplePrint(c, stream, Int<0>()); }
+ static void print_body(const element_type &c, ostream_type &stream) { tuple_print(c, stream, Int<0>()); }
- static void tuplePrint(const element_type&, ostream_type&, Int<sizeof...(Args)>) {}
+ static void tuple_print(const element_type &, ostream_type &, Int<sizeof...(Args)>) {}
- static void tuplePrint(const element_type& c, ostream_type& stream,
- typename std::conditional<sizeof...(Args) != 0, Int<0>, std::nullptr_t>::type)
- {
- stream << std::get<0>(c);
- tuplePrint(c, stream, Int<1>());
- }
+ static void tuple_print(const element_type &c,
+ ostream_type &stream,
+ typename std::conditional<sizeof...(Args) != 0, Int<0>, std::nullptr_t>::type) {
+ stream << std::get<0>(c);
+ tuple_print(c, stream, Int<1>());
+ }
- template <std::size_t N>
- static void tuplePrint(const element_type& c, ostream_type& stream, Int<N>)
- {
- if (PrintContainerHelper<T, TChar, TCharTraits, TDelimiters>::delimiters_type::values.delimiter != NULL)
- stream << PrintContainerHelper<T, TChar, TCharTraits, TDelimiters>::delimiters_type::values.delimiter;
+ template <std::size_t N>
+ static void tuple_print(const element_type &c, ostream_type &stream, Int<N>) {
+ if (print_container_helper<T, TChar, TCharTraits, TDelimiters>::delimiters_type::values.delimiter != NULL)
+ stream << print_container_helper<T, TChar, TCharTraits, TDelimiters>::delimiters_type::values.delimiter;
- stream << std::get<N>(c);
+ stream << std::get<N>(c);
- tuplePrint(c, stream, Int<N + 1>());
- }
+ tuple_print(c, stream, Int<N + 1>());
+ }
};
-// Prints a PrintContainerHelper to the specified stream.
+// Prints a print_container_helper to the specified stream.
template <typename T, typename TChar, typename TCharTraits, typename TDelimiters>
-inline std::basic_ostream<TChar, TCharTraits>& operator<<(std::basic_ostream<TChar, TCharTraits>& stream,
- const PrintContainerHelper<T, TChar, TCharTraits, TDelimiters>& helper)
-{
- helper(stream);
- return stream;
+inline std::basic_ostream<TChar, TCharTraits> &operator<<(
+ std::basic_ostream<TChar, TCharTraits> &stream,
+ const print_container_helper<T, TChar, TCharTraits, TDelimiters> &helper) {
+ helper(stream);
+ return stream;
}
-// Basic IsContainer template; specialize to derive from std::true_type for all desired container types
+// Basic is_container template; specialize to derive from std::true_type for all desired container types
template <typename T>
-struct IsContainer : std::integral_constant<bool, HasBeginEnd<T>::value>
-{
-};
+struct is_container : std::integral_constant<bool, has_begin_end<T>::value> {};
template <typename... T>
-struct IsContainer<std::pair<T...>> : std::true_type
-{
-};
+struct is_container<std::pair<T...>> : std::true_type {};
template <typename... T>
-struct IsContainer<std::tuple<T...>> : std::true_type
-{
-};
+struct is_container<std::tuple<T...>> : std::true_type {};
-// Default Delimiters
+// Default delimiters
template <typename T>
-struct Delimiters<T, char>
-{
- static constexpr DelimitersValues<char> kValues = {"[", ", ", "]"};
+struct delimiters<T, char> {
+ static constexpr delimiters_values<char> values = {"[", ", ", "]"};
};
// Delimiters for (unordered_)(multi)set
template <typename... T>
-struct Delimiters<std::set<T...>>
-{
- static constexpr DelimitersValues<char> kValues = {"{", ", ", "}"};
+struct delimiters<std::set<T...>> {
+ static constexpr delimiters_values<char> values = {"{", ", ", "}"};
};
template <typename... T>
-struct Delimiters<std::multiset<T...>>
-{
- static constexpr DelimitersValues<char> kValues = {"{", ", ", "}"};
+struct delimiters<std::multiset<T...>> {
+ static constexpr delimiters_values<char> values = {"{", ", ", "}"};
};
template <typename... T>
-struct Delimiters<std::unordered_set<T...>>
-{
- static constexpr DelimitersValues<char> kValues = {"{", ", ", "}"};
+struct delimiters<std::unordered_set<T...>> {
+ static constexpr delimiters_values<char> values = {"{", ", ", "}"};
};
template <typename... T>
-struct Delimiters<std::unordered_multiset<T...>>
-{
- static constexpr DelimitersValues<char> kValues = {"{", ", ", "}"};
+struct delimiters<std::unordered_multiset<T...>> {
+ static constexpr delimiters_values<char> values = {"{", ", ", "}"};
};
// Delimiters for pair and tuple
template <typename... T>
-struct Delimiters<std::pair<T...>>
-{
- static constexpr DelimitersValues<char> kValues = {"(", ", ", ")"};
+struct delimiters<std::pair<T...>> {
+ static constexpr delimiters_values<char> values = {"(", ", ", ")"};
};
template <typename... T>
-struct Delimiters<std::tuple<T...>>
-{
- static constexpr DelimitersValues<char> kValues = {"(", ", ", ")"};
+struct delimiters<std::tuple<T...>> {
+ static constexpr delimiters_values<char> values = {"(", ", ", ")"};
};
-// Type-erasing helper class for easy use of custom Delimiters.
+// Type-erasing helper class for easy use of custom delimiters.
// Requires TCharTraits = std::char_traits<TChar> and TChar = char or wchar_t, and MyDelims needs to be defined for
-// TChar. Usage: "cout << pretty_print::CustomDelims<MyDelims>(x)".
+// TChar. Usage: "cout << pretty_print::custom_delims<MyDelims>(x)".
-struct CustomDelimsInterface
-{
- virtual ~CustomDelimsInterface() {}
- virtual std::ostream& stream(std::ostream&) = 0;
+struct custom_delims_base {
+ virtual ~custom_delims_base() {}
+ virtual std::ostream &stream(std::ostream &) = 0;
};
template <typename T, typename Delims>
-struct CustomDelimsWrapper : CustomDelimsInterface
-{
- CustomDelimsWrapper(const T& t_) : t(t_) {}
+struct custom_delims_wrapper : custom_delims_base {
+ custom_delims_wrapper(const T &t_) : t(t_) {}
- std::ostream& stream(std::ostream& s) { return s << PrintContainerHelper<T, char, std::char_traits<char>, Delims>(t); }
+ std::ostream &stream(std::ostream &s) {
+ return s << print_container_helper<T, char, std::char_traits<char>, Delims>(t);
+ }
- private:
- const T& t;
+private:
+ const T &t;
};
template <typename Delims>
-struct CustomDelims
-{
- template <typename Container>
- CustomDelims(const Container& c) : base(new CustomDelimsWrapper<Container, Delims>(c))
- {
- }
-
- std::unique_ptr<CustomDelimsInterface> base;
+struct custom_delims {
+ template <typename Container>
+ custom_delims(const Container &c) : base(new custom_delims_wrapper<Container, Delims>(c)) {}
+
+ std::unique_ptr<custom_delims_base> base;
};
template <typename TChar, typename TCharTraits, typename Delims>
-inline std::basic_ostream<TChar, TCharTraits>& operator<<(std::basic_ostream<TChar, TCharTraits>& s, const CustomDelims<Delims>& p)
-{
- return p.base->stream(s);
+inline std::basic_ostream<TChar, TCharTraits> &operator<<(std::basic_ostream<TChar, TCharTraits> &s,
+ const custom_delims<Delims> &p) {
+ return p.base->stream(s);
}
} // namespace utils
@@ -268,13 +236,12 @@ inline std::basic_ostream<TChar, TCharTraits>& operator<<(std::basic_ostream<TCh
// Can we do better?
namespace std {
-// Prints a container to the stream using default Delimiters
+// Prints a container to the stream using default delimiters
template <typename T, typename TChar, typename TCharTraits>
-inline typename enable_if<::utils::IsContainer<T>::value, basic_ostream<TChar, TCharTraits>&>::type operator<<(
- basic_ostream<TChar, TCharTraits>& stream, const T& container)
-{
- return stream << ::utils::PrintContainerHelper<T, TChar, TCharTraits>(container);
+inline typename enable_if<::utils::is_container<T>::value, basic_ostream<TChar, TCharTraits> &>::type operator<<(
+ basic_ostream<TChar, TCharTraits> &stream, const T &container) {
+ return stream << ::utils::print_container_helper<T, TChar, TCharTraits>(container);
}
} // namespace std
\ No newline at end of file