From a98b25da1dd2daeaf38fce7b60e5e5b7db922250 Mon Sep 17 00:00:00 2001 From: Krzysztof Bieganski Date: Tue, 21 May 2024 12:49:16 +0200 Subject: [PATCH 1/2] Skip known bad vertices in power recovery Signed-off-by: Krzysztof Bieganski --- src/rsz/src/RecoverPower.cc | 23 ++++++++++++++++------- src/rsz/src/RecoverPower.hh | 7 ++++--- 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/src/rsz/src/RecoverPower.cc b/src/rsz/src/RecoverPower.cc index 210fb6f25fe..cf34c6fa69e 100644 --- a/src/rsz/src/RecoverPower.cc +++ b/src/rsz/src/RecoverPower.cc @@ -66,7 +66,8 @@ using sta::Edge; using sta::PathExpanded; using sta::VertexOutEdgeIterator; -RecoverPower::RecoverPower(Resizer* resizer) : resizer_(resizer) +RecoverPower::RecoverPower(Resizer* resizer) + : resizer_(resizer), bad_vertices_(resizer->graph_) { } @@ -142,7 +143,7 @@ void RecoverPower::recoverPower(const float recover_power_percent) //===================================================================== resizer_->journalBegin(); PathRef end_path = sta_->vertexWorstSlackPath(end, max_); - const bool changed = recoverPower(end_path, end_slack_before); + Vertex* const changed = recoverPower(end_path, end_slack_before); if (changed) { resizer_->updateParasitics(true); sta_->findRequireds(); @@ -179,6 +180,8 @@ void RecoverPower::recoverPower(const float recover_power_percent) worst_slack_before, worst_slack_after); } else { + // Save the vertex to avoid trying it again. + bad_vertices_.insert(changed); // Undo the change here. ++failed_move_threshold; if (failed_move_threshold > failed_move_threshold_limit_) { @@ -223,10 +226,11 @@ void RecoverPower::recoverPower(const float recover_power_percent) if (resizer_->overMaxArea()) { logger_->error(RSZ, 125, "max utilization reached."); } + bad_vertices_.clear(); } // For testing. -void RecoverPower::recoverPower(const Pin* end_pin) +Vertex* RecoverPower::recoverPower(const Pin* end_pin) { init(); resize_count_ = 0; @@ -235,7 +239,7 @@ void RecoverPower::recoverPower(const Pin* end_pin) const Slack slack = sta_->vertexSlack(vertex, max_); const PathRef path = sta_->vertexWorstSlackPath(vertex, max_); resizer_->incrementalParasiticsBegin(); - recoverPower(path, slack); + Vertex* drvr_vertex = recoverPower(path, slack); // Leave the parasitices up to date. resizer_->updateParasitics(); resizer_->incrementalParasiticsEnd(); @@ -243,13 +247,14 @@ void RecoverPower::recoverPower(const Pin* end_pin) if (resize_count_ > 0) { logger_->info(RSZ, 3111, "Resized {} instances.", resize_count_); } + return drvr_vertex; } // This is the main routine for recovering power. -bool RecoverPower::recoverPower(const PathRef& path, const Slack path_slack) +Vertex* RecoverPower::recoverPower(const PathRef& path, const Slack path_slack) { PathExpanded expanded(&path, sta_); - bool changed = false; + Vertex* changed = nullptr; if (expanded.size() > 1) { const int path_length = expanded.size(); @@ -295,6 +300,10 @@ bool RecoverPower::recoverPower(const PathRef& path, const Slack path_slack) for (const auto& [drvr_index, ignored] : load_delays) { PathRef* drvr_path = expanded.path(drvr_index); Vertex* drvr_vertex = drvr_path->vertex(sta_); + // If we already tried this vertex and got a worse result, skip it. + if (bad_vertices_.find(drvr_vertex) != bad_vertices_.end()) { + continue; + } const Pin* drvr_pin = drvr_vertex->pin(); const LibertyPort* drvr_port = network_->libertyPort(drvr_pin); const LibertyCell* drvr_cell @@ -309,7 +318,7 @@ bool RecoverPower::recoverPower(const PathRef& path, const Slack path_slack) drvr_cell ? drvr_cell->name() : "none", fanout); if (downsizeDrvr(drvr_path, drvr_index, &expanded, true, path_slack)) { - changed = true; + changed = drvr_vertex; break; } } diff --git a/src/rsz/src/RecoverPower.hh b/src/rsz/src/RecoverPower.hh index b897bba846a..307b8a217ec 100644 --- a/src/rsz/src/RecoverPower.hh +++ b/src/rsz/src/RecoverPower.hh @@ -37,6 +37,7 @@ #include "db_sta/dbSta.hh" #include "sta/FuncExpr.hh" +#include "sta/Graph.hh" #include "sta/MinMax.hh" #include "sta/StaState.hh" #include "utl/Logger.h" @@ -80,11 +81,11 @@ class RecoverPower : StaState RecoverPower(Resizer* resizer); void recoverPower(float recover_power_percent); // For testing. - void recoverPower(const Pin* end_pin); + Vertex* recoverPower(const Pin* end_pin); private: void init(); - bool recoverPower(const PathRef& path, Slack path_slack); + Vertex* recoverPower(const PathRef& path, Slack path_slack); bool meetsSizeCriteria(const LibertyCell* cell, const LibertyCell* equiv, bool match_size); @@ -130,7 +131,7 @@ class RecoverPower : StaState // trying static constexpr int failed_move_threshold_limit_ = 500; - sta::UnorderedMap equiv_pin_map_; + sta::VertexSet bad_vertices_; static constexpr int decreasing_slack_max_passes_ = 50; static constexpr int rebuffer_max_fanout_ = 20; From 67f4c49f71ac435df02b0a50f3617ca1e22e6159 Mon Sep 17 00:00:00 2001 From: Krzysztof Bieganski Date: Mon, 27 May 2024 11:26:52 +0200 Subject: [PATCH 2/2] Move clear before throwing statement Signed-off-by: Krzysztof Bieganski --- src/rsz/src/RecoverPower.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rsz/src/RecoverPower.cc b/src/rsz/src/RecoverPower.cc index cf34c6fa69e..fe471ebc0d1 100644 --- a/src/rsz/src/RecoverPower.cc +++ b/src/rsz/src/RecoverPower.cc @@ -215,6 +215,7 @@ void RecoverPower::recoverPower(const float recover_power_percent) } } } + bad_vertices_.clear(); resizer_->incrementalParasiticsEnd(); // TODO: Add the appropriate metric here @@ -226,7 +227,6 @@ void RecoverPower::recoverPower(const float recover_power_percent) if (resizer_->overMaxArea()) { logger_->error(RSZ, 125, "max utilization reached."); } - bad_vertices_.clear(); } // For testing.