sync - #2
Open
nanocoh wants to merge 2336 commits into
Open
Conversation
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>
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: LucasYuki <lucasyuki@yahoo.com.br>
Signed-off-by: LucasYuki <lucasyuki@yahoo.com.br>
Signed-off-by: LucasYuki <lucasyuki@yahoo.com.br>
Signed-off-by: LucasYuki <lucasyuki@yahoo.com.br>
Signed-off-by: LucasYuki <lucasyuki@yahoo.com.br>
Signed-off-by: LucasYuki <lucasyuki@yahoo.com.br>
A candidate whose displacement + congestion cost exactly ties the incumbent cannot win unless its scan rank is smaller: the DRC term only adds cost, so a nonzero count disqualifies it and a zero count leaves a tie the rank comparison rejects. Return before countDRCViolations - the most expensive term - in that case. Exact pre-DRC ties are common in uncontended regions (free sites at equal displacement over uniform history), and wavefront visit order equals rank order, so every tie after the first in a wavefront now skips its DRC evaluation. Addresses review feedback on the pull request. Signed-off-by: Matt Liberty <mliberty@precisioninno.com>
The man page cat build emitted several classes of troff/groff warnings: - 'cannot select font C/V': Pandoc renders code/verbatim text in the Courier font family, which the nroff/tty device lacks. Add src/man_fontfix.tmac (injected via --include-in-header) to remap those fonts to available ones on devices without Courier. - 'tbl preprocessor failed': the OPTIONS tables need tbl; add -t. - 'character with input code N not defined' / mojibake: non-ASCII README content (e.g. accented author names) was decoded as Latin-1. Run the build in a UTF-8 locale and render with 'groff -Kutf8 ... -Tutf8'. - 'table wider than line length': Pandoc sizes tables at nearly full width while the man body is indented; narrow the indent with -rIN=4n. Register man_fontfix.tmac as a Bazel input for //docs:man_pages. Signed-off-by: Matt Liberty <mliberty@precisioninno.com>
For the module docs that render as man pages (cgt, est, ram, syn, tap, web), Pandoc derives roff table column widths from the relative number of dashes in the Markdown separator row. The uniform '| ----- | ----- |' separators forced a 50/50 split, leaving the short 'Switch Name' column half-empty while squeezing the long descriptions. Size column 1 to the longest option name, capped so the description keeps the majority of the width. Modules excluded from man-page generation are left unchanged -- their dash ratios have no effect on any rendered output. Also drop the 'Check out GitHub discussion' FAQ footers, whose long inline URLs were not usable as links in man/cat output. Signed-off-by: Matt Liberty <mliberty@precisioninno.com>
- Define GROFF ?= groff and use it in the cat recipes so the man renderer can be overridden (e.g. gnroff/macOS); drop the now-unused NROFF variable. - Detect an installed UTF-8 locale instead of hard-coding C.UTF-8, which is absent on some hosts (e.g. stock macOS). Fall back to the user's locale if none is found rather than exporting an invalid LC_ALL. Signed-off-by: Matt Liberty <mliberty@precisioninno.com>
Signed-off-by: Mike Inouye <mikeinouye@google.com>
…_sta_0729 Update sta ptr to latest 7/29
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>
…ved-soft-ndr GRT: improved soft-NDR
Signed-off-by: Eder Monteiro <emrmonteiro@precisioninno.com>
rsz: check for dont touch before applying CloneMove
The viewer created one Leaflet pane per (tech layer x chiplet instance).
On a 3DBlox multi-die design that is 97 panes, each holding a full grid
of ~24 tiles, each tile decoding to (256*dpr)^2 * 4 bytes: 582 MB of
decoded images at dpr 1 in a 1240x999 window. Past roughly 458 MB on
the machine profiled, Chrome discards decoded images, and the discarded
regions paint white and stay white until something forces a full
invalidation -- a window resize, or opening DevTools. A single-die
design shows ~20 panes and ~120 MB, which is why only multi-die designs
hit it.
Measured by replacing tile images with a 1x1 pixel, which removes the
bytes while leaving the pane count, the DOM and the composited-layer
structure untouched. The symptom is monotonic in bytes across seven
points and indifferent to how the bytes are distributed: at a matched
516 vs 517 MB, 86 and 97 content-bearing panes fail identically. That
rules out pane count and stack depth; it is the bytes. docs/tile-memory.md
records the full elimination, including tile delivery, decode failure,
positioning, clipping, GPU rasterization (it reproduces under
--disable-gpu), compositor raster memory and JS heap.
Routing layers are now partitioned into N groups, each rasterized into
one canvas per tile position, with N derived from a memory budget
(default 350 MB) and the viewport's tile count -- which matters, since
97 panes at 2560x1440 would be ~1.9 GB and any fixed N would fail there.
Decodes go through createImageBitmap so they can be close()d immediately;
an <img> gives no control over when its bitmap is released, which is the
whole problem. _instances, _pins and _modules keep their own panes.
Three invariants, each with tests:
- Groups are contiguous runs of the z-order. Each becomes one image,
and {1,3},{2,4} has no stacking that reproduces [1,2,3,4].
- The merged pane's opacity is 1. Leaflet applies layer opacity to
the container, so per-layer opacity now lives inside the canvas; a
translucent pane would apply it twice and wash the view out.
- The client and server agree on dpr to the pixel, since the canvas
backing store is sized from it.
The server also stops snapping dpr to a five-step ladder and honours the
ratio the client reports, rounded to two decimals to bound the tile-cache
key space. 1.75 and 2.5 are ordinary Windows scale factors and both were
off the ladder, so those displays received tiles 17% and 25% too small
and had the browser rescale them -- the resampling the tile pipeline
exists to avoid.
Selecting a layer no longer adds or removes a map layer: it flips a flag
in the owning pane's draw list and refreshes that pane, so the pane count
never moves. refreshTiles() keeps the same contract the per-layer panes
had, so the design-changed refresh push, pattern changes and visibility
changes all continue to arrive through redrawAllLayers().
?mergetiles=0 one pane per layer (previous behaviour)
?tilebudget=<MB> override the budget
?mergegroups=<N> pin N directly
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Signed-off-by: Peter Gadfort <gadfort@zeroasic.com>
web: remove memory
Signed-off-by: Peter Gadfort <gadfort@zeroasic.com>
web: keep tile merging enabled when the map is not laid out yet
Two ways the group count could be computed against a viewport that is not
the one the tiles will actually be drawn in, both of which silently
defeat the merging.
A container that is hidden or not yet laid out reports clientWidth 0.
estimateTilesPerPane then returns 1, so computeGroupCount divides the
whole budget by a single tile and comes back with groupCount ==
paneCount: one pane per layer, no merging at all, while the startup log
reports "merged 94 layers into 94 panes". The failure the merging
exists to prevent then arrives as soon as the panel is shown. Measure
the viewport through measureViewport(), which falls back to the window
and then to 1024x768. Over-estimating is the safe direction, since more
tiles per pane means fewer panes.
The grouping was also computed once at startup and never revisited, so
enlarging the window raised the per-pane cost until a grouping that fit
the budget no longer did -- the same failure, arriving later. Recompute
on map resize and redo the grouping when it has to shrink. Growing N
back when the window shrinks is deliberately not done: it would churn
panes on every splitter drag for no safety benefit, and leaves the merge
coarser than necessary, which is the harmless direction.
Reported by Peter Gadfort.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Signed-off-by: Peter Gadfort <gadfort@zeroasic.com>
…repair_antennas grt: repair antennas with diodes when using CUGR
…toggles The group header is a <label> wrapping the visibility checkbox, so a click that misses the expand triangle activates the label and toggles visibility instead. The arrow's hit box was only its own 10px line box (font-size 9px) inside a 25px row, so 15 of 25 pixel rows in the triangle's column landed on the label. Stretch the arrow to the full row height and extend it over the header's vertical padding with negative margins. Rendering is byte-identical; the 14px column width and all checkbox positions are unchanged. Signed-off-by: Matt Liberty <mliberty@precisioninno.com>
… checkbox A <label> wrapping the visibility checkbox activates that checkbox for a click anywhere in the row, so any click that missed a checkbox -- the expand triangle, the group name, the empty space to the right -- toggled the whole category's visibility. Widening the triangle's hit box only shrank the window for that misfire. Make the header a <div> and give the whole row minus its checkboxes the expand/collapse action, so a stray click can no longer change visibility. Clicking a group's name now expands it, matching Qt's displayControls tree where the name never affects visibility. Shared makeGroupHeader() and attachGroupCollapse() helpers in ui-utils.js replace the four hand-rolled headers (vis-tree groups, layer groups, Chiplets, Heat Maps). This supersedes the arrow hit-box CSS from the previous commit, which is reverted: every part of the header now performs the same action, so stretching the arrow no longer changes anything. Rendering is byte-identical (same PNG md5 at 3x device scale). A real-Chrome sweep clicking all 25 pixel rows of a header's triangle column, plus the name and the empty space, expands/collapses every time with visibility untouched. Signed-off-by: Matt Liberty <mliberty@precisioninno.com>
The blocklist guard (skip inputs, selects, buttons) fails toward a wrong action: a control added to the header later that is not in the list both acts and collapses the group. Test the two targets that should collapse instead -- the triangle, and the header itself, which is what a click on the group name or the empty space targets. A new child then cannot double fire; the worst it can do is not respond, which is immediately visible. Also covers a <label>-wrapped checkbox in a header: it toggles its own checkbox and leaves the group alone, without the guard having to name <label> and thereby turn any label in a header into a dead zone. Signed-off-by: Matt Liberty <mliberty@precisioninno.com>
…ay-controls-arrow-hitbox gui: fix display-controls expand arrow stealing clicks as visibility toggles
Refresh only the panes whose visibility changed. The layer tree's onChange walks every node and asserts the desired state on each one, so marking the owning pane dirty unconditionally meant a single checkbox click re-requested every tile in every pane -- roughly 2300 requests on the 97-layer design this was written for, each with a new server cache key because visible_layers had changed. The per-layer panes never had this problem, since Leaflet's addTo() is a no-op for a layer already on the map. setItemVisible() now reports whether the state actually moved and only a real change dirties a pane. Charge the unmerged panes against the budget. _instances, _pins and the always-on highlight overlay each hold a full tile grid and are never merged. At dpr 1 that is ~6 MB each and immaterial, but at dpr 3 a tile is 2.25 MB, so a pane is ~54 MB and the three together are ~162 MB -- enough that the budget reported a comfortable fit while the real total sat above the measured ceiling. reserveForUnmergedPanes() subtracts them first, and the logged estimate now covers the whole viewer rather than only the part the grouping controls. Resize the canvas backing store when the device pixel ratio changes. createTile fixed it at the ratio in force at creation, but devicePixelRatio changes when the window moves between monitors or the browser zoom changes, and a refresh then requests images at the new ratio. The old backing store scaled every incoming tile, leaving existing tiles blurry and inconsistent with any created afterwards. Sizing is now re-applied on every render, and skipped when unchanged because assigning width clears the canvas. Reported by codex on #11045. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Signed-off-by: Peter Gadfort <gadfort@zeroasic.com>
A merged tile waited for every layer in its group before drawing
anything, so first paint was gated by the slowest of its ~6 subtiles and
a request that never settled left the tile blank indefinitely. The
per-layer panes showed each layer the moment it landed; grouping turned
one stuck request from one blank layer into a blank group.
The canvas is now recomposited from scratch on every arrival, with slots
that have not arrived drawn as nothing. That is exact rather than an
approximation: transparent is the identity for src-over, so compositing
the arrived subset in list order gives precisely the pixels the full
composite would have where those layers are absent. Because every paint
walks the whole item list in order, the stacking cannot depend on which
response happens to land first -- there is no prefix pointer or gap
handling to get wrong, which was the alternative.
done() is reported on the first paint rather than on completion.
Leaflet keeps a tile hidden until then (.leaflet-tile { visibility:
hidden }), so deferring it would have made every incremental paint
invisible and the tile would still have appeared only once its slowest
layer had landed.
Decodes are held until the tile is complete rather than released per
paint: a late arrival belongs underneath layers already drawn, so the
recomposite needs every source still available. Peak memory is the same
K bitmaps the batch version already held.
A tile whose every layer fails now paints an all-blank composite instead
of never painting, since a tile that never calls done() stays invisible
rather than merely empty.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Signed-off-by: Peter Gadfort <gadfort@zeroasic.com>
The HTTP handler matched the raw request target against the embedded asset table, so "/?mergetiles=0" was looked up as a filename, missed, and returned "Resource not found." for the whole page. Every viewer option is a query parameter, which made all of them unusable -- including the ?mergetiles=0 escape hatch back to the pre-merge rendering path, documented in the previous commits and never reachable. assetPathFromTarget() drops the query and fragment and maps "/" onto the index document. It lives in request_handler.h rather than staying a static in web.cpp so it can be tested; nothing covered this path, which is how the options shipped broken. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Signed-off-by: Peter Gadfort <gadfort@zeroasic.com>
WebSocketManager.cancel() settled the promise only for a request still in the queue. For one already on the wire it dropped the handler from `pending` and returned, and the eventual reply then found no handler and was discarded, so the caller's promise never settled at all. That was harmless while a tile was an <img>. A merged tile releases its decoded ImageBitmaps in renderMergedTile's finally, and a finally does not run while an await is still outstanding. Every tile pruned by a pan and every tile re-requested by refreshTiles cancels its in-flight requests, so the sibling layers that had already decoded were stranded -- explicit close() is the entire reason this path uses ImageBitmap over <img>, and unlike an <img> decode an ImageBitmap is not discardable by the browser's image cache, which makes leaving it to GC weaker than what the per-layer panes had. The sent branch now rejects like the queued one. The wire accounting is unchanged: the slot still frees only when the (still ignored) reply lands, so cancellation churn cannot re-flood the socket. done() also moves off the render and onto the tile. refreshTiles re-renders in place without a done callback, so a refresh landing before the first paint left the handshake with the render it superseded; Leaflet keeps a tile hidden until done() marks it loaded, so the replacement render painted a canvas that stayed invisible until the tile was pruned and recreated. A superseded render now declines to report it -- it painted nothing, so reporting there would reveal whatever the canvas held before the refresh instead of what replaced it. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Signed-off-by: Matt Liberty <mliberty@precisioninno.com>
Signed-off-by: Matt Liberty <mliberty@precisioninno.com>
web: bound tile memory by compositing layers into N panes
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
[Describe your changes here]
Type of Change
Impact
[How does this change the tool's behavior?]
Verification
./etc/Build.sh).Related Issues
[Link issues here]