Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 13 additions & 19 deletions src/grt/src/cugr/src/GridGraph.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,15 @@
#include "GRTree.h"
#include "Layers.h"
#include "geo.h"
#include "GeoTypes.h"
#include "odb/db.h"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: included header GeoTypes.h is not used directly [misc-include-cleaner]

Suggested change
#include "odb/db.h"
"

#include "odb/geom.h"
#include "robin_hood.h"

namespace grt {

struct GPoint3D;

using CapacityT = double;
class GRNet;
template <typename Type>
Expand All @@ -34,7 +37,6 @@ struct AccessPoint
}
};

// Only hash and compare on the point, not the layers
class AccessPointHash
{
public:
Expand Down Expand Up @@ -71,6 +73,7 @@ struct GraphEdge
class GridGraph
{
public:
int findPointIndex(const std::vector<GPoint3D>& path, int x, int y, int layer) const;
GridGraph(const Design* design,
const Constants& constants,
utl::Logger* logger);
Expand Down Expand Up @@ -105,53 +108,43 @@ class GridGraph
return graph_edges_[layer_index][x][y];
}

// Costs
int getEdgeLength(int direction, int edge_index) const;
CostT getWireCost(int layer_index, PointT u, PointT v) const;
CostT getViaCost(int layer_index, PointT loc) const;
CostT getUnitViaCost() const { return unit_via_cost_; }

// Misc
AccessPointSet selectAccessPoints(GRNet* net) const;

// Methods for updating demands
void commitTree(const std::shared_ptr<GRTreeNode>& tree, bool rip_up = false);

// Checks
bool checkOverflow(int layer_index, int x, int y) const
{
return getEdge(layer_index, x, y).getResource() < 0.0;
}
int checkOverflow(int layer_index,
PointT u,
PointT v) const; // Check wire overflow
PointT v) const;
int checkOverflow(const std::shared_ptr<GRTreeNode>& tree)
const; // Check routing tree overflow (Only wires are checked)
const;
std::string getPythonString(
const std::shared_ptr<GRTreeNode>& routing_tree) const;

// 2D maps
void extractBlockageView(GridGraphView<bool>& view) const;
void extractCongestionView(
GridGraphView<bool>& view) const; // 2D overflow look-up table
GridGraphView<bool>& view) const;
void extractWireCostView(GridGraphView<CostT>& view) const;
void updateWireCostView(
GridGraphView<CostT>& view,
const std::shared_ptr<GRTreeNode>& routing_tree) const;

// For visualization
void write(const std::string& heatmap_file = "heatmap.txt") const;

private:
IntervalT rangeSearchGridlines(int dimension,
const IntervalT& loc_interval) const;
// Find the gridlines_ within [locInterval.low, locInterval.high]
IntervalT rangeSearchRows(int dimension, const IntervalT& loc_interval) const;
// Find the rows/columns overlapping with [locInterval.low, locInterval.high]

// Utility functions for cost calculation
CostT getUnitLengthWireCost() const { return unit_length_wire_cost_; }
// CostT getUnitViaCost() const { return unit_via_cost_; }
CostT getUnitLengthShortCost(int layer_index) const
{
return unit_length_short_costs_[layer_index];
Expand All @@ -169,7 +162,6 @@ class GridGraph
PointT lower,
CapacityT demand = 1.0) const;

// Methods for updating demands
void commit(int layer_index, PointT lower, CapacityT demand);
void commitWire(int layer_index, PointT lower, bool rip_up = false);
void commitVia(int layer_index, PointT loc, bool rip_up = false);
Expand All @@ -190,15 +182,12 @@ class GridGraph

const Design* design_;

// Unit costs
CostT unit_length_wire_cost_;
CostT unit_via_cost_;
std::vector<CostT> unit_length_short_costs_;

int total_length_ = 0;
int total_num_vias_ = 0;
// gridEdges[l][x][y] stores the edge {(l, x, y), (l, x+1, y)} or {(l, x, y),
// (l, x, y+1)} depending on the routing direction of the layer
std::vector<std::vector<std::vector<GraphEdge>>> graph_edges_;
const Constants constants_;
};
Expand Down Expand Up @@ -250,4 +239,9 @@ class GridGraphView : public std::vector<std::vector<std::vector<Type>>>
}
};

} // namespace grt
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: namespace 'grt' not terminated with a closing comment [google-readability-namespace-comments]

src/grt/src/cugr/src/GridGraph.h:243:

+   // namespace grt
Additional context

src/grt/src/cugr/src/GridGraph.h:20: namespace 'grt' starts here

            ^





10 changes: 10 additions & 0 deletions src/grt/src/fastroute/include/FastRoute.h
Original file line number Diff line number Diff line change
Expand Up @@ -277,8 +277,14 @@ class FastRouteCore
void getPlanarRoute(odb::dbNet* db_net, GRoute& route);
void get3DRoute(odb::dbNet* db_net, GRoute& route);
void setIncrementalGrt(bool is_incremental);
int computeNetSttWirelength(int netID);
int computeNetFinalWirelength(int netID);
const std::unordered_map<int, int>& getSttWirelengths() { return stt_wirelengths_; }
int computeTotalWirelength();

private:
std::vector<int> stt_wirelengths_;
int computeNetSttWirelength(int netID);
int getEdgeCapacity(FrNet* net, int x1, int y1, EdgeDirection direction);
void getNetId(odb::dbNet* db_net, int& net_id, bool& exists);
void clearNetRoute(int netID);
Expand Down Expand Up @@ -721,6 +727,7 @@ class FastRouteCore
horizontal_blocked_intervals_;

std::vector<int> net_ids_;
std::unordered_map<int, int> stt_wirelengths_; // netID -> STT wirelength

// Maze 3D variables
multi_array<Direction, 3> directions_3D_;
Expand All @@ -738,3 +745,6 @@ class FastRouteCore
extern const char* getNetName(odb::dbNet* db_net);

} // namespace grt



70 changes: 34 additions & 36 deletions src/grt/src/fastroute/src/RSMT.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ static int ordery(const Pnt* a, const Pnt* b)
return a->y < b->y;
}

// binary search to map the new coordinates to original coordinates
static int mapxy(const int nx,
const std::vector<int>& xs,
const std::vector<int>& nxs,
Expand Down Expand Up @@ -71,16 +70,13 @@ void FastRouteCore::copyStTree(const int ind, const stt::Tree& rsmt)
auto& treenodes = sttrees_[ind].nodes;
auto& treeedges = sttrees_[ind].edges;

// initialize the nbrcnt for treenodes
const int sizeV = 2 * nets_[ind]->getNumPins();
std::vector<int> nbrcnt(sizeV);
for (int i = 0; i < numnodes; i++) {
nbrcnt[i] = 0;
}

int edgecnt = 0;
// original rsmt has 2*d-2 branch (one is a loop for root), in StTree 2*d-3
// edges (no original loop)
for (int i = 0; i < numnodes; i++) {
const int x1 = rsmt.branch[i].x;
const int y1 = rsmt.branch[i].y;
Expand All @@ -94,9 +90,8 @@ void FastRouteCore::copyStTree(const int ind, const stt::Tree& rsmt)
} else {
treenodes[i].status = 0;
}
if (n != i) { // not root
if (n != i) {
treeedges[edgecnt].len = abs(x1 - x2) + abs(y1 - y2);
// make x1 always less than x2
if (x1 < x2) {
treeedges[edgecnt].n1 = i;
treeedges[edgecnt].n2 = n;
Expand All @@ -119,7 +114,6 @@ void FastRouteCore::copyStTree(const int ind, const stt::Tree& rsmt)
}
}

// Map the node indices to the pin indices of the net
std::map<odb::Point, int> pos_count;
for (int i = 0; i < d; i++) {
odb::Point pos{treenodes[i].x, treenodes[i].y};
Expand All @@ -129,7 +123,6 @@ void FastRouteCore::copyStTree(const int ind, const stt::Tree& rsmt)
sttrees_[ind].node_to_pin_idx[i] = pin_idx;
}

// Copy num neighbors
for (int i = 0; i < numnodes; i++) {
treenodes[i].nbr_count = nbrcnt[i];
}
Expand Down Expand Up @@ -257,7 +250,6 @@ void FastRouteCore::fluteNormal(const int netID,
ptp[i]->o = i;
}

// sort y to find s[]
if (d < 1000) {
for (int i = 0; i < d - 1; i++) {
int minval = ptp[i]->y;
Expand Down Expand Up @@ -398,18 +390,17 @@ void FastRouteCore::fluteCongest(const int netID,
s[i] = gs_[netID][i];
}

// get the new coordinates considering congestion
for (int i = 0; i < d - 1; i++) {
x_seg[i] = (xs[i + 1] - xs[i]) * 100;
y_seg[i] = (ys[i + 1] - ys[i]) * 100;
}

const int height = ys[d - 1] - ys[0] + 1; // # vertical grids the net span
const int width = xs[d - 1] - xs[0] + 1; // # horizontal grids the net span
const int height = ys[d - 1] - ys[0] + 1;
const int width = xs[d - 1] - xs[0] + 1;

for (int i = 0; i < d - 1; i++) {
int usageH = 0;
for (int k = ys[0]; k <= ys[d - 1]; k++) // all grids in the column
for (int k = ys[0]; k <= ys[d - 1]; k++)
{
for (int j = xs[i]; j < xs[i + 1]; j++) {
usageH += graph2d_.getEstUsageRedH(j, k);
Expand All @@ -418,20 +409,18 @@ void FastRouteCore::fluteCongest(const int netID,
if (x_seg[i] != 0 && usageH != 0) {
x_seg[i]
*= coeffH * usageH / ((xs[i + 1] - xs[i]) * height * h_capacity_);
x_seg[i] = std::max(1, x_seg[i]); // the segment len is at least 1 if
// original segment len > 0
x_seg[i] = std::max(1, x_seg[i]);
}
int usageV = 0;
for (int j = ys[i]; j < ys[i + 1]; j++) {
for (int k = xs[0]; k <= xs[d - 1]; k++) { // all grids in the row
for (int k = xs[0]; k <= xs[d - 1]; k++) {
usageV += graph2d_.getEstUsageRedV(k, j);
}
}
if (y_seg[i] != 0 && usageV != 0) {
y_seg[i]
*= coeffV * usageV / ((ys[i + 1] - ys[i]) * width * v_capacity_);
y_seg[i] = std::max(1, y_seg[i]); // the segment len is at least 1 if
// original segment len > 0
y_seg[i] = std::max(1, y_seg[i]);
}
}

Expand All @@ -444,7 +433,6 @@ void FastRouteCore::fluteCongest(const int netID,

t = stt_builder_->makeSteinerTree(nxs, nys, s, acc);

// map the new coordinates back to original coordinates
for (auto& branch : t.branch) {
branch.x = mapxy(branch.x, xs, nxs, d);
branch.y = mapxy(branch.y, ys, nys, d);
Expand All @@ -457,7 +445,6 @@ bool FastRouteCore::netCongestion(const int netID)
for (const Segment& seg : seglist_[netID]) {
const auto [ymin, ymax] = std::minmax(seg.y1, seg.y2);

// remove L routing
if (seg.xFirst) {
for (int i = seg.x1; i < seg.x2; i++) {
const int cap = getEdgeCapacity(
Expand Down Expand Up @@ -574,9 +561,6 @@ float FastRouteCore::coeffADJ(const int netID)
Vusage += graph2d_.getEstUsageV(i, j);
}
}
// (Husage * Vcap) resulting in zero is unlikely, but
// this check was added to avoid undefined behavior if
// the expression results in zero
if ((Husage * Vcap) > 0) {
coef = (Hcap * Vusage) / (Husage * Vcap);
} else {
Expand Down Expand Up @@ -614,7 +598,6 @@ void FastRouteCore::gen_brk_RSMT(const bool congestionDriven,
const auto& treeedges = sttrees_[netID].edges;
const auto& treenodes = sttrees_[netID].nodes;
for (int j = 0; j < sttrees_[netID].num_edges(); j++) {
// only route the non-degraded edges (len>0)
if (sttrees_[netID].edges[j].len > 0) {
const TreeEdge* treeedge = &(treeedges[j]);
const int n1 = treeedge->n1;
Expand All @@ -627,15 +610,12 @@ void FastRouteCore::gen_brk_RSMT(const bool congestionDriven,
}
}
} else {
// remove the est_usage due to the segments in this net
for (auto& seg : seglist_[netID]) {
ripupSegL(&seg);
}
}
}

// check net alpha because FastRoute has a special implementation of flute
// TODO: move this flute implementation to SteinerTreeBuilder
const float net_alpha = stt_builder_->getAlpha(net->getDbNet());
if (net_alpha > 0.0) {
rsmt = stt_builder_->makeSteinerTree(
Expand All @@ -644,7 +624,6 @@ void FastRouteCore::gen_brk_RSMT(const bool congestionDriven,
float coeffV = 1.36;

if (congestionDriven) {
// call congestion driven flute to generate RSMT
bool cong;
coeffV = noADJ ? 1.2 : coeffADJ(netID);
cong = netCongestion(netID);
Expand All @@ -667,7 +646,6 @@ void FastRouteCore::gen_brk_RSMT(const bool congestionDriven,
numShift += edgeShiftNew(rsmt, netID);
}
} else {
// call FLUTE to generate RSMT for each net
if (noADJ || HTreeSuite(netID)) {
coeffV = 1.2;
}
Expand Down Expand Up @@ -708,27 +686,27 @@ void FastRouteCore::gen_brk_RSMT(const bool congestionDriven,

wl += abs(x1 - x2) + abs(y1 - y2);

if (x1 != x2 || y1 != y2) { // the branch is not degraded (a point)
// the position of this segment in seglist
if (x1 != x2 || y1 != y2) {
const int8_t cost = nets_[netID]->getEdgeCost();
if (x1 < x2) {
seglist_[netID].emplace_back(netID, x1, y1, x2, y2, cost);
} else {
seglist_[netID].emplace_back(netID, x2, y2, x1, y1, cost);
}
}
} // loop j
}

totalNumSeg += seglist_[netID].size();

if (reRoute) {
// update the est_usage due to the segments in this net
newrouteL(
netID,
RouteType::NoRoute,
true); // route the net with no previous route for each tree edge
true);
}
} // loop i

stt_wirelengths_[netID] = computeNetSttWirelength(netID);
}

debugPrint(logger_,
GRT,
Expand All @@ -742,4 +720,24 @@ void FastRouteCore::gen_brk_RSMT(const bool congestionDriven,
numShift);
}

} // namespace grt
int FastRouteCore::computeNetSttWirelength(int netID)
{
int stt_wl = 0;
const auto& treeedges = sttrees_[netID].edges;
const auto& treenodes = sttrees_[netID].nodes;
for (int j = 0; j < sttrees_[netID].num_edges(); j++) {
const TreeEdge* treeedge = &(treeedges[j]);
if (treeedge->len > 0) {
const int n1 = treeedge->n1;
const int n2 = treeedge->n2;
const int x1 = treenodes[n1].x;
const int y1 = treenodes[n1].y;
const int x2 = treenodes[n2].x;
const int y2 = treenodes[n2].y;
stt_wl += abs(x1 - x2) + abs(y1 - y2);
}
}
return stt_wl;
}

}
2 changes: 2 additions & 0 deletions src/grt/src/fastroute/src/maze3D.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1580,3 +1580,5 @@ void FastRouteCore::mazeRouteMSMDOrder3D(int expand,
}

} // namespace grt