grt: add read-only net detour metric (report_net_detours) (#8941)#10713
grt: add read-only net detour metric (report_net_detours) (#8941)#10713saurav-fermions wants to merge 1 commit into
Conversation
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>
There was a problem hiding this comment.
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); |
There was a problem hiding this comment.
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);| std::sort(entries.begin(), | ||
| entries.end(), | ||
| [](const DetourEntry& a, const DetourEntry& b) { | ||
| return a.ratio > b.ratio; | ||
| }); |
There was a problem hiding this comment.
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
- 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.
| 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"; | ||
| } | ||
| } |
There was a problem hiding this comment.
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);
}
}| 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"; | ||
| } | ||
| } | ||
| } |
There was a problem hiding this comment.
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);
}
}
Summary
Adds a read-only
report_net_detoursmetric 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
Impact
New reporting command only; routing behavior and all goldens are unchanged.
Verification
ctest -R '^grt\.'132/132 incl. the newreport_net_detourstest.Related Issues
Fixes #8941
Developed with SAIGE, Fermions' autonomous RTL/EDA debugging agent; root-caused, tested, and signed off by the submitter (@saurav-fermions).