Skip to content

Commit

Permalink
mpl2:
Browse files Browse the repository at this point in the history
1) Make functions that should not live in the SACore interface to live in their respective class.
2) Store shapes inside the result to avoid using a wron floorplan when incorporating the best valid result.

Signed-off-by: Arthur Koucher <arthurkoucher@precisioninno.com>
  • Loading branch information
AcKoucher committed Nov 1, 2024
1 parent 718e43f commit 8ad3ac8
Show file tree
Hide file tree
Showing 7 changed files with 134 additions and 100 deletions.
13 changes: 13 additions & 0 deletions src/mpl2/src/SACoreHardMacro.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,19 @@ SACoreHardMacro::SACoreHardMacro(
flip_prob_ = flip_prob;
}

void SACoreHardMacro::run()
{
if (graphics_) {
graphics_->startSA();
}

fastSA();

if (graphics_) {
graphics_->endSA(calNormCost());
}
}

float SACoreHardMacro::getAreaPenalty() const
{
const float outline_area = outline_.getWidth() * outline_.getHeight();
Expand Down
2 changes: 2 additions & 0 deletions src/mpl2/src/SACoreHardMacro.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@ class SACoreHardMacro : public SimulatedAnnealingCore<HardMacro>
Mpl2Observer* graphics,
utl::Logger* logger);

void run() override;

void setWeights(const SACoreWeights& weights);

// Initialize the SA worker
Expand Down
83 changes: 83 additions & 0 deletions src/mpl2/src/SACoreSoftMacro.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,39 @@ SACoreSoftMacro::SACoreSoftMacro(
logger_ = logger;
}

void SACoreSoftMacro::run()
{
if (graphics_) {
graphics_->startSA();
}

best_valid_result_ = std::make_unique<Result>();

fastSA();

if (!isValid() && !best_valid_result_->sequence_pair.pos_sequence.empty()) {
pos_seq_ = best_valid_result_->sequence_pair.pos_sequence;
neg_seq_ = best_valid_result_->sequence_pair.neg_sequence;

for (const int macro_id : pos_seq_) {
SoftMacro& macro = macros_[macro_id];
macro.setWidth(best_valid_result_->macro_id_to_width.at(macro_id));
}

packFloorplan();
if (graphics_) {
graphics_->doNotSkip();
}
calPenalty();
}

attemptCentralization(calNormCost());

if (graphics_) {
graphics_->endSA(calNormCost());
}
}

// acessors functions
float SACoreSoftMacro::getBoundaryPenalty() const
{
Expand Down Expand Up @@ -1104,4 +1137,54 @@ void SACoreSoftMacro::addBlockages(const std::vector<Rect>& blockages)
blockages_.insert(blockages_.end(), blockages.begin(), blockages.end());
}

void SACoreSoftMacro::attemptCentralization(const float pre_cost)
{
if (outline_penalty_ > 0) {
return;
}

// In order to revert the centralization, we cache the current location
// of the clusters to avoid floating-point evilness when creating the
// x,y grid to fill the dead space by expanding mixed clusters.
std::map<int, std::pair<float, float>> clusters_locations;

for (int& id : pos_seq_) {
clusters_locations[id] = {macros_[id].getX(), macros_[id].getY()};
}

std::pair<float, float> offset((outline_.getWidth() - width_) / 2,
(outline_.getHeight() - height_) / 2);
moveFloorplan(offset);

// revert centralization
if (calNormCost() > pre_cost) {
centralization_was_reverted_ = true;

for (int& id : pos_seq_) {
macros_[id].setX(clusters_locations[id].first);
macros_[id].setY(clusters_locations[id].second);
}

if (graphics_) {
graphics_->saStep(macros_);
}

calPenalty();
}
}

void SACoreSoftMacro::moveFloorplan(const std::pair<float, float>& offset)
{
for (auto& id : pos_seq_) {
macros_[id].setX(macros_[id].getX() + offset.first);
macros_[id].setY(macros_[id].getY() + offset.second);
}

if (graphics_) {
graphics_->saStep(macros_);
}

calPenalty();
}

} // namespace mpl2
6 changes: 6 additions & 0 deletions src/mpl2/src/SACoreSoftMacro.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,9 @@ class SACoreSoftMacro : public SimulatedAnnealingCore<SoftMacro>
unsigned seed,
Mpl2Observer* graphics,
utl::Logger* logger);

void run() override;

// accessors
float getBoundaryPenalty() const;
float getNormBoundaryPenalty() const;
Expand All @@ -97,6 +100,9 @@ class SACoreSoftMacro : public SimulatedAnnealingCore<SoftMacro>
void addBlockages(const std::vector<Rect>& blockages);

private:
void attemptCentralization(float pre_cost);
void moveFloorplan(const std::pair<float, float>& offset);

float getAreaPenalty() const;
float calNormCost() const override;
void calPenalty() override;
Expand Down
105 changes: 19 additions & 86 deletions src/mpl2/src/SimulatedAnnealingCore.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -560,10 +560,6 @@ float SimulatedAnnealingCore<T>::calAverage(std::vector<float>& value_list)
template <class T>
void SimulatedAnnealingCore<T>::fastSA()
{
if (graphics_) {
graphics_->startSA();
}

float cost = calNormCost();
float pre_cost = cost;
float delta_cost = 0.0;
Expand All @@ -580,21 +576,22 @@ void SimulatedAnnealingCore<T>::fastSA()
int num_restart = 1;
const int max_num_restart = 2;

SequencePair best_valid_result;
if (isValid()) {
updateBestValidResult(best_valid_result);
if (best_valid_result_ && isValid()) {
updateBestValidResult(best_valid_result_.get());
}

while (step <= max_num_step_) {
for (int i = 0; i < num_perturb_per_step_; i++) {
perturb();
cost = calNormCost();

const bool keep_result
= cost < pre_cost || best_valid_result.pos_sequence.empty();

if (isValid() && keep_result) {
updateBestValidResult(best_valid_result);
if (best_valid_result_) {
const bool keep_result
= cost < pre_cost
|| best_valid_result_->sequence_pair.pos_sequence.empty();
if (isValid() && keep_result) {
updateBestValidResult(best_valid_result_.get());
}
}

delta_cost = cost - pre_cost;
Expand Down Expand Up @@ -640,86 +637,22 @@ void SimulatedAnnealingCore<T>::fastSA()
graphics_->doNotSkip();
}
calPenalty();

if (!isValid() && !best_valid_result.pos_sequence.empty()) {
pos_seq_ = best_valid_result.pos_sequence;
neg_seq_ = best_valid_result.neg_sequence;

packFloorplan();
if (graphics_) {
graphics_->doNotSkip();
}
calPenalty();
}

if (centralization_on_) {
attemptCentralization(calNormCost());
}

if (graphics_) {
graphics_->endSA(calNormCost());
}
}

// The same sequence pair can have macros with different shapes,
// so it may generate both valid/invalid floorplans. To ensure
// that a result is truly the one we're looking for, we need to
// also keep its shapes.
template <class T>
void SimulatedAnnealingCore<T>::attemptCentralization(const float pre_cost)
void SimulatedAnnealingCore<T>::updateBestValidResult(Result* best_valid_result)
{
if (outline_penalty_ > 0) {
return;
}
best_valid_result->sequence_pair.pos_sequence = pos_seq_;
best_valid_result->sequence_pair.neg_sequence = neg_seq_;

// In order to revert the centralization, we cache the current location
// of the clusters to avoid floating-point evilness when creating the
// x,y grid to fill the dead space by expanding mixed clusters.
std::map<int, std::pair<float, float>> clusters_locations;

for (int& id : pos_seq_) {
clusters_locations[id] = {macros_[id].getX(), macros_[id].getY()};
for (const int macro_id : pos_seq_) {
T& macro = macros_[macro_id];
best_valid_result->macro_id_to_width[macro_id] = macro.getWidth();
}

std::pair<float, float> offset((outline_.getWidth() - width_) / 2,
(outline_.getHeight() - height_) / 2);
moveFloorplan(offset);

// revert centralization
if (calNormCost() > pre_cost) {
centralization_was_reverted_ = true;

for (int& id : pos_seq_) {
macros_[id].setX(clusters_locations[id].first);
macros_[id].setY(clusters_locations[id].second);
}

if (graphics_) {
graphics_->saStep(macros_);
}

calPenalty();
}
}

template <class T>
void SimulatedAnnealingCore<T>::moveFloorplan(
const std::pair<float, float>& offset)
{
for (auto& id : pos_seq_) {
macros_[id].setX(macros_[id].getX() + offset.first);
macros_[id].setY(macros_[id].getY() + offset.second);
}

if (graphics_) {
graphics_->saStep(macros_);
}

calPenalty();
}

template <class T>
void SimulatedAnnealingCore<T>::updateBestValidResult(
SequencePair& best_valid_result)
{
best_valid_result.pos_sequence = pos_seq_;
best_valid_result.neg_sequence = neg_seq_;
}

template <class T>
Expand Down
21 changes: 11 additions & 10 deletions src/mpl2/src/SimulatedAnnealingCore.h
Original file line number Diff line number Diff line change
Expand Up @@ -95,10 +95,6 @@ class SimulatedAnnealingCore
{
macros_to_place_ = macros_to_place;
};
void setCentralizationAttemptOn(bool centralization_on)
{
centralization_on_ = centralization_on;
};
bool centralizationWasReverted() { return centralization_was_reverted_; }

void setNets(const std::vector<BundledNet>& nets);
Expand Down Expand Up @@ -126,15 +122,19 @@ class SimulatedAnnealingCore

// Initialize the SA worker
virtual void initialize() = 0;
// Run FastSA algorithm
virtual void run() = 0;
void fastSA();
virtual void fillDeadSpace() = 0;

protected:
struct Result
{
SequencePair sequence_pair;
std::map<int, float> macro_id_to_width; // Result's shapes.
};

void initSequencePair();
void attemptCentralization(float pre_cost);
void moveFloorplan(const std::pair<float, float>& offset);
void updateBestValidResult(SequencePair& best_valid_result);
void updateBestValidResult(Result* best_valid_result);

virtual float calNormCost() const = 0;
virtual void calPenalty() = 0;
Expand Down Expand Up @@ -239,14 +239,15 @@ class SimulatedAnnealingCore
utl::Logger* logger_ = nullptr;
Mpl2Observer* graphics_ = nullptr;

std::unique_ptr<Result> best_valid_result_;

std::vector<float> cost_list_; // store the cost in the list
std::vector<float> T_list_; // store the temperature
// we define accuracy to determine whether the floorplan is valid
// because the error introduced by the type conversion
static constexpr float acc_tolerance_ = 0.001;

bool has_initial_sequence_pair_ = false;
bool centralization_on_ = false;
bool centralization_was_reverted_ = false;
};

Expand All @@ -256,7 +257,7 @@ template <class T>
void runSA(T* sa_core)
{
sa_core->initialize();
sa_core->fastSA();
sa_core->run();
}

} // namespace mpl2
4 changes: 0 additions & 4 deletions src/mpl2/src/hier_rtlmp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1682,7 +1682,6 @@ void HierRTLMP::runHierarchicalMacroPlacement(Cluster* parent)
graphics_.get(),
logger_);
sa->setNumberOfMacrosToPlace(num_of_macros_to_place);
sa->setCentralizationAttemptOn(true);
sa->setFences(fences);
sa->setGuides(guides);
sa->setNets(nets);
Expand Down Expand Up @@ -1940,7 +1939,6 @@ void HierRTLMP::runHierarchicalMacroPlacement(Cluster* parent)
graphics_.get(),
logger_);
sa->setNumberOfMacrosToPlace(num_of_macros_to_place);
sa->setCentralizationAttemptOn(true);
sa->setFences(fences);
sa->setGuides(guides);
sa->setNets(nets);
Expand Down Expand Up @@ -2512,7 +2510,6 @@ void HierRTLMP::runHierarchicalMacroPlacementWithoutBusPlanning(Cluster* parent)
graphics_.get(),
logger_);
sa->setNumberOfMacrosToPlace(num_of_macros_to_place);
sa->setCentralizationAttemptOn(true);
sa->setFences(fences);
sa->setGuides(guides);
sa->setNets(nets);
Expand Down Expand Up @@ -2994,7 +2991,6 @@ void HierRTLMP::runEnhancedHierarchicalMacroPlacement(Cluster* parent)
graphics_.get(),
logger_);
sa->setNumberOfMacrosToPlace(macros_to_place);
sa->setCentralizationAttemptOn(true);
sa->setFences(fences);
sa->setGuides(guides);
sa->setNets(nets);
Expand Down

0 comments on commit 8ad3ac8

Please sign in to comment.