Skip to content

Commit 3f5a91c

Browse files
authored
Merge pull request #5809 from AcKoucher/mpl2-constraints
mpl2: IOs abstraction adaptation to ORFS flow - first version (simplified)
2 parents 9706cd2 + 2d9b99d commit 3f5a91c

29 files changed

+2968
-344
lines changed

src/mpl2/README.md

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ rtl_macro_placer
2525
[-tolerance tolerance]
2626
[-max_num_level max_num_level]
2727
[-coarsening_ratio coarsening_ratio]
28-
[-num_bundled_ios num_bundled_ios]
2928
[-large_net_threshold large_net_threshold]
3029
[-signature_net_threshold signature_net_threshold]
3130
[-halo_width halo_width]
@@ -61,7 +60,6 @@ rtl_macro_placer
6160
| `-tolerance` | Add a margin to the minimum and maximum number of macros/std cells in a cluster. For min, we multiply by (1 - `tol`), and for the max (1 + `tol`). This is to improve the robustness of hierarchical clustering. The allowed values are floats `[0, 1)`, and the default value is `0.1`. |
6261
| `-max_num_level` | Maximum depth of physical hierarchical tree. The default value is `2`, and the allowed values are integers `[0, MAX_INT]`. |
6362
| `-coarsening_ratio` | The larger the coarsening_ratio, the faster the convergence process. The allowed values are floats, and the default value is `10.0`. |
64-
| `-num_bundled_ios` | Specifies the number of bundled pins for the left, right, top, and bottom boundaries. The default value is `3`, and the allowed values are integers `[0, MAX_INT]`. |
6563
| `-large_net_threshold` | Ignore nets with many connections during clustering, such as global nets. The default value is `50`, and the allowed values are integers `[0, MAX_INT]`. |
6664
| `-signature_net_threshold` | Minimum number of connections between two clusters to be identified as connected. The default value is `50`, and the allowed values are integers `[0, MAX_INT]`. |
6765
| `-halo_width` | Horizontal/vertical halo around macros (microns). The allowed values are floats, and the default value is `0.0`. |

src/mpl2/include/mpl2/rtl_mp.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,6 @@ class MacroPlacer2
8080
float tolerance,
8181
int max_num_level,
8282
float coarsening_ratio,
83-
int num_bundled_ios,
8483
int large_net_threshold,
8584
int signature_net_threshold,
8685
float halo_width,

src/mpl2/src/Mpl2Observer.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
#include <optional>
3939
#include <vector>
4040

41+
#include "clusterEngine.h"
4142
#include "object.h"
4243
#include "odb/geom.h"
4344
#include "utl/Logger.h"
@@ -68,7 +69,7 @@ class Mpl2Observer
6869
virtual void endSA(float norm_cost) {}
6970
virtual void drawResult() {}
7071

71-
virtual void finishedClustering(Cluster* root) {}
72+
virtual void finishedClustering(PhysicalHierarchy* tree) {}
7273

7374
virtual void setMaxLevel(int max_level) {}
7475
virtual void setMacroBlockages(const std::vector<mpl2::Rect>& macro_blockages)

src/mpl2/src/SACoreHardMacro.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ using utl::MPL;
4545
// Class SACoreHardMacro
4646
// constructors
4747
SACoreHardMacro::SACoreHardMacro(
48+
PhysicalHierarchy* tree,
4849
const Rect& outline,
4950
const std::vector<HardMacro>& macros,
5051
// weight for different penalty
@@ -66,7 +67,8 @@ SACoreHardMacro::SACoreHardMacro(
6667
unsigned seed,
6768
Mpl2Observer* graphics,
6869
utl::Logger* logger)
69-
: SimulatedAnnealingCore<HardMacro>(outline,
70+
: SimulatedAnnealingCore<HardMacro>(tree,
71+
outline,
7072
macros,
7173
area_weight,
7274
outline_weight,

src/mpl2/src/SACoreHardMacro.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,8 @@ namespace mpl2 {
4949
class SACoreHardMacro : public SimulatedAnnealingCore<HardMacro>
5050
{
5151
public:
52-
SACoreHardMacro(const Rect& outline,
52+
SACoreHardMacro(PhysicalHierarchy* tree,
53+
const Rect& outline,
5354
const std::vector<HardMacro>& macros,
5455
// weight for different penalty
5556
float area_weight,

src/mpl2/src/SACoreSoftMacro.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ using utl::MPL;
4545
// Class SACoreSoftMacro
4646
// constructors
4747
SACoreSoftMacro::SACoreSoftMacro(
48-
Cluster* root,
48+
PhysicalHierarchy* tree,
4949
const Rect& outline,
5050
const std::vector<SoftMacro>& macros,
5151
// weight for different penalty
@@ -73,7 +73,8 @@ SACoreSoftMacro::SACoreSoftMacro(
7373
unsigned seed,
7474
Mpl2Observer* graphics,
7575
utl::Logger* logger)
76-
: SimulatedAnnealingCore<SoftMacro>(outline,
76+
: SimulatedAnnealingCore<SoftMacro>(tree,
77+
outline,
7778
macros,
7879
area_weight,
7980
outline_weight,
@@ -90,7 +91,7 @@ SACoreSoftMacro::SACoreSoftMacro(
9091
seed,
9192
graphics,
9293
logger),
93-
root_(root)
94+
root_(tree->root.get())
9495
{
9596
boundary_weight_ = boundary_weight;
9697
macro_blockage_weight_ = macro_blockage_weight;

src/mpl2/src/SACoreSoftMacro.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ class Graphics;
5050
class SACoreSoftMacro : public SimulatedAnnealingCore<SoftMacro>
5151
{
5252
public:
53-
SACoreSoftMacro(Cluster* root,
53+
SACoreSoftMacro(PhysicalHierarchy* tree,
5454
const Rect& outline,
5555
const std::vector<SoftMacro>& macros,
5656
// weight for different penalty

src/mpl2/src/SimulatedAnnealingCore.cpp

Lines changed: 103 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ using std::string;
4949
// Class SimulatedAnnealingCore
5050
template <class T>
5151
SimulatedAnnealingCore<T>::SimulatedAnnealingCore(
52+
PhysicalHierarchy* tree,
5253
const Rect& outline, // boundary constraints
5354
const std::vector<T>& macros, // macros (T = HardMacro or T = SoftMacro)
5455
// weight for different penalty
@@ -69,7 +70,9 @@ SimulatedAnnealingCore<T>::SimulatedAnnealingCore(
6970
unsigned seed,
7071
Mpl2Observer* graphics,
7172
utl::Logger* logger)
72-
: outline_(outline), graphics_(graphics)
73+
: outline_(outline),
74+
blocked_boundaries_(tree->blocked_boundaries),
75+
graphics_(graphics)
7376
{
7477
area_weight_ = area_weight;
7578
outline_weight_ = outline_weight;
@@ -94,6 +97,28 @@ SimulatedAnnealingCore<T>::SimulatedAnnealingCore(
9497

9598
logger_ = logger;
9699
macros_ = macros;
100+
101+
setBlockedBoundariesForIOs();
102+
}
103+
104+
template <class T>
105+
void SimulatedAnnealingCore<T>::setBlockedBoundariesForIOs()
106+
{
107+
if (blocked_boundaries_.find(Boundary::L) != blocked_boundaries_.end()) {
108+
left_is_blocked_ = true;
109+
}
110+
111+
if (blocked_boundaries_.find(Boundary::R) != blocked_boundaries_.end()) {
112+
right_is_blocked_ = true;
113+
}
114+
115+
if (blocked_boundaries_.find(Boundary::B) != blocked_boundaries_.end()) {
116+
bottom_is_blocked_ = true;
117+
}
118+
119+
if (blocked_boundaries_.find(Boundary::T) != blocked_boundaries_.end()) {
120+
top_is_blocked_ = true;
121+
}
97122
}
98123

99124
template <class T>
@@ -274,10 +299,18 @@ void SimulatedAnnealingCore<T>::calWirelength()
274299
}
275300

276301
for (const auto& net : nets_) {
277-
const float x1 = macros_[net.terminals.first].getPinX();
278-
const float y1 = macros_[net.terminals.first].getPinY();
279-
const float x2 = macros_[net.terminals.second].getPinX();
280-
const float y2 = macros_[net.terminals.second].getPinY();
302+
T& source = macros_[net.terminals.first];
303+
T& target = macros_[net.terminals.second];
304+
305+
if (target.isIOCluster()) {
306+
addBoundaryDistToWirelength(source, target, net.weight);
307+
continue;
308+
}
309+
310+
const float x1 = source.getPinX();
311+
const float y1 = source.getPinY();
312+
const float x2 = target.getPinX();
313+
const float y2 = target.getPinY();
281314
wirelength_ += net.weight * (std::abs(x2 - x1) + std::abs(y2 - y1));
282315
}
283316

@@ -291,6 +324,71 @@ void SimulatedAnnealingCore<T>::calWirelength()
291324
}
292325
}
293326

327+
template <class T>
328+
void SimulatedAnnealingCore<T>::addBoundaryDistToWirelength(
329+
const T& macro,
330+
const T& io,
331+
const float net_weight)
332+
{
333+
Cluster* io_cluster = io.getCluster();
334+
const Rect die = io_cluster->getBBox();
335+
const float die_hpwl = die.getWidth() + die.getHeight();
336+
337+
if (isOutsideTheOutline(macro)) {
338+
wirelength_ += net_weight * die_hpwl;
339+
return;
340+
}
341+
342+
const float x1 = macro.getPinX();
343+
const float y1 = macro.getPinY();
344+
345+
Boundary constraint_boundary = io_cluster->getConstraintBoundary();
346+
347+
if (constraint_boundary == NONE) {
348+
float dist_to_left = die_hpwl;
349+
if (!left_is_blocked_) {
350+
dist_to_left = std::abs(x1 - die.xMin());
351+
}
352+
353+
float dist_to_right = die_hpwl;
354+
if (!right_is_blocked_) {
355+
dist_to_right = std::abs(x1 - die.xMax());
356+
}
357+
358+
float dist_to_bottom = die_hpwl;
359+
if (!bottom_is_blocked_) {
360+
dist_to_right = std::abs(y1 - die.yMin());
361+
}
362+
363+
float dist_to_top = die_hpwl;
364+
if (!top_is_blocked_) {
365+
dist_to_top = std::abs(y1 - die.yMax());
366+
}
367+
368+
wirelength_
369+
+= net_weight
370+
* std::min(
371+
{dist_to_left, dist_to_right, dist_to_bottom, dist_to_top});
372+
} else if (constraint_boundary == Boundary::L
373+
|| constraint_boundary == Boundary::R) {
374+
const float x2 = io.getPinX();
375+
wirelength_ += net_weight * std::abs(x2 - x1);
376+
} else if (constraint_boundary == Boundary::T
377+
|| constraint_boundary == Boundary::B) {
378+
const float y2 = io.getPinY();
379+
wirelength_ += net_weight * std::abs(y2 - y1);
380+
}
381+
}
382+
383+
// We consider the macro outside the outline based on the location of
384+
// the pin to avoid too many checks.
385+
template <class T>
386+
bool SimulatedAnnealingCore<T>::isOutsideTheOutline(const T& macro) const
387+
{
388+
return macro.getPinX() > outline_.getWidth()
389+
|| macro.getPinY() > outline_.getHeight();
390+
}
391+
294392
template <class T>
295393
void SimulatedAnnealingCore<T>::calFencePenalty()
296394
{

src/mpl2/src/SimulatedAnnealingCore.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
#include <vector>
3939

4040
#include "Mpl2Observer.h"
41+
#include "clusterEngine.h"
4142

4243
namespace utl {
4344
class Logger;
@@ -68,6 +69,7 @@ class SimulatedAnnealingCore
6869
{
6970
public:
7071
SimulatedAnnealingCore(
72+
PhysicalHierarchy* tree,
7173
const Rect& outline, // boundary constraints
7274
const std::vector<T>& macros, // macros (T = HardMacro or T = SoftMacro)
7375
// weight for different penalty
@@ -134,13 +136,18 @@ class SimulatedAnnealingCore
134136
void fastSA();
135137

136138
void initSequencePair();
139+
void setBlockedBoundariesForIOs();
137140
void updateBestValidResult();
138141
void useBestValidResult();
139142

140143
virtual float calNormCost() const = 0;
141144
virtual void calPenalty() = 0;
142145
void calOutlinePenalty();
143146
void calWirelength();
147+
void addBoundaryDistToWirelength(const T& macro,
148+
const T& io,
149+
float net_weight);
150+
bool isOutsideTheOutline(const T& macro) const;
144151
void calGuidancePenalty();
145152
void calFencePenalty();
146153

@@ -165,6 +172,9 @@ class SimulatedAnnealingCore
165172
// boundary constraints
166173
Rect outline_;
167174

175+
// Boundaries blocked for IO pins
176+
std::set<Boundary> blocked_boundaries_;
177+
168178
// Number of macros that will actually be part of the sequence pair
169179
int macros_to_place_ = 0;
170180

@@ -249,6 +259,13 @@ class SimulatedAnnealingCore
249259
static constexpr float acc_tolerance_ = 0.001;
250260

251261
bool has_initial_sequence_pair_ = false;
262+
263+
// Blocked boundaries data is kept in bools to avoid overhead
264+
// during SA steps.
265+
bool left_is_blocked_ = false;
266+
bool right_is_blocked_ = false;
267+
bool bottom_is_blocked_ = false;
268+
bool top_is_blocked_ = false;
252269
};
253270

254271
// SACore wrapper function

0 commit comments

Comments
 (0)