Skip to content

cts: clock-tree synthesis performance + QoR knobs#10850

Open
saurav-fermions wants to merge 2 commits into
The-OpenROAD-Project:masterfrom
Fermions-ASI:feat/cts-perf
Open

cts: clock-tree synthesis performance + QoR knobs#10850
saurav-fermions wants to merge 2 commits into
The-OpenROAD-Project:masterfrom
Fermions-ASI:feat/cts-perf

Conversation

@saurav-fermions

Copy link
Copy Markdown
Contributor

Summary

Clock-tree synthesis performance improvements (bit-identical clock tree) plus two additive knobs/commands.

  • TechChar incremental timing — in the characterization inner loop, switch 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.
  • SinkClustering matching — precompute per-point insertion delay once into a flat vector, replacing two hash-map lookups per inner iteration with two array reads (same FP addition order). Bit-identical clock tree; findBestMatching self-time -41% on an 18k-sink case.
  • Benchmark harnesses — bit-identity/perf bench scripts (not registered ctest targets).
  • -num_max_leaf_sinks knob on clock_tree_synthesis.
  • report_clock_tree — read-only clock-tree QoR command.

Testing

Built openroad; full cts regression suite passes (57/57, incl. golden log_compare). Clock tree bit-identical to baseline for the perf changes.

Notes

  • Performance changes are bit-identical; the two new commands/knobs are additive and read-only/opt-in.
  • No src/sta change; no cross-repo dependency.

@saurav-fermions saurav-fermions requested review from a team as code owners July 9, 2026 07:19
@github-actions github-actions Bot added the size/L label Jul 9, 2026
@gemini-code-assist

Copy link
Copy Markdown
Contributor

Warning

Gemini encountered an error creating the review. You can try again by commenting /gemini review.

@arthurjolo

Copy link
Copy Markdown
Contributor

/gemini review

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment thread src/cts/src/TritonCTS.cpp Outdated
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);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

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 arthurjolo left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please separate this PR into 2 PRs:

  1. PR with the speedup changes.
  2. PR with the new tcl option to set num_max_leaf_sinks and 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.

…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>
@saurav-fermions

Copy link
Copy Markdown
Contributor Author

Thanks @arthurjolo — split as requested:

The gemini comment on the clock-power basis is addressed in #10864 (where report_clock_tree now lives): the multi-clock total now sums each clock's own C·Vdd²·f instead of aggregating capacitance under a single frequency.

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.

2 participants