Skip to content

Commit b160876

Browse files
authored
Merge pull request #8949 from luis201420/cts_improve_automatic_clustering
CTS: improve automatic clustering
2 parents 7984c88 + 9421b05 commit b160876

21 files changed

+579
-631
lines changed

src/cts/src/CtsOptions.cpp

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,14 +31,11 @@ void CtsOptions::inDbInstCreate(odb::dbInst* inst, odb::dbRegion* region)
3131

3232
void CtsOptions::limitSinkClusteringSizes(unsigned limit)
3333
{
34+
unsigned new_size = limit;
3435
if (sinkClustersSizeSet_) {
35-
setSinkClusteringSize(std::min(limit, sinkClustersSize_));
36-
return;
36+
new_size = std::min(new_size, sinkClustersSize_);
3737
}
38-
auto lowerBound = std::lower_bound(
39-
sinkClusteringSizes_.begin(), sinkClusteringSizes_.end(), limit);
40-
sinkClusteringSizes_.erase(lowerBound, sinkClusteringSizes_.end());
41-
sinkClusteringSizes_.push_back(limit);
38+
setSinkClusteringSize(new_size);
4239
}
4340

4441
void CtsOptions::recordBuffer(odb::dbMaster* master, MasterType type)

src/cts/src/CtsOptions.h

Lines changed: 2 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -84,11 +84,6 @@ class CtsOptions : public odb::dbBlockCallBackObj
8484

8585
void setSinkClustering(bool enable) { sinkClusteringEnable_ = enable; }
8686
bool getSinkClustering() const { return sinkClusteringEnable_; }
87-
void setSinkClusteringUseMaxCap(bool useMaxCap)
88-
{
89-
sinkClusteringUseMaxCap_ = useMaxCap;
90-
}
91-
bool getSinkClusteringUseMaxCap() const { return sinkClusteringUseMaxCap_; }
9287
void setNumMaxLeafSinks(unsigned numSinks) { numMaxLeafSinks_ = numSinks; }
9388
unsigned getNumMaxLeafSinks() const { return numMaxLeafSinks_; }
9489
void setMaxSlew(unsigned slew) { maxSlew_ = slew; }
@@ -209,38 +204,26 @@ class CtsOptions : public odb::dbBlockCallBackObj
209204
void setMaxDiameter(double distance)
210205
{
211206
maxDiameter_ = distance;
212-
sinkClusteringUseMaxCap_ = false;
213207
maxDiameterSet_ = true;
214208
}
215209
void resetMaxDiameter()
216210
{
217211
maxDiameter_ = 50;
218-
sinkClusteringUseMaxCap_ = true;
219212
maxDiameterSet_ = false;
220213
}
221214
bool isMaxDiameterSet() const { return maxDiameterSet_; }
222-
const std::vector<unsigned>& getSinkClusteringDiameters()
223-
{
224-
return sinkClusteringDiameters_;
225-
}
226215
unsigned getSinkClusteringSize() const { return sinkClustersSize_; }
227216
void setSinkClusteringSize(unsigned size)
228217
{
229218
sinkClustersSize_ = size;
230-
sinkClusteringUseMaxCap_ = false;
231219
sinkClustersSizeSet_ = true;
232220
}
233221
void resetSinkClusteringSize()
234222
{
235-
sinkClustersSize_ = 20;
236-
sinkClusteringUseMaxCap_ = true;
223+
sinkClustersSize_ = 30;
237224
sinkClustersSizeSet_ = false;
238225
}
239226
bool isSinkClusteringSizeSet() const { return sinkClustersSizeSet_; }
240-
const std::vector<unsigned>& getSinkClusteringSizes()
241-
{
242-
return sinkClusteringSizes_;
243-
}
244227
void limitSinkClusteringSizes(unsigned limit);
245228
unsigned getSinkClusteringLevels() const { return sinkClusteringLevels_; }
246229
void setSinkClusteringLevels(unsigned levels)
@@ -363,7 +346,6 @@ class CtsOptions : public odb::dbBlockCallBackObj
363346
unsigned wireSegmentUnit_ = 0;
364347
bool plotSolution_ = false;
365348
bool sinkClusteringEnable_ = true;
366-
bool sinkClusteringUseMaxCap_ = true;
367349
bool simpleSegmentsEnable_ = false;
368350
bool vertexBuffersEnable_ = false;
369351
std::unique_ptr<CtsObserver> observer_;
@@ -390,10 +372,8 @@ class CtsOptions : public odb::dbBlockCallBackObj
390372
int sinks_ = 0;
391373
double maxDiameter_ = 50;
392374
bool maxDiameterSet_ = false;
393-
std::vector<unsigned> sinkClusteringDiameters_ = {50, 100, 200};
394-
unsigned sinkClustersSize_ = 20;
375+
unsigned sinkClustersSize_ = 30;
395376
bool sinkClustersSizeSet_ = false;
396-
std::vector<unsigned> sinkClusteringSizes_ = {10, 20, 30};
397377
double macroMaxDiameter_ = 50;
398378
bool macroMaxDiameterSet_ = false;
399379
unsigned macroSinkClustersSize_ = 4;

src/cts/src/HTreeBuilder.cpp

Lines changed: 34 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -80,63 +80,15 @@ void HTreeBuilder::preSinkClustering(
8080

8181
unsigned bestClusterSize = 0;
8282
float bestDiameter = 0.0;
83-
if (clusterSizeSet && maxDiameterSet) {
84-
// clang-format off
85-
debugPrint(logger_, CTS, "clustering", 1, "**** match.run({}, {}, {}) ****",
86-
clusterSize, maxDiameter, wireSegmentUnit_);
87-
// clang-format on
88-
matching.run(clusterSize,
89-
maxDiameter,
90-
wireSegmentUnit_,
91-
bestClusterSize,
92-
bestDiameter);
93-
} else if (!clusterSizeSet && maxDiameterSet) {
94-
// only diameter is set, try clustering sizes of 10, 20 and 30
95-
for (unsigned clusterSize2 : options_->getSinkClusteringSizes()) {
96-
// clang-format off
97-
debugPrint(logger_, CTS, "clustering", 1, "**** match.run({}, {}, {}) ****",
98-
clusterSize2, maxDiameter, wireSegmentUnit_);
99-
// clang-format on
100-
matching.run(clusterSize2,
101-
maxDiameter,
102-
wireSegmentUnit_,
103-
bestClusterSize,
104-
bestDiameter);
105-
}
106-
} else if (clusterSizeSet && !maxDiameterSet) {
107-
// only clustering size is set, try diameters of 50, 100 and 200 um
108-
for (unsigned clusterDiameter2 : options_->getSinkClusteringDiameters()) {
109-
// clang-format off
110-
debugPrint(logger_, CTS, "clustering", 1, "**** match.run({}, {}, {}) ****",
111-
clusterSize, clusterDiameter2, wireSegmentUnit_);
112-
// clang-format on
113-
float maxDiameter2 = clusterDiameter2 * (float) options_->getDbUnits()
114-
/ wireSegmentUnit_;
115-
matching.run(clusterSize,
116-
maxDiameter2,
117-
wireSegmentUnit_,
118-
bestClusterSize,
119-
bestDiameter);
120-
}
121-
} else { // neighther clustering size nor diameter is set
122-
// try diameters of 50, 100 and 200 um
123-
for (unsigned clusterDiameter2 : clusterDiameters()) {
124-
// try clustering sizes of 10, 20 and 30
125-
for (unsigned clusterSize2 : options_->getSinkClusteringSizes()) {
126-
// clang-format off
127-
debugPrint(logger_, CTS, "clustering", 1, "**** match.run({}, {}, {}) ****",
128-
clusterSize2, clusterDiameter2, wireSegmentUnit_);
129-
// clang-format on
130-
float maxDiameter2 = clusterDiameter2 * (float) options_->getDbUnits()
131-
/ wireSegmentUnit_;
132-
matching.run(clusterSize2,
133-
maxDiameter2,
134-
wireSegmentUnit_,
135-
bestClusterSize,
136-
bestDiameter);
137-
}
138-
}
139-
}
83+
// clang-format off
84+
debugPrint(logger_, CTS, "clustering", 1, "**** match.run({}, {}, {}) ****",
85+
clusterSize, maxDiameter, wireSegmentUnit_);
86+
// clang-format on
87+
matching.run(clusterSize,
88+
maxDiameter,
89+
wireSegmentUnit_,
90+
bestClusterSize,
91+
bestDiameter);
14092

14193
if (clusterSizeSet || maxDiameterSet) {
14294
logger_->info(
@@ -1176,18 +1128,21 @@ void HTreeBuilder::run()
11761128
unsigned clusterSize = (type_ == TreeType::MacroTree)
11771129
? options_->getMacroSinkClusteringSize()
11781130
: options_->getSinkClusteringSize();
1131+
bool use_max_diameter = (type_ == TreeType::MacroTree)
1132+
? options_->isMacroMaxDiameterSet()
1133+
: options_->isMaxDiameterSet();
1134+
bool use_max_size = (type_ == TreeType::MacroTree)
1135+
? options_->isMacroSinkClusteringSizeSet()
1136+
: options_->isSinkClusteringSizeSet();
11791137
bool useMaxCap = (type_ == TreeType::MacroTree)
11801138
? false
1181-
: options_->getSinkClusteringUseMaxCap();
1139+
: !(use_max_size && use_max_diameter);
11821140

11831141
logger_->info(
11841142
CTS, 27, "Generating H-Tree topology for net {}.", clock_.getName());
11851143
logger_->info(CTS, 28, " Total number of sinks: {}.", clock_.getNumSinks());
11861144
if (options_->getSinkClustering()) {
1187-
if (useMaxCap) {
1188-
logger_->info(
1189-
CTS, 90, " Sinks will be clustered based on buffer max cap.");
1190-
} else {
1145+
if (!useMaxCap) {
11911146
logger_->info(
11921147
CTS,
11931148
29,
@@ -1196,6 +1151,23 @@ void HTreeBuilder::run()
11961151
type_ == TreeType::MacroTree ? "Macro " : "Register",
11971152
clusterSize,
11981153
clusterDiameter);
1154+
} else if (use_max_diameter && !use_max_size) {
1155+
logger_->info(CTS,
1156+
59,
1157+
" {} sinks will be clustered with maximum cluster diameter "
1158+
"of {:.1f} um and based on buffer max cap.",
1159+
type_ == TreeType::MacroTree ? "Macro " : "Register",
1160+
clusterDiameter);
1161+
} else if (!use_max_diameter && use_max_size) {
1162+
logger_->info(CTS,
1163+
60,
1164+
" {} sinks will be clustered in groups of up to {} and "
1165+
"based on buffer max cap.",
1166+
type_ == TreeType::MacroTree ? "Macro " : "Register",
1167+
clusterSize);
1168+
} else {
1169+
logger_->info(
1170+
CTS, 90, " Sinks will be clustered based on buffer max cap.");
11991171
}
12001172
}
12011173
logger_->info(

src/cts/src/SinkClustering.cpp

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include <sstream>
1313
#include <vector>
1414

15+
#include "TreeBuilder.h"
1516
#include "stt/SteinerTreeBuilder.h"
1617
#include "utl/Logger.h"
1718

@@ -28,9 +29,15 @@ SinkClustering::SinkClustering(const CtsOptions* options,
2829
techChar_(techChar),
2930
maxInternalDiameter_(10),
3031
capPerUnit_(0.0),
32+
use_max_diameter_((HTree->getTreeType() == TreeType::MacroTree)
33+
? options->isMacroMaxDiameterSet()
34+
: options->isMaxDiameterSet()),
35+
use_max_size_((HTree->getTreeType() == TreeType::MacroTree)
36+
? options->isMacroSinkClusteringSizeSet()
37+
: options->isSinkClusteringSizeSet()),
3138
useMaxCapLimit_((HTree->getTreeType() == TreeType::MacroTree)
3239
? false
33-
: options->getSinkClusteringUseMaxCap()),
40+
: !(use_max_size_ && use_max_diameter_)),
3441
scaleFactor_(1),
3542
HTree_(HTree)
3643
{
@@ -414,11 +421,20 @@ bool SinkClustering::isLimitExceeded(const unsigned size,
414421
const double capCost,
415422
const unsigned sizeLimit)
416423
{
424+
bool is_limit_exceeded = false;
417425
if (useMaxCapLimit_) {
418-
return (capCost > options_->getSinkBufferInputCap() * max_cap__factor_);
426+
is_limit_exceeded
427+
|= (capCost > options_->getSinkBufferInputCap() * max_cap__factor_);
419428
}
420-
421-
return (size >= sizeLimit || cost > maxInternalDiameter_);
429+
// size is defined by the user
430+
if (use_max_size_) {
431+
is_limit_exceeded |= (size >= sizeLimit);
432+
}
433+
// diameter is defined by the user
434+
if (use_max_diameter_) {
435+
is_limit_exceeded |= (cost > maxInternalDiameter_);
436+
}
437+
return is_limit_exceeded;
422438
}
423439

424440
void SinkClustering::writePlotFile(unsigned groupSize)

src/cts/src/SinkClustering.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,8 @@ class SinkClustering
9090
std::vector<std::vector<unsigned>> bestSolution_;
9191
float maxInternalDiameter_;
9292
float capPerUnit_;
93+
bool use_max_diameter_;
94+
bool use_max_size_;
9395
bool useMaxCapLimit_;
9496
int scaleFactor_;
9597
static constexpr double max_cap__factor_ = 10;

0 commit comments

Comments
 (0)