Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
df7963c
gpl: set minInflationRatio as TCL parameter,
gudeh Dec 13, 2025
cf81a62
Merge remote-tracking branch 'private/master' into gpl-min-congestion…
gudeh Dec 15, 2025
9c55230
gpl: 0.85 default min congestion inflation
gudeh Dec 15, 2025
e2b67ea
gpl: fix typo
gudeh Dec 15, 2025
500ba37
Merge remote-tracking branch 'private/master' into gpl-min-congestion…
gudeh Dec 18, 2025
838a862
Merge remote-tracking branch 'private/master' into gpl-min-congestion…
gudeh Dec 18, 2025
9e149fe
gpl: remove comments, modify defualt value
gudeh Dec 18, 2025
0ecacc1
gpl: move cell inflation report to function and call it after TD
gudeh Dec 18, 2025
3a1bd76
gpl: call print properly
gudeh Dec 18, 2025
295d7b4
Merge remote-tracking branch 'private/master' into gpl-min-congestion…
gudeh Dec 23, 2025
1108e8f
gpl: rename minInflationRatio to minCongestionForInflation
gudeh Dec 23, 2025
80069fe
gpl: reduce min congestion threshold for inflating from 1.01 to 0.95,
gudeh Dec 23, 2025
ff9d9b2
Merge remote-tracking branch 'private/master' into gpl-min-congestion…
gudeh Dec 24, 2025
44ec6aa
Merge remote-tracking branch 'private/master' into gpl-min-congestion…
gudeh Dec 29, 2025
1188f89
gpl: lower inflation
gudeh Dec 29, 2025
32052f6
Merge remote-tracking branch 'private/master' into gpl-min-congestion…
gudeh Jan 2, 2026
8108c2f
gpl: use best pobserved default inflation values with slang
gudeh Jan 2, 2026
b0e2406
Merge remote-tracking branch 'private/master' into gpl-min-congestion…
gudeh Jan 4, 2026
5f06f8f
gpl: remove unecessary prints and transform new ones into debugCheck
gudeh Jan 4, 2026
12471c3
gpl: clang-tidy
gudeh Jan 4, 2026
24a0cf9
gpl: address gemini reviews,
gudeh Jan 4, 2026
9da1e25
test: update after gpl inflation modifications
gudeh Jan 5, 2026
8375fa4
Merge remote-tracking branch 'private/master' into gpl-min-congestion…
gudeh Jan 5, 2026
a91c913
test: update after gpl inflation modifcations
gudeh Jan 5, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion src/gpl/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ if the RC is not decreasing for three consecutive iterations.

Routability-driven arguments
- They begin with `-routability`.
- `-routability_target_rc_metric`, `-routability_snapshot_overflow`, `-routability_check_overflow`, `-routability_max_density`, `-routability_inflation_ratio_coef`, `-routability_max_inflation_ratio`, `-routability_rc_coefficients`
- `-routability_target_rc_metric`, `-routability_snapshot_overflow`, `-routability_check_overflow`, `-routability_max_density`, `-routability_inflation_ratio_coef`, `-routability_max_inflation_ratio`, `-routability_min_congestion_for_inflation`, `-routability_rc_coefficients`

Timing-driven arguments
- They begin with `-timing_driven`.
Expand Down Expand Up @@ -90,6 +90,7 @@ global_placement
[-routability_max_density routability_max_density]
[-routability_inflation_ratio_coef routability_inflation_ratio_coef]
[-routability_max_inflation_ratio routability_max_inflation_ratio]
[-routability_min_congestion_for_inflation routability_min_congestion_for_inflation]
[-routability_rc_coefficients routability_rc_coefficients]
[-timing_driven_net_reweight_overflow]
[-timing_driven_net_weight_max]
Expand Down Expand Up @@ -133,6 +134,7 @@ global_placement
| `-routability_max_density` | Set density threshold for routability mode. The default value is `0.99`, and the allowed values are floats `[0, 1]`. |
| `-routability_inflation_ratio_coef` | Set inflation ratio coefficient for routability mode. The default value is `2`, and the allowed values are floats. |
| `-routability_max_inflation_ratio` | Set inflation ratio threshold for routability mode to prevent overly aggressive adjustments. The default value is `3`, and the allowed values are floats. |
| `-routability_min_congestion_for_inflation` | Tiles with a congestion value below this value will not be inflated. The default value is `0.8`, and the allowed values are floats `[0, 1]`. |
| `-routability_rc_coefficients` | Set routability RC coefficients for calculating the averate routing congestion. They relate to the 0.5%, 1%, 2%, and 5% most congested tiles. It comes in the form of a Tcl List `{k1, k2, k3, k4}`. The default value for each coefficient is `{1.0, 1.0, 0.0, 0.0}` respectively, and the allowed values are floats. |

#### Timing-Driven Arguments
Expand Down
3 changes: 2 additions & 1 deletion src/gpl/include/gpl/Replace.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,9 @@ struct PlaceOptions
float routabilitySnapshotOverflow = 0.6;
float routabilityMaxDensity = 0.99;
float routabilityTargetRcMetric = 1.01;
float routabilityInflationRatioCoef = 2;
float routabilityInflationRatioCoef = 0.5;
float routabilityMaxInflationRatio = 3;
float routabilityMinCongestionForInflation = 0.8;

// routability RC metric coefficients
float routabilityRcK1 = 1.0;
Expand Down
3 changes: 3 additions & 0 deletions src/gpl/src/replace.i
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@ static gpl::PlaceOptions getOptions(
checkKey(keys,
"-routability_max_inflation_ratio",
options.routabilityMaxInflationRatio);
checkKey(keys,
"-routability_min_congestion_for_inflation",
options.routabilityMinCongestionForInflation);
checkKey(keys, "-pad_left", options.padLeft);
checkKey(keys, "-pad_right", options.padRight);
checkKey(keys,
Expand Down
2 changes: 2 additions & 0 deletions src/gpl/src/replace.tcl
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ sta::define_cmd_args "global_placement" {\
[-routability_max_density routability_max_density]\
[-routability_inflation_ratio_coef routability_inflation_ratio_coef]\
[-routability_max_inflation_ratio routability_max_inflation_ratio]\
[-routability_min_congestion_for_inflation routability_min_congestion_for_inflation]\
[-routability_rc_coefficients routability_rc_coefficients]\
[-keep_resize_below_overflow keep_resize_below_overflow]\
[-timing_driven_net_reweight_overflow timing_driven_net_reweight_overflow]\
Expand All @@ -50,6 +51,7 @@ proc global_placement { args } {
-routability_target_rc_metric \
-routability_inflation_ratio_coef \
-routability_max_inflation_ratio \
-routability_min_congestion_for_inflation \
-routability_rc_coefficients \
-timing_driven_net_reweight_overflow \
-timing_driven_net_weight_max \
Expand Down
219 changes: 184 additions & 35 deletions src/gpl/src/routeBase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,7 @@ RouteBaseVars::RouteBaseVars(const PlaceOptions& options)
maxInflationRatio(options.routabilityMaxInflationRatio),
maxDensity(options.routabilityMaxDensity),
ignoreEdgeRatio(0.8),
minInflationRatio(1.01),
minCongestionForInflation(options.routabilityMinCongestionForInflation),
rcK1(options.routabilityRcK1),
rcK2(options.routabilityRcK2),
rcK3(options.routabilityRcK3),
Expand Down Expand Up @@ -394,13 +394,81 @@ void RouteBase::calculateRudyTiles()
float ratio = rudy->getTile(tile->x(), tile->y()).getRudy() / 100.0;

// update inflation Ratio
if (ratio >= rbVars_.minInflationRatio) {
float inflationRatio = std::pow(ratio, rbVars_.inflationRatioCoef);
if (ratio >= rbVars_.minCongestionForInflation) {
float inflationRatio = std::pow(ratio / rbVars_.minCongestionForInflation,
rbVars_.inflationRatioCoef);
inflationRatio = std::fmin(inflationRatio, rbVars_.maxInflationRatio);
tile->setInflationRatio(inflationRatio);
}
}

// Calculate statistics for inflation ratios
if (log_->debugCheck(GPL, "rudy", 1)) {
std::vector<float> inflation_ratios;
inflation_ratios.reserve(tg_->tiles().size());
for (auto& tile : tg_->tiles()) {
inflation_ratios.push_back(tile->inflationRatio());
}

if (!inflation_ratios.empty()) {
std::ranges::sort(inflation_ratios.begin(), inflation_ratios.end());
float sum = 0.0f;
for (float val : inflation_ratios) {
sum += val;
}
float mean = sum / inflation_ratios.size();
float median = inflation_ratios[inflation_ratios.size() / 2];
float variance = 0.0f;
for (float val : inflation_ratios) {
variance += (val - mean) * (val - mean);
}
float stddev = std::sqrt(variance / inflation_ratios.size());
log_->report(
"RUDY Inflation ratio statistics - Mean: {:.4f}, Median: {:.4f}, Std "
"Dev: "
"{:.4f}",
mean,
median,
stddev);

// Histogram (10 buckets)
float min_val = inflation_ratios.front();
float max_val = inflation_ratios.back();

if (max_val - min_val < 1e-6) {
log_->report(
"RUDY Inflation ratio statistics - All tiles have inflation ratio: "
"{:.4f}",
min_val);
} else {
const int num_buckets = 10;
float step = (max_val - min_val) / num_buckets;
std::vector<int> bucket_counts(num_buckets, 0);

for (float val : inflation_ratios) {
int bucket = static_cast<int>((val - min_val) / step);
if (bucket >= num_buckets) {
bucket = num_buckets - 1;
}
bucket_counts[bucket]++;
}

log_->report("RUDY Inflation ratio distribution:");
for (int i = 0; i < num_buckets; i++) {
float range_start = min_val + i * step;
float range_end = min_val + (i + 1) * step;
float percentage = static_cast<float>(bucket_counts[i])
/ inflation_ratios.size() * 100.0f;
log_->report("[{:.2f}, {:.2f}): {} ({:.2f}%)",
range_start,
range_end,
bucket_counts[i],
percentage);
}
}
}
}

if (log_->debugCheck(GPL, "updateInflationRatio", 1)) {
auto log = [this](auto... param) {
log_->debug(GPL, "updateInflationRatio", param...);
Expand Down Expand Up @@ -487,8 +555,10 @@ void RouteBase::updateGrtRoute()
ratio = 0.0;
}
// update inflation Ratio
if (ratio >= rbVars_.minInflationRatio) {
float inflationRatio = std::pow(ratio, rbVars_.inflationRatioCoef);
if (ratio >= rbVars_.minCongestionForInflation) {
float inflationRatio
= std::pow(ratio / rbVars_.minCongestionForInflation,
rbVars_.inflationRatioCoef);
inflationRatio = std::fmin(inflationRatio, rbVars_.maxInflationRatio);
tile->setInflationRatio(inflationRatio);
}
Expand Down Expand Up @@ -610,10 +680,10 @@ std::pair<bool, bool> RouteBase::routability(
std::vector<double> prev_total_gcells_area(nbVec_.size());
std::vector<double> prev_expected_gcells_area(nbVec_.size());
dbBlock* block = db_->getChip()->getBlock();
for (int i = 0; i < nbVec_.size(); i++) {
inflatedAreaDelta_[i] = 0;
for (int nb_index = 0; nb_index < nbVec_.size(); nb_index++) {
inflatedAreaDelta_[nb_index] = 0;
// run bloating and get inflatedAreaDelta_
for (auto& gCellHandle : nbVec_[i]->getGCells()) {
for (auto& gCellHandle : nbVec_[nb_index]->getGCells()) {
// only care about "standard cell"
if (!gCellHandle->isStdInstance()) {
continue;
Expand All @@ -624,7 +694,7 @@ std::pair<bool, bool> RouteBase::routability(
"Gcell {} from group {} is a Std instance, but is not "
"from NesterovBaseCommon. This shouldn't happen.",
gCellHandle->getName(),
nbVec_[i]->getGroup()->getName());
nbVec_[nb_index]->getGroup()->getName());
}
auto gCell = nbc_->getGCellByIndex(gCellHandle.getStorageIndex());

Expand All @@ -644,8 +714,8 @@ std::pair<bool, bool> RouteBase::routability(
continue;
}

int64_t prevCellArea = static_cast<int64_t>(gCell->dx())
* static_cast<int64_t>(gCell->dy());
int64_t prev_cell_area = static_cast<int64_t>(gCell->dx())
* static_cast<int64_t>(gCell->dy());

// bloat
gCell->setSize(static_cast<int>(std::round(
Expand All @@ -654,19 +724,23 @@ std::pair<bool, bool> RouteBase::routability(
gCell->dy() * std::sqrt(tile->inflatedRatio()))),
GCell::GCellChange::kRoutability);

int64_t newCellArea = static_cast<int64_t>(gCell->dx())
* static_cast<int64_t>(gCell->dy());
int64_t new_cell_area = static_cast<int64_t>(gCell->dx())
* static_cast<int64_t>(gCell->dy());

// deltaArea is equal to area * deltaRatio
// both of original and density size will be changed
inflatedAreaDelta_[i] += newCellArea - prevCellArea;
inflatedAreaDelta_[nb_index] += new_cell_area - prev_cell_area;
}

if (log_->debugCheck(GPL, "rudy", 1)) {
printGCellInflation();
}

float inflated_area_delta_microns
= block->dbuAreaToMicrons(inflatedAreaDelta_[i]);
= block->dbuAreaToMicrons(inflatedAreaDelta_[nb_index]);
float inflated_area_delta_percentage
= (static_cast<float>(inflatedAreaDelta_[i])
/ nbVec_[i]->getNesterovInstsArea())
= (static_cast<float>(inflatedAreaDelta_[nb_index])
/ nbVec_[nb_index]->getNesterovInstsArea())
* 100.0f;
log_->info(GPL,
51,
Expand All @@ -678,28 +752,29 @@ std::pair<bool, bool> RouteBase::routability(
52,
format_label_float,
"Placement target density:",
nbVec_[i]->getTargetDensity());
nbVec_[nb_index]->getTargetDensity());

prev_white_space_area[i] = nbVec_[i]->getWhiteSpaceArea();
prev_movable_area[i] = nbVec_[i]->getMovableArea();
prev_total_filler_area[i] = nbVec_[i]->getTotalFillerArea();
prev_total_gcells_area[i]
= nbVec_[i]->getNesterovInstsArea() + nbVec_[i]->getTotalFillerArea();
prev_expected_gcells_area[i]
= inflatedAreaDelta_[i] + prev_total_gcells_area[i];
prev_white_space_area[nb_index] = nbVec_[nb_index]->getWhiteSpaceArea();
prev_movable_area[nb_index] = nbVec_[nb_index]->getMovableArea();
prev_total_filler_area[nb_index] = nbVec_[nb_index]->getTotalFillerArea();
prev_total_gcells_area[nb_index] = nbVec_[nb_index]->getNesterovInstsArea()
+ nbVec_[nb_index]->getTotalFillerArea();
prev_expected_gcells_area[nb_index]
= inflatedAreaDelta_[nb_index] + prev_total_gcells_area[nb_index];

nbVec_[i]->cutFillerCells(inflatedAreaDelta_[i]);
nbVec_[nb_index]->cutFillerCells(inflatedAreaDelta_[nb_index]);

// max density detection
if (nbVec_[i]->getTargetDensity() > rbVars_.maxDensity) {
log_->info(GPL,
53,
"Target density {:.4f} exceeds the maximum allowed {:.4f}{}.",
nbVec_[i]->getTargetDensity(),
rbVars_.maxDensity,
nbVec_[i]->getGroup()
? " in group " + string(nbVec_[i]->getGroup()->getName())
: "");
if (nbVec_[nb_index]->getTargetDensity() > rbVars_.maxDensity) {
log_->info(
GPL,
53,
"Target density {:.4f} exceeds the maximum allowed {:.4f}{}.",
nbVec_[nb_index]->getTargetDensity(),
rbVars_.maxDensity,
nbVec_[nb_index]->getGroup()
? " in group " + string(nbVec_[nb_index]->getGroup()->getName())
: "");

revertToMinCongestion();
return std::make_pair(false, true);
Expand Down Expand Up @@ -1006,4 +1081,78 @@ void RouteBase::increaseCounter()
log_->info(GPL, 40, "Routability iteration: {}", revert_count_);
}

void RouteBase::printGCellInflation() const
{
std::vector<float> cell_inflation_ratios;
for (auto& gCell : nbc_->getGCells()) {
if (!gCell->isStdInstance()) {
continue;
}
auto master = gCell->insts()[0]->dbInst()->getMaster();
int64_t orig_cell_area = static_cast<int64_t>(master->getWidth())
* static_cast<int64_t>(master->getHeight());

int64_t cur_cell_area
= static_cast<int64_t>(gCell->dx()) * static_cast<int64_t>(gCell->dy());
if (orig_cell_area > 0) {
float inflation_ratio
= static_cast<float>(cur_cell_area) / orig_cell_area;
cell_inflation_ratios.push_back(inflation_ratio);
}
}

if (!cell_inflation_ratios.empty()) {
std::ranges::sort(cell_inflation_ratios);
float sum = 0.0f;
for (float val : cell_inflation_ratios) {
sum += val;
}
float mean = sum / cell_inflation_ratios.size();
float median = cell_inflation_ratios[cell_inflation_ratios.size() / 2];
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

The median calculation cell_inflation_ratios[cell_inflation_ratios.size() / 2] is only correct for vectors with an odd number of elements. For an even number of elements, the median should be the average of the two middle elements. This issue also exists in the duplicated statistics calculation logic in calculateRudyTiles. This should be fixed in the suggested helper function.

Additionally, for calculating sum and variance, you could use std::accumulate from the <numeric> header for more concise code.

    float median;
    const size_t size = cell_inflation_ratios.size();
    if (size % 2 == 0) {
      median = (cell_inflation_ratios[size / 2 - 1] + cell_inflation_ratios[size / 2]) / 2.0f;
    } else {
      median = cell_inflation_ratios[size / 2];
    }

float variance = 0.0f;
for (float val : cell_inflation_ratios) {
variance += (val - mean) * (val - mean);
}
float stddev = std::sqrt(variance / cell_inflation_ratios.size());
log_->report(
"Cell inflation ratio statistics - Mean: {:.4f}, Median: {:.4f}, Std "
"Dev: {:.4f}",
mean,
median,
stddev);

// Histogram (10 buckets)
float min_val = cell_inflation_ratios.front();
float max_val = cell_inflation_ratios.back();

if (max_val - min_val < 1e-6) {
log_->report("All cells have inflation ratio: {:.4f}", min_val);
} else {
const int num_buckets = 10;
float step = (max_val - min_val) / num_buckets;
std::vector<int> bucket_counts(num_buckets, 0);

for (float val : cell_inflation_ratios) {
int bucket = static_cast<int>((val - min_val) / step);
if (bucket >= num_buckets) {
bucket = num_buckets - 1;
}
bucket_counts[bucket]++;
}

log_->report("Cell inflation ratio distribution:");
for (int j = 0; j < num_buckets; j++) {
float range_start = min_val + j * step;
float range_end = min_val + (j + 1) * step;
float percentage = static_cast<float>(bucket_counts[j])
/ cell_inflation_ratios.size() * 100.0f;
log_->report("[{:.2f}, {:.2f}): {} ({:.2f}%)",
range_start,
range_end,
bucket_counts[j],
percentage);
}
}
}
}
} // namespace gpl
8 changes: 4 additions & 4 deletions src/gpl/src/routeBase.h
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ struct RouteBaseVars
const float maxInflationRatio;
const float maxDensity;
const float ignoreEdgeRatio;
const float minInflationRatio;
const float minCongestionForInflation;

// targetRC metric coefficients.
const float rcK1, rcK2, rcK3, rcK4;
Expand Down Expand Up @@ -174,6 +174,8 @@ class RouteBase
std::vector<int64_t> inflatedAreaDelta() const;
int getRevertCount() const;

void printGCellInflation() const;

private:
RouteBaseVars rbVars_;
odb::dbDatabase* db_ = nullptr;
Expand Down Expand Up @@ -209,8 +211,6 @@ class RouteBase

// update revert_count_
void increaseCounter();

// routability funcs
void initGCells();
};

} // namespace gpl
Loading