cts: clock-tree synthesis performance + QoR knobs#10850
cts: clock-tree synthesis performance + QoR knobs#10850saurav-fermions wants to merge 2 commits into
Conversation
|
Warning Gemini encountered an error creating the review. You can try again by commenting |
|
/gemini review |
There was a problem hiding this comment.
Code Review
This pull request introduces a new report_clock_tree command to report post-CTS QoR metrics (such as sinks, buffers, levels, wire length, latency, skew, and estimated switching power) and adds a -num_max_leaf_sinks option to control the H-tree stop criterion. It also includes performance optimizations in SinkClustering by caching sink insertion delays to avoid hash-map lookups, and in TechChar by switching to incremental timing updates. The review feedback correctly identifies a bug in the total clock power calculation when multiple clocks have different periods, where summing the load capacitances and multiplying by the minimum frequency underestimates the total power. It is recommended to calculate the power for each clock individually and sum them up directly.
| totals.latency_samples += report.latency_samples; | ||
| } | ||
| // Use the largest period for the totals power frequency basis. | ||
| totals.clock_period = std::max(totals.clock_period, report.clock_period); |
There was a problem hiding this comment.
Calculating the total clock power by summing the load capacitances and multiplying by the minimum frequency (corresponding to std::max(totals.clock_period, report.clock_period)) leads to a significant underestimation of the total power when clocks have different periods. The total power should be the sum of the estimated powers of each individual clock. Consider adding a power field to ClockTreeReport, calculating the power for each clock during collection, and then summing them up directly (totals.power += report.power).
arthurjolo
left a comment
There was a problem hiding this comment.
Please separate this PR into 2 PRs:
- PR with the speedup changes.
- PR with the new tcl option to set
num_max_leaf_sinksand its ok files.
There is no need to create benchmarks test for aes, gcd, array and techchar. They are already tested in CTS unity test or OR regression.
Also the report seems redundant, most of the information is already reported on during the flow, the total power estimation is also done by sta so I don't think we need to add one in CTS.
2786153 to
95ab51d
Compare
…identical clock tree) The TechChar characterization inner loop set a new input slew (setAnnotatedSlew) and net parasitics (makePiElmore/setElmore) for each (buffer-combo, load, slew) point, then called updateTiming(true). The 'true' argument invalidates ALL arrivals (arrivalsInvalid) and forces a full re-traversal every iteration, defeating the incremental delay invalidation that those annotation/parasitic calls already perform (delayInvalid / delaysInvalidFrom). Switch to updateTiming(false) so the search respects the incremental invalid markers and recomputes only the affected cones. Results are identical because the only changed inputs each iteration are the slew annotation and the last-net parasitic, both of which already mark their downstream delays invalid. Measured on a 537-sink Nangate45 design (buf_list X1/X2/X3): - post-CTS clock tree MD5 identical to baseline (bit-identical) - TechChar self-time ~153ms -> ~61ms - updateTiming portion ~138ms -> ~46ms - CTS wall-clock ~234ms -> ~143ms (median of 5, interleaved) Signed-off-by: Saurav Singh <saurav.singh@fermions.co>
…bit-identical clock tree) The sink-clustering matching inner loops (findBestMatching and repairClusteringSolution) called HTree_->computeDist(p, comparisonPoint) for every comparison point, which internally performs two boost::unordered_map lookups (getSinkInsertionDelay) keyed by the point coordinates -- one for the fixed point p and one for the comparison point. On high-fanout designs this is the single biggest CTS-owned leaf cost (matches profile/cts CTS_PROFILE_FINDINGS.md candidate The-OpenROAD-Project#3). Precompute the per-point insertion delay once (after normalizePoints, in the same normalized coordinate space the original lookups used) into a flat vector, and evaluate the distance via the cached values with the exact same floating-point addition order. This replaces two hash-map lookups per inner iteration with two array reads. Bit-identical clock tree verified (sorted clock-iterm dump, MD5): gcd_nangate45 c633c5e3... (1 & 8 threads) aes placed/577 009fdd7d... (1 & 8 threads) array 18k sinks 72a30a16... (1 & 8 threads) cts ctest: 57/57 passed. Measured findBestMatching self-time on the 18k-sink array synthetic (median of 3): 164.0 ms -> 97.4 ms (-41%, 1.68x). On normal register designs (aes, gcd) CTS is dominated by TechChar characterization so the end-to-end win is small there; the matching win matters at high fanout. Signed-off-by: Saurav Singh <saurav.singh@fermions.co>
95ab51d to
397855b
Compare
|
Thanks @arthurjolo — split as requested:
The gemini comment on the clock-power basis is addressed in #10864 (where |
Summary
Clock-tree synthesis performance improvements (bit-identical clock tree) plus two additive knobs/commands.
updateTiming(true)->updateTiming(false)so incremental delay invalidation is respected instead of forcing a full re-traversal each iteration. Bit-identical clock tree (post-CTS MD5 unchanged); TechChar self-time ~153ms -> ~61ms.findBestMatchingself-time -41% on an 18k-sink case.-num_max_leaf_sinksknob onclock_tree_synthesis.report_clock_tree— read-only clock-tree QoR command.Testing
Built
openroad; full cts regression suite passes (57/57, incl. goldenlog_compare). Clock tree bit-identical to baseline for the perf changes.Notes
src/stachange; no cross-repo dependency.