dpl: fix topological sort cycle with multi-height cells in shift lega…#10137
dpl: fix topological sort cycle with multi-height cells in shift lega…#10137Divinesoumyadip wants to merge 3 commits intoThe-OpenROAD-Project:masterfrom
Conversation
…lizer Multi-height cells appear in segments across multiple rows. When a single-height cell sits inside the row span of two multi-height cells, the ordering differs per row, creating a cycle in the topological sort which triggers DPL-0400. Fix: only add dependency edges when both cells' bottom Y matches the current segment's row bottom, ensuring each multi-height cell contributes edges only from its primary (bottom) row. Fixes The-OpenROAD-Project#9932 Signed-off-by: Divinesoumyadip <soumyacode7@gmail.com>
There was a problem hiding this comment.
Code Review
This pull request modifies the dependency graph construction in ShiftLegalizer::legalize by only adding edges between cells that align with the current row's bottom, aiming to prevent cycles in the topological sort. The reviewer pointed out that this logic is flawed as it ignores necessary constraints between cells of varying heights, which could lead to overlaps. A more robust solution was suggested: making the cell comparison deterministic by using cell IDs as a tie-breaker in the sorting logic, while also noting that the current changes create an inconsistency with the shifting logic in the same class.
| if (prev->getBottom() != rowBottom || curr->getBottom() != rowBottom) { | ||
| continue; | ||
| } |
There was a problem hiding this comment.
The logic introduced here to avoid cycles by only adding edges when both cells' bottom matches the current row's bottom is problematic for correctness. It effectively ignores dependency constraints between cells of different heights or cells that start at different rows.
For example, if a multi-height cell
- In Row 0:
$S$ is not present. - In Row 1:
$M.getBottom()$ (Row 0) does not matchrowBottom(Row 1), so the edge is skipped.
This lack of constraints can lead to overlaps during the shifting process, as the legalizer will not maintain the required relative ordering of these cells.
The root cause of the topological sort cycles is likely the non-deterministic sorting in DetailedMgr::compareNodesX (in detailed_manager.h). When two cells have the same X center, std::sort may produce different relative orders in different row segments, creating a cycle. A more robust fix would be to make the cell comparison deterministic by adding a tie-breaker, such as the cell ID:
struct compareNodesX {
bool operator()(Node* p, Node* q) const {
if (p->getCenterX() != q->getCenterX())
return p->getCenterX() < q->getCenterX();
return p->getId() < q->getId();
}
};Additionally, note that this PR only modifies the first loop that builds the dependency graph for the topological sort check, but leaves the second loop in ShiftLegalizer::shift (lines 273-282) unchanged. This inconsistency means the clump logic will still operate on the original, potentially cyclic/inconsistent graph.
References
- Iteration or sorting over pointer-based collections requires a custom comparator or a unique tie-breaker (like an ID) to ensure deterministic behavior across different runs.
|
clang-tidy review says "All clean, LGTM! 👍" |
|
FYI, our efforts are mostly going towards the new negotiation based legalizer which will become the new default. |
should I still pursue this or skip given the new legalizer? |
|
The new legalizer is executed before improve placement. So I say you should go for the fix! We should still run improve placement even with the new legalizer. Legalization is performed with |
…aker Signed-off-by: Divinesoumyadip <soumyacode7@gmail.com>
d9f111e to
7b5d315
Compare
| { | ||
| return p->getCenterX() < q->getCenterX(); | ||
| if (p->getCenterX() != q->getCenterX()) | ||
| return p->getCenterX() < q->getCenterX(); |
There was a problem hiding this comment.
warning: statement should be inside braces [google-readability-braces-around-statements]
| return p->getCenterX() < q->getCenterX(); | |
| if (p->getCenterX() != q->getCenterX()) { | |
| return p->getCenterX() < q->getCenterX(); | |
| } |
gudeh
left a comment
There was a problem hiding this comment.
LGTM
OR tests seem to indicate no-op. I also triggered a secure-CI to be sure.
@Divinesoumyadip have you confirmed this solves the issue with the reproducible ?
|
You also need to solve the clang-format and clang-tidy |
Signed-off-by: Divinesoumyadip <soumyacode7@gmail.com>
61728a3 to
39a00e7
Compare
|
clang-tidy review says "All clean, LGTM! 👍" |
1 similar comment
|
clang-tidy review says "All clean, LGTM! 👍" |
Summary
improve_placementfails withDPL-0400 Cells incorrectly ordered during shiftingon designs with multi-height cells. Multi-height cells appear in segments across multiple rows. When a single-height cell sits inside the row span of two multi-height cells, the ordering differs per row, creating a cycle in the topological sort. Fix: inlegalize_shift.cxx, only add dependency edges when both cells' bottom Y matches the current segment's row bottom. Multi-height cells contribute edges only from their primary (bottom) row, eliminating the cycle.Type of Change
Bug fix
Impact
improve_placementno longer crashes with DPL-0400 on designs containing multi-height cells such as SRAMs. No behavioral change for single-height-only designs.Related Issues
Fixes #9932