Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ppl: fix infinite loop in annealing #5919

Merged
merged 5 commits into from
Oct 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion src/ppl/src/IOPlacer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1004,6 +1004,7 @@ std::vector<Section> IOPlacer::createSectionsPerConstraint(
? hor_layers_
: ver_layers_;

bool first_layer = true;
for (int layer : layers) {
std::vector<Slot>::iterator it
= std::find_if(slots_.begin(), slots_.end(), [&](const Slot& s) {
Expand Down Expand Up @@ -1032,10 +1033,13 @@ std::vector<Section> IOPlacer::createSectionsPerConstraint(
|| s.layer != layer);
});
int constraint_end = it - slots_.begin() - 1;
constraint.first_slot = constraint_begin;
if (first_layer) {
constraint.first_slot = constraint_begin;
}
constraint.last_slot = constraint_end;

findSections(constraint_begin, constraint_end, edge, sections);
first_layer = false;
}
} else {
sections = findSectionsForTopLayer(constraint.box);
Expand Down Expand Up @@ -1812,6 +1816,7 @@ void IOPlacer::initConstraints(bool annealing)
IOPin& io_pin = netlist_->getIoPin(pin_idx);
io_pin.setConstraintIdx(constraint_idx);
constraint.pin_indices.push_back(pin_idx);
constraint.mirrored_pins_count += io_pin.isMirrored() ? 1 : 0;
if (io_pin.getGroupIdx() != -1) {
constraint.pin_groups.insert(io_pin.getGroupIdx());
}
Expand Down
102 changes: 85 additions & 17 deletions src/ppl/src/SimulatedAnnealing.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -86,17 +86,18 @@ void SimulatedAnnealing::run(float init_temperature,

const int64 cost = pre_cost + getDeltaCost(prev_cost);
const int delta_cost = cost - pre_cost;
debugPrint(
logger_,
utl::PPL,
"annealing",
2,
"iteration: {}; temperature: {}; assignment cost: {}um; delta "
"cost: {}um",
iter,
temperature,
block->dbuToMicrons(cost),
block->dbuToMicrons(delta_cost));
debugPrint(logger_,
utl::PPL,
"annealing",
2,
"iteration: {}; perturb: {}; temperature: {}; assignment "
"cost: {}um; delta "
"cost: {}um",
iter,
perturb,
temperature,
block->dbuToMicrons(cost),
block->dbuToMicrons(delta_cost));

const float rand_float = distribution(generator_);
const float accept_prob = std::exp((-1) * delta_cost / temperature);
Expand Down Expand Up @@ -410,7 +411,10 @@ int SimulatedAnnealing::swapPins()
= constraints_[constraint_idx].pin_indices;
// if there is only one pin in the constraint, do not swap and fallback to
// move a pin to a free slot
if (pin_indices.size() == 1) {
const int pin_count = pin_indices.size();
const int mirrored_pins_count
= constraints_[constraint_idx].mirrored_pins_count;
if (pin_count == 1 || (pin_count - mirrored_pins_count) <= 1) {
return move_fail_;
}
distribution = boost::random::uniform_int_distribution<int>(
Expand Down Expand Up @@ -796,15 +800,13 @@ void SimulatedAnnealing::getSlotsRange(const IOPin& io_pin,
const Constraint& constraint = constraints_[pin_constraint_idx];
first_slot = constraint.first_slot;
last_slot = constraint.last_slot;
}

if (io_pin.isMirrored()) {
} else if (io_pin.isMirrored()) {
const IOPin& mirrored_pin = netlist_->getIoPin(io_pin.getMirrorPinIdx());
const int mirrored_constraint_idx = mirrored_pin.getConstraintIdx();
if (mirrored_constraint_idx != -1) {
const Constraint& constraint = constraints_[mirrored_constraint_idx];
first_slot = getMirroredSlotIdx(constraint.first_slot);
last_slot = getMirroredSlotIdx(constraint.last_slot);
getMirroredSlotRange(
constraint.first_slot, constraint.last_slot, first_slot, last_slot);
if (first_slot > last_slot) {
std::swap(first_slot, last_slot);
}
Expand Down Expand Up @@ -859,6 +861,72 @@ int SimulatedAnnealing::getMirroredSlotIdx(int slot_idx) const
return mirrored_idx;
}

void SimulatedAnnealing::getMirroredSlotRange(const int slot_idx1,
const int slot_idx2,
int& mirrored_slot1,
int& mirrored_slot2) const
{
const Slot& slot1 = slots_[slot_idx1];
const Slot& slot2 = slots_[slot_idx2];
if (slot1.edge != slot2.edge) {
logger_->error(
utl::PPL, 36, "Constraint cannot have positions in different edges.");
}
const Edge edge = slot1.edge;
const odb::Point& mirrored_pos1 = core_->getMirroredPosition(slot1.pos);
const odb::Point& mirrored_pos2 = core_->getMirroredPosition(slot2.pos);

// find the approximated mirrored position of the original slot range
// endpoints. this is only necessary because when using multiple layers, the
// mirrored position of the original slots endpoints are not in the beginning
// of the mirrored range.
if (slot1.edge == Edge::bottom || slot1.edge == Edge::right) {
for (int i = slots_.size() - 1; i >= 0; i--) {
const Slot& slot = slots_[i];
if ((edge == Edge::bottom && slot.pos.getX() >= mirrored_pos1.getX()
&& slot.pos.getY() == mirrored_pos1.getY())
|| (edge == Edge::right && slot.pos.getX() == mirrored_pos1.getX()
&& slot.pos.getY() >= mirrored_pos1.getY())) {
mirrored_slot1 = i;
break;
}
}

for (int i = 0; i < slots_.size(); i++) {
const Slot& slot = slots_[i];
if ((edge == Edge::bottom && slot.pos.getX() <= mirrored_pos2.getX()
&& slot.pos.getY() == mirrored_pos2.getY())
|| (edge == Edge::right && slot.pos.getX() == mirrored_pos2.getX()
&& slot.pos.getY() <= mirrored_pos2.getY())) {
mirrored_slot2 = i;
break;
}
}
} else {
for (int i = 0; i < slots_.size(); i++) {
const Slot& slot = slots_[i];
if ((edge == Edge::top && slot.pos.getX() >= mirrored_pos1.getX()
&& slot.pos.getY() == mirrored_pos1.getY())
|| (edge == Edge::left && slot.pos.getX() == mirrored_pos1.getX()
&& slot.pos.getY() >= mirrored_pos1.getY())) {
mirrored_slot1 = i;
break;
}
}

for (int i = slots_.size() - 1; i >= 0; i--) {
const Slot& slot = slots_[i];
if ((edge == Edge::top && slot.pos.getX() <= mirrored_pos2.getX()
&& slot.pos.getY() == mirrored_pos2.getY())
|| (edge == Edge::left && slot.pos.getX() == mirrored_pos2.getX()
&& slot.pos.getY() <= mirrored_pos2.getY())) {
mirrored_slot2 = i;
break;
}
}
}
}

void SimulatedAnnealing::updateSlotsFromGroup(
const std::vector<int>& prev_slots_,
bool block)
Expand Down
4 changes: 4 additions & 0 deletions src/ppl/src/SimulatedAnnealing.h
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,10 @@ class SimulatedAnnealing
int getSlotIdxByPosition(const odb::Point& position, int layer) const;
bool isFreeForMirrored(int slot_idx, int& mirrored_idx) const;
int getMirroredSlotIdx(int slot_idx) const;
void getMirroredSlotRange(int slot_idx1,
int slot_idx2,
int& mirrored_slot1,
int& mirrored_slot2) const;
void updateSlotsFromGroup(const std::vector<int>& prev_slots_, bool block);
int computeGroupPrevCost(int group_idx);
void updateGroupSlots(const std::vector<int>& pin_indices, int& new_slot);
Expand Down
1 change: 1 addition & 0 deletions src/ppl/src/Slots.h
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,7 @@ struct Constraint
float pins_per_slots;
int first_slot = 0;
int last_slot = 0;
int mirrored_pins_count = 0;
};

template <typename T>
Expand Down
Loading