Repository navigation
Conversation
Tiling and Interval are plain value types; a library of their own lets code that needs only them depend on them without object.cpp and odb. No change in behaviour. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.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 exact fixed-outline packing feasibility checker using the OR-Tools CP-SAT solver, integrating it as a fallback mechanism when annealing fails to find a valid tiling. It adds adapter classes to map the macro placer's internal representations to the packing problem, provides detailed user-facing explanations for packing failures, and includes comprehensive unit tests and benchmarks. The code review identified several critical robustness issues in the new code, such as potential division-by-zero errors, infinite loops in the bisection search, null pointer dereferences, out-of-bounds accesses, and undefined behavior with std::isspace. Resolving these edge cases is highly recommended to ensure the stability and safety of the solver integration.
checkPacking() decides whether rectangles fit in a fixed outline without overlap, with OR-tools CP-SAT, which OpenROAD already links: rigid blocks with one or more shapes, soft blocks whose height is floor(area / width) as SoftMacro computes it, and fixed blocks. The answer is kFits with a placement, kDoesNotFit with a cause (a block too wide or too tall, the area, or the arrangement), or kUndecided when the deterministic budget runs out; it does not depend on machine load or thread scheduling. Cheap bounds and constructions settle most problems first: a block that fits nowhere, the area, blocks wider than half the outline that must stack, identical blocks that must fit as a grid, and a shelf packing. The rest go to CP-SAT on a ladder of grids, coarse first: rounding blocks up gives placements legal at full resolution, rounding them down gives proofs that nothing fits. Nothing calls it yet. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
smallestHeight(), smallestWidth() and smallestSameAspect() bisect over exact checks for the one outline change that makes a problem fit, on a given grid (rows, sites); a bigger outline never makes a packing impossible, so a bisection is exact. The questions share one budget, and an undecided one widens the reported range instead of stalling. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
explainDoesNotFit() states that the problem is proven not to fit, its cause, and each single change to the outline that fixes it, in microns. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
toPackingProblem() states what an annealer is asked: its sequence-pair macros inside its outline, each with every shape the annealer can give it (SoftMacro::resizeRandomly's area per width interval), fixed ones where they are; terminals and empty macros take no room. The test checks that every shape the annealer produces is one the problem allows. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
MPL-0003 said only that annealing found no tiling. When no run finds
one, the exact check now either finds an arrangement, whose bounding box
becomes the tiling, or proves that none exists, and the error says why
and which single change to the core fixes it, on the row and site grid:
[ERROR MPL-0003] There are no valid tilings for mixed cluster root.
The blocks, halos included, cannot fit in the 108.432 x 108.270 um
outline (proven).
Cause: the area suffices (83% of the outline), but no arrangement of
the blocks does.
It fits with any one of:
same width 108.432 um: height >= 109.350 um
same height 108.270 um: width >= 109.350 um
same aspect ratio: width >= 109.296 um
The outline is the core area.
That is asap7/aes-block at a core of 110.5 um; a core 109.350 um wide
(2025 sites) places, one site narrower does not. A problem the check
cannot decide within its budget keeps the plain error; the README's
limitations say so.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
The step budget of each annealing run was a constant. A setter lets a caller trade time for quality, for a measurement or a design-space search; the default stays 2000. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
writePackingProblem() and readPackingProblem() write and read a problem one line per item, so a problem can be shared as a reproducer and read by tests. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
mpl_bench runs the macro placer on a floorplanned .odb as often, and with as large an annealing budget, as asked, and prints per run the wall time and the half-perimeter wirelength of the nets that touch a macro. It is tagged manual: long runs and statements about annealing quality belong on a developer's machine, not in CI. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
7b3b50a to
4c8ddb1
Compare
136 problems mpl's annealer was asked on 18 ORFS designs, and XiangShan's parent floorplan: wherever the annealer placed the macros, the exact check must decide the problem and find a legal placement too; wherever it proves that they do not fit, the proposed fix must fit. A problem the annealer could not place either may stay undecided; one, at 99% fill, does. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
4c8ddb1 to
a3812ce
Compare
Opened for discussion, and offered: take it or leave it. You may well prefer another way to test mpl. This is what suited me for fast iteration.
Stacked on #11808; review only the last four commits.
Two things:
mpl_bench, a manual binary (taggedmanual, not run in CI) that runs the macro placer on an ORFS2_1_floorplan.odbas often and with as large an annealing budget as asked, and prints per run the wall time, whether it placed, and the half-perimeter wirelength of the nets that touch a macro.MacroPlacer::setAnnealingStepsis its only caller. The numbers in mpl: stop annealing once the best result stops improving #11807 come from it. It does not need the exact check: it lifts out of this stack withsetAnnealingStepsalone.The text form doubles as a reproducer format: a problem that misbehaves can be pasted into an issue and read back with
readPackingProblem().The extraction tooling and the full study: The-OpenROAD-Project/bazel-orfs#1290.
Commits
MacroPlacer::setAnnealingStepssets the annealing budget (default 2000)mpl_benchClaude made the changes and stared at paint drying.
🤖 Generated with Claude Code