Skip to content

Commit

Permalink
Merge pull request #6561 from The-OpenROAD-Project-staging/gpl-revert…
Browse files Browse the repository at this point in the history
…-if-diverge

gpl: revert if diverge
  • Loading branch information
eder-matheus authored Jan 24, 2025
2 parents ee5f559 + 3a40747 commit 1ab5157
Show file tree
Hide file tree
Showing 12 changed files with 119 additions and 35 deletions.
2 changes: 2 additions & 0 deletions src/gpl/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ global_placement
[-timing_driven_net_weight_max]
[-timing_driven_nets_percentage]
[-keep_resize_below_overflow]
[-disable_revert_if_diverge]
```

#### Options
Expand All @@ -119,6 +120,7 @@ global_placement
| `-pad_left` | Set left padding in terms of number of sites. The default value is 0, and the allowed values are integers `[1, MAX_INT]` |
| `-pad_right` | Set right padding in terms of number of sites. The default value is 0, and the allowed values are integers `[1, MAX_INT]` |
| `-skip_io` | Flag to ignore the IO ports when computing wirelength during placement. The default value is False, allowed values are boolean. |
| `-disable_revert_if_diverge` | Flag to make gpl store the placement state along iterations, if a divergence is detected, gpl reverts to the snapshot state. The default value is disabled. |

#### Routability-Driven Arguments

Expand Down
5 changes: 2 additions & 3 deletions src/gpl/include/gpl/Replace.h
Original file line number Diff line number Diff line change
Expand Up @@ -119,18 +119,16 @@ class Replace
void setTimingDrivenMode(bool mode);

void setSkipIoMode(bool mode);
void setDisableRevertIfDiverge(bool mode);

void setRoutabilityDrivenMode(bool mode);
void setRoutabilityUseGrt(bool mode);
void setRoutabilityCheckOverflow(float overflow);
void setRoutabilityMaxDensity(float density);

void setRoutabilityMaxInflationIter(int iter);

void setRoutabilityTargetRcMetric(float rc);
void setRoutabilityInflationRatioCoef(float coef);
void setRoutabilityMaxInflationRatio(float ratio);

void setRoutabilityRcCoefficients(float k1, float k2, float k3, float k4);

void addTimingNetWeightOverflow(int overflow);
Expand Down Expand Up @@ -204,6 +202,7 @@ class Replace
bool routabilityUseRudy_ = true;
bool uniformTargetDensityMode_ = false;
bool skipIoMode_ = false;
bool disableRevertIfDiverge_ = false;

std::vector<int> timingNetWeightOverflows_;

Expand Down
1 change: 1 addition & 0 deletions src/gpl/src/nesterovBase.h
Original file line number Diff line number Diff line change
Expand Up @@ -782,6 +782,7 @@ class NesterovPlaceVars
bool timingDrivenMode = true;
int timingDrivenIterCounter = 0;
bool routabilityDrivenMode = true;
bool disableRevertIfDiverge = false;

bool debug = false;
int debug_pause_iterations = 10;
Expand Down
90 changes: 64 additions & 26 deletions src/gpl/src/nesterovPlace.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -318,14 +318,15 @@ int NesterovPlace::doNesterovPlace(int start_iter)
graphics_->cellPlot(true);
}

// snapshot saving detection
bool isSnapshotSaved = false;

// snapshot info
float snapshotA = 0;
float snapshotWlCoefX = 0, snapshotWlCoefY = 0;
// routability snapshot info
bool is_routability_snapshot_saved = false;
float route_snapshotA = 0;
float route_snapshot_WlCoefX = 0, route_snapshot_WlCoefY = 0;
bool isDivergeTriedRevert = false;

// divergence snapshot info
float diverge_snapshot_WlCoefX = 0, diverge_snapshot_WlCoefY = 0;

// backTracking variable.
float curA = 1.0;

Expand All @@ -342,7 +343,6 @@ int NesterovPlace::doNesterovPlace(int start_iter)

// here, prevA is a_(k), curA is a_(k+1)
// See, the ePlace-MS paper's Algorithm 1
//
curA = (1.0 + sqrt(4.0 * prevA * prevA + 1.0)) * 0.5;

// coeff is (a_k - 1) / ( a_(k+1) ) in paper.
Expand Down Expand Up @@ -412,9 +412,18 @@ int NesterovPlace::doNesterovPlace(int start_iter)

updateNextIter(iter);

if (!npVars_.disableRevertIfDiverge) {
if (is_min_hpwl_) {
diverge_snapshot_WlCoefX = wireLengthCoefX_;
diverge_snapshot_WlCoefY = wireLengthCoefY_;
for (auto& nb : nbVec_) {
nb->snapshot();
}
}
}

// For JPEG Saving
// debug

const int debug_start_iter = npVars_.debug_start_iter;
if (graphics_ && (debug_start_iter == 0 || iter + 1 >= debug_start_iter)) {
bool update
Expand Down Expand Up @@ -531,13 +540,10 @@ int NesterovPlace::doNesterovPlace(int start_iter)
if (!isDivergeTriedRevert && rb_->numCall() >= 1) {
// get back to the working rc size
rb_->revertGCellSizeToMinRc();

curA = snapshotA;
wireLengthCoefX_ = snapshotWlCoefX;
wireLengthCoefY_ = snapshotWlCoefY;

curA = route_snapshotA;
wireLengthCoefX_ = route_snapshot_WlCoefX;
wireLengthCoefY_ = route_snapshot_WlCoefY;
nbc_->updateWireLengthForceWA(wireLengthCoefX_, wireLengthCoefY_);

for (auto& nb : nbVec_) {
nb->revertDivergence();
}
Expand All @@ -548,27 +554,46 @@ int NesterovPlace::doNesterovPlace(int start_iter)
isDivergeTriedRevert = true;
// turn off the RD forcely
isRoutabilityNeed_ = false;
} else if (!npVars_.disableRevertIfDiverge) {
// In case diverged and not in routability mode, finish with min hpwl
// stored since overflow below 0.25
log_->warn(GPL,
90,
"Divergence detected, reverting to snapshot with min hpwl.");
log_->warn(GPL,
91,
"Revert to iter: {:4d} overflow: {:.3f} HPWL: {}",
diverge_snapshot_iter_,
diverge_snapshot_average_overflow_unscaled_,
min_hpwl_);
wireLengthCoefX_ = diverge_snapshot_WlCoefX;
wireLengthCoefY_ = diverge_snapshot_WlCoefY;
nbc_->updateWireLengthForceWA(wireLengthCoefX_, wireLengthCoefY_);
for (auto& nb : nbVec_) {
nb->revertDivergence();
}
isDiverged_ = false;
break;
} else {
// no way to revert
break;
}
}

if (!isSnapshotSaved && npVars_.routabilityDrivenMode
if (!is_routability_snapshot_saved && npVars_.routabilityDrivenMode
&& 0.6 >= average_overflow_unscaled_) {
snapshotWlCoefX = wireLengthCoefX_;
snapshotWlCoefY = wireLengthCoefY_;
snapshotA = curA;
isSnapshotSaved = true;
route_snapshot_WlCoefX = wireLengthCoefX_;
route_snapshot_WlCoefY = wireLengthCoefY_;
route_snapshotA = curA;
is_routability_snapshot_saved = true;

for (auto& nb : nbVec_) {
nb->snapshot();
}

log_->report("[NesterovSolve] Snapshot saved at iter = {}", iter);
log_->info(GPL, 88, "Routability snapshot saved at iter = {}", iter);
}

// check routability using GR
// check routability using RUDY or GR
if (npVars_.routabilityDrivenMode && isRoutabilityNeed_
&& npVars_.routabilityCheckOverflow >= average_overflow_unscaled_) {
// recover the densityPenalty values
Expand All @@ -582,17 +607,17 @@ int NesterovPlace::doNesterovPlace(int start_iter)
// cutFillerCoordinates();

// revert back the current density penality
curA = snapshotA;
wireLengthCoefX_ = snapshotWlCoefX;
wireLengthCoefY_ = snapshotWlCoefY;
curA = route_snapshotA;
wireLengthCoefX_ = route_snapshot_WlCoefX;
wireLengthCoefY_ = route_snapshot_WlCoefY;

nbc_->updateWireLengthForceWA(wireLengthCoefX_, wireLengthCoefY_);

for (auto& nb : nbVec_) {
nb->revertDivergence();
nb->resetMinSumOverflow();
}
log_->report("[NesterovSolve] Revert back to snapshot coordi");
log_->info(GPL, 89, "Routability: revert back to snapshot");
}
}

Expand Down Expand Up @@ -658,6 +683,19 @@ void NesterovPlace::updateNextIter(const int iter)

// For coefficient, using average regions' overflow
updateWireLengthCoef(average_overflow_);

// Update divergence snapshot
if (!npVars_.disableRevertIfDiverge) {
int64_t hpwl = nbc_->getHpwl();
if (hpwl < min_hpwl_ && average_overflow_unscaled_ <= 0.25) {
min_hpwl_ = hpwl;
diverge_snapshot_average_overflow_unscaled_ = average_overflow_unscaled_;
diverge_snapshot_iter_ = iter;
is_min_hpwl_ = true;
} else {
is_min_hpwl_ = false;
}
}
}

void NesterovPlace::updateDb()
Expand Down
7 changes: 7 additions & 0 deletions src/gpl/src/nesterovPlace.h
Original file line number Diff line number Diff line change
Expand Up @@ -115,9 +115,16 @@ class NesterovPlace

float total_sum_overflow_ = 0;
float total_sum_overflow_unscaled_ = 0;
// The average here is between regions (NB objects)
float average_overflow_ = 0;
float average_overflow_unscaled_ = 0;

// Snapshot saving for revert if diverge
float diverge_snapshot_average_overflow_unscaled_ = 0;
int64_t min_hpwl_ = INT64_MAX;
int diverge_snapshot_iter_ = 0;
bool is_min_hpwl_ = false;

// densityPenalty stor
std::vector<float> densityPenaltyStor_;

Expand Down
22 changes: 21 additions & 1 deletion src/gpl/src/replace.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ void Replace::reset()
routabilityUseRudy_ = true;
uniformTargetDensityMode_ = false;
skipIoMode_ = false;
disableRevertIfDiverge_ = false;

padLeft_ = padRight_ = 0;

Expand Down Expand Up @@ -354,6 +355,7 @@ bool Replace::initNesterovPlace(int threads)
npVars.debug_draw_bins = gui_debug_draw_bins_;
npVars.debug_inst = gui_debug_inst_;
npVars.debug_start_iter = gui_debug_start_iter_;
npVars.disableRevertIfDiverge = disableRevertIfDiverge_;

for (const auto& nb : nbVec_) {
nb->setNpVars(&npVars);
Expand All @@ -375,7 +377,20 @@ int Replace::doNesterovPlace(int threads, int start_iter)
if (timingDrivenMode_) {
rs_->resizeSlackPreamble();
}
return np_->doNesterovPlace(start_iter);

auto start = std::chrono::high_resolution_clock::now();

int return_do_nesterov = np_->doNesterovPlace(start_iter);

auto end = std::chrono::high_resolution_clock::now();
std::chrono::duration<double> elapsed = end - start;
debugPrint(log_,
GPL,
"runtime",
1,
"NP->doNesterovPlace() runtime: {} seconds ",
elapsed.count());
return return_do_nesterov;
}

void Replace::setInitialPlaceMaxIter(int iter)
Expand Down Expand Up @@ -485,6 +500,11 @@ void Replace::setDebug(int pause_iterations,
gui_debug_start_iter_ = start_iter;
}

void Replace::setDisableRevertIfDiverge(bool mode)
{
disableRevertIfDiverge_ = mode;
}

void Replace::setSkipIoMode(bool mode)
{
skipIoMode_ = mode;
Expand Down
7 changes: 7 additions & 0 deletions src/gpl/src/replace.i
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,13 @@ set_skip_io_mode_cmd(bool mode)
replace->setSkipIoMode(mode);
}

void
set_disable_revert_if_diverge(bool disable_revert_if_diverge)
{
Replace* replace = getReplace();
replace->setDisableRevertIfDiverge(disable_revert_if_diverge);
}

float
get_global_placement_uniform_density_cmd()
{
Expand Down
12 changes: 11 additions & 1 deletion src/gpl/src/replace.tcl
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ sta::define_cmd_args "global_placement" {\
[-timing_driven_nets_percentage timing_driven_nets_percentage]\
[-pad_left pad_left]\
[-pad_right pad_right]\
[-disable_revert_if_diverge]\
}

proc global_placement { args } {
Expand Down Expand Up @@ -92,7 +93,8 @@ proc global_placement { args } {
-disable_timing_driven \
-disable_routability_driven \
-skip_io \
-incremental}
-incremental\
-disable_revert_if_diverge}

# flow control for initial_place
if { [info exists flags(-skip_initial_place)] } {
Expand Down Expand Up @@ -176,6 +178,14 @@ proc global_placement { args } {
}
}

# Disable revert to saved snapshot if a divergence is detected.
set disable_revert_if_diverge [info exists flags(-disable_revert_if_diverge)]
gpl::set_disable_revert_if_diverge $disable_revert_if_diverge
if { $disable_revert_if_diverge } {
utl::info "GPL" 153 \
"Revert-to-snapshot on divergence detection is disabled."
}

if { [info exists keys(-initial_place_max_fanout)] } {
set initial_place_max_fanout $keys(-initial_place_max_fanout)
sta::check_positive_integer "-initial_place_max_fanout" $initial_place_max_fanout
Expand Down
2 changes: 1 addition & 1 deletion src/gpl/test/simple01-rd.ok
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@
[NesterovSolve] Iter: 190 overflow: 0.683 HPWL: 4375212
[NesterovSolve] Iter: 200 overflow: 0.661 HPWL: 4447293
[NesterovSolve] Iter: 210 overflow: 0.625 HPWL: 4516566
[NesterovSolve] Snapshot saved at iter = 216
[INFO GPL-0088] Routability snapshot saved at iter = 216
[NesterovSolve] Iter: 220 overflow: 0.586 HPWL: 4589913
[NesterovSolve] Iter: 230 overflow: 0.547 HPWL: 4672006
[NesterovSolve] Iter: 240 overflow: 0.494 HPWL: 4711101
Expand Down
2 changes: 1 addition & 1 deletion src/gpl/test/simple02-rd.ok
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@
[NesterovSolve] Iter: 190 overflow: 0.683 HPWL: 4375212
[NesterovSolve] Iter: 200 overflow: 0.661 HPWL: 4447293
[NesterovSolve] Iter: 210 overflow: 0.625 HPWL: 4516566
[NesterovSolve] Snapshot saved at iter = 216
[INFO GPL-0088] Routability snapshot saved at iter = 216
[NesterovSolve] Iter: 220 overflow: 0.586 HPWL: 4589913
[NesterovSolve] Iter: 230 overflow: 0.547 HPWL: 4672006
[NesterovSolve] Iter: 240 overflow: 0.494 HPWL: 4711101
Expand Down
2 changes: 1 addition & 1 deletion src/gpl/test/simple03-rd.ok
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@
[NesterovSolve] Iter: 190 overflow: 0.683 HPWL: 4375212
[NesterovSolve] Iter: 200 overflow: 0.661 HPWL: 4447293
[NesterovSolve] Iter: 210 overflow: 0.625 HPWL: 4516566
[NesterovSolve] Snapshot saved at iter = 216
[INFO GPL-0088] Routability snapshot saved at iter = 216
[NesterovSolve] Iter: 220 overflow: 0.586 HPWL: 4589913
[NesterovSolve] Iter: 230 overflow: 0.547 HPWL: 4672006
[NesterovSolve] Iter: 240 overflow: 0.494 HPWL: 4711101
Expand Down
2 changes: 1 addition & 1 deletion src/gpl/test/simple04-rd.ok
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@
[NesterovSolve] Iter: 190 overflow: 0.683 HPWL: 4375212
[NesterovSolve] Iter: 200 overflow: 0.661 HPWL: 4447293
[NesterovSolve] Iter: 210 overflow: 0.625 HPWL: 4516566
[NesterovSolve] Snapshot saved at iter = 216
[INFO GPL-0088] Routability snapshot saved at iter = 216
[NesterovSolve] Iter: 220 overflow: 0.586 HPWL: 4589913
[NesterovSolve] Iter: 230 overflow: 0.547 HPWL: 4672006
[NesterovSolve] Iter: 240 overflow: 0.494 HPWL: 4711101
Expand Down

0 comments on commit 1ab5157

Please sign in to comment.