Skip to content

grt: implement CUGR net merge mirroring FastRoute path#10899

Open
sparsh-karna wants to merge 4 commits into
The-OpenROAD-Project:masterfrom
sparsh-karna:cugr-merge-net
Open

grt: implement CUGR net merge mirroring FastRoute path#10899
sparsh-karna wants to merge 4 commits into
The-OpenROAD-Project:masterfrom
sparsh-karna:cugr-merge-net

Conversation

@sparsh-karna

Copy link
Copy Markdown
Contributor

Summary

When GlobalRouter::mergeNetsRouting() fires for the CUGR path, this PR enables attempting to stitch the two existing route segments at the former buffer pin position (connectCUGRRouting) rather than ripping up and rerouting the survivor from scratch.

Key changes:

  • GlobalRouter::connectCUGRRouting(preserved, removed): Mirrors connectRouting() but uses cugr_->hasAvailableResources() instead of fastroute_->hasAvailableResources() for the capacity check. Reuses the existing geometry helpers findBufferPinPostions, findTopLayerOverPosition, and createConnectionForPositions, which are FastRoute-agnostic.

  • GlobalRouter::mergeNetsRouting() (CUGR branch): If stitching succeeds, calls cugr_->mergeNet() to transfer tree ownership and save guides. On failure, falls back to addDirtyNet() so the survivor is rerouted incrementally (matching the previous safe behavior).

  • CUGR::mergeNet(preserved, removed): Attaches the removed net's GRTreeNode subtree as a child of the preserved net's routing tree so getRoutes() emits all wire segments. Inserts the removed net into merged_nets_ so removeNet() knows not to decrement GridGraph demand for it (the wires are still physically there, just owned by the preserved net).

  • CUGR::removeNet() (merged-net guard): Skips removeTreeUsage() for nets that were transferred via mergeNet, preventing double-decrement of GridGraph congestion numbers.

  • CUGR::hasAvailableResources(layer, tile_x, tile_y): A thin wrapper over GridGraph::getEdge().getResource() >= 1.0, equivalent to FastRouteCore::hasAvailableResources().

Type of Change

  • New feature

Impact

Improves QoR (Quality of Results) and runtime during incremental routing by preserving existing routing topology during buffer removal ECOs when using CUGR, matching FastRoute's behavior.

Verification

  • I have verified that the local build succeeds (./etc/Build.sh).
  • I have run the relevant tests and they pass. (All 143 GRT regression tests pass.)
  • My code follows the repository's formatting guidelines.
  • I have included tests to prevent regressions.
  • I have signed my commits (DCO).

Related Issues

None.

When GlobalRouter::mergeNetsRouting() fires for the CUGR path, attempt
to stitch the two existing route segments at the former buffer pin
position (connectCUGRRouting) rather than ripping up and rerouting the
survivor from scratch.

Key changes:

  GlobalRouter::connectCUGRRouting(preserved, removed)
    Mirrors connectRouting() but uses cugr_->hasAvailableResources()
    instead of fastroute_->hasAvailableResources() for the capacity
    check.  Reuses the existing geometry helpers findBufferPinPostions,
    findTopLayerOverPosition, and createConnectionForPositions which are
    FastRoute-agnostic.

  GlobalRouter::mergeNetsRouting() -- CUGR branch
    If stitching succeeds, call cugr_->mergeNet() to transfer tree
    ownership and save guides.  On failure, fall back to addDirtyNet so
    the survivor is rerouted incrementally (matching the previous safe
    behaviour).

  CUGR::mergeNet(preserved, removed)
    Attaches the removed net's GRTreeNode subtree as a child of the
    preserved net's routing tree so getRoutes() emits all wire segments.
    Inserts the removed net into merged_nets_ so removeNet() knows not
    to decrement GridGraph demand for it (the wires are still there,
    now owned by the preserved net).

  CUGR::removeNet() -- merged-net guard
    Skips removeTreeUsage() for nets that were transferred via mergeNet,
    preventing double-decrement of GridGraph congestion numbers.

  CUGR::hasAvailableResources(layer, tile_x, tile_y)
    Thin wrapper over GridGraph::getEdge().getResource() >= 1.0,
    equivalent to FastRouteCore::hasAvailableResources.

All 143 GRT regression tests pass.

Signed-off-by: Sparsh Karna <sparsh2005karna@gmail.com>
@sparsh-karna sparsh-karna requested a review from a team as a code owner July 13, 2026 17:17
@sparsh-karna sparsh-karna requested a review from jfgava July 13, 2026 17:17

@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 implements support for merging nets in CUGR rather than always falling back to a full dirty-net reroute. It introduces connectCUGRRouting to stitch two CUGR routes together at the former buffer pin position and perform capacity checks against the CUGR GridGraph, and updates the CUGR class to handle routing tree ownership transfer during net merges. Feedback was provided to add an early return check if either route is empty to prevent a potential crash when finding the top layer over a position.

Comment on lines +5600 to +5601
GRoute& net1_route = routes_[db_net1];
GRoute& net2_route = routes_[db_net2];

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.

high

If either net1_route or net2_route is empty, calling findTopLayerOverPosition downstream will fail to find any segments and trigger a program-terminating logger_->error call. Adding an early return check for empty routes prevents this crash and safely falls back to the dirty-net rerouting path.

  GRoute& net1_route = routes_[db_net1];
  GRoute& net2_route = routes_[db_net2];

  if (net1_route.empty() || net2_route.empty()) {
    return false;
  }

@eder-matheus

Copy link
Copy Markdown
Member

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 98e1a41ad8

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/grt/src/cugr/src/CUGR.cpp Outdated
const auto& preserved_tree = preserved_gr->getRoutingTree();
const auto& removed_tree = removed_gr->getRoutingTree();
if (preserved_tree && removed_tree) {
preserved_tree->addChild(removed_tree);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Preserve the actual CUGR stitch edge

When the incremental session ends, the CUGR path rebuilds routes_ from cugr_->getRoutes() in updateDirtyRoutes(), so the stitch segments appended only in connectCUGRRouting() are discarded. This root-to-root attachment makes getRoutes() synthesize a direct edge between the two tree roots instead of the connection between the former buffer pins; for merged nets whose CUGR roots are not those pins, the final guides/parasitics describe the wrong topology. The CUGR tree needs to encode the actual connection geometry before taking ownership of the removed tree.

Useful? React with 👍 / 👎.

@eder-matheus eder-matheus self-requested a review July 13, 2026 17:29
Signed-off-by: Sparsh Karna <sparsh2005karna@gmail.com>
Signed-off-by: Sparsh Karna <sparsh2005karna@gmail.com>
Signed-off-by: Sparsh Karna <sparsh2005karna@gmail.com>
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