Skip to content

grt: add read-only net detour metric (report_net_detours) (#8941)#10713

Open
saurav-fermions wants to merge 1 commit into
The-OpenROAD-Project:masterfrom
Fermions-ASI:fix/8941
Open

grt: add read-only net detour metric (report_net_detours) (#8941)#10713
saurav-fermions wants to merge 1 commit into
The-OpenROAD-Project:masterfrom
Fermions-ASI:fix/8941

Conversation

@saurav-fermions

Copy link
Copy Markdown
Contributor

Summary

Adds a read-only report_net_detours metric to global routing that flags nets with large detours by comparing a net's initial STT topology wirelength to its final routed wirelength. Strictly analysis/reporting.

Type of Change

  • New feature

Impact

New reporting command only; routing behavior and all goldens are unchanged.

Verification

  • Local build succeeds.
  • Relevant tests pass (rebuilt from source): ctest -R '^grt\.' 132/132 incl. the new report_net_detours test.
  • Code follows the repository's formatting guidelines.
  • I have signed my commits (DCO).

Related Issues

Fixes #8941


Developed with SAIGE, Fermions' autonomous RTL/EDA debugging agent; root-caused, tested, and signed off by the submitter (@saurav-fermions).

Adds an analysis/reporting command that compares each net's final routed
wirelength against its initial Steiner-tree wirelength captured before
overflow-removal routing.

- computeInitialSteinerWirelengths(): before any overflow-removal routing
  runs in globalRoute(), build the STT Steiner tree for each net (using the
  same SteinerTreeBuilder FastRoute uses) from on-grid pin positions and
  store its length per net. Read-only; does not feed the routing engine.
- report_net_detours [-net ...] [-top_n N] [-file f]: reports per-net and
  summary detour ratio (final_wl / initial_steiner_wl) and delta, with the
  worst nets by ratio. Also exposed via report_net_detour for a single net.
- Adds grt test report_net_detours1 (gcd_nangate45) with CMake + Bazel
  registration and golden .ok output.

The metric is purely read-only: routing behavior and all existing grt
goldens are unchanged (full grt regression passes 132/132).

Intermediate-stage wirelengths (post-pattern, per-congestion-iteration,
post-3D maze) are deferred as future work; this first increment captures
the initial-vs-final detour.

Fixes The-OpenROAD-Project#8941

Signed-off-by: Saurav Singh <saurav.singh@fermions.co>
@saurav-fermions saurav-fermions requested a review from a team as a code owner June 21, 2026 05:16
@saurav-fermions saurav-fermions requested a review from jfgava June 21, 2026 05:16

@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 a read-only detour reporting metric to the global router, which compares final routed wirelengths against initial Steiner-tree wirelengths. Feedback on these changes suggests using the makeSteinerTree overload that accepts odb::dbNet* to ensure correct net-specific parameters are used, adding a deterministic tie-breaker based on net IDs when sorting detour entries, and logging warnings if the detour report files fail to open.

return std::abs(x[0] - x[1]) + std::abs(y[0] - y[1]);
}

stt::Tree tree = stt_builder_->makeSteinerTree(x, y, driver_index);

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.

medium

To ensure that the initial Steiner wirelength is computed using the exact same parameters (such as net-specific alpha values) that FastRoute uses for each net, please use the makeSteinerTree overload that accepts the odb::dbNet* object.

stt::Tree tree = stt_builder_->makeSteinerTree(net->getDbNet(), x, y, driver_index);

Comment on lines +4246 to +4250
std::sort(entries.begin(),
entries.end(),
[](const DetourEntry& a, const DetourEntry& b) {
return a.ratio > b.ratio;
});

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.

medium

When sorting detour entries, if multiple nets have the same detour ratio, their relative order is non-deterministic. To ensure deterministic reporting (which is critical for regression testing), please add a tie-breaker using the unique net ID (net->getId()). This aligns with the repository's general rule of preferring unique integer IDs for tie-breaking in sort comparators.

  std::sort(entries.begin(),
            entries.end(),
            [](const DetourEntry& a, const DetourEntry& b) {
              if (a.ratio != b.ratio) {
                return a.ratio > b.ratio;
              }
              return a.net->getId() < b.net->getId();
            });
References
  1. For tie-breaking in sort comparators, prefer using unique integer IDs (e.g., cell1->id() < cell2->id()) instead of string comparisons (e.g., cell1->name() < cell2->name()), as string comparisons are highly expensive.

Comment on lines +4189 to +4197
if (!file.empty()) {
std::ofstream out(file, std::ios::app);
if (out.is_open()) {
out << "grt_detour: " << net->getName() << " "
<< block_->dbuToMicrons(initial_wl) << " "
<< block_->dbuToMicrons(final_wl) << " "
<< block_->dbuToMicrons(delta) << " " << ratio << "\n";
}
}

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.

medium

If the specified detour report file cannot be opened, the tool currently fails silently. It is better to log a warning to inform the user that the report could not be written.

  if (!file.empty()) {
    std::ofstream out(file, std::ios::app);
    if (out.is_open()) {
      out << "grt_detour: " << net->getName() << " "
          << block_->dbuToMicrons(initial_wl) << " "
          << block_->dbuToMicrons(final_wl) << " "
          << block_->dbuToMicrons(delta) << " " << ratio << "\n";
    } else {
      logger_->warn(GRT, 337, "Could not open detour report file {}.", file_name);
    }
  }

Comment on lines +4285 to +4296
std::string file(file_name);
if (!file.empty()) {
std::ofstream out(file, std::ios::app);
if (out.is_open()) {
for (const DetourEntry& e : entries) {
out << "grt_detour: " << e.net->getName() << " "
<< block_->dbuToMicrons(e.initial_wl) << " "
<< block_->dbuToMicrons(e.final_wl) << " "
<< block_->dbuToMicrons(e.delta) << " " << e.ratio << "\n";
}
}
}

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.

medium

If the specified detour report file cannot be opened, the tool currently fails silently. It is better to log a warning to inform the user that the report could not be written.

  std::string file(file_name);
  if (!file.empty()) {
    std::ofstream out(file, std::ios::app);
    if (out.is_open()) {
      for (const DetourEntry& e : entries) {
        out << "grt_detour: " << e.net->getName() << " "
            << block_->dbuToMicrons(e.initial_wl) << " "
            << block_->dbuToMicrons(e.final_wl) << " "
            << block_->dbuToMicrons(e.delta) << " " << e.ratio << "\n";
      }
    } else {
      logger_->warn(GRT, 338, "Could not open detour report file {}.", file_name);
    }
  }

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.

GRT: add "detour metric" comparing the Steiner tree and the final routing of a net

1 participant