Skip to content

Commit 17f494d

Browse files
authored
Merge pull request #10838 from Fermions-ASI/feat/grt-dedup
grt: O(1) coordinate dedup in setTreeNodesVariables (FastRoute)
2 parents 7113097 + 0b60604 commit 17f494d

2 files changed

Lines changed: 33 additions & 9 deletions

File tree

src/grt/src/fastroute/include/FastRoute.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -808,6 +808,11 @@ class FastRouteCore
808808
std::vector<int> xcor_;
809809
std::vector<int> ycor_;
810810
std::vector<int> dcor_;
811+
// Scratch map for setTreeNodesVariables() coordinate deduplication.
812+
// Maps a packed (x,y) grid position to the dcor index of the first node
813+
// inserted at that position, replacing an O(numpoints^2) linear scan with
814+
// O(1) average lookups. Reused across calls to avoid per-call allocation.
815+
std::unordered_map<uint32_t, int> tree_node_coord_dedup_;
811816

812817
std::vector<FrNet*> nets_;
813818
std::unordered_map<odb::dbNet*, int> db_net_id_map_; // db net -> net id

src/grt/src/fastroute/src/utility.cpp

Lines changed: 28 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2996,6 +2996,18 @@ void FastRouteCore::setTreeNodesVariables(const int netID)
29962996
auto& treenodes = sttrees_[netID].nodes;
29972997

29982998
// Setting the values needed for each TreeNode
2999+
//
3000+
// Coordinate deduplication: non-terminal nodes that share a grid (x,y)
3001+
// position with an earlier node are aliased (stackAlias) to that earlier
3002+
// node. The original implementation found the earliest matching node with an
3003+
// O(numpoints) linear scan, making the whole loop O(numpoints^2). For large
3004+
// multi-pin nets this dominates global routing runtime. We replace the scan
3005+
// with a hash-map keyed by the packed (x,y) position, mapping to the dcor
3006+
// index of the FIRST node inserted at that position. This yields identical
3007+
// results (same first-match semantics, same xcor_/ycor_/dcor_ contents)
3008+
// with O(1) average lookups.
3009+
auto& coord_map = tree_node_coord_dedup_;
3010+
coord_map.clear();
29993011
for (int d = 0; d < sttrees_[netID].num_nodes(); d++) {
30003012
treenodes[d].topL = -1;
30013013
treenodes[d].botL = num_layers_;
@@ -3006,27 +3018,34 @@ void FastRouteCore::setTreeNodesVariables(const int netID)
30063018
treenodes[d].lID = BIG_INT;
30073019
treenodes[d].status = 0;
30083020

3021+
// Pack the int16_t grid coordinates into a single unsigned 32-bit key.
3022+
// Unsigned avoids undefined behavior from shifting into the sign bit.
3023+
const uint32_t key
3024+
= (static_cast<uint32_t>(static_cast<uint16_t>(treenodes[d].x)) << 16)
3025+
| static_cast<uint32_t>(static_cast<uint16_t>(treenodes[d].y));
3026+
30093027
if (d < num_terminals) {
30103028
const int pin_idx = sttrees_[netID].node_to_pin_idx[d];
30113029
treenodes[d].botL = nets_[netID]->getPinL()[pin_idx];
30123030
treenodes[d].topL = nets_[netID]->getPinL()[pin_idx];
30133031
treenodes[d].assigned = true;
30143032
treenodes[d].status = 1;
30153033

3034+
// Terminals are always appended (they are never aliased away), matching
3035+
// the original behavior. Record only the first dcor per position so
3036+
// later lookups resolve to the earliest insertion, as the linear scan
3037+
// did.
3038+
coord_map.try_emplace(key, d);
30163039
xcor_[numpoints] = treenodes[d].x;
30173040
ycor_[numpoints] = treenodes[d].y;
30183041
dcor_[numpoints] = d;
30193042
numpoints++;
30203043
} else {
3021-
bool redundant = false;
3022-
for (int k = 0; k < numpoints; k++) {
3023-
if ((treenodes[d].x == xcor_[k]) && (treenodes[d].y == ycor_[k])) {
3024-
treenodes[d].stackAlias = dcor_[k];
3025-
redundant = true;
3026-
break;
3027-
}
3028-
}
3029-
if (!redundant) {
3044+
const auto it = coord_map.find(key);
3045+
if (it != coord_map.end()) {
3046+
treenodes[d].stackAlias = it->second;
3047+
} else {
3048+
coord_map.emplace(key, d);
30303049
xcor_[numpoints] = treenodes[d].x;
30313050
ycor_[numpoints] = treenodes[d].y;
30323051
dcor_[numpoints] = d;

0 commit comments

Comments
 (0)