Skip to content

Optimize floorplan checks during place moves #1983

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

Merged
merged 7 commits into from
Feb 25, 2022
Merged
Show file tree
Hide file tree
Changes from 4 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
51 changes: 51 additions & 0 deletions vpr/src/pack/attraction_groups.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,57 @@ void AttractionInfo::create_att_groups_for_overfull_regions() {
VTR_LOG("%d clustering attraction groups created. \n", num_att_grps);
}

void AttractionInfo::create_att_groups_for_all_regions() {
auto& floorplanning_ctx = g_vpr_ctx.mutable_floorplanning();
auto& atom_ctx = g_vpr_ctx.atom();
int num_parts = floorplanning_ctx.constraints.get_num_partitions();

//clear the data structures before continuing
atom_attraction_group.clear();
attraction_groups.clear();

//Initialize every atom to have no attraction group id
int num_atoms = atom_ctx.nlist.blocks().size();

atom_attraction_group.resize(num_atoms);
fill(atom_attraction_group.begin(), atom_attraction_group.end(), AttractGroupId::INVALID());

/*
* Create a PartitionRegion that contains all the overfull regions so that you can
* make an attraction group for any partition that intersects with any of these regions
*/

/*
* Create an attraction group for each parition with an overfull region.
*/

for (int ipart = 0; ipart < num_parts; ipart++) {
PartitionId partid(ipart);

AttractionGroup group_info;
group_info.group_atoms = floorplanning_ctx.constraints.get_part_atoms(partid);

attraction_groups.push_back(group_info);
}

//Then, fill in the group id for the atoms that do have an attraction group
int num_att_grps = attraction_groups.size();

for (int igroup = 0; igroup < num_att_grps; igroup++) {
AttractGroupId group_id(igroup);

AttractionGroup att_group = attraction_groups[group_id];

for (unsigned int iatom = 0; iatom < att_group.group_atoms.size(); iatom++) {
atom_attraction_group[att_group.group_atoms[iatom]] = group_id;
}
}

att_group_pulls = 1;

VTR_LOG("%d clustering attraction groups created. \n", num_att_grps);
}

void AttractionInfo::set_attraction_group_info(AttractGroupId group_id, const AttractionGroup& group_info) {
attraction_groups[group_id] = group_info;
}
Expand Down
2 changes: 2 additions & 0 deletions vpr/src/pack/attraction_groups.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ class AttractionInfo {

void create_att_groups_for_overfull_regions();

void create_att_groups_for_all_regions();

//Setters and getters for the class
AttractGroupId get_atom_attraction_group(const AtomBlockId atom_id);

Expand Down
23 changes: 20 additions & 3 deletions vpr/src/pack/cluster.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2764,13 +2764,29 @@ static void add_cluster_molecule_candidates_by_attraction_group(t_pb* cur_pb,
}

AttractionGroup& group = attraction_groups.get_attraction_group_info(grp_id);
int num_available_atoms = group.group_atoms.size();
std::vector<AtomBlockId> available_atoms;
for (AtomBlockId atom_id : group.group_atoms) {
const auto& atom_model = atom_ctx.nlist.block_model(atom_id);
auto itr = primitive_candidate_block_types.find(atom_model);
VTR_ASSERT(itr != primitive_candidate_block_types.end());
std::vector<t_logical_block_type_ptr>& candidate_types = itr->second;

//Only consider molecules that are unpacked and of the correct type
if (atom_ctx.lookup.atom_clb(atom_id) == ClusterBlockId::INVALID()
&& std::find(candidate_types.begin(), candidate_types.end(), cluster_type) != candidate_types.end()) {
available_atoms.push_back(atom_id);
}
}

//int num_available_atoms = group.group_atoms.size();
int num_available_atoms = available_atoms.size();
if (num_available_atoms == 0) {
return;
}

if (num_available_atoms < 500) {
for (AtomBlockId atom_id : group.group_atoms) {
//for (AtomBlockId atom_id : group.group_atoms) {
for (AtomBlockId atom_id : available_atoms) {
const auto& atom_model = atom_ctx.nlist.block_model(atom_id);
auto itr = primitive_candidate_block_types.find(atom_model);
VTR_ASSERT(itr != primitive_candidate_block_types.end());
Expand Down Expand Up @@ -2804,7 +2820,8 @@ static void add_cluster_molecule_candidates_by_attraction_group(t_pb* cur_pb,
std::uniform_int_distribution<> distr(min, max);
int selected_atom = distr(gen);

AtomBlockId blk_id = group.group_atoms[selected_atom];
//AtomBlockId blk_id = group.group_atoms[selected_atom];
AtomBlockId blk_id = available_atoms[selected_atom];
const auto& atom_model = atom_ctx.nlist.block_model(blk_id);
auto itr = primitive_candidate_block_types.find(atom_model);
VTR_ASSERT(itr != primitive_candidate_block_types.end());
Expand Down
1 change: 1 addition & 0 deletions vpr/src/pack/output_clustering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ static void print_stats() {
}
VTR_LOG("Absorbed logical nets %d out of %d nets, %d nets not absorbed.\n",
total_nets_absorbed, (int)atom_ctx.nlist.nets().size(), (int)atom_ctx.nlist.nets().size() - total_nets_absorbed);
VTR_LOG("Netlist num_blocks: %d \n", cluster_ctx.clb_nlist.blocks().size());
free(num_clb_types);
free(num_clb_inputs_used);
free(num_clb_outputs_used);
Expand Down
22 changes: 16 additions & 6 deletions vpr/src/pack/pack.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -184,12 +184,22 @@ bool try_pack(t_packer_opts* packer_opts,
attraction_groups.set_att_group_pulls(1);

} else if (pack_iteration >= 2 && pack_iteration < 5 && floorplan_not_fitting) {
VTR_LOG("Floorplan regions are overfull: trying to pack again with more attraction groups exploration and higher target pin utilization. \n");
attraction_groups.create_att_groups_for_overfull_regions();
VTR_LOG("Pack iteration is %d\n", pack_iteration);
attraction_groups.set_att_group_pulls(4);
t_ext_pin_util pin_util(1.0, 1.0);
target_external_pin_util.set_block_pin_util("clb", pin_util);
if (pack_iteration == 2) {
VTR_LOG("Floorplan regions are overfull: trying to pack again with more attraction groups exploration. \n");
attraction_groups.create_att_groups_for_overfull_regions();
VTR_LOG("Pack iteration is %d\n", pack_iteration);
} else if (pack_iteration == 3) {
attraction_groups.create_att_groups_for_all_regions();
VTR_LOG("Floorplan regions are overfull: trying to pack again with more attraction groups exploration. \n");
VTR_LOG("Pack iteration is %d\n", pack_iteration);
} else if (pack_iteration == 4) {
attraction_groups.create_att_groups_for_all_regions();
VTR_LOG("Floorplan regions are overfull: trying to pack again with more attraction groups exploration and higher target pin utilization. \n");
VTR_LOG("Pack iteration is %d\n", pack_iteration);
attraction_groups.set_att_group_pulls(4);
t_ext_pin_util pin_util(1.0, 1.0);
target_external_pin_util.set_block_pin_util("clb", pin_util);
}

} else {
//Unable to pack densely enough: Give Up
Expand Down
2 changes: 1 addition & 1 deletion vpr/src/place/centroid_move_generator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ e_create_move CentroidMoveGenerator::propose_move(t_pl_blocks_to_be_moved& block
calculate_centroid_loc(b_from, false, centroid, NULL);

/* Find a location near the weighted centroid_loc */
if (!find_to_loc_centroid(cluster_from_type, from, centroid, range_limiters, to)) {
if (!find_to_loc_centroid(cluster_from_type, from, centroid, range_limiters, to, b_from)) {
return e_create_move::ABORT;
}

Expand Down
2 changes: 1 addition & 1 deletion vpr/src/place/critical_uniform_move_generator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ e_create_move CriticalUniformMoveGenerator::propose_move(t_pl_blocks_to_be_moved

t_pl_loc to;

if (!find_to_loc_uniform(cluster_from_type, rlim, from, to)) {
if (!find_to_loc_uniform(cluster_from_type, rlim, from, to, b_from)) {
return e_create_move::ABORT;
}

Expand Down
4 changes: 2 additions & 2 deletions vpr/src/place/feasible_region_move_generator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -112,14 +112,14 @@ e_create_move FeasibleRegionMoveGenerator::propose_move(t_pl_blocks_to_be_moved&
range_limiters.first_rlim = place_move_ctx.first_rlim;

// Try to find a legal location inside the feasible region
if (!find_to_loc_median(cluster_from_type, from, &FR_coords, to)) {
if (!find_to_loc_median(cluster_from_type, from, &FR_coords, to, b_from)) {
/** If there is no legal location in the feasible region, calculate the center of the FR and try to find a legal location
* in a range around this center.
*/
t_pl_loc center;
center.x = (FR_coords.xmin + FR_coords.xmax) / 2;
center.y = (FR_coords.ymin + FR_coords.ymax) / 2;
if (!find_to_loc_centroid(cluster_from_type, from, center, range_limiters, to))
if (!find_to_loc_centroid(cluster_from_type, from, center, range_limiters, to, b_from))
return e_create_move::ABORT;
}

Expand Down
2 changes: 1 addition & 1 deletion vpr/src/place/median_move_generator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ e_create_move MedianMoveGenerator::propose_move(t_pl_blocks_to_be_moved& blocks_
t_pl_loc median_point;
median_point.x = (limit_coords.xmin + limit_coords.xmax) / 2;
median_point.y = (limit_coords.ymin + limit_coords.ymax) / 2;
if (!find_to_loc_centroid(cluster_from_type, from, median_point, range_limiters, to))
if (!find_to_loc_centroid(cluster_from_type, from, median_point, range_limiters, to, b_from))
return e_create_move::ABORT;

e_create_move create_move = ::create_move(blocks_affected, b_from, to);
Expand Down
69 changes: 66 additions & 3 deletions vpr/src/place/move_utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
#include "draw_debug.h"
#include "draw.h"

#include "place_constraints.h"

//f_placer_breakpoint_reached is used to stop the placer when a breakpoint is reached. When this flag is true, it stops the placer after the current perturbation. Thus, when a breakpoint is reached, this flag is set to true.
//Note: The flag is only effective if compiled with VTR_ENABLE_DEBUG_LOGGING
bool f_placer_breakpoint_reached = false;
Expand Down Expand Up @@ -532,7 +534,8 @@ ClusterBlockId pick_from_block() {
bool find_to_loc_uniform(t_logical_block_type_ptr type,
float rlim,
const t_pl_loc from,
t_pl_loc& to) {
t_pl_loc& to,
ClusterBlockId b_from) {
//Finds a legal swap to location for the given type, starting from 'from.x' and 'from.y'
//
//Note that the range limit (rlim) is applied in a logical sense (i.e. 'compressed' grid space consisting
Expand Down Expand Up @@ -566,6 +569,13 @@ bool find_to_loc_uniform(t_logical_block_type_ptr type,
int cy_to = OPEN;
bool legal = false;

if (is_cluster_constrained(b_from)) {
bool intersect = intersect_range_limit_with_floorplan_constraints(type, b_from, min_cx, min_cy, max_cx, max_cy, delta_cx);
if (!intersect) {
return false;
}
}

legal = find_compatible_compressed_loc_in_range(type, min_cx, max_cx, min_cy, max_cy, delta_cx, cx_from, cy_from, cx_to, cy_to, false);

if (!legal) {
Expand Down Expand Up @@ -601,7 +611,8 @@ void set_placer_breakpoint_reached(bool flag) {
bool find_to_loc_median(t_logical_block_type_ptr blk_type,
const t_pl_loc& from_loc,
const t_bb* limit_coords,
t_pl_loc& to_loc) {
t_pl_loc& to_loc,
ClusterBlockId b_from) {
const auto& compressed_block_grid = g_vpr_ctx.placement().compressed_block_grids[blk_type->index];

//Determine the coordinates in the compressed grid space of the current block
Expand Down Expand Up @@ -630,6 +641,13 @@ bool find_to_loc_median(t_logical_block_type_ptr blk_type,
int cy_to = OPEN;
bool legal = false;

if (is_cluster_constrained(b_from)) {
bool intersect = intersect_range_limit_with_floorplan_constraints(blk_type, b_from, min_cx, min_cy, max_cx, max_cy, delta_cx);
if (!intersect) {
return false;
}
}

legal = find_compatible_compressed_loc_in_range(blk_type, min_cx, max_cx, min_cy, max_cy, delta_cx, cx_from, cy_from, cx_to, cy_to, true);

if (!legal) {
Expand Down Expand Up @@ -657,7 +675,8 @@ bool find_to_loc_centroid(t_logical_block_type_ptr blk_type,
const t_pl_loc& from_loc,
const t_pl_loc& centroid,
const t_range_limiters& range_limiters,
t_pl_loc& to_loc) {
t_pl_loc& to_loc,
ClusterBlockId b_from) {
//Retrieve the compressed block grid for this block type
const auto& compressed_block_grid = g_vpr_ctx.placement().compressed_block_grids[blk_type->index];

Expand Down Expand Up @@ -707,6 +726,13 @@ bool find_to_loc_centroid(t_logical_block_type_ptr blk_type,
int cy_to = OPEN;
bool legal = false;

if (is_cluster_constrained(b_from)) {
bool intersect = intersect_range_limit_with_floorplan_constraints(blk_type, b_from, min_cx, min_cy, max_cx, max_cy, delta_cx);
if (!intersect) {
return false;
}
}

legal = find_compatible_compressed_loc_in_range(blk_type, min_cx, max_cx, min_cy, max_cy, delta_cx, cx_from, cy_from, cx_to, cy_to, false);

if (!legal) {
Expand Down Expand Up @@ -848,6 +874,43 @@ bool find_compatible_compressed_loc_in_range(t_logical_block_type_ptr type, int
return legal;
}

bool intersect_range_limit_with_floorplan_constraints(t_logical_block_type_ptr type, ClusterBlockId b_from, int& min_cx, int& min_cy, int& max_cx, int& max_cy, int& delta_cx) {
//Retrieve the compressed block grid for this block type
const auto& compressed_block_grid = g_vpr_ctx.placement().compressed_block_grids[type->index];

int min_x = compressed_block_grid.compressed_to_grid_x[min_cx];
int max_x = compressed_block_grid.compressed_to_grid_x[max_cx];
int min_y = compressed_block_grid.compressed_to_grid_y[min_cy];
int max_y = compressed_block_grid.compressed_to_grid_y[max_cy];
Region range_reg;
range_reg.set_region_rect(min_x, min_y, max_x, max_y);

auto& floorplanning_ctx = g_vpr_ctx.floorplanning();

PartitionRegion pr = floorplanning_ctx.cluster_constraints[b_from];
std::vector<Region> regions;
if (!pr.empty()) {
regions = pr.get_partition_region();
}
Region intersect_reg;
if (regions.size() == 1) {
intersect_reg = intersection(regions[0], range_reg);

if (intersect_reg.empty()) {
return false;
} else {
vtr::Rect<int> rect = intersect_reg.get_region_rect();
min_cx = grid_to_compressed_approx(compressed_block_grid.compressed_to_grid_x, rect.xmin());
max_cx = grid_to_compressed_approx(compressed_block_grid.compressed_to_grid_x, rect.xmax());
min_cy = grid_to_compressed_approx(compressed_block_grid.compressed_to_grid_y, rect.ymin());
max_cy = grid_to_compressed_approx(compressed_block_grid.compressed_to_grid_y, rect.ymax());
delta_cx = max_cx - min_cx;
}
}

return true;
}

std::string e_move_result_to_string(e_move_result move_outcome) {
std::string move_result_to_string[] = {"Rejected", "Accepted", "Aborted"};
return move_result_to_string[move_outcome];
Expand Down
17 changes: 14 additions & 3 deletions vpr/src/place/move_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,8 @@ ClusterBlockId pick_from_block();
bool find_to_loc_uniform(t_logical_block_type_ptr type,
float rlim,
const t_pl_loc from,
t_pl_loc& to);
t_pl_loc& to,
ClusterBlockId b_from);

// Accessor f_placer_breakpoint_reached
// return true when a placer breakpoint is reached
Expand All @@ -125,7 +126,7 @@ void set_placer_breakpoint_reached(bool);
* @param limit_coords: the region where I can move the block to
* @param to_loc: the new location that the function picked for the block
*/
bool find_to_loc_median(t_logical_block_type_ptr blk_type, const t_pl_loc& from_loc, const t_bb* limit_coords, t_pl_loc& to_loc);
bool find_to_loc_median(t_logical_block_type_ptr blk_type, const t_pl_loc& from_loc, const t_bb* limit_coords, t_pl_loc& to_loc, ClusterBlockId b_from);

/**
* @brief Find a legal swap to location for the given type in a range around a specific location.
Expand All @@ -145,7 +146,8 @@ bool find_to_loc_centroid(t_logical_block_type_ptr blk_type,
const t_pl_loc& from_loc,
const t_pl_loc& centeroid,
const t_range_limiters& range_limiters,
t_pl_loc& to_loc);
t_pl_loc& to_loc,
ClusterBlockId b_from);

std::string move_type_to_string(e_move_type);

Expand All @@ -171,6 +173,15 @@ void compressed_grid_to_loc(t_logical_block_type_ptr blk_type, int cx, int cy, t
*/
bool find_compatible_compressed_loc_in_range(t_logical_block_type_ptr type, int min_cx, int max_cx, int min_cy, int max_cy, int delta_cx, int cx_from, int cy_from, int& cx_to, int& cy_to, bool is_median);

/*
* If the block to be moved (b_from) has a floorplan constraint, this routine changes the max and min coords
* in the compressed grid (min_cx, min_cy, max_cx, max_cy) to make sure the range limit is within the floorplan constraint.
*
* Returns false if there is no intersection between the range limit and the floorplan constraint,
* true otherwise.
*/
bool intersect_range_limit_with_floorplan_constraints(t_logical_block_type_ptr type, ClusterBlockId b_from, int& min_cx, int& min_cy, int& max_cx, int& max_cy, int& delta_cx);

std::string e_move_result_to_string(e_move_result move_outcome);

#endif
2 changes: 1 addition & 1 deletion vpr/src/place/uniform_move_generator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ e_create_move UniformMoveGenerator::propose_move(t_pl_blocks_to_be_moved& blocks

t_pl_loc to;

if (!find_to_loc_uniform(cluster_from_type, rlim, from, to)) {
if (!find_to_loc_uniform(cluster_from_type, rlim, from, to, b_from)) {
return e_create_move::ABORT;
}

Expand Down
2 changes: 1 addition & 1 deletion vpr/src/place/weighted_centroid_move_generator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ e_create_move WeightedCentroidMoveGenerator::propose_move(t_pl_blocks_to_be_move
calculate_centroid_loc(b_from, true, centroid, criticalities);

/* Find a */
if (!find_to_loc_centroid(cluster_from_type, from, centroid, range_limiters, to)) {
if (!find_to_loc_centroid(cluster_from_type, from, centroid, range_limiters, to, b_from)) {
return e_create_move::ABORT;
}

Expand Down
2 changes: 1 addition & 1 deletion vpr/src/place/weighted_median_move_generator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ e_create_move WeightedMedianMoveGenerator::propose_move(t_pl_blocks_to_be_moved&
t_pl_loc w_median_point;
w_median_point.x = (limit_coords.xmin + limit_coords.xmax) / 2;
w_median_point.y = (limit_coords.ymin + limit_coords.ymax) / 2;
if (!find_to_loc_centroid(cluster_from_type, from, w_median_point, range_limiters, to)) {
if (!find_to_loc_centroid(cluster_from_type, from, w_median_point, range_limiters, to, b_from)) {
return e_create_move::ABORT;
}

Expand Down