Skip to content

Commit 4011709

Browse files
authored
Merge pull request #10632 from eder-matheus/pad_non_determinism
pad: add custom comparator for GridGraphEdge set to prevent non-determinism
2 parents fbffde0 + f2ae0d8 commit 4011709

4 files changed

Lines changed: 53 additions & 43 deletions

File tree

src/pad/src/RDLRouter.cpp

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,17 @@ namespace pad {
4141

4242
namespace {
4343

44+
// Order routes by their source terminal id so ripup iteration (and the edge
45+
// re-add order it drives) is deterministic, not heap-address dependent.
46+
struct RDLRoutePtrLess
47+
{
48+
bool operator()(const std::shared_ptr<RDLRoute>& lhs,
49+
const std::shared_ptr<RDLRoute>& rhs) const
50+
{
51+
return lhs->getTerminal()->getId() < rhs->getTerminal()->getId();
52+
}
53+
};
54+
4455
bool compareRouteTargets(const RouteTarget& lhs, const RouteTarget& rhs)
4556
{
4657
if (lhs.center.x() != rhs.center.x()) {
@@ -381,7 +392,7 @@ void RDLRouter::route(const std::vector<odb::dbNet*>& nets)
381392
makeGraph();
382393

383394
// Determine access points
384-
std::unordered_map<odb::Point, std::set<GridGraphEdge>> remove_edges;
395+
std::unordered_map<odb::Point, GridGraphEdgeSet> remove_edges;
385396
for (auto& [net, iterm_targets] : routing_targets_) {
386397
for (auto& [iterm, targets] : iterm_targets) {
387398
for (auto& target : targets) {
@@ -649,7 +660,7 @@ void RDLRouter::route(const std::vector<odb::dbNet*>& nets)
649660
}
650661

651662
// find routes to ripup
652-
std::set<RDLRoutePtr> ripup;
663+
std::set<RDLRoutePtr, RDLRoutePtrLess> ripup;
653664
for (const auto& failed_route : failed) {
654665
for (const auto& route : routes_) {
655666
if (!route->isRouted()) {
@@ -797,7 +808,7 @@ static odb::Point getValidGridPoint(
797808
}
798809

799810
void RDLRouter::cleanupGraphEdges(
800-
const std::unordered_map<odb::Point, std::set<GridGraphEdge>>& edges)
811+
const std::unordered_map<odb::Point, GridGraphEdgeSet>& edges)
801812
{
802813
if (edges.empty()) {
803814
return;
@@ -824,7 +835,7 @@ void RDLRouter::cleanupGraphEdges(
824835

825836
void RDLRouter::populateTerminalAccessPoints(
826837
RouteTarget& target,
827-
std::unordered_map<odb::Point, std::set<GridGraphEdge>>& edges) const
838+
std::unordered_map<odb::Point, GridGraphEdgeSet>& edges) const
828839
{
829840
// determine new access point in graph
830841
std::set<odb::Point> snap_pts;
@@ -1181,29 +1192,24 @@ bool RDLRouter::is45DegreeEdge(const odb::Point& pt0,
11811192
return RDLRoute::is45DegreeEdge(pt0, pt1);
11821193
}
11831194

1184-
std::set<GridGraphEdge> RDLRouter::getVertexEdges(
1185-
const GridGraphVertex& vertex) const
1195+
GridGraphEdgeSet RDLRouter::getVertexEdges(const GridGraphVertex& vertex) const
11861196
{
1187-
std::set<GridGraphEdge> edges;
1197+
GridGraphEdgeSet edges;
11881198

1199+
// The graph is undirected, so out_edges already yields every incident edge.
11891200
GridGraph::out_edge_iterator oit, oend;
11901201
std::tie(oit, oend) = boost::out_edges(vertex, graph_);
11911202
for (; oit != oend; oit++) {
11921203
edges.insert(*oit);
11931204
}
1194-
GridGraph::in_edge_iterator iit, iend;
1195-
std::tie(iit, iend) = boost::in_edges(vertex, graph_);
1196-
for (; iit != iend; iit++) {
1197-
edges.insert(*iit);
1198-
}
11991205

12001206
return edges;
12011207
}
12021208

12031209
std::vector<RDLRouter::GridEdge> RDLRouter::commitRoute(
12041210
const std::vector<GridGraphVertex>& route)
12051211
{
1206-
std::set<GridGraphEdge> edges;
1212+
GridGraphEdgeSet edges;
12071213
for (const auto& v : route) {
12081214
const auto v_edges = getVertexEdges(v);
12091215
edges.insert(v_edges.begin(), v_edges.end());

src/pad/src/RDLRouter.h

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
#pragma once
55

6+
#include <algorithm>
67
#include <cstdint>
78
#include <map>
89
#include <memory>
@@ -67,6 +68,18 @@ using GridWeightMap
6768
using GridGraphVertex = GridGraph::vertex_descriptor;
6869
using GridGraphEdge = GridGraph::edge_descriptor;
6970

71+
// Order edges by (source, target) vertex indices; the descriptor's default
72+
// operator< compares a heap pointer, giving build-dependent iteration.
73+
struct GridGraphEdgeLess
74+
{
75+
bool operator()(const GridGraphEdge& lhs, const GridGraphEdge& rhs) const
76+
{
77+
return std::minmax(lhs.m_source, lhs.m_target)
78+
< std::minmax(rhs.m_source, rhs.m_target);
79+
}
80+
};
81+
using GridGraphEdgeSet = std::set<GridGraphEdge, GridGraphEdgeLess>;
82+
7083
struct RouteTarget
7184
{
7285
// center point of the target shape
@@ -213,11 +226,11 @@ class RDLRouter
213226

214227
void populateTerminalAccessPoints(
215228
RouteTarget& target,
216-
std::unordered_map<odb::Point, std::set<GridGraphEdge>>& edges) const;
229+
std::unordered_map<odb::Point, GridGraphEdgeSet>& edges) const;
217230
void cleanupTerminalAccessPoints(odb::dbITerm* iterm,
218231
std::vector<RouteTarget>& targets) const;
219232
void cleanupGraphEdges(
220-
const std::unordered_map<odb::Point, std::set<GridGraphEdge>>& edges);
233+
const std::unordered_map<odb::Point, GridGraphEdgeSet>& edges);
221234
std::set<odb::Point> generateTerminalAccessPoints(const odb::Point& pt,
222235
bool do_x) const;
223236
TerminalAccess insertTerminalAccess(const RouteTarget& target,
@@ -227,7 +240,7 @@ class RDLRouter
227240
odb::PtrMap<odb::dbITerm, std::vector<RouteTarget>> generateRoutingTargets(
228241
odb::dbNet* net) const;
229242
odb::dbTechLayer* getOtherLayer(odb::dbTechVia* via) const;
230-
std::set<GridGraphEdge> getVertexEdges(const GridGraphVertex& vertex) const;
243+
GridGraphEdgeSet getVertexEdges(const GridGraphVertex& vertex) const;
231244

232245
void buildIntialRouteSet();
233246
int reportFailedRoutes(

src/pad/test/rdl_route_failed.ok

Lines changed: 18 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -10,53 +10,45 @@
1010
[INFO PAD-0037] End of routing iteration 2: 85.4% complete
1111
[INFO PAD-0037] End of routing iteration 3: 81.9% complete
1212
[INFO PAD-0037] End of routing iteration 4: 84.4% complete
13-
[INFO PAD-0037] End of routing iteration 5: 89.0% complete
14-
[INFO PAD-0037] End of routing iteration 6: 89.9% complete
15-
[INFO PAD-0037] End of routing iteration 7: 89.5% complete
16-
[INFO PAD-0037] End of routing iteration 8: 89.0% complete
17-
[INFO PAD-0037] End of routing iteration 9: 88.8% complete
18-
[INFO PAD-0037] End of routing iteration 10: 88.8% complete
19-
[WARNING PAD-0006] Failed to route the following 17 nets:
13+
[INFO PAD-0037] End of routing iteration 5: 89.2% complete
14+
[INFO PAD-0037] End of routing iteration 6: 90.1% complete
15+
[INFO PAD-0037] End of routing iteration 7: 90.3% complete
16+
[INFO PAD-0037] End of routing iteration 8: 90.3% complete
17+
[INFO PAD-0037] End of routing iteration 9: 89.2% complete
18+
[INFO PAD-0037] End of routing iteration 10: 90.3% complete
19+
[WARNING PAD-0006] Failed to route the following 13 nets:
2020
DVDD
2121
BUMP_11_3/PAD -> u_v18_6/DVDD, u_v18_7/DVDD, u_v18_5/DVDD, u_v18_4/DVDD, u_v18_8/DVDD, ... (67 possible terminals)
2222
BUMP_16_11/PAD -> u_v18_15/DVDD, u_v18_16/DVDD, u_v18_14/DVDD, u_v18_13/DVDD, u_v18_12/DVDD, ... (67 possible terminals)
2323
BUMP_1_13/PAD -> u_v18_26/DVDD, u_v18_27/DVDD, u_v18_28/DVDD, u_v18_25/DVDD, u_v18_29/DVDD, ... (67 possible terminals)
24-
BUMP_4_1/PAD -> u_v18_1/DVDD, u_v18_2/DVDD, u_v18_0/DVDD, u_v18_3/DVDD, u_v18_4/DVDD, ... (67 possible terminals)
2524
DVSS
26-
BUMP_0_8/PAD -> u_vzz_30/DVSS, u_vzz_29/DVSS, u_vzz_31/DVSS, u_vzz_32/DVSS, u_vzz_28/DVSS, ... (67 possible terminals)
2725
BUMP_15_11/PAD -> u_vzz_15/DVSS, u_vzz_16/DVSS, u_vzz_14/DVSS, u_vzz_13/DVSS, u_vzz_12/DVSS, ... (67 possible terminals)
2826
BUMP_15_7/PAD -> u_vzz_12/DVSS, u_vzz_13/DVSS, u_vzz_11/DVSS, u_vzz_14/DVSS, u_vzz_10/DVSS, ... (67 possible terminals)
2927
BUMP_1_9/PAD -> u_vzz_29/DVSS, u_vzz_30/DVSS, u_vzz_28/DVSS, u_vzz_31/DVSS, u_vzz_27/DVSS, ... (67 possible terminals)
28+
VDD
29+
BUMP_11_12/PAD -> u_vdd_9/VDD, u_vdd_pll/VDD, u_vdd_8/VDD, u_vdd_7/VDD, u_vdd_10/VDD, ... (33 possible terminals)
30+
BUMP_1_10/PAD -> u_vdd_13/VDD, u_vdd_14/VDD, u_vdd_12/VDD, u_vdd_15/VDD, u_vdd_11/VDD, ... (33 possible terminals)
3031
VSS
32+
BUMP_0_10/PAD -> u_vss_13/VSS, u_vss_14/VSS, u_vss_12/VSS, u_vss_15/VSS, u_vss_11/VSS, ... (33 possible terminals)
3133
BUMP_14_9/PAD -> u_vss_6/VSS, u_vss_5/VSS, u_vss_7/VSS, u_vss_4/VSS, u_vss_8/VSS, ... (33 possible terminals)
3234
BUMP_16_6/PAD -> u_vss_5/VSS, u_vss_6/VSS, u_vss_4/VSS, u_vss_7/VSS, u_vss_3/VSS, ... (33 possible terminals)
35+
p_bsg_tag_data_o
36+
BUMP_2_10/PAD -> u_bsg_tag_data_o/PAD
3337
p_clk_A_i
3438
BUMP_7_13/PAD -> u_clk_A_i/PAD
35-
p_clk_async_reset_i
36-
BUMP_9_14/PAD -> u_clk_async_reset_i/PAD
3739
p_co2_v_o
3840
BUMP_0_13/PAD -> u_co2_v_o/PAD
39-
p_ddr_addr_15_o
40-
BUMP_4_0/PAD -> u_ddr_addr_15_o/PAD
4141
p_ddr_addr_2_o
4242
BUMP_8_2/PAD -> u_ddr_addr_2_o/PAD
43-
p_ddr_addr_6_o
44-
BUMP_7_0/PAD -> u_ddr_addr_6_o/PAD
45-
p_ddr_addr_7_o
46-
BUMP_7_1/PAD -> u_ddr_addr_7_o/PAD
43+
p_ddr_addr_4_o
44+
BUMP_7_4/PAD -> u_ddr_addr_4_o/PAD
4745
p_ddr_ck_n_o
4846
BUMP_11_4/PAD -> u_ddr_ck_n_o/PAD
49-
p_ddr_dq_0_io
50-
BUMP_3_7/PAD -> u_ddr_dq_0_io/PAD
51-
p_ddr_dq_11_io
52-
BUMP_4_5/PAD -> u_ddr_dq_11_io/PAD
53-
p_ddr_dq_13_io
54-
BUMP_3_5/PAD -> u_ddr_dq_13_io/PAD
55-
p_ddr_dq_2_io
56-
BUMP_1_8/PAD -> u_ddr_dq_2_io/PAD
47+
p_ddr_dq_7_io
48+
BUMP_4_10/PAD -> u_ddr_dq_7_io/PAD
5749
p_ddr_dq_8_io
5850
BUMP_0_4/PAD -> u_ddr_dq_8_io/PAD
5951
p_ddr_dq_9_io
6052
BUMP_1_4/PAD -> u_ddr_dq_9_io/PAD
61-
[ERROR PAD-0007] Failed to route 17 nets.
53+
[ERROR PAD-0007] Failed to route 13 nets.
6254
pass

src/pad/test/rdl_route_max_iterations.ok

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313
[WARNING PAD-0006] Failed to route the following 18 nets:
1414
DVDD
1515
BUMP_11_13/PAD -> u_v18_19/DVDD, u_v18_20/DVDD, u_v18_18/DVDD, u_v18_21/DVDD, u_v18_17/DVDD, ... (67 possible terminals)
16-
BUMP_7_3/PAD -> u_v18_3/DVDD, u_v18_4/DVDD, u_v18_2/DVDD, u_v18_5/DVDD, u_v18_1/DVDD, ... (67 possible terminals)
1716
VSS
1817
BUMP_0_7/PAD -> u_vss_14/VSS, u_vss_13/VSS, u_vss_15/VSS, u_vss_12/VSS, u_vss_0/VSS, ... (33 possible terminals)
1918
BUMP_10_13/PAD -> u_vss_9/VSS, u_vss_pll/VSS, u_vss_10/VSS, u_vss_8/VSS, u_vss_7/VSS, ... (33 possible terminals)

0 commit comments

Comments
 (0)