dpl: make optimize_mirroring deterministic#10573
Conversation
net_box_map_ is an unordered_map, so equal-hpwl boxes sorted in heap-address order (ranges::sort is not stable), making the mirroring result and the written db non-deterministic. Tie-break by net id. Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
There was a problem hiding this comment.
Code Review
This pull request updates the sorting logic for net boxes in OptimizeMirroring::run by introducing a tie-breaker based on the net ID when the HPWL values are equal, ensuring stable and deterministic output. There are no review comments, and I have no feedback to provide.
|
While here, I swept the codebase for the same shape: a non-stable sort whose comparator is not a strict total order (single key, ties possible), over a sequence whose order is itself non-deterministic — built by iterating a pointer-keyed Likely bugs
OpenROAD/src/rsz/src/RepairDesign.cc Lines 648 to 651 in 73ab739 OpenROAD/src/rsz/src/Rebuffer.cc Lines 1502 to 1504 in 73ab739
OpenROAD/src/odb/src/defout/defout_impl.cpp Lines 1136 to 1147 in 73ab739 Suspects (single-key comparator feeding output; only deterministic if the input source happens to be ordered today)DEF blockage sort — keyed on rect only, no unique tie-break: OpenROAD/src/odb/src/defout/defout_impl.cpp Lines 1203 to 1207 in 73ab739 DEF
OpenROAD/src/dft/src/replace/ScanReplace.cpp Lines 179 to 190 in 73ab739
OpenROAD/src/cts/src/TritonCTS.cpp Lines 2466 to 2470 in 73ab739
OpenROAD/src/grt/src/fastroute/src/graph2d.cpp Lines 549 to 551 in 73ab739
OpenROAD/src/par/src/PartitionMgr.cpp Line 744 in 73ab739 For reference, OpenROAD/src/dbSta/src/dbNetwork.cc Lines 419 to 422 in 73ab739 |
|
/gemini review |
There was a problem hiding this comment.
Code Review
This pull request updates the sorting logic for sorted_boxes in OptimizeMirroring::run within src/dpl/src/OptMirror.cpp. It introduces a tie-breaker using the net ID when the HPWL values are equal, ensuring stable sorting output since the underlying map is unordered. There are no review comments, so I have no feedback to provide.
| }); | ||
| std::ranges::sort( | ||
| sorted_boxes, [](NetBox* net_box1, NetBox* net_box2) -> bool { | ||
| if (net_box1->hpwl() != net_box2->hpwl()) { |
There was a problem hiding this comment.
you might want to do:
const auto hpwl1 = net_box1->hpwl();
const auto hpwl2 = net_box2->hpwl();
if (hpwl1 != hpwl2 ) {
return hpwl1 > hpwl2;
}
To avoid recomputing the hpwl twice
net_box_map_is astd::unordered_map<dbNet*, NetBox>, so thesorted_boxesvector built from it starts in heap-address order. Thecomparator keys on
hpwl()alone andstd::ranges::sortis not stable,so equal-hpwl boxes keep that non-deterministic order. The greedy
mirrorCandidates()then mutates boxes in that order, so the mirroringresult — and the written db — differs run to run.
Tie-break the sort by net id for a stable total order.
src/dpl/testmirror1/2/3 output is unchanged.