WIP: GRT: Add detour metric tracking for routing stages (#8941)#9641
WIP: GRT: Add detour metric tracking for routing stages (#8941)#9641Divinesoumyadip wants to merge 4 commits intoThe-OpenROAD-Project:masterfrom
Conversation
There was a problem hiding this comment.
Code Review
This pull request introduces functionality for tracking detour metrics in the global router. The changes include a new Tcl command, C++ bindings, and core metric computation functions. The overall structure is sound and the new functionality is well-integrated. I have one suggestion to refactor a newly added function to improve code reuse and maintainability, aligning with our guidelines on avoiding code duplication.
Note: Security Review did not run due to the size of the PR.
| int total = 0; | ||
| for (const int& netID : net_ids_) { | ||
| const auto& treeedges = sttrees_[netID].edges; | ||
| const int num_edges = sttrees_[netID].num_edges(); | ||
| for (int edgeID = 0; edgeID < num_edges; edgeID++) { | ||
| const auto& edge = treeedges[edgeID]; | ||
| if (edge.len > 0) { | ||
| total += edge.route.routelen; | ||
| } | ||
| } | ||
| } | ||
| return total; |
There was a problem hiding this comment.
The logic within computeTotalWirelength duplicates the functionality of computeNetFinalWirelength. To enhance maintainability and reduce code duplication, computeTotalWirelength can be refactored to iterate through the nets and call computeNetFinalWirelength for each one.
int total = 0;
for (const int netID : net_ids_) {
total += computeNetFinalWirelength(netID);
}
return total;References
- Encapsulate the logic for calculating master symmetry in a helper function to avoid code duplication.
src/grt/src/GlobalRouter.tcl
Outdated
|
|
||
| set block [ord::get_db_block] | ||
| if { $block == "NULL" } { | ||
| utl::error GRT 240 "Missing dbBlock." |
There was a problem hiding this comment.
Notice that the message ID 240 and 241 are already used in the code. You can check the file OpenROAD/src/grt/messages.txt to see all the IDs already used.
src/grt/src/GlobalRouter.cpp
Outdated
| if (!nets.empty()) { | ||
| routes = fastroute_->run(); | ||
| int wl_after_routing = fastroute_->computeTotalWirelength(); | ||
| logger_->info(GRT, 300, "Total wirelength after routing: {} tiles", wl_after_routing); |
There was a problem hiding this comment.
Why this message is necessary? We already report the wire length at the end of the routing flow (check the computeWirelength function).
I see that your new computeTotalWirelength uses the internal FastRouteCore unit. This is good for debug purposes (which is the goal of the detour metric feature), but not really useful for users to have it as a default message.
src/grt/src/fastroute/src/maze.cpp
Outdated
| return total; | ||
| } | ||
| } // namespace grt | ||
|
|
There was a problem hiding this comment.
Remove the extra lines (here and in other files where it might happens).
| int FastRouteCore::computeNetSttWirelength(int netID) | ||
| { | ||
| int total = 0; | ||
| for (const auto& edge : sttrees_[netID].edges) { | ||
| total += edge.len; | ||
| } | ||
| return total; | ||
| } |
There was a problem hiding this comment.
In this function, the sttrees_ name is misleading. What you really want is to track the wirelength computed inside RSMT.cpp file, at the gen_brk_RSMT function. There we'll get the Steiner tree directly from Flute/PD, which is the starting point of the routing topology.
| int FastRouteCore::computeNetFinalWirelength(int netID) | ||
| { | ||
| int total = 0; | ||
| for (const auto& edge : sttrees_[netID].edges) { | ||
| if (edge.len > 0) { | ||
| total += edge.route.routelen; | ||
| } | ||
| } | ||
| return total; | ||
| } |
There was a problem hiding this comment.
You can use this function for general purposes. We want to track the wire length at 4 main stages:
- After Steiner tree construction from Flute/PD
- After building the Rectilinear Steiner Tree, before congestion iterations
- Rectilinear Steiner Tree, after congestion iterations
- Rectilinear Steiner Tree, after layer assignment and 3D maze route
You can check where in the code each of these steps happen by searching for the steinerTreeVisualization and StTreeVisualization functions. They are used for debug on the GUI, and are called at the locations where we want to track WL.
I think this function can be used to track the WL on stages 2, 3 and 4, and the computeNetSttWirelength can be used for 1.
|
@Divinesoumyadip DCO is failing in the PR. You need to sign-off your commits by adding the -s flag to the git commit call: Check the DCO link in the checks for advise on how to fix DCO. |
Thanks for the incredibly detailed review, Eder! This clarifies the internal topology flow perfectly. I will:
I will get these changes implemented, sign-off the commits to clear the DCO, and push the update shortly |
29d6a86 to
95f904b
Compare
Hi @eder-matheus , I have now amended the commits with the --signoff flag to satisfy the DCO requirement. I also included the GPoint3D forward declaration in GridGraph.h to fix the Jenkins build error. Everything should be green once the current build finishes. |
- Add computeTotalWirelength() to FastRouteCore in maze.cpp - Add public declaration in FastRoute.h - Call after fastroute_->run() in GlobalRouter::findRouting() Part of issue The-OpenROAD-Project#8941: GRT detour metric implementation Signed-off-by: Divinesoumyadip <soumyadipdasmahapatra343@gmail.com>
- Add computeNetSttWirelength() to get STT wirelength per net - Add computeNetFinalWirelength() to get final wirelength per net - Add stt_wirelengths_ map to store per-net STT wirelength - Add getSttWirelengths() accessor Part of issue The-OpenROAD-Project#8941 Signed-off-by: Divinesoumyadip <soumyadipdasmahapatra343@gmail.com>
Signed-off-by: Divinesoumyadip <soumyadipdasmahapatra343@gmail.com>
Signed-off-by: Divinesoumyadip <soumyadipdasmahapatra343@gmail.com>
95f904b to
6203c83
Compare
eder-matheus
left a comment
There was a problem hiding this comment.
Most of the changes in the code are related to comments being removed. I can't see a reason for it, so please undo these changes and make sure new updates will stay on the scope of the PR.
| const auto& treeedges = sttrees_[net_id].edges; | ||
| const int num_edges = sttrees_[net_id].num_edges(); | ||
|
|
||
| // group all edges that crosses the same position |
There was a problem hiding this comment.
Why removing this and the other comments? They don't relate to the goal of this PR
| } | ||
|
|
||
| for (const int netID : net_ids_) { | ||
| final_wirelengths_[netID] = computeNetFinalWirelength(netID); |
There was a problem hiding this comment.
final_wirelengths_ does not exists in the main class, causing a build error.
Hey @eder-matheus , opening this as a draft PR to get the initial architecture up. I've wired up the full Tcl -> C++ pipeline based on your feedback.
What's working so far:
Still left to do:
Let me know if this structural direction looks good to you before I finalize the internal variable mapping!