Skip to content

sync - #2

Open
nanocoh wants to merge 2324 commits into
keplertech:masterfrom
The-OpenROAD-Project:master
Open

sync#2
nanocoh wants to merge 2324 commits into
keplertech:masterfrom
The-OpenROAD-Project:master

Conversation

@nanocoh

@nanocoh nanocoh commented May 23, 2026

Copy link
Copy Markdown

Summary

[Describe your changes here]

Type of Change

  • Bug fix
  • New feature
  • Breaking change
  • Refactoring
  • Documentation update

Impact

[How does this change the tool's behavior?]

Verification

  • I have verified that the local build succeeds (./etc/Build.sh).
  • I have run the relevant tests and they pass.
  • My code follows the repository's formatting guidelines.
  • I have included tests to prevent regressions.
  • I have signed my commits (DCO).

Related Issues

[Link issues here]

eder-matheus and others added 9 commits July 17, 2026 17:03
Signed-off-by: Eder Monteiro <emrmonteiro@precisioninno.com>
Signed-off-by: Arthur Koucher <arthurkoucher@precisioninno.com>
Signed-off-by: Arthur Koucher <arthurkoucher@precisioninno.com>
…l route

Signed-off-by: Eder Monteiro <emrmonteiro@precisioninno.com>
Signed-off-by: Eder Monteiro <emrmonteiro@precisioninno.com>
Signed-off-by: Eder Monteiro <emrmonteiro@precisioninno.com>
Signed-off-by: Eder Monteiro <emrmonteiro@precisioninno.com>
@github-actions github-actions Bot added size/XL and removed size/XS labels Jul 18, 2026
maliberty and others added 16 commits July 18, 2026 02:11
…ly-exit

Signed-off-by: Matt Liberty <mliberty@precisioninno.com>
…ly-exit

Signed-off-by: Matt Liberty <mliberty@precisioninno.com>

# Conflicts:
#	src/dpl/src/NegotiationLegalizerPass.cpp
Order swappable cells from higher to lower drive resistance so legacy size-up chooses the smallest improving step and MT score ties prefer it. Rename the shared comparator and update its regression test while retaining the drive-resistance and intrinsic-delay ordering keys.

Signed-off-by: Jaehyun Kim <jhkim@precisioninno.com>
Treat larger intrinsic delay as weaker when drive resistance ties so both comparator keys use descending order. Add an equal-drive Liberty fixture and regression coverage because the Nangate45 buffer family cannot isolate the intrinsic-delay tie.

Signed-off-by: Jaehyun Kim <jhkim@precisioninno.com>
dpl: remove negotiation post-optimization
odb: make 3DBlox connection region check direction-aware
Permit legacy size-up to select an equal-drive replacement when its estimated stage delay improves. Extend the MT drive filter to equal resistance while retaining the strict delay-improvement check in candidate estimation and excluding the current cell.

Signed-off-by: Jaehyun Kim <jhkim@precisioninno.com>
Remove the weaker-to-stronger ordering from the multi-threaded size-up generator. The policy estimates every candidate and selects the highest score, so sorting only added unnecessary work and an implicit equal-score tie break.

Signed-off-by: Jaehyun Kim <jhkim@precisioninno.com>
Rename the current-cell drive resistance variable to drive_r in both size-up generators. This makes the resistance comparison direction explicit and avoids reading the value as drive strength.

Signed-off-by: Jaehyun Kim <jhkim@precisioninno.com>
Stop the legacy setup repair loop before starting another endpoint once the configured global iteration limit is reached.

The endpoint-local check allowed one extra iteration for each remaining endpoint, so a limit of 20 could report 65 iterations.

Reuse reachedIterationLimit in the outer endpoint loop and rebase the affected regression outputs.

Signed-off-by: Jaehyun Kim <jhkim@precisioninno.com>
rcx: fix deadcode coverity issue
Assisted-by: Claude (various models)
Signed-off-by: Martin Povišer <povik@cutebit.org>
Signed-off-by: Martin Povišer <povik@cutebit.org>
Signed-off-by: Martin Povišer <povik@cutebit.org>
Signed-off-by: Martin Povišer <povik@cutebit.org>
Assisted-by: Claude (various models)
Signed-off-by: Martin Povišer <povik@cutebit.org>
maliberty and others added 30 commits July 30, 2026 16:37
…_dfs

rsz: replace BfsIterator pull-API usage with local DFS traversal
grt: report fractional congestion information for CUGR
Boost's rtree invokes its indexable getter on every element a query
visits, and BBoxIndexableGetter derived each element's box from ODB
(inst->getBBox()->getBox(), sbox->getBox()) — a chain of dbTable lookups
per visit.  The MinSize/MinHeight predicates then derived it a second
time.  At zoom-out the query box spans the whole design, so nothing
prunes and the getter runs once per element per tile per layer; on a
676k-instance design that was ~40% of tile-render CPU, and 91% of what
remained once every visibility flag was switched off.

Store the Rect in the tree instead: insts, blockages, obstructions and
both special-net shape maps become RtreeRect, whose value is the
std::pair<Rect, payload> boost indexes on directly.  The predicates
collapse to one pair overload that reads the stored box.  Public range
types are unchanged — the queries unpack .second when collecting — so no
caller outside this file is affected.  Costs 16 bytes per entry.

Rendering is bit-identical: verified over 3744 tiles (51 layers x 8
zoom/position combos x 9 visibility variants) plus a dpr 1/1.5/2/2.5/3
sweep, comparing PNG hashes against the unpatched binary.

Signed-off-by: Matt Liberty <mliberty@precisioninno.com>
The per-instance and special-net-via passes each walked all of a
master's geometry and called dbBox::getTechLayer() on every box to
filter for the layer being drawn.  getTechLayer() resolves through
getOwner -> block/lib -> chip -> tech -> layer_tbl, so it is several
dependent pointer chases, and the web viewer pays it once per layer per
tile — 49 times per view where the Qt viewer draws every layer into one
image and pays it once.  Together the master and via sides were ~54% of
tile-render CPU on a 676k-instance design with a 30k-net power grid.

Bucket both by layer up front, in a GeomCache built once and published
as an immutable snapshot:

  master_geom: layer -> master -> {OBS polys/boxes, pin polys/boxes}
  via_boxes:   layer -> via master -> boxes in via-local coordinates

The master half mirrors gui::LayoutViewer::boxesByLayer; the via half
has no Qt counterpart because dbBox::getViaLayerBoxes() carries the same
per-box getTechLayer() walk internally.  Nesting is layer-major rather
than master-major because the render loop has the layer fixed and
iterates many instances and sboxes: one lock per tile to take the
snapshot, then lock-free lookups.  Renders run on N I/O threads, unlike
Qt's single render thread, and the shared_ptr also keeps an in-flight
render's snapshot alive across an invalidation.

A layer absent from a map has nothing any instance or via could draw
there, which also lets the searchInsts and searchSNetViaShapes queries be
skipped outright on implant/marker layers and upper metals rather than
scanning the design and discarding the result.

Pin boxes stay grouped by dbMTerm in declaration order so the ITerm
label pass keeps labelling the first drawable box per pin.  The
no-layer-filter path (a layer name a chiplet's tech does not have, which
draws every master shape in the fallback color) keeps its original
unfiltered loops: a layer-keyed cache cannot reproduce its cross-layer
draw and label ordering, and only multi-tech designs reach it.

Also give drawFilledRect and fillPolygon the optional dim parameter
setPixel and blendPixel already had.  Both called bufferDim() —
lround(sqrt(size/4)) — once per drawn shape to recover a buffer side the
render loop already knows, which was another 14% once the traversal cost
above was gone.

Measured on that design, per-tile CPU at fit-to-view: 7940 -> 1576 ms
(5.0x), with M1 89x and M2 51x; a zoomed viewport is 563 -> 424 ms.
Every ODB accessor and the libm lround leave the profile, which is now
dominated by rasterization.  Costs 0.28 GB resident.

Rendering is bit-identical: verified over 3744 tiles (51 layers x 8
zoom/position combos x 9 visibility variants) plus a dpr 1/1.5/2/2.5/3
sweep, comparing PNG hashes against the unpatched binary.

Signed-off-by: Matt Liberty <mliberty@precisioninno.com>
The geometry cache was dropped from TileGenerator::onDesignChanged, which
Search reaches only through announceModified:

    const bool prev_flag = flag.exchange(false);
    if (prev_flag) { notifyModified(); }

That debounce exists so a batch of edits does not flood connected clients
with redraws, and each index has its own flag — so an edit clearing an
index that is already invalid is silent.  Reachable whenever a render has
touched some indices but not others: draw an _instances tile (insts_init
true, shapes_init still false), then add an SWire, and the callback never
fires.  The shape R-tree rebuilds correctly but the cache keeps a
pre-edit snapshot, so findViaBoxes returns nothing for a via master the
edit introduced and those shapes silently stop drawing.  Nothing could go
stale this way before the cache existed, since layer membership was read
live from ODB per box.

Give Search an undebounced revision counter — bumped by every edit it
hears about, whether or not the callback fires — and have geomCache()
rebuild when it moves.  This separates "did anything change" (cheap,
pull-based) from "tell the browser" (debounced, push-based), so the
redraw debounce is untouched.  The revision is read before the rebuild,
so an edit landing mid-build leaves the recorded value behind and the
next call rebuilds again.

eagerInit keeps dropping the cache outright: a reload's fresh dbMaster
and dbVia objects can be allocated where the old ones were, so a
revision bump alone would not prove the keys still mean the same thing —
the same address-reuse hazard the layer-color cache is cleared for.

GeomCacheRebuiltAfterDebouncedEdit reproduces the silent path and fails
without this fix.  Also covers the layer bucketing (a Nangate45 cell's
metal1 pins must not appear on a metal2 tile) and snapshot reuse across
tiles with no intervening edit.

Verified on a 676k-instance design: rendering is still bit-identical over
the same 3744-tile sweep, and fit-to-view wall clock is unchanged at
1169 ms, confirming the poll does not rebuild per tile.

Signed-off-by: Matt Liberty <mliberty@precisioninno.com>
Signed-off-by: dsengupta0628 <dsengupta@precisioninno.com>
Signed-off-by: Eder Monteiro <emrmonteiro@precisioninno.com>
…oft-NDR demotion

Signed-off-by: Jonas Gava <jfgava@precisioninno.com>
Signed-off-by: Mike Inouye <mikeinouye@google.com>
Two gaps in buildGeomCache(), both on the chiplet side.

chiplets() reports one node per dbChipInst, so every instance of a shared
master chip reports the same dbBlock.  The via-master loop visited that
block once per instance and appended each dbVia's boxes again every time,
so the render pass redrew every box once per instance of the chiplet —
invisible in the output, since the fills are opaque, but quadratic in the
repeat count and it multiplies the cache's memory by it as well.  Track
the blocks already visited.

Separately, geomCache() keyed only on Search::revision(), which cannot
move when a dbChipInst is created: dbBlockCallBackObj has no chip-instance
hook.  Every other source of new geometry reaches revision() transitively
— a dbVia or dbMaster only becomes drawable once an sbox or instance
references it, and those do notify — but a chip instance makes an
already-populated block's vias newly reachable with no block edit at all.
chiplets() notices, via its own root-pointer + dbChipInst-count
fingerprint, so the render loop starts drawing the new chiplet while the
cache keeps a snapshot built without that block's dbVia masters:
findViaBoxes returns nothing and the chiplet's special-net vias silently
do not draw until an unrelated block edit or eagerInit() rebuilds.

Give chiplets() a generation counter, bumped whenever it rebuilds, and
add it to the geometry cache's key.  Read before the build like the
revision, so a hierarchy edit landing mid-build leaves the recorded value
behind the live one and the next call rebuilds.

GeomCacheVisitsASharedChipletBlockOnce and
GeomCacheRebuiltAfterChipletInstCreated fail without these fixes (3
duplicate boxes instead of 1; a snapshot missing the new chiplet's via).

Signed-off-by: Matt Liberty <mliberty@precisioninno.com>
Signed-off-by: Jonas Gava <jfgava@precisioninno.com>
Signed-off-by: Mike Inouye <mikeinouye@google.com>
Signed-off-by: Mike Inouye <mikeinouye@google.com>
Signed-off-by: Jonas Gava <jfgava@precisioninno.com>
…antennas

grt: fix antenna check based on CUGR guides
Signed-off-by: bnmfw <bernardoborgessandoval@gmail.com>
…render-perf

web: remove per-tile ODB traversal from tile rendering
Signed-off-by: Eder Monteiro <emrmonteiro@precisioninno.com>
Signed-off-by: Eder Monteiro <emrmonteiro@precisioninno.com>
Signed-off-by: Eder Monteiro <emrmonteiro@precisioninno.com>
rsz: check for dont touch before applying CloneMove
…repair_antennas

grt: repair antennas with diodes when using CUGR
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.