Skip to content

Commit

Permalink
Merge pull request The-OpenROAD-Project#4507 from antmicro/steiner-tr…
Browse files Browse the repository at this point in the history
…ee-pinlocs

Reduce number of pin location lookups in Steiner tree construction
  • Loading branch information
maliberty authored Jan 9, 2024
2 parents 3e205b5 + 3ed4e73 commit 4535a05
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 29 deletions.
50 changes: 25 additions & 25 deletions src/rsz/src/SteinerTree.cc
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,9 @@ using sta::NetConnectedPinIterator;
static void
connectedPins(const Net *net,
Network *network,
dbNetwork* db_network,
// Return value.
PinSeq &pins);
Vector<PinLoc> &pins);

SteinerPt SteinerTree::null_pt = -1;

Expand All @@ -74,18 +75,16 @@ Resizer::makeSteinerTree(const Pin *drvr_pin)
debugPrint(logger_, RSZ, "steiner", 1, "Net {}",
sdc_network->pathName(net));
SteinerTree *tree = new SteinerTree(drvr_pin, this);
PinSeq &pins = tree->pins();
Vector<PinLoc> &pinlocs = tree->pinlocs();
// Find all the connected pins
connectedPins(net, network_, pins);
connectedPins(net, network_, db_network_, pinlocs);
// Sort pins by location because connectedPins order is not deterministic.
sort(pins, [=](const Pin *pin1, const Pin *pin2) {
Point loc1 = db_network_->location(pin1);
Point loc2 = db_network_->location(pin2);
return loc1.getX() < loc2.getX()
|| (loc1.getX() == loc2.getX()
&& loc1.getY() < loc2.getY());
sort(pinlocs, [=](const PinLoc& pin1, const PinLoc& pin2) {
return pin1.loc.getX() < pin2.loc.getX()
|| (pin1.loc.getX() == pin2.loc.getX()
&& pin1.loc.getY() < pin2.loc.getY());
});
int pin_count = pins.size();
int pin_count = pinlocs.size();
bool is_placed = true;
// Warn if there are too many pins (>10000)
if (pin_count > max_steiner_pin_count_) {
Expand All @@ -96,23 +95,22 @@ Resizer::makeSteinerTree(const Pin *drvr_pin)
vector<int> x, y; // Two separate vectors of coordinates needed by flute.
int drvr_idx = 0; // The "driver_pin" or the root of the Steiner tree.
for (int i = 0; i < pin_count; i++) {
const Pin *pin = pins[i];
if (pin == drvr_pin) {
const PinLoc& pinloc = pinlocs[i];
if (pinloc.pin == drvr_pin) {
drvr_idx = i; // drvr_index is needed by flute.
}
Point loc = db_network_->location(pin);
x.push_back(loc.x());
y.push_back(loc.y());
x.push_back(pinloc.loc.x());
y.push_back(pinloc.loc.y());
debugPrint(logger_, RSZ, "steiner", 3, " {} ({} {})",
sdc_network->pathName(pin),
loc.x(), loc.y());
sdc_network->pathName(pinloc.pin),
pinloc.loc.x(), pinloc.loc.y());
// Track that all our pins are placed.
is_placed &= db_network_->isPlaced(pin);
is_placed &= db_network_->isPlaced(pinloc.pin);

// Flute may reorder the input points, so it takes some unravelling
// to find the mapping back to the original pins. The complication is
// that multiple pins can occupy the same location.
tree->locAddPin(loc, pin);
tree->locAddPin(pinloc.loc, pinloc.pin);
}
if (is_placed) {
stt::Tree ftree = stt_builder_->makeSteinerTree(db_network_->staToDb(net),
Expand All @@ -130,13 +128,15 @@ Resizer::makeSteinerTree(const Pin *drvr_pin)
static void
connectedPins(const Net *net,
Network *network,
dbNetwork* db_network,
// Return value.
PinSeq &pins)
Vector<PinLoc> &pins)
{
NetConnectedPinIterator *pin_iter = network->connectedPinIterator(net);
while (pin_iter->hasNext()) {
const Pin *pin = pin_iter->next();
pins.push_back(pin);
Point loc = db_network->location(pin);
pins.push_back({pin, loc});
}
delete pin_iter;
}
Expand Down Expand Up @@ -174,7 +174,7 @@ SteinerTree::SteinerTree(const Pin *drvr_pin, Resizer *resizer) :
void
SteinerTree::createSteinerPtToPinMap()
{
unsigned int pin_count = pins_.size();
unsigned int pin_count = pinlocs_.size();

point_pin_array_.resize(pin_count);
for (unsigned int i = 0; i < pin_count; i++) {
Expand All @@ -193,7 +193,7 @@ SteinerTree::branchCount() const
}

void
SteinerTree::locAddPin(Point &loc,
SteinerTree::locAddPin(const Point& loc,
const Pin *pin)
{
PinSeq &pins = loc_pin_map_[loc];
Expand Down Expand Up @@ -372,7 +372,7 @@ SteinerTree::populateSides(const SteinerPt from, const SteinerPt to,
const std::vector<SteinerPt>& adj2,
const std::vector<SteinerPt>& adj3)
{
if (to >= (int) pins_.size()) {
if (to >= (int) pinlocs_.size()) {
SteinerPt adj;
adj = adj1[to];
populateSides(from, to, adj, adj1, adj2, adj3);
Expand Down Expand Up @@ -440,7 +440,7 @@ int SteinerTree::distance(SteinerPt& from, SteinerPt& to) const
const Pin *SteinerTree::pin(SteinerPt pt) const
{
validatePoint(pt);
if (pt < (int)pins_.size()) {
if (pt < (int)pinlocs_.size()) {
return point_pin_array_[pt];
}
return nullptr;
Expand Down
15 changes: 11 additions & 4 deletions src/rsz/src/SteinerTree.hh
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,13 @@ public:
const Point &pt2) const;
};

class PinLoc
{
public:
const Pin* pin;
Point loc;
};

using LocPinMap = std::unordered_map<Point, PinSeq, PointHash, PointEqual>;

class SteinerTree;
Expand All @@ -97,8 +104,8 @@ class SteinerTree
{
public:
SteinerTree(const Pin *drvr_pin, Resizer *resizer);
PinSeq &pins() { return pins_; }
int pinCount() const { return pins_.size(); }
Vector<PinLoc> &pinlocs() { return pinlocs_; }
int pinCount() const { return pinlocs_.size(); }
int branchCount() const;
void branch(int index,
// Return values.
Expand Down Expand Up @@ -147,13 +154,13 @@ public:
static SteinerPt null_pt;

protected:
void locAddPin(Point &loc,
void locAddPin(const Point &loc,
const Pin *pin);

stt::Tree tree_;
const Pin *drvr_pin_;
int drvr_steiner_pt_; // index into tree_.branch
PinSeq pins_; // Initial input
Vector<PinLoc> pinlocs_; // Initial input
LocPinMap loc_pin_map_; // location -> pins map
std::vector<SteinerPt> left_;
std::vector<SteinerPt> right_;
Expand Down

0 comments on commit 4535a05

Please sign in to comment.