Skip to content

Commit feb144d

Browse files
authored
Merge pull request #8729 from AcKoucher/mpl-macro-arrays
mpl: fix convergence problems with large macro arrays
2 parents b4dad65 + 33be1ad commit feb144d

File tree

8 files changed

+67
-27
lines changed

8 files changed

+67
-27
lines changed

src/mpl/src/SACoreHardMacro.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,13 @@ void SACoreHardMacro::initialize()
200200
graphics_ = nullptr;
201201

202202
for (int i = 0; i < num_perturb_per_step_; i++) {
203+
saveState();
203204
perturb();
205+
if (!invalid_states_allowed_ && !isValid()) {
206+
restoreState();
207+
continue;
208+
}
209+
204210
// store current penalties
205211
width_list.push_back(width_);
206212
height_list.push_back(height_);

src/mpl/src/SACoreSoftMacro.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -314,8 +314,13 @@ void SACoreSoftMacro::initialize()
314314
graphics_ = nullptr;
315315

316316
for (int i = 0; i < num_perturb_per_step_; i++) {
317+
saveState();
317318
perturb();
318-
// store current penalties
319+
if (!invalid_states_allowed_ && !isValid()) {
320+
restoreState();
321+
continue;
322+
}
323+
319324
width_list.push_back(width_);
320325
height_list.push_back(height_);
321326
area_penalty_list.push_back(width_ * height_ / outline_.getWidth()

src/mpl/src/SimulatedAnnealingCore.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -725,6 +725,11 @@ void SimulatedAnnealingCore<T>::fastSA()
725725
cost = calNormCost();
726726

727727
const bool is_valid = isValid();
728+
if (!invalid_states_allowed_ && !is_valid) {
729+
restoreState();
730+
continue;
731+
}
732+
728733
const bool improved = cost < pre_cost || best_result_.empty();
729734
if ((!is_best_result_valid_ || is_valid) && improved) {
730735
updateBestResult(cost);

src/mpl/src/SimulatedAnnealingCore.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ class SimulatedAnnealingCore
6767
void setFences(const std::map<int, Rect>& fences);
6868
void setGuides(const std::map<int, Rect>& guides);
6969
void setInitialSequencePair(const SequencePair& sequence_pair);
70+
void disallowInvalidStates() { invalid_states_allowed_ = false; }
7071

7172
virtual bool isValid() const;
7273
bool fitsIn(const Rect& outline) const;
@@ -220,6 +221,7 @@ class SimulatedAnnealingCore
220221
static constexpr float acc_tolerance_ = 0.001;
221222

222223
bool has_initial_sequence_pair_ = false;
224+
bool invalid_states_allowed_{true};
223225
};
224226

225227
// SACore wrapper function

src/mpl/src/clusterEngine.cpp

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2087,13 +2087,16 @@ void ClusteringEngine::breakMixedLeaf(Cluster* mixed_leaf)
20872087
continue; // this macro cluster has been merged
20882088
}
20892089

2090+
Cluster* movable_macro_cluster = movable_macro_clusters[i];
2091+
movable_macro_cluster->setAsMacroArray();
2092+
20902093
if (interconn_class[i] != -1) {
2091-
movable_macro_clusters[i]->setAsArrayOfInterconnectedMacros();
2094+
movable_macro_cluster->setAsArrayOfInterconnectedMacros();
20922095
}
20932096

2094-
movable_macro_clusters[i]->setClusterType(HardMacroCluster);
2095-
setClusterMetrics(movable_macro_clusters[i]);
2096-
virtual_conn_clusters.push_back(movable_macro_clusters[i]->getId());
2097+
movable_macro_cluster->setClusterType(HardMacroCluster);
2098+
setClusterMetrics(movable_macro_cluster);
2099+
virtual_conn_clusters.push_back(movable_macro_cluster->getId());
20972100
}
20982101

20992102
// Deal with the fixed macros.

src/mpl/src/hier_rtlmp.cpp

Lines changed: 36 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2151,14 +2151,21 @@ void HierRTLMP::placeMacros(Cluster* cluster)
21512151
: minimum_perturbations_per_step;
21522152

21532153
SequencePair initial_seq_pair;
2154-
if (cluster->isArrayOfInterconnectedMacros()) {
2155-
setArrayTilingSequencePair(
2156-
cluster, number_of_sequence_pair_macros, initial_seq_pair);
2154+
bool invalid_states_allowed = true;
2155+
if (cluster->isMacroArray()) {
2156+
bool array_has_empty_space = false;
2157+
initial_seq_pair = computeArraySequencePair(cluster, array_has_empty_space);
21572158

2158-
pos_swap_prob = 0.0f;
2159-
neg_swap_prob = 0.0f;
2160-
double_swap_prob = 0.0f;
2161-
exchange_swap_prob = 1.0f;
2159+
if (array_has_empty_space) {
2160+
invalid_states_allowed = false;
2161+
} else {
2162+
// We don't need to explore different shapes, so we just swap
2163+
// macros until we find the best wire length.
2164+
pos_swap_prob = 0.0f;
2165+
neg_swap_prob = 0.0f;
2166+
double_swap_prob = 0.0f;
2167+
exchange_swap_prob = 1.0f;
2168+
}
21622169

21632170
// Large arrays need more steps to properly converge.
21642171
if (large_macro_cluster) {
@@ -2208,6 +2215,9 @@ void HierRTLMP::placeMacros(Cluster* cluster)
22082215
sa->setFences(fences);
22092216
sa->setGuides(guides);
22102217
sa->setInitialSequencePair(initial_seq_pair);
2218+
if (!invalid_states_allowed) {
2219+
sa->disallowInvalidStates();
2220+
}
22112221

22122222
sa_batch.push_back(std::move(sa));
22132223

@@ -2292,26 +2302,33 @@ void HierRTLMP::placeMacros(Cluster* cluster)
22922302
//
22932303
// Obs: Doing this will still keep the IO clusters at the end
22942304
// of the sequence pair, which is needed for the way SA handles it.
2295-
void HierRTLMP::setArrayTilingSequencePair(Cluster* cluster,
2296-
const int macros_to_place,
2297-
SequencePair& initial_seq_pair)
2305+
SequencePair HierRTLMP::computeArraySequencePair(Cluster* cluster,
2306+
bool& array_has_empty_space)
22982307
{
2299-
// Set positive sequence
2300-
for (int i = 0; i < macros_to_place; ++i) {
2301-
initial_seq_pair.pos_sequence.push_back(i);
2308+
SequencePair sequence_pair;
2309+
const std::vector<HardMacro*>& hard_macros = cluster->getHardMacros();
2310+
const int number_of_macros = static_cast<int>(hard_macros.size());
2311+
2312+
for (int id = 0; id < number_of_macros; ++id) {
2313+
sequence_pair.pos_sequence.push_back(id);
23022314
}
23032315

2304-
// Set negative sequence
2305-
const int columns
2306-
= cluster->getWidth() / cluster->getHardMacros().front()->getWidth();
2307-
const int rows
2308-
= cluster->getHeight() / cluster->getHardMacros().front()->getHeight();
2316+
const HardMacro* hard_macro = hard_macros.front();
2317+
const int columns = std::round(cluster->getWidth() / hard_macro->getWidth());
2318+
const int rows = std::round(cluster->getHeight() / hard_macro->getHeight());
23092319

23102320
for (int i = 1; i <= columns; ++i) {
23112321
for (int j = 1; j <= rows; j++) {
2312-
initial_seq_pair.neg_sequence.push_back(rows * i - j);
2322+
const int macro_id = (rows * i) - j;
2323+
if (macro_id < number_of_macros) {
2324+
sequence_pair.neg_sequence.push_back(macro_id);
2325+
} else {
2326+
array_has_empty_space = true;
2327+
}
23132328
}
23142329
}
2330+
2331+
return sequence_pair;
23152332
}
23162333

23172334
void HierRTLMP::computeFencesAndGuides(

src/mpl/src/hier_rtlmp.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -213,9 +213,8 @@ class HierRTLMP
213213
std::vector<BundledNet> computeBundledNets(
214214
const UniqueClusterVector& macro_clusters,
215215
const std::map<int, int>& cluster_to_macro);
216-
void setArrayTilingSequencePair(Cluster* cluster,
217-
int macros_to_place,
218-
SequencePair& initial_seq_pair);
216+
SequencePair computeArraySequencePair(Cluster* cluster,
217+
bool& array_has_empty_space);
219218

220219
// Orientation Improvement
221220
void generateTemporaryStdCellsPlacement(Cluster* cluster);

src/mpl/src/object.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,8 @@ class Cluster
171171

172172
void setAsArrayOfInterconnectedMacros();
173173
bool isArrayOfInterconnectedMacros() const;
174+
void setAsMacroArray() { is_macro_array_ = true; }
175+
bool isMacroArray() const { return is_macro_array_; }
174176
bool isEmpty() const;
175177
bool correspondsToLogicalModule() const;
176178

@@ -247,6 +249,7 @@ class Cluster
247249
bool is_io_pad_cluster_{false};
248250
bool is_io_bundle_{false};
249251
bool is_array_of_interconnected_macros_ = false;
252+
bool is_macro_array_{false};
250253
bool is_fixed_macro_{false};
251254

252255
std::unique_ptr<SoftMacro> soft_macro_;

0 commit comments

Comments
 (0)