Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

rsz: Try multiple repairs per iteration #6262

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions src/rsz/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,7 @@ repair_timing
[-skip_last_gasp]
[-repair_tns tns_end_percent]
[-max_passes passes]
[-max_repairs_per_iter max_repairs_per_iter]
[-max_utilization util]
[-max_buffer_percent buffer_percent]
[-match_cell_footprint]
Expand Down
9 changes: 6 additions & 3 deletions src/rsz/include/rsz/Resizer.hh
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,7 @@ class Resizer : public dbStaState
bool repairSetup(double setup_margin,
double repair_tns_end_percent,
int max_passes,
int max_repairs_per_iter,
bool match_cell_footprint,
bool verbose,
bool skip_pin_swap,
Expand Down Expand Up @@ -622,9 +623,11 @@ class Resizer : public dbStaState
bool journal);

void findResizeSlacks1();
bool removeBuffer(Instance* buffer,
bool honorDontTouchFixed = true,
bool recordJournal = false);
bool removeBufferIfPossible(Instance* buffer,
bool honorDontTouchFixed = true,
bool recordJournal = false);
bool canRemoveBuffer(Instance* buffer, bool honorDontTouchFixed = true);
void removeBuffer(Instance* buffer, bool recordJournal = false);
Instance* makeInstance(LibertyCell* cell,
const char* name,
Instance* parent,
Expand Down
68 changes: 51 additions & 17 deletions src/rsz/src/RepairSetup.cc
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ void RepairSetup::init()
bool RepairSetup::repairSetup(const float setup_slack_margin,
const double repair_tns_end_percent,
const int max_passes,
const int max_repairs_per_iter,
const bool verbose,
const bool skip_pin_swap,
const bool skip_gate_cloning,
Expand All @@ -100,6 +101,7 @@ bool RepairSetup::repairSetup(const float setup_slack_margin,
bool repaired = false;
init();
constexpr int digits = 3;
max_repairs_per_iter_ = max_repairs_per_iter;
inserted_buffer_count_ = 0;
split_load_buffer_count_ = 0;
resize_count_ = 0;
Expand Down Expand Up @@ -174,7 +176,12 @@ bool RepairSetup::repairSetup(const float setup_slack_margin,
printProgress(opto_iteration, false, false, false, num_viols);
}
float fix_rate_threshold = inc_fix_rate_threshold_;
if (!violating_ends.empty()) {
min_viol_ = -violating_ends.back().second;
max_viol_ = -violating_ends.front().second;
}
for (const auto& end_original_slack : violating_ends) {
fallback_ = false;
Vertex* end = end_original_slack.first;
Slack end_slack = sta_->vertexSlack(end, max_);
Slack worst_slack;
Expand Down Expand Up @@ -325,6 +332,7 @@ bool RepairSetup::repairSetup(const float setup_slack_margin,
// Progress, Save checkpoint so we can back up to here.
resizer_->journalBegin();
} else {
fallback_ = true;
// Allow slack to increase to get out of local minima.
// Do not update prev_end_slack so it saves the high water mark.
decreasing_slack_passes++;
Expand Down Expand Up @@ -439,6 +447,7 @@ bool RepairSetup::repairSetup(const float setup_slack_margin,
void RepairSetup::repairSetup(const Pin* end_pin)
{
init();
max_repairs_per_iter_ = 1;
inserted_buffer_count_ = 0;
resize_count_ = 0;
swap_pin_count_ = 0;
Expand Down Expand Up @@ -495,7 +504,7 @@ bool RepairSetup::repairPath(PathRef& path,
const float setup_slack_margin)
{
PathExpanded expanded(&path, sta_);
bool changed = false;
int changed = 0;

if (expanded.size() > 1) {
const int path_length = expanded.size();
Expand Down Expand Up @@ -537,7 +546,26 @@ bool RepairSetup::repairPath(PathRef& path,
|| (pair1.second == pair2.second && pair1.first > pair2.first);
});
// Attack gates with largest load delays first.
int repairs_per_iter = 1;
if (max_viol_ - min_viol_ != 0.0) {
repairs_per_iter
+= std::round((max_repairs_per_iter_ - 1) * (-path_slack - min_viol_)
/ (max_viol_ - min_viol_));
}
if (fallback_) {
repairs_per_iter = 1;
}
debugPrint(logger_,
RSZ,
"repair_setup",
3,
"Path slack: {}, repairs: {}",
delayAsString(path_slack, sta_, 3),
repairs_per_iter);
for (const auto& [drvr_index, ignored] : load_delays) {
if (changed >= repairs_per_iter) {
break;
}
const PathRef* drvr_path = expanded.path(drvr_index);
Vertex* drvr_vertex = drvr_path->vertex(sta_);
const Pin* drvr_pin = drvr_vertex->pin();
Expand All @@ -561,21 +589,21 @@ bool RepairSetup::repairPath(PathRef& path,
drvr_index,
&expanded,
setup_slack_margin)) {
changed = true;
break;
changed++;
continue;
}
}

if (upsizeDrvr(drvr_path, drvr_index, &expanded)) {
changed = true;
break;
changed++;
continue;
}

// Pin swapping
if (!skip_pin_swap) {
if (swapPins(drvr_path, drvr_index, &expanded)) {
changed = true;
break;
changed++;
continue;
}
}

Expand All @@ -597,8 +625,8 @@ bool RepairSetup::repairPath(PathRef& path,
network_->pathName(drvr_pin),
rebuffer_count);
inserted_buffer_count_ += rebuffer_count;
changed = true;
break;
changed++;
continue;
}
}

Expand All @@ -609,8 +637,8 @@ bool RepairSetup::repairPath(PathRef& path,
db_network_->instance(drvr_pin))
== resizer_->inserted_buffer_set_.end()
&& cloneDriver(drvr_path, drvr_index, path_slack, &expanded)) {
changed = true;
break;
changed++;
continue;
}

if (!skip_buffering) {
Expand All @@ -620,13 +648,17 @@ bool RepairSetup::repairPath(PathRef& path,
const int init_buffer_count = inserted_buffer_count_;
splitLoads(drvr_path, drvr_index, path_slack, &expanded);
split_load_buffer_count_ = inserted_buffer_count_ - init_buffer_count;
changed = true;
break;
changed++;
continue;
}
}
}
for (auto inst : buf_to_remove_) {
resizer_->removeBuffer(inst, /* recordJournal */ true);
}
buf_to_remove_.clear();
}
return changed;
return changed > 0;
}

void RepairSetup::debugCheckMultipleBuffers(PathRef& path,
Expand Down Expand Up @@ -858,8 +890,8 @@ bool RepairSetup::removeDrvr(const PathRef* drvr_path,
return false;
}

if (resizer_->removeBuffer(
drvr, /* honorDontTouch */ true, /* recordJournal */ true)) {
if (resizer_->canRemoveBuffer(drvr, /* honorDontTouch */ true)) {
buf_to_remove_.push_back(drvr);
removed_buffer_count_++;
return true;
}
Expand Down Expand Up @@ -977,7 +1009,7 @@ bool RepairSetup::estimatedSlackOK(const SlackEstimatorParams& params)
"because side input pin {} will have a violating slack of {}:"
" old slack={}, slack margin={}, delay_degrad={}",
db_network_->name(params.driver),
db_network_->name(side_input_pin), new_slack, old_slack,
db_network_->name(side_input_pin), new_slack, old_slack,
params.setup_slack_margin, delay_degrad);
// clang-format on
return false;
Expand Down Expand Up @@ -1917,6 +1949,7 @@ void RepairSetup::repairSetupLastGasp(const OptoParams& params, int& num_viols)
float fix_rate_threshold = inc_fix_rate_threshold_;

for (const auto& end_original_slack : violating_ends) {
fallback_ = false;
Vertex* end = end_original_slack.first;
Slack end_slack = sta_->vertexSlack(end, max_);
Slack worst_slack;
Expand Down Expand Up @@ -2001,6 +2034,7 @@ void RepairSetup::repairSetupLastGasp(const OptoParams& params, int& num_viols)
resizer_->journalEnd();
resizer_->journalBegin();
} else {
fallback_ = true;
resizer_->journalRestore(resize_count_,
inserted_buffer_count_,
cloned_gate_count_,
Expand Down
6 changes: 6 additions & 0 deletions src/rsz/src/RepairSetup.hh
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ class RepairSetup : public sta::dbStaState
// reduce tns (0.0-1.0).
double repair_tns_end_percent,
int max_passes,
int max_repairs_per_iter,
bool verbose,
bool skip_pin_swap,
bool skip_gate_cloning,
Expand Down Expand Up @@ -235,12 +236,17 @@ class RepairSetup : public sta::dbStaState
int num_endpts);
void repairSetupLastGasp(const OptoParams& params, int& num_viols);

std::vector<Instance*> buf_to_remove_;
Logger* logger_ = nullptr;
dbNetwork* db_network_ = nullptr;
Resizer* resizer_;
const Corner* corner_ = nullptr;
LibertyPort* drvr_port_ = nullptr;

bool fallback_ = false;
float min_viol_ = 0.0;
float max_viol_ = 0.0;
int max_repairs_per_iter_ = 1;
int resize_count_ = 0;
int inserted_buffer_count_ = 0;
int split_load_buffer_count_ = 0;
Expand Down
Loading
Loading