Repository navigation
Conversation
Carry forward the reviewed changes from The-OpenROAD-Project#11853 under the correct contributor account. The source tree matches 5e30ad2. Signed-off-by: Naveen Venkat <81929600+naveenvenk17@users.noreply.github.com>
|
This PR exceeds the recommended size of 1000 lines. Please make sure you are NOT addressing multiple issues with one PR. Note this PR might be rejected due to its size. |
There was a problem hiding this comment.
Code Review
This pull request introduces an experimental, opt-in -timing_driven_congestion_inflation option to global_placement. When enabled alongside timing-driven and routability-driven modes, it refreshes RUDY after timing repairs and inflates newly inserted standard cells without restarting the routability search. Feedback on the implementation identifies a potential segmentation fault in GCell::inflationArea() where insts_.front() is accessed without checking if insts_ is empty, and suggests adding a defensive check.
| int64_t GCell::inflationArea() const | ||
| { | ||
| if (isFiller()) { | ||
| return 0; | ||
| } | ||
| // Instance geometry carries current master dimensions, placement padding | ||
| // and pin-density extension. A move callback can make the GCell unpadded; | ||
| // it must not change this reference or turn padding into congestion area. | ||
| int64_t physical_area = insts_.front()->getArea(); | ||
| if (insts_.size() > 1) { | ||
| const GCell physical(insts_); | ||
| physical_area = static_cast<int64_t>(physical.dx()) * physical.dy(); | ||
| } | ||
| return std::max<int64_t>(0, | ||
| static_cast<int64_t>(dx()) * dy() - physical_area); | ||
| } |
There was a problem hiding this comment.
In GCell::inflationArea(), calling insts_.front() without verifying if insts_ is empty can lead to undefined behavior or a segmentation fault if the GCell has no associated instances. Adding a defensive check for insts_.empty() ensures robustness.
int64_t GCell::inflationArea() const
{
if (isFiller()) {
return 0;
}
if (insts_.empty()) {
return 0;
}
// Instance geometry carries current master dimensions, placement padding
// and pin-density extension. A move callback can make the GCell unpadded;
// it must not change this reference or turn padding into congestion area.
int64_t physical_area = insts_.front()->getArea();
if (insts_.size() > 1) {
const GCell physical(insts_);
physical_area = static_cast<int64_t>(physical.dx()) * physical.dy();
}
return std::max<int64_t>(0,
static_cast<int64_t>(dx()) * dy() - physical_area);
}There was a problem hiding this comment.
isFiller() is defined as insts_.empty(), so the existing early return already guards front().
Regenerated against the current upstream merge and checked for idempotence on the GCP VM. Only the missing Bison registry checksum is added; no dependency versions change. Signed-off-by: Naveen Venkat <81929600+naveenvenk17@users.noreply.github.com>
Signed-off-by: Naveen Venkat <81929600+naveenvenk17@users.noreply.github.com>
Signed-off-by: Naveen Venkat <81929600+naveenvenk17@users.noreply.github.com>
|
|
gudeh
left a comment
There was a problem hiding this comment.
To approve this PR we need QoR experiments, I should try to run a secure-CI to asses the impact of this.
| value is calculated based on the weight coefficients. The algorithm will stop | ||
| if the RC is not decreasing for three consecutive iterations. | ||
|
|
||
| The optional `-timing_driven_congestion_inflation` experiment is disabled by |
There was a problem hiding this comment.
This description is way more complex than necessary.
There was a problem hiding this comment.
Shortened this to the option's behavior, its prerequisites and the filler-budget limit.
| = tb_->executeTimingDriven(virtual_td_iter, enable_repair_timing); | ||
| // fixPointers() may have moved the GPins the IO pins point at. | ||
| getTopLevelNB()->refreshIoPins(); | ||
| const bool retained_inflation |
There was a problem hiding this comment.
We shouldn't do this on TD iterations that happen before routability mode. I am not entirely sure only !is_routability_need_ guarantees that, could be reviewed to make sure.
There was a problem hiding this comment.
I checked the state transitions and added regressions for early timing passes, active routability passes, completion and re-entry. The new path requires a retained repair, the opt-in flag, routability mode and !is_routability_need_. That state starts true; only runRoutability() changes it, and any final restore completes before the next timing-repair iteration. The early and active cases leave new cells uninflated.
|
|
||
| const std::vector<GCellHandle>& getGCells() const { return nb_gcells_; } | ||
|
|
||
| // Pending callback creations, consumed by updateGCellState(). Resolve these |
There was a problem hiding this comment.
Pending callback creations? Does this ever happen? If so, we may have a bug.
There was a problem hiding this comment.
The callbacks are synchronous and have already created the GCells. new_instances_ tracks those creations until the optimizer-state update; it does not represent callbacks waiting to run. I removed the misleading wording and added tests for deduplication, reindexing, deletion and consuming each creation once.
| debugInflatedTiles(); | ||
| } | ||
|
|
||
| int64_t RouteBase::inflateNewCells() |
There was a problem hiding this comment.
Why are inflations being handled here different from the default ones? Can't we have a single function to be used both here (for new instances), and at the original routability inflations?
There was a problem hiding this comment.
Both paths now call inflateCell(). Ordinary routability keeps its existing float arithmetic and rounding; late insertions pass an area limit so the result fits the live allowance and available whole fillers. I reran the GCD/AES default-off comparison against upstream plus the separate TileGrid fix in #11917. All 15 saved result files and all checked non-runtime metrics match on both designs.
|
Thanks for the review. I'll rename the getter, shorten the README text, and remove the extra comment. I'm also tracing the TD/routability transition and the callback updates, then refactoring the shared inflation logic so the two paths use the same geometry calculation. I'll post refreshed VM QoR runs after that update. The existing GCD/AES results are mixed, which is why the option is still off by default. A broader secure-CI run would be useful before approval. |
Signed-off-by: Naveen Venkat <81929600+naveenvenk17@users.noreply.github.com>
Signed-off-by: Naveen Venkat <81929600+naveenvenk17@users.noreply.github.com>
Preserve ordinary float rounding and bounded late filler funding. Document the completed-routability latch and synchronous callback staging, and cover real retained repairs across phase gates and shared geometry rounding boundaries. Signed-off-by: Naveen Venkat <81929600+naveenvenk17@users.noreply.github.com>
|
Updated this in I ran baseline, OFF and ON for Nangate45 GCD and AES through legalization, CTS and global routing. The baseline is AES exercised the new path. TNS and wirelength improved, but WNS, area and estimated power got slightly worse. GCD added no inflation. I've put the actual numbers and test scope in the description, and kept this opt-in. All 47 focused cases passed under ASan, with leak detection disabled. The focused regressions and flow evidence also received independent agent review. Larger secure-CI runs would still be useful before judging whether this is worth keeping. |
vvbandeira
left a comment
There was a problem hiding this comment.
approved from devops team side
| global_placement | ||
| [-skip_initial_place] | ||
| [-incremental] | ||
| [-timing_driven_congestion_inflation] |
There was a problem hiding this comment.
Lets make this default behavior and remove the TCL parameter.
There was a problem hiding this comment.
Done. The switch and C++ option are gone, and the late-inflation path is now the default for timing-driven, routability-driven placement.
I merged master and updated the snapshot/API fixtures too. The merged head passed 139 selected checks, 494 normal native case executions and 347 ASan executions. Fresh GCD/AES runs matched the old switch-enabled behavior through global routing, including the AES late-inflation event. The hardware INFO-line mismatch in mt_invariance01 is unchanged on both versions; the DEFs match the upstream golden.
I also resolved the BUILD conflict with the merged #11917 by moving the test declaration. No target attributes or C++ sources changed. The focused suite and default-behavior Tcl check passed again.
Signed-off-by: Naveen Venkat <81929600+naveenvenk17@users.noreply.github.com>
Signed-off-by: Naveen Venkat <81929600+naveenvenk17@users.noreply.github.com>
Signed-off-by: Naveen Venkat <81929600+naveenvenk17@users.noreply.github.com>
Signed-off-by: Naveen Venkat <81929600+naveenvenk17@users.noreply.github.com>
maliberty
left a comment
There was a problem hiding this comment.
approve for openroad-maintainers
|
I think we should merge this @maliberty. We seem to have improvements in congestion and and really small (chance level) slack improvement. Other metrics look stable. I triggered a secure-CI yesterday for large designs, I will check today if all is ok to merge. |
|
@gudeh approve and merge when ready |



Retained timing repairs can add cells after ordinary routability refinement has finished. This refreshes RUDY and inflates those surviving new cells without restarting the routability search. Virtual timing iterations and passes where routability refinement is still active do not take this path.
Following @gudeh's review, this now runs by default when timing-driven and routability-driven placement are enabled. I removed the Tcl switch and its C++ option plumbing. Late inflation uses the existing allowance and whole-filler budget; it does not raise target density.
I also merged master, updated the fixtures for the current GPL APIs and fixed the integration test to save the placer-owned routability snapshot before testing restoration. The TileGrid reset fix is separate and has merged as #11917.
After that merge, I moved this PR's test declaration to avoid a BUILD insertion-point conflict. Every target attribute and C++ source/test file is unchanged. All 49 focused cases, the default-behavior Tcl test and BUILD format/lint checks passed again after the move.
Testing on the merged head, on a Linux GCP VM with test-result caching disabled:
The earlier baseline/OFF/ON experiment had mixed tradeoffs: AES TNS and wirelength improved, while WNS, area, buffer count and estimated power worsened. The new matched runs establish equivalence between the old enabled behavior and the new default, not a general QoR improvement. No golden or metric limit was changed. No GPU, detailed-route, signoff-power or speedup claim is made.
Related to #8402.