dpl: negotiation dynamic window#10807
Conversation
make sure the window fits properly with valid rows, Y range is given by min between: (cell height * constantY), versus max y displacement X range is given by min between: max(constantX, cell width), versus max x displacement Signed-off-by: Augusto Berndt <augusto.berndt@precisioninno.com>
include new debug messa for debuging window range Signed-off-by: Augusto Berndt <augusto.berndt@precisioninno.com>
…gotiation-dynamic-window Signed-off-by: Augusto Berndt <augusto.berndt@precisioninno.com>
…verbosity Signed-off-by: Augusto Berndt <augusto.berndt@precisioninno.com>
…t row only Signed-off-by: Augusto Berndt <augusto.berndt@precisioninno.com>
…d macros Signed-off-by: Augusto Berndt <augusto.berndt@precisioninno.com>
Signed-off-by: Augusto Berndt <augusto.berndt@precisioninno.com>
…larity also Signed-off-by: Augusto Berndt <augusto.berndt@precisioninno.com>
Signed-off-by: Augusto Berndt <augusto.berndt@precisioninno.com>
|
The diffs here should be more clear after #10681 is merged. |
There was a problem hiding this comment.
Code Review
This pull request enhances the detailed_placement command in OpenDP by introducing configurable search windows (-site_search_window, -row_search_window) and DRC penalties (-drc_penalty) for the NegotiationLegalizer. It also adds stuck-cell diagnostics, improves GUI debugging with a negotiation violations chart, and updates the observer to track current-iteration movers. Feedback is provided regarding a potential null pointer dereference when retrieving the master of an instance in Opendp::detailedPlacement, which should be guarded to prevent segmentation faults.
| for (odb::dbInst* inst : block_->getInsts()) { | ||
| odb::dbMaster* master = inst->getMaster(); | ||
| total_inst_area += static_cast<int64_t>(master->getWidth()) | ||
| * static_cast<int64_t>(master->getHeight()); | ||
| } |
There was a problem hiding this comment.
In the calculation of total_inst_area, inst->getMaster() is called and dereferenced directly without checking if it is nullptr. While instances in a placed design typically have a master, it is safer to add a null check to prevent potential segmentation faults in edge cases or during intermediate database states.
for (odb::dbInst* inst : block_->getInsts()) {
odb::dbMaster* master = inst->getMaster();
if (master != nullptr) {
total_inst_area += static_cast<int64_t>(master->getWidth())
* static_cast<int64_t>(master->getHeight());
}
}Signed-off-by: Augusto Berndt <augusto.berndt@precisioninno.com>
Signed-off-by: Augusto Berndt <augusto.berndt@precisioninno.com>
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 9a14e87477
ℹ️ 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".
… macro or offcore Signed-off-by: Augusto Berndt <augusto.berndt@precisioninno.com>
Signed-off-by: Augusto Berndt <augusto.berndt@precisioninno.com>
Signed-off-by: Augusto Berndt <augusto.berndt@precisioninno.com>
|
@eder-matheus @osamahammad21 This one should be our priority considering DPL. With this PR merged we have solved all known issues with Negotiation legalizer. |
|
@gudeh please give ispd15_mgc_superblue12 a try. |
…sion, use the base values as the window size itself Signed-off-by: Augusto Berndt <augusto.berndt@precisioninno.com>
Signed-off-by: Augusto Berndt <augusto.berndt@precisioninno.com>
osamahammad21
left a comment
There was a problem hiding this comment.
Instead of the per-side deficit-and-reallocate logic, model each axis as one budget of 2 * window positions explored by two pointers walking outward from the anchor. Each consumes from the shared budget until it runs out or hits a wall; when one side walls early, the other naturally absorbs the rest. No separate deficit computation, nothing explored past a wall, and the both-walls case falls out for free. disable_window_extension reduces to just the per-side cap (window vs max_displacement).
Also, Can we get a multi-height test here? All the negotiation tests are single-height gcd, so none of the new code paths actually run.
| const int left_deficit | ||
| = disable_window_extension_ ? 0 : site_window - left_avail; | ||
| const int right_deficit | ||
| = disable_window_extension_ ? 0 : site_window - right_avail; |
There was a problem hiding this comment.
what if both ends are hitting a wall? or what if the extended window itself is hitting a wall?
There was a problem hiding this comment.
I see an example with only a 2 row strip sandwiched by macros. The window fits nicely on the available space.
And if it were to overlap with the macro (as it did before) is a problem because before we accept any actual movement we check for site validity, even after the window extension.
| // TODO: check if this second call is actually impactful, maybe this impacts | ||
| // runtime without actual better convergence, mostly considering first | ||
| // iteration, maybe always skip this at first iteration. | ||
| // |
There was a problem hiding this comment.
how do you plan to test this?
…_window_extension Signed-off-by: Augusto Berndt <augusto.berndt@precisioninno.com>
Signed-off-by: Augusto Berndt <augusto.berndt@precisioninno.com>
Signed-off-by: Augusto Berndt <augusto.berndt@precisioninno.com>
| = disable_window_extension_ ? 0 : site_window - left_avail; | ||
| const int right_deficit | ||
| = disable_window_extension_ ? 0 : site_window - right_avail; | ||
| int dx_lo = -(site_window + right_deficit); |
There was a problem hiding this comment.
why not?
| int dx_lo = -(site_window + right_deficit); | |
| int dx_lo = -(left_avail + right_deficit); |
|
@gudeh
The availability scan stops at the first wall, so dx_lo = -(site_window + right_deficit) = -40
dx_hi = (site_window + left_deficit) = +76Window = [−40, +76]. The inconsistency: The macro only covers 10 sites, but we extend the right by 36. The cell ends up eligible to move +76 on the strength of open space it never actually lost. If the deficit measured how much the macro actually covers (10), it'd be I think a two-pointer walk out from BASE would avoid this entirely: each side keeps walking through walls (a blocked site just doesn't count, it doesn't stop the pointer), collecting usable sites up to |
|
|
I should push my latest changes. And I will review the last situation you described. I do not think we could have such a small macro, but a fixed instance is possible definetevely. While I was implementing the change you requested, I also realized this limitation, we were early stopping. |
…xed instances), Replace the per-side deficit-and-reallocate logic with two pointers walking out from the anchor. Keep loking past fixed instances and budget it cannot spend is used on the other side. Include the consideration of row-less spaces. Signed-off-by: Augusto Berndt <augusto.berndt@precisioninno.com>
|
Latest secure-CI requires updates on two designs, PR is already open. |
|
@osamahammad21 your comments can be taken up in another PR |

Summary
Makes the Negotiation Legalizer search window range adaptive instead of fixed X and Y dimensions.
We apply two extensions:
Experiments showed far more problems on the Y direction with multi-height and hybrid row structures, requiring more extensions on such dimension.
Type of Change
Impact
This solves convergence issues Negotiation Legalizer was having with multi-height cells designs. We were getting search windows too small, and a few instances never moving.
Verification
./etc/Build.sh).Related Issues
This is one of multiple PRs splitting up PR #10226 to make Negotiation the default algorithm at DPL.
This is the last PR to solve all known issues with Negotiation Legalizer. After this one I expect only to make cosmetic modifications and actually switching to the new default.