Skip to content

Automatically generate floorplan test files after placement, and enhancements to cluster attraction groups #1938

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 60 commits into from
Feb 10, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
60 commits
Select commit Hold shift + click to select a range
2276efb
Fixed bug in region tile count by intersecting region with grid befor…
sfkhalid Nov 15, 2021
bbaa785
Added ability to generate different constraints file by creating part…
sfkhalid Nov 17, 2021
0b71f8b
Added ability to print multiple constraints files at once and add deb…
sfkhalid Nov 24, 2021
15ee41d
Commented out debug line
sfkhalid Nov 24, 2021
1280f59
Adding changes to way molecule gain is updated according to attractio…
sfkhalid Nov 24, 2021
b24ce10
Changed way molecule gain is updated when it is part of an attraction…
sfkhalid Nov 24, 2021
0aa6e7a
Added new error checking routines during clustering and placement, ad…
sfkhalid Dec 14, 2021
2702e13
When a cluster fails routing, its PartitionRegion must be reset set t…
sfkhalid Dec 14, 2021
066a996
Merge branch 'master' into generate_test_constraints_files
sfkhalid Dec 15, 2021
b521467
Improved comment for new routine in initial placement
sfkhalid Dec 15, 2021
e370bbf
Cleaned up control routine for generating constraints files
sfkhalid Dec 15, 2021
2f654cd
Replaced numbers in get_molecule_gain with defined constants and adde…
sfkhalid Dec 15, 2021
1def2e3
Ran make format
sfkhalid Dec 15, 2021
9cab9b2
Reversed some changes during clustering which were degrading the qor …
sfkhalid Dec 16, 2021
7dcdeb8
Added more detailed comments about the --floorplan_split vpr option, …
sfkhalid Dec 16, 2021
9c37438
Corrected a mistake where one of the constraint generating function w…
sfkhalid Dec 16, 2021
5830eaf
Added comment to explain bug fix in do_clustering
sfkhalid Dec 17, 2021
f479b76
Added more detail to try_pack_molecule comment
sfkhalid Dec 17, 2021
87ac95e
Improved constraints report routine - every region in PartitionRegion…
sfkhalid Dec 17, 2021
4e761ed
Added more detailed commenting to constraints report header file
sfkhalid Dec 17, 2021
7735f74
Improved error message that is printed when some blocks are not place…
sfkhalid Dec 17, 2021
581c498
Took out loop in do_clustering that counted number of failed molecule…
sfkhalid Dec 21, 2021
5f4685e
Added hash function and equal operator to the Region class. Refactore…
sfkhalid Dec 22, 2021
ea133c1
Added constructor to GridTileLookup class which initializes the data …
sfkhalid Dec 22, 2021
7107b45
Ran make format
sfkhalid Dec 22, 2021
7d2abcc
Overhauled the way molecules are pulled from attraction groups during…
sfkhalid Jan 4, 2022
88150c9
Added a fix to the while loop in do_clustering, which counts how many…
sfkhalid Jan 4, 2022
746bf8a
Added return line to make sure that when a molecule is removed it is …
sfkhalid Jan 4, 2022
fd636f3
Added a re-try loop that makes the the cluster's attraction group be …
sfkhalid Jan 12, 2022
9607452
Removed unused code
sfkhalid Jan 14, 2022
ae969b1
Added routine for filling attraction groups based on overfull regions…
sfkhalid Jan 17, 2022
5bcc77d
Made changes to constraints writer to ensure that it works in all cases
sfkhalid Jan 18, 2022
04a2b28
Added comments and removed unused code
sfkhalid Jan 19, 2022
a806ffb
Resolved cluster.cpp merge conflicts
sfkhalid Jan 19, 2022
7375979
Ran make format
sfkhalid Jan 19, 2022
fbdd65c
Fixed parameter type in writer setup function
sfkhalid Jan 19, 2022
8f92765
Fixed variable type that was causing compiler errors and warnings
sfkhalid Jan 19, 2022
609d16b
Minor fixes to get rid of compiler warnings
sfkhalid Jan 19, 2022
839d256
Added a routine to be able to constrain half of all blocks with the c…
sfkhalid Jan 20, 2022
07727d1
Added comments and removed unnecessary lines
sfkhalid Jan 23, 2022
7bc8468
Added a helper function to record molecule failures during clustering
sfkhalid Jan 23, 2022
b3cf6b8
Edited the comment which explain how to use the floorplan constraints…
sfkhalid Jan 24, 2022
954d60f
Removed outdated code from the constraints generator
sfkhalid Jan 24, 2022
968e82c
Changed packing flow when running with floorplan constraints. Before,…
sfkhalid Jan 24, 2022
7097a30
ran make format
sfkhalid Jan 24, 2022
553c323
Reversed a minor change with adding constrained atoms because it was …
sfkhalid Jan 25, 2022
0567b68
Ran make format
sfkhalid Jan 25, 2022
4dccac4
Initialized att_group_pulls value, as it was causing a memory leak
sfkhalid Jan 25, 2022
a449463
Added comments to further clarify how the attraction groups are worki…
sfkhalid Jan 25, 2022
8a5951c
Changed the formation of attraction groups - only create them for ove…
sfkhalid Jan 30, 2022
545ca65
Merge branch 'master' into generate_test_constraints_files
sfkhalid Jan 30, 2022
b79865b
Changed routine that gets molecule candidates from the attraction gro…
sfkhalid Jan 31, 2022
553766b
Added more detailed commenting to clustering stage
sfkhalid Jan 31, 2022
9bdc971
Refactored the way attraction group molecules are added when looking …
sfkhalid Jan 31, 2022
9f14605
Changed vpr command line options used for generating test constraints…
sfkhalid Jan 31, 2022
f26768a
cleaned up names of routines which check whether floorplan regions ar…
sfkhalid Jan 31, 2022
f1506e8
Ran make format
sfkhalid Jan 31, 2022
20097c5
Added a comment to state which pack iteration we are on when we are d…
sfkhalid Feb 2, 2022
39b78b5
Added to-do note for routine that needs to be enhanced in another pul…
sfkhalid Feb 2, 2022
ca7d60a
Merge branch 'master' into generate_test_constraints_files
sfkhalid Feb 2, 2022
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
2 changes: 2 additions & 0 deletions vpr/src/base/SetupVPR.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -613,6 +613,8 @@ static void SetupPlacerOpts(const t_options& Options, t_placer_opts* PlacerOpts)
PlacerOpts->place_agent_algorithm = Options.place_agent_algorithm;
PlacerOpts->place_constraint_expand = Options.place_constraint_expand;
PlacerOpts->place_constraint_subtile = Options.place_constraint_subtile;
PlacerOpts->floorplan_num_horizontal_partitions = Options.floorplan_num_horizontal_partitions;
PlacerOpts->floorplan_num_vertical_partitions = Options.floorplan_num_vertical_partitions;
}

static void SetupAnalysisOpts(const t_options& Options, t_analysis_opts& analysis_opts) {
Expand Down
16 changes: 16 additions & 0 deletions vpr/src/base/read_options.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2024,6 +2024,22 @@ argparse::ArgumentParser create_arg_parser(std::string prog_name, t_options& arg
.default_value("off")
.show_in(argparse::ShowIn::HELP_ONLY);

place_grp.add_argument(args.floorplan_num_horizontal_partitions, "--floorplan_num_horizontal_partitions")
.help(
"An argument used for generating test constraints files. Specifies how many partitions to "
"make in the horizontal dimension. Must be used in conjunction with "
"--floorplan_num_vertical_partitions")
.default_value("0")
.show_in(argparse::ShowIn::HELP_ONLY);

place_grp.add_argument(args.floorplan_num_vertical_partitions, "--floorplan_num_vertical_partitions")
.help(
"An argument used for generating test constraints files. Specifies how many partitions to "
"make in the vertical dimension. Must be used in conjunction with "
"--floorplan_num_horizontal_partitions")
.default_value("0")
.show_in(argparse::ShowIn::HELP_ONLY);

/*
* place_grp.add_argument(args.place_timing_cost_func, "--place_timing_cost_func")
* .help(
Expand Down
2 changes: 2 additions & 0 deletions vpr/src/base/read_options.h
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,8 @@ struct t_options {
argparse::ArgValue<float> place_crit_limit;
argparse::ArgValue<int> place_constraint_expand;
argparse::ArgValue<bool> place_constraint_subtile;
argparse::ArgValue<int> floorplan_num_horizontal_partitions;
argparse::ArgValue<int> floorplan_num_vertical_partitions;

/* Timing-driven placement options only */
argparse::ArgValue<float> PlaceTimingTradeoff;
Expand Down
19 changes: 19 additions & 0 deletions vpr/src/base/region.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,10 @@ class Region {
*/
bool is_loc_in_reg(t_pl_loc loc);

bool operator==(const Region& reg) const {
return (reg.get_region_rect() == this->get_region_rect() && reg.get_sub_tile() == this->get_sub_tile());
}

private:
//may need to include zmin, zmax for future use in 3D FPGA designs
vtr::Rect<int> region_bounds; ///< xmin, ymin, xmax, ymax inclusive
Expand Down Expand Up @@ -88,4 +92,19 @@ Region intersection(const Region& r1, const Region& r2);
///@brief Used to print data from a Region
void print_region(FILE* fp, Region region);

namespace std {
template<>
struct hash<Region> {
std::size_t operator()(const Region& reg) const noexcept {
vtr::Rect<int> rect = reg.get_region_rect();
std::size_t seed = std::hash<int>{}(rect.xmin());
vtr::hash_combine(seed, rect.ymin());
vtr::hash_combine(seed, rect.xmax());
vtr::hash_combine(seed, rect.ymax());
vtr::hash_combine(seed, reg.get_sub_tile());
return seed;
}
};
} // namespace std

#endif /* REGION_H */
3 changes: 2 additions & 1 deletion vpr/src/base/vpr_api.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -632,7 +632,8 @@ bool vpr_place_flow(t_vpr_setup& vpr_setup, const t_arch& arch) {

//Write out a vpr floorplanning constraints file if the option is specified
if (!filename_opts.write_vpr_constraints_file.empty()) {
write_vpr_floorplan_constraints(filename_opts.write_vpr_constraints_file.c_str(), placer_opts.place_constraint_expand, placer_opts.place_constraint_subtile);
write_vpr_floorplan_constraints(filename_opts.write_vpr_constraints_file.c_str(), placer_opts.place_constraint_expand, placer_opts.place_constraint_subtile,
placer_opts.floorplan_num_horizontal_partitions, placer_opts.floorplan_num_vertical_partitions);
}

return true;
Expand Down
7 changes: 3 additions & 4 deletions vpr/src/base/vpr_constraints.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,12 @@
#include "partition.h"

void VprConstraints::add_constrained_atom(const AtomBlockId blk_id, const PartitionId part_id) {
constrained_atoms.insert({blk_id, part_id});

auto got = constrained_atoms.find(blk_id);

/**
* Each atom can only be in one partition. If the atoms already has a partition id assigned to it,
* the id will be switched to the new part_id being passed in instead
* Each atom can only be in one partition. If the atom is not found in constrained_atoms, it
* will be added with its partition id.
* If the atom is already in constrained_atoms, the partition id will be updated.
*/
if (got == constrained_atoms.end()) {
constrained_atoms.insert({blk_id, part_id});
Expand Down
143 changes: 139 additions & 4 deletions vpr/src/base/vpr_constraints_writer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,16 @@

#include <fstream>
#include "vpr_constraints_writer.h"
#include "region.h"

void write_vpr_floorplan_constraints(const char* file_name, int expand, bool subtile) {
//Fill in the constraints object to be printed out.
void write_vpr_floorplan_constraints(const char* file_name, int expand, bool subtile, int horizontal_partitions, int vertical_partitions) {
VprConstraints constraints;

setup_vpr_floorplan_constraints(constraints, expand, subtile);
if (horizontal_partitions != 0 && vertical_partitions != 0) {
setup_vpr_floorplan_constraints_cutpoints(constraints, horizontal_partitions, vertical_partitions);
} else {
setup_vpr_floorplan_constraints_one_loc(constraints, expand, subtile);
}

VprConstraintsSerializer writer(constraints);

Expand All @@ -39,7 +43,7 @@ void write_vpr_floorplan_constraints(const char* file_name, int expand, bool sub
}
}

void setup_vpr_floorplan_constraints(VprConstraints& constraints, int expand, bool subtile) {
void setup_vpr_floorplan_constraints_one_loc(VprConstraints& constraints, int expand, bool subtile) {
auto& cluster_ctx = g_vpr_ctx.clustering();
auto& place_ctx = g_vpr_ctx.placement();
ClusterAtomsLookup atoms_lookup;
Expand Down Expand Up @@ -83,3 +87,134 @@ void setup_vpr_floorplan_constraints(VprConstraints& constraints, int expand, bo
part_id++;
}
}

void setup_vpr_floorplan_constraints_cutpoints(VprConstraints& constraints, int horizontal_cutpoints, int vertical_cutpoints) {
auto& cluster_ctx = g_vpr_ctx.clustering();
auto& place_ctx = g_vpr_ctx.placement();
auto& device_ctx = g_vpr_ctx.device();
ClusterAtomsLookup atoms_lookup;

//calculate the cutpoint values according to the grid size
//load two arrays - one for horizontal cutpoints and one for vertical

std::vector<int> horizontal_cuts;

std::vector<int> vertical_cuts;

int horizontal_interval = device_ctx.grid.width() / horizontal_cutpoints;
VTR_LOG("Device grid width is %d, horizontal interval is %d\n", device_ctx.grid.width(), horizontal_interval);

unsigned int horizontal_point = horizontal_interval;
horizontal_cuts.push_back(0);
int num_horizontal_cuts = 0;
while (num_horizontal_cuts < horizontal_cutpoints - 1) {
horizontal_cuts.push_back(horizontal_point);
horizontal_point = horizontal_point + horizontal_interval;
num_horizontal_cuts++;
}
//Add in the last point after your exit the while loop
horizontal_cuts.push_back(device_ctx.grid.width());

int vertical_interval = device_ctx.grid.height() / vertical_cutpoints;
VTR_LOG("Device grid height is %d, vertical interval is %d\n", device_ctx.grid.height(), vertical_interval);

unsigned int vertical_point = vertical_interval;
vertical_cuts.push_back(0);
int num_vertical_cuts = 0;
while (num_vertical_cuts < vertical_cutpoints - 1) {
vertical_cuts.push_back(vertical_point);
vertical_point = vertical_point + vertical_interval;
num_vertical_cuts++;
}
//Add in the last point after your exit the while loop
vertical_cuts.push_back(device_ctx.grid.height());

//Create floorplan regions based on the cutpoints
std::unordered_map<Region, std::vector<AtomBlockId>> region_atoms;

for (unsigned int i = 0; i < horizontal_cuts.size() - 1; i++) {
int xmin = horizontal_cuts[i];
int xmax = horizontal_cuts[i + 1] - 1;

for (unsigned int j = 0; j < vertical_cuts.size() - 1; j++) {
int ymin = vertical_cuts[j];
int ymax = vertical_cuts[j + 1] - 1;

Region reg;
reg.set_region_rect(xmin, ymin, xmax, ymax);
std::vector<AtomBlockId> atoms;

region_atoms.insert({reg, atoms});
}
}

/*
* For each cluster block, see which region it belongs to, and add its atoms to the
* appropriate region accordingly
*/
for (auto blk_id : cluster_ctx.clb_nlist.blocks()) {
std::vector<AtomBlockId> atoms = atoms_lookup.atoms_in_cluster(blk_id);
int num_atoms = atoms.size();
int x = place_ctx.block_locs[blk_id].loc.x;
int y = place_ctx.block_locs[blk_id].loc.y;
int width = device_ctx.grid.width();
int height = device_ctx.grid.height();
VTR_ASSERT(x >= 0 && x < width);
VTR_ASSERT(y >= 0 && y < height);
int xminimum = 0, yminimum = 0, xmaximum = 0, ymaximum = 0;

for (unsigned int h = 1; h < horizontal_cuts.size(); h++) {
if (x < horizontal_cuts[h]) {
xmaximum = horizontal_cuts[h] - 1;
xminimum = horizontal_cuts[h - 1];
break;
}
}

for (unsigned int v = 1; v < vertical_cuts.size(); v++) {
if (y < vertical_cuts[v]) {
ymaximum = vertical_cuts[v] - 1;
yminimum = vertical_cuts[v - 1];
break;
}
}

Region current_reg;
current_reg.set_region_rect(xminimum, yminimum, xmaximum, ymaximum);

auto got = region_atoms.find(current_reg);

VTR_ASSERT(got != region_atoms.end());

for (int at = 0; at < num_atoms; at++) {
got->second.push_back(atoms[at]);
}
}

int num_partitions = 0;
for (auto region : region_atoms) {
Partition part;
PartitionId partid(num_partitions);
std::string part_name = "Part" + std::to_string(num_partitions);
vtr::Rect<int> rect = region.first.get_region_rect();
create_partition(part, part_name, rect.xmin(), rect.ymin(), rect.xmax(), rect.ymax());
constraints.add_partition(part);

for (unsigned int k = 0; k < region.second.size(); k++) {
constraints.add_constrained_atom(region.second[k], partid);
}

num_partitions++;
}
}

void create_partition(Partition& part, std::string part_name, int xmin, int ymin, int xmax, int ymax) {
part.set_name(part_name);
PartitionRegion part_pr;
Region part_region;
part_region.set_region_rect(xmin, ymin, xmax, ymax);
std::vector<Region> part_regions;
part_regions.push_back(part_region);
part_pr.set_partition_region(part_regions);
part.set_part_region(part_pr);
}
21 changes: 19 additions & 2 deletions vpr/src/base/vpr_constraints_writer.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,16 @@
* Routines related to writing out the file are in vpr/src/base/vpr_constraints_serializer.h. For more information on how
* the writing interface works, refer to vpr/src/route/SCHEMA_GENERATOR.md
*
* The option --write_vpr_constraints can be used to generate the constraints files.
*
* The routines in this file are currently used to generate floorplan constraints for testing purposes.
* The constraints files they generate are used to determine whether VPR is correctly adhering to
* floorplan constraints during its packing and placement stages.
*
* The placer options --floorplan_num_horizontal_partitions (int) and --floorplan_num_vertical_partitions (int) can be used
* to specify how many partitions should be created in the test constraints file.
* For example, if both options are 2, the constraints file will split the grid into quadrants, dividing the blocks between
* four partitions - two partitions in the horizontal dimension, and two partitions in the vertical dimension.
*/

#ifndef VPR_SRC_BASE_VPR_CONSTRAINTS_WRITER_H_
Expand All @@ -26,8 +35,16 @@
* @param subtile Specifies whether to write out the constraint regions with or without
* subtile values.
*/
void write_vpr_floorplan_constraints(const char* file_name, int expand, bool subtile);
void write_vpr_floorplan_constraints(const char* file_name, int expand, bool subtile, int horizontal_partitions, int vertical_partitions);

//Generate constraints which lock all blocks to one location.
void setup_vpr_floorplan_constraints_one_loc(VprConstraints& constraints, int expand, bool subtile);

/* Generate constraints which divide the grid into partition according to the horizontal and vertical partition values passed in
* and lock down blocks to their appropriate partition.
*/
void setup_vpr_floorplan_constraints_cutpoints(VprConstraints& constraints, int horizontal_cutpoints, int vertical_cutpoints);

void setup_vpr_floorplan_constraints(VprConstraints& constraints, int expand, bool subtile);
void create_partition(Partition& part, std::string part_name, int xmin, int ymin, int xmax, int ymax);

#endif /* VPR_SRC_BASE_VPR_CONSTRAINTS_WRITER_H_ */
2 changes: 2 additions & 0 deletions vpr/src/base/vpr_context.h
Original file line number Diff line number Diff line change
Expand Up @@ -398,6 +398,8 @@ struct FloorplanningContext : public Context {
* The constraints on each cluster are computed during the clustering process and can change.
*/
vtr::vector<ClusterBlockId, PartitionRegion> cluster_constraints;

std::vector<Region> overfull_regions;
};

/**
Expand Down
2 changes: 2 additions & 0 deletions vpr/src/base/vpr_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -1076,6 +1076,8 @@ struct t_placer_opts {
float place_crit_limit;
int place_constraint_expand;
bool place_constraint_subtile;
int floorplan_num_horizontal_partitions;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Placer opts doesn't seem like the right place for this. Seems like a constraints opts structure would be worthwhile.

int floorplan_num_vertical_partitions;

/**
* @brief Tile types that should be used during delay sampling.
Expand Down
Loading