Skip to content

grt: multicore congestion handling#10229

Merged
eder-matheus merged 33 commits into
The-OpenROAD-Project:masterfrom
The-OpenROAD-Project-staging:multicore_congestion
Apr 29, 2026
Merged

grt: multicore congestion handling#10229
eder-matheus merged 33 commits into
The-OpenROAD-Project:masterfrom
The-OpenROAD-Project-staging:multicore_congestion

Conversation

@openroad-ci

Copy link
Copy Markdown
Member

Summary

Finishes PR #9598.

Type of Change

  • New feature

Impact

No change in ORFS. This PR adds multithreading to GRT congestion iterations under specific circunstances (see original PR for reference).

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 signed my commits (DCO).

@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 implements snapshot-batched routing in the global router, enabling parallelized maze routing by partitioning nets into batches and routing them against a frozen graph snapshot. It introduces the -snapshot_batched_width parameter, adds OpenMP parallelization for wirelength and resource calculations, and includes comprehensive regression tests. The review identifies several critical implementation issues, including missing member and data copies during worker initialization, potential data loss from truncating edge costs to unsigned char, and memory growth issues caused by failing to clear cost tables between iterations.

Comment thread src/grt/src/fastroute/src/FastRoute.cpp
Comment thread src/grt/src/fastroute/src/FastRoute.cpp
Comment thread src/grt/src/fastroute/src/FastRoute.cpp
Comment thread src/grt/src/fastroute/src/maze.cpp
Comment thread src/grt/src/fastroute/src/maze.cpp

@github-actions github-actions 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.

clang-tidy made some suggestions

#pragma omp parallel for num_threads(num_threads_) \
reduction(+ : total_wirelength)
for (int i = 0; i < static_cast<int>(routed_nets.size()); i++) {
total_wirelength += computeNetWirelength(routed_nets[i]);

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.

warning: use range-based for loop instead [modernize-loop-convert]

Suggested change
total_wirelength += computeNetWirelength(routed_nets[i]);
(auto & routed_net : routed_nets)routed_net

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

The range-based loop doesn't work for the omp parallel.

Comment thread src/grt/src/fastroute/src/FastRoute.cpp Outdated
Comment thread src/grt/src/fastroute/src/FastRoute.cpp Outdated
= std::min(semantic_wave_size,
static_cast<int>(batch_net_ids.size())
- static_cast<int>(wave_begin));
const int active_threads

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.

warning: Value stored to 'active_threads' during its initialization is never read [clang-analyzer-deadcode.DeadStores]

      const int active_threads
                ^
Additional context

src/grt/src/fastroute/src/maze.cpp:1137: Value stored to 'active_threads' during its initialization is never read

      const int active_threads
                ^

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

It is actually used on omp parallel. This is a false positive.

std::vector<bool> pop_heap2(y_grid_ * x_range_, false);
src_heap.clear();
dest_heap.clear();
std::fill(pop_heap2.begin(), pop_heap2.end(), false);

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.

warning: use a ranges version of this algorithm [modernize-use-ranges]

Suggested change
std::fill(pop_heap2.begin(), pop_heap2.end(), false);
std::ranges::fill(pop_heap2,, false);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

From CC:

std::ranges doesn't work with std::vector — vector is a special proxy-reference container whose iterators don't satisfy the standard std::ranges iterator concepts. std::ranges::fill requires output_range, and vector may not satisfy that depending on the standard library implementation. std::fill with explicit iterators works because it predates these stricter concept requirements.

ebrevdo and others added 26 commits April 28, 2026 16:32
Convert streamable custom types before logging or formatting in a few
cleanup paths, and teach utl::Logger to fall back to streamed formatting
for non-formattable arguments.

Signed-off-by: Eugene Brevdo <ebrevdo@users.noreply.github.com>
Co-authored-by: Codex <noreply@openai.com>
Reuse 2D maze scratch storage across iterations, retain capacity in hot route containers, replace the linear-search 2D decrease-key path with an indexed heap, and plumb OpenRoad thread count into safe read-only GRT/FastRoute reductions.

Signed-off-by: Eugene Brevdo <ebrevdo@users.noreply.github.com>
Co-authored-by: Codex <noreply@openai.com>
Complete the remaining exact-track work from optimize_global_route.md by adding phase timing instrumentation in FastRouteCore::run and a focused threaded grt regression.

The FastRoute change wraps the major routing phases with DebugScopedTimer scopes and emits phase metrics for the exact-preserving path without changing existing routing behavior or the normal verbose report surface. The new timings cover the full run, initial RSMT, initial routeLAll, congestion-driven RSMT, via-guided routeLAll, spiral routing, initial routeZAll, monotonic routing, overflow iterations, and finalization.

The test change adds src/grt/test/thread_count_reports.tcl, which runs global_route -verbose at thread counts 1 and 2 and compares only the reporting paths that were newly parallelized: the routing resources analysis block, the final congestion report block, and the total wirelength line. CMake wires it in as a pass/fail regression, and Bazel uses an explicit regression_test target with check_passfail=True instead of the default log-diff flow.

The earlier indexed 2D decrease-key heap experiment was not a win on the stress profile, so this final exact-track state drops A1 and keeps the scratch reuse, capacity retention, timing, and reporting-threading work that held up under profiling.

Validation:
- git -c core.fsmonitor=false diff --check
- dev-cpu-boron rebuild of build-linux-tests after reconfiguring against /root/openroad-deps completed successfully
- ctest --output-on-failure -R '^grt\.thread_count_reports\.tcl$|^grt\.report_wire_length1\.tcl$' passed (2/2)
- ctest -N confirmed grt.thread_count_reports.tcl registration
- stress-case gprof on shuffle_stress showed the A1 rollback recovered the prior regression

Signed-off-by: Eugene Brevdo <ebrevdo@users.noreply.github.com>
Co-authored-by: Codex <noreply@openai.com>
Add the optional Track B multicore global routing path to FastRoute. The new path batches contiguous nets against frozen planar congestion snapshots, routes each batch on worker copies, commits results deterministically, and falls back to bounded serial cleanup later in overflow reduction. The default path remains the existing serial route flow unless `global_route -multicore` is enabled.

Expose the Track B surface through the Tcl, SWIG, and GlobalRouter plumbing, and add the internal FastRoute helpers needed to build snapshot workers, copy planar routing state, and apply routed batches back into the main overflow loop. Add Graph2D routing-state copy support and Track B timing metrics so the new path can be measured without changing the default router behavior.

Keep the measured multicore taper behavior baked into the implementation instead of exposing runtime tuning knobs. The final tree uses the validated 25/50/75 taper trajectory and always uses the built-in thread-count heuristic for snapshot batch sizing inside Track B.

Local benchmark, regression, profiling, and initiative artifacts are intentionally kept out of the git tree. This commit carries only the product code and user-facing command documentation that back the optional Track B path.

- add the `-multicore` opt-in routing control
- implement snapshot-batch workers and deterministic batch commit order in `FastRouteCore`
- copy planar routing state into per-wave workers with `Graph2D::copyRoutingStateFrom`
- bound late Track B cleanup with best-route snapshots and patience tracking
- export snapshot batch sync, route, and apply metrics for profiling
- route the new control through Tcl, SWIG, and `GlobalRouter`
- keep the taper schedule fixed at the validated default operating point
- always use the built-in batch-sizing heuristic inside Track B
- document the new grt command option in the README

Signed-off-by: Eugene Brevdo <ebrevdo@users.noreply.github.com>
Co-authored-by: Codex <noreply@openai.com>
Fix Track B state management for incremental reroute and snapshot workers, tighten batching behavior for tiny designs, and add multicore regression coverage including a fixed-thread congestion7 variant.

Validated on dev-cpu-fluorine with the focused grt multicore slice.

Signed-off-by: Eugene Brevdo <ebrevdo@users.noreply.github.com>
Co-authored-by: Codex <noreply@openai.com>
Reset the public snapshot-batched-width default to 0, keep explicit width-16 coverage in dedicated snapshot-batched regressions, and rename the old multicore-specific tests to the snapshot-batched terminology. Add congestion1/2 snapshot-batched variants and refresh the congestion7 snapshot-batched goldens from one-thread runs, then verify the focused fluorine slice still passes with the checked-in tests pinned at 16 threads.

Signed-off-by: Eugene Brevdo <ebrevdo@users.noreply.github.com>
Co-authored-by: Codex <noreply@openai.com>
Reset the third-party/abc gitlink to the commit recorded on origin/master so the parent repo no longer points at the divergent submodule hash.

Signed-off-by: Eugene Brevdo <ebrevdo@users.noreply.github.com>
Co-authored-by: Codex <noreply@openai.com>
Update the parent-repo gitlink for third-party/abc so it matches the current origin/master submodule commit exactly.

Signed-off-by: Eugene Brevdo <ebrevdo@users.noreply.github.com>
Co-authored-by: Codex <noreply@openai.com>
Make snapshot-batched width 16 the default surface for global_route while
keeping the current internal fallback gates that protect legacy regressions.
Retarget explicit snapshot-batched coverage to a real high-overflow stress
case, remove the old gcd-based snapshot_batched goldens that no longer batch,
and add the tracked shuffle_stress DEF needed by the new smoke tests.

Validation:
- dev-cpu-fluorine rebuild of /root/openroad-builds/build-linux-tests
- focused width16-default slice: 11/11 passed
- full grt suite on fluorine: 119/119 passed

Signed-off-by: Eugene Brevdo <ebrevdo@users.noreply.github.com>
Co-authored-by: Codex <noreply@openai.com>
…ROAD into multicore_congestion

Signed-off-by: Eder Monteiro <emrmonteiro@precisioninno.com>
Signed-off-by: Eder Monteiro <emrmonteiro@precisioninno.com>
Signed-off-by: Eder Monteiro <emrmonteiro@precisioninno.com>
…ROAD into multicore_congestion

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>
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>
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>
Signed-off-by: Eder Monteiro <emrmonteiro@precisioninno.com>
Signed-off-by: Eder Monteiro <emrmonteiro@precisioninno.com>
Signed-off-by: Eder Monteiro <emrmonteiro@precisioninno.com>
@openroad-ci openroad-ci force-pushed the multicore_congestion branch from 4becd8e to 2be8781 Compare April 29, 2026 22:49
@eder-matheus eder-matheus requested a review from maliberty April 29, 2026 22:53
@eder-matheus eder-matheus enabled auto-merge April 29, 2026 23:10
@eder-matheus eder-matheus merged commit f9e2e01 into The-OpenROAD-Project:master Apr 29, 2026
15 of 16 checks passed
@openroad-ci openroad-ci deleted the multicore_congestion branch April 29, 2026 23:46
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.

4 participants