Skip to content

drt: make guide and GR pin query order deterministic#10918

Open
naveenvenk17 wants to merge 2 commits into
The-OpenROAD-Project:masterfrom
naveenvenk17:nv-drt-canonical-query-order
Open

drt: make guide and GR pin query order deterministic#10918
naveenvenk17 wants to merge 2 commits into
The-OpenROAD-Project:masterfrom
naveenvenk17:nv-drt-canonical-query-order

Conversation

@naveenvenk17

Copy link
Copy Markdown
Contributor

What

Sort guide query results by net name, layer, geometry, and owner index. Sort global-routing pin results by stable instance and terminal identity.

Only results appended by the current query are sorted, so callers that accumulate results keep the existing API behavior.

Why

Boost R-tree ordering is not defined when entries have equal bounding boxes. Track assignment uses guide iteration order when it creates internal routes, and some pin handling paths select the first matching global-routing pin. Different standard-library implementations can therefore choose different routing states from identical inputs.

The new regression inserts two equal-geometry guides in reverse lexical net order. It fails on current master with n2, n1 and passes with this change as n1, n2.

This addresses the remaining R-tree query-order problem described in #10336. It is independent of the priority-queue comparator work in #10816.

Testing

  • Confirmed the new regression fails before the implementation change
  • bazel test //src/drt/test:ta_unittest --test_filter=*guide_query_has_canonical_order*
  • bazel test //src/drt/test:gc_unittest //src/drt/test:ta_unittest
  • Both native DRT suites with ASan and detect_leaks=0
  • bazel build --config=lint //src/drt:drt //src/drt/test:ta_unittest
  • 24 of 25 non-documentation DRT targets pass

The remaining aes_nangate45-py_test failure is unchanged on current master: its Python harness cannot import openroad.

Signed-off-by: Naveen Venkat <archgen.guest@nyayanidhi.in>
@naveenvenk17
naveenvenk17 requested a review from a team as a code owner July 15, 2026 06:02

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Code Review

This pull request introduces deterministic sorting for guide and GR pin queries in frRegionQuery by implementing custom comparators (guideLess and grPinLess) and sorting the query results. A unit test was also added to verify the canonical ordering. The review feedback recommends optimizing these comparators by replacing expensive string comparisons (getName()) with unique integer IDs (getId()) for tie-breaking, and adjusting the unit test creation order to align with this ID-based sorting.

Comment thread src/drt/src/frRegionQuery.cpp Outdated
Comment thread src/drt/src/frRegionQuery.cpp
Comment thread src/drt/test/taTest.cpp Outdated
Signed-off-by: Naveen Venkat <archgen.guest@nyayanidhi.in>
@naveenvenk17

Copy link
Copy Markdown
Contributor Author

Updated the comparators to use object IDs and adjusted the fixture creation order. Both DRT native suites pass in the normal configuration, and the DRT lint build passes on the VM. I am also running the suites with the sanitizer runtime fix from #10911 layered underneath because the current master branch cannot link ASan binaries by itself.

@naveenvenk17

Copy link
Copy Markdown
Contributor Author

The sanitizer run is complete. I tested the updated branch with #10911 layered underneath so the ASan runtime can link. Both ta_unittest and gc_unittest pass with ASAN_OPTIONS=detect_leaks=0.

@osamahammad21 osamahammad21 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Unrelated, but original guides query has the same issue. It would be good to fix it as well, but it could be in a separate PR.

Comment thread src/drt/test/taTest.cpp
Comment on lines +157 to +174
TEST_F(TAFixture, guide_query_has_canonical_order)
{
frNet* n1 = makeNet("n1");
frNet* n2 = makeNet("n2");
makeGuide(n2, /*layer_num=*/2, {500, 500}, {1500, 500});
makeGuide(n1, /*layer_num=*/2, {500, 500}, {1500, 500});

initTAQueries();

frRegionQuery::Objects<frGuide> result;
design->getRegionQuery()->queryGuide(
odb::Rect(0, 0, 2000, 2000), /*layerNum=*/2, result);

ASSERT_EQ(result.size(), 2);
EXPECT_EQ(result[0].second->getNet()->getName(), "n1");
EXPECT_EQ(result[1].second->getNet()->getName(), "n2");
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This is not directly relevant to TA testing. I would prefer to move it to a separate test focused specifically on region query.

Comment on lines +39 to +57
bool guideLess(const frGuide* lhs, const frGuide* rhs)
{
const auto [lhs_begin, lhs_end] = lhs->getPoints();
const auto [rhs_begin, rhs_end] = rhs->getPoints();
return std::make_tuple(lhs->getNet()->getId(),
lhs->getLayerNum(),
lhs_begin.x(),
lhs_begin.y(),
lhs_end.x(),
lhs_end.y(),
lhs->getIndexInOwner())
< std::make_tuple(rhs->getNet()->getId(),
rhs->getLayerNum(),
rhs_begin.x(),
rhs_begin.y(),
rhs_end.x(),
rhs_end.y(),
rhs->getIndexInOwner());
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Why not sort by the ID? the GuidesProcessor assigns a global unique id for each guide before initializing the guide RQ

Comment on lines +74 to +79
if (lhs->typeId() == frcBTerm) {
const auto* lhs_term = static_cast<const frBTerm*>(lhs);
const auto* rhs_term = static_cast<const frBTerm*>(rhs);
return lhs_term->getId() < rhs_term->getId();
}
return lhs->getId() < rhs->getId();

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Those are equivalent !!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants