-
Notifications
You must be signed in to change notification settings - Fork 415
Refactor init place for floorplanning #1817
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
Changes from 10 commits
Commits
Show all changes
15 commits
Select commit
Hold shift + click to select a range
eabd91f
Added a routine to calculate number of tiles covered by a floorplan r…
sfkhalid 5ae899b
Added a sort pl macros function to initial placement so that macros a…
sfkhalid 41c7925
Added comment for new routines and renamed variables for clarity
sfkhalid de0a806
Changed the way the floorplan constraints number is added to the tota…
sfkhalid c90a8b2
Created GridTileLookup class for storing number of tiles of each type…
sfkhalid a1078e2
Made changes to get_region_size function and added get_region_with_su…
sfkhalid 1828622
Added comments for grid tile counting and cleaned up code by removing…
sfkhalid 6cb8e02
Merge branch 'master' into refactor_init_place_for_floorplanning
sfkhalid 13b1f78
Added a comment
sfkhalid 8df329e
Removed unused lines of code
sfkhalid 6f47ee0
Change cumulative total to be the number of subtiles at each location…
sfkhalid 7e0f712
Moved region tile count routines to GridTileLookup class, added comme…
sfkhalid be92c46
Merge branch 'master' into refactor_init_place_for_floorplanning
sfkhalid e1d3211
Added comments to data members of GridTileLookup class
sfkhalid e073a4d
Updated golden results for vtr_reg_qor_chain_predictor_off
sfkhalid File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
#include "grid_tile_lookup.h" | ||
|
||
void GridTileLookup::initialize_grid_tile_matrices() { | ||
auto& device_ctx = g_vpr_ctx.device(); | ||
|
||
for (const auto& type : device_ctx.logical_block_types) { | ||
vtr::NdMatrix<grid_tile_info, 2> type_count({device_ctx.grid.width(), device_ctx.grid.height()}); | ||
fill_type_matrix(&type, type_count); | ||
block_type_matrices.push_back(type_count); | ||
} | ||
} | ||
|
||
void GridTileLookup::fill_type_matrix(t_logical_block_type_ptr block_type, vtr::NdMatrix<grid_tile_info, 2>& type_count) { | ||
auto& device_ctx = g_vpr_ctx.device(); | ||
|
||
int num_rows = device_ctx.grid.height(); | ||
int num_cols = device_ctx.grid.width(); | ||
|
||
for (int i_col = type_count.dim_size(0) - 1; i_col >= 0; i_col--) { | ||
for (int j_row = type_count.dim_size(1) - 1; j_row >= 0; j_row--) { | ||
auto& tile = device_ctx.grid[i_col][j_row].type; | ||
type_count[i_col][j_row].cumulative_total = 0; | ||
type_count[i_col][j_row].st_range.set(0, 0); | ||
|
||
if (is_tile_compatible(tile, block_type)) { | ||
for (const auto& sub_tile : tile->sub_tiles) { | ||
if (is_sub_tile_compatible(tile, block_type, sub_tile.capacity.low)) { | ||
type_count[i_col][j_row].st_range.set(sub_tile.capacity.low, sub_tile.capacity.high); | ||
type_count[i_col][j_row].cumulative_total = 1; | ||
sfkhalid marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
} | ||
} | ||
|
||
if (i_col < num_cols - 1) { | ||
type_count[i_col][j_row].cumulative_total += type_count[i_col + 1][j_row].cumulative_total; | ||
} | ||
if (j_row < num_rows - 1) { | ||
type_count[i_col][j_row].cumulative_total += type_count[i_col][j_row + 1].cumulative_total; | ||
} | ||
if (i_col < (num_cols - 1) && j_row < (num_rows - 1)) { | ||
type_count[i_col][j_row].cumulative_total -= type_count[i_col + 1][j_row + 1].cumulative_total; | ||
} | ||
} | ||
} | ||
} | ||
|
||
vtr::NdMatrix<grid_tile_info, 2>& GridTileLookup::get_type_grid(t_logical_block_type_ptr block_type) { | ||
return block_type_matrices[block_type->index]; | ||
} | ||
|
||
void GridTileLookup::print_type_matrix(vtr::NdMatrix<grid_tile_info, 2>& type_count) { | ||
for (int i_col = type_count.dim_size(0) - 1; i_col >= 0; i_col--) { | ||
for (int j_row = type_count.dim_size(1) - 1; j_row >= 0; j_row--) { | ||
VTR_LOG("%d ", type_count[i_col][j_row].cumulative_total); | ||
} | ||
VTR_LOG("\n"); | ||
} | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
/* | ||
* This class is used to stores a grid for each logical block type. The grid stores the number of cumulative | ||
sfkhalid marked this conversation as resolved.
Show resolved
Hide resolved
|
||
* tiles that are available for this block type at each grid location. At each grid location, it also stores | ||
* the range of compatible subtiles for the block type. | ||
* This lookup class is used during initial placement when sorting blocks by the size of their floorplan constraint | ||
* regions. | ||
*/ | ||
#ifndef VPR_SRC_PLACE_GRID_TILE_LOOKUP_H_ | ||
#define VPR_SRC_PLACE_GRID_TILE_LOOKUP_H_ | ||
|
||
#include "place_util.h" | ||
#include "globals.h" | ||
|
||
struct grid_tile_info { | ||
sfkhalid marked this conversation as resolved.
Show resolved
Hide resolved
|
||
t_capacity_range st_range; | ||
sfkhalid marked this conversation as resolved.
Show resolved
Hide resolved
|
||
int cumulative_total; | ||
}; | ||
|
||
class GridTileLookup { | ||
public: | ||
vtr::NdMatrix<grid_tile_info, 2>& get_type_grid(t_logical_block_type_ptr block_type); | ||
|
||
void initialize_grid_tile_matrices(); | ||
|
||
void fill_type_matrix(t_logical_block_type_ptr block_type, vtr::NdMatrix<grid_tile_info, 2>& type_count); | ||
|
||
void print_type_matrix(vtr::NdMatrix<grid_tile_info, 2>& type_count); | ||
|
||
sfkhalid marked this conversation as resolved.
Show resolved
Hide resolved
|
||
private: | ||
std::vector<vtr::NdMatrix<grid_tile_info, 2>> block_type_matrices; | ||
}; | ||
|
||
#endif /* VPR_SRC_PLACE_GRID_TILE_LOOKUP_H_ */ |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -15,9 +15,11 @@ | |
struct t_block_score { | ||
int macro_size = 0; //how many members does the macro have, if the block is part of one, this value is zero if the block is not in a macro | ||
|
||
int floorplan_constraints = 0; //how many floorplan constraints does it have, if any | ||
|
||
int num_equivalent_tiles = 1; //num of physical locations at which this block could be placed | ||
/* | ||
* The number of tiles NOT covered by the block's floorplan constraints. The higher this number, the more | ||
* difficult the block is to place. | ||
*/ | ||
int tiles_outside_of_floorplan_constraints = 0; | ||
}; | ||
|
||
/* The maximum number of tries when trying to place a carry chain at a * | ||
|
@@ -31,9 +33,9 @@ static int get_free_sub_tile(std::vector<std::vector<int>>& free_locations, int | |
|
||
static int check_macro_can_be_placed(t_pl_macro pl_macro, int itype, t_pl_loc head_pos); | ||
static int try_place_macro(int itype, int ipos, int isub_tile, t_pl_macro pl_macro); | ||
static void initial_placement_pl_macros(int macros_max_num_tries, std::vector<std::vector<int>>& free_locations); | ||
static void initial_placement_pl_macros(int macros_max_num_tries, std::vector<std::vector<int>>& free_locations, const std::vector<t_pl_macro>& sorted_macros); | ||
|
||
static void initial_placement_blocks(std::vector<std::vector<int>>& free_locations, enum e_pad_loc_type pad_loc_type, std::vector<ClusterBlockId> sorted_blocks); | ||
static void initial_placement_blocks(std::vector<std::vector<int>>& free_locations, enum e_pad_loc_type pad_loc_type, const std::vector<ClusterBlockId>& sorted_blocks); | ||
|
||
static t_physical_tile_type_ptr pick_placement_type(t_logical_block_type_ptr logical_block, | ||
int num_needed_types, | ||
|
@@ -44,10 +46,13 @@ static t_physical_tile_type_ptr pick_placement_type(t_logical_block_type_ptr log | |
* Used for relative placement, so that the blocks that are more difficult to place can be placed first during initial placement. | ||
* A higher score indicates that the block is more difficult to place. | ||
*/ | ||
vtr::vector<ClusterBlockId, t_block_score> assign_block_scores(); | ||
static vtr::vector<ClusterBlockId, t_block_score> assign_block_scores(); | ||
|
||
//Sort the blocks according to how difficult they are to place, prior to initial placement | ||
std::vector<ClusterBlockId> sort_blocks(const vtr::vector<ClusterBlockId, t_block_score>& block_scores); | ||
static std::vector<ClusterBlockId> sort_blocks(const vtr::vector<ClusterBlockId, t_block_score>& block_scores); | ||
|
||
//Sort the macros according to how difficult they are to place, prior to initial placement | ||
sfkhalid marked this conversation as resolved.
Show resolved
Hide resolved
|
||
static std::vector<t_pl_macro> sort_macros(const vtr::vector<ClusterBlockId, t_block_score>& block_scores); | ||
|
||
void print_sorted_blocks(const std::vector<ClusterBlockId>& sorted_blocks, const vtr::vector<ClusterBlockId, t_block_score>& block_scores); | ||
|
||
|
@@ -161,33 +166,15 @@ static int try_place_macro(int itype, int ipos, int isub_tile, t_pl_macro pl_mac | |
return (macro_placed); | ||
} | ||
|
||
static void initial_placement_pl_macros(int macros_max_num_tries, std::vector<std::vector<int>>& free_locations) { | ||
static void initial_placement_pl_macros(int macros_max_num_tries, std::vector<std::vector<int>>& free_locations, const std::vector<t_pl_macro>& sorted_macros) { | ||
int macro_placed; | ||
int itype, itry, ipos, isub_tile; | ||
ClusterBlockId blk_id; | ||
|
||
auto& cluster_ctx = g_vpr_ctx.clustering(); | ||
auto& place_ctx = g_vpr_ctx.placement(); | ||
|
||
auto& pl_macros = place_ctx.pl_macros; | ||
|
||
// Sorting blocks to place to have most constricted ones to be placed first | ||
std::vector<t_pl_macro> sorted_pl_macros(pl_macros.begin(), pl_macros.end()); | ||
|
||
auto criteria = [&cluster_ctx](const t_pl_macro lhs, t_pl_macro rhs) { | ||
auto lhs_logical_block = cluster_ctx.clb_nlist.block_type(lhs.members[0].blk_index); | ||
auto rhs_logical_block = cluster_ctx.clb_nlist.block_type(rhs.members[0].blk_index); | ||
|
||
auto lhs_num_tiles = lhs_logical_block->equivalent_tiles.size(); | ||
auto rhs_num_tiles = rhs_logical_block->equivalent_tiles.size(); | ||
|
||
return lhs_num_tiles < rhs_num_tiles; | ||
}; | ||
|
||
std::stable_sort(sorted_pl_macros.begin(), sorted_pl_macros.end(), criteria); | ||
|
||
/* Macros are harder to place. Do them first */ | ||
for (auto pl_macro : sorted_pl_macros) { | ||
for (auto pl_macro : sorted_macros) { | ||
// Every macro are not placed in the beginnning | ||
macro_placed = false; | ||
|
||
|
@@ -255,7 +242,7 @@ static void initial_placement_pl_macros(int macros_max_num_tries, std::vector<st | |
|
||
/* Place blocks that are NOT a part of any macro. | ||
* We'll randomly place each block in the clustered netlist, one by one. */ | ||
static void initial_placement_blocks(std::vector<std::vector<int>>& free_locations, enum e_pad_loc_type pad_loc_type, std::vector<ClusterBlockId> sorted_blocks) { | ||
static void initial_placement_blocks(std::vector<std::vector<int>>& free_locations, enum e_pad_loc_type pad_loc_type, const std::vector<ClusterBlockId>& sorted_blocks) { | ||
auto& cluster_ctx = g_vpr_ctx.clustering(); | ||
auto& place_ctx = g_vpr_ctx.mutable_placement(); | ||
|
||
|
@@ -346,18 +333,25 @@ static t_physical_tile_type_ptr pick_placement_type(t_logical_block_type_ptr log | |
return nullptr; | ||
} | ||
|
||
vtr::vector<ClusterBlockId, t_block_score> assign_block_scores() { | ||
static vtr::vector<ClusterBlockId, t_block_score> assign_block_scores() { | ||
auto& cluster_ctx = g_vpr_ctx.clustering(); | ||
auto& place_ctx = g_vpr_ctx.placement(); | ||
auto& floorplan_ctx = g_vpr_ctx.floorplanning(); | ||
auto& device_ctx = g_vpr_ctx.device(); | ||
|
||
auto blocks = cluster_ctx.clb_nlist.blocks(); | ||
auto pl_macros = place_ctx.pl_macros; | ||
int num_grid_tiles = device_ctx.grid.height() * device_ctx.grid.width(); | ||
|
||
auto& pl_macros = place_ctx.pl_macros; | ||
sfkhalid marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
t_block_score score; | ||
|
||
vtr::vector<ClusterBlockId, t_block_score> block_scores; | ||
|
||
block_scores.resize(blocks.size()); | ||
block_scores.resize(cluster_ctx.clb_nlist.blocks().size()); | ||
|
||
//GridTileLookup class provides info needed for calculating number of tiles covered by a region | ||
GridTileLookup grid_tiles; | ||
grid_tiles.initialize_grid_tile_matrices(); | ||
|
||
/* | ||
* For the blocks with no floorplan constraints, and the blocks that are not part of macros, | ||
|
@@ -366,13 +360,21 @@ vtr::vector<ClusterBlockId, t_block_score> assign_block_scores() { | |
*/ | ||
|
||
//go through all blocks and store floorplan constraints and num equivalent tiles | ||
for (auto blk_id : blocks) { | ||
for (auto blk_id : cluster_ctx.clb_nlist.blocks()) { | ||
if (is_cluster_constrained(blk_id)) { | ||
block_scores[blk_id].floorplan_constraints = 1; | ||
PartitionRegion pr = floorplan_ctx.cluster_constraints[blk_id]; | ||
auto block_type = cluster_ctx.clb_nlist.block_type(blk_id); | ||
int num_floorplan_tiles = get_part_reg_size(pr, block_type, grid_tiles); | ||
if (num_floorplan_tiles == 0) { | ||
VPR_FATAL_ERROR(VPR_ERROR_PLACE, | ||
"Initial placement failed.\n" | ||
"The specified floorplan region for block %s (# %d) has no available locations for its type. \n" | ||
"Please specify a different floorplan region for the block. Note that if the region has a specified subtile, " | ||
"an incompatible subtile location may be the cause of the floorplan region failure. \n", | ||
cluster_ctx.clb_nlist.block_name(blk_id).c_str(), blk_id); | ||
} | ||
block_scores[blk_id].tiles_outside_of_floorplan_constraints = num_grid_tiles - num_floorplan_tiles; | ||
} | ||
auto logical_block = cluster_ctx.clb_nlist.block_type(blk_id); | ||
auto num_tiles = logical_block->equivalent_tiles.size(); | ||
block_scores[blk_id].num_equivalent_tiles = num_tiles; | ||
} | ||
|
||
//go through placement macros and store size of macro for each block | ||
|
@@ -386,16 +388,24 @@ vtr::vector<ClusterBlockId, t_block_score> assign_block_scores() { | |
return block_scores; | ||
} | ||
|
||
std::vector<ClusterBlockId> sort_blocks(const vtr::vector<ClusterBlockId, t_block_score>& block_scores) { | ||
static std::vector<ClusterBlockId> sort_blocks(const vtr::vector<ClusterBlockId, t_block_score>& block_scores) { | ||
auto& cluster_ctx = g_vpr_ctx.clustering(); | ||
|
||
auto blocks = cluster_ctx.clb_nlist.blocks(); | ||
|
||
std::vector<ClusterBlockId> sorted_blocks(blocks.begin(), blocks.end()); | ||
|
||
/* | ||
* The criteria considers blocks that belong to a macro or to a floorplan region more difficult to place. | ||
* The bigger the macro, and/or the tighter the floorplan constraint, the earlier the block will be in | ||
* the list of sorted blocks. | ||
* The tiles_outside_of_floorplan_constraints will dominate the criteria, since the number of tiles will | ||
* likely be significantly bigger than the macro size. This is okay since the floorplan constraints give | ||
* a more accurate picture of how difficult a block is to place. | ||
*/ | ||
auto criteria = [block_scores](ClusterBlockId lhs, ClusterBlockId rhs) { | ||
sfkhalid marked this conversation as resolved.
Show resolved
Hide resolved
|
||
int lhs_score = 100 * block_scores[lhs].macro_size + 10 * block_scores[lhs].floorplan_constraints + 10 / (block_scores[lhs].num_equivalent_tiles); | ||
int rhs_score = 100 * block_scores[rhs].macro_size + 10 * block_scores[rhs].floorplan_constraints + 10 / (block_scores[rhs].num_equivalent_tiles); | ||
int lhs_score = 10 * block_scores[lhs].macro_size + block_scores[lhs].tiles_outside_of_floorplan_constraints; | ||
int rhs_score = 10 * block_scores[rhs].macro_size + block_scores[rhs].tiles_outside_of_floorplan_constraints; | ||
|
||
return lhs_score > rhs_score; | ||
}; | ||
|
@@ -406,10 +416,29 @@ std::vector<ClusterBlockId> sort_blocks(const vtr::vector<ClusterBlockId, t_bloc | |
return sorted_blocks; | ||
} | ||
|
||
static std::vector<t_pl_macro> sort_macros(const vtr::vector<ClusterBlockId, t_block_score>& block_scores) { | ||
auto& place_ctx = g_vpr_ctx.placement(); | ||
auto& pl_macros = place_ctx.pl_macros; | ||
|
||
// Sorting blocks to place to have most constricted ones to be placed first | ||
std::vector<t_pl_macro> sorted_pl_macros(pl_macros.begin(), pl_macros.end()); | ||
|
||
auto criteria = [block_scores](const t_pl_macro lhs, t_pl_macro rhs) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this should be refactored to place blocks & macros in one loop, with the sorted_blocks vector controlling it all. |
||
int lhs_score = 10 * block_scores[lhs.members[0].blk_index].macro_size + block_scores[lhs.members[0].blk_index].tiles_outside_of_floorplan_constraints; | ||
int rhs_score = 10 * block_scores[rhs.members[0].blk_index].macro_size + block_scores[rhs.members[0].blk_index].tiles_outside_of_floorplan_constraints; | ||
|
||
return lhs_score > rhs_score; | ||
}; | ||
|
||
std::stable_sort(sorted_pl_macros.begin(), sorted_pl_macros.end(), criteria); | ||
|
||
return sorted_pl_macros; | ||
} | ||
|
||
void print_sorted_blocks(const std::vector<ClusterBlockId>& sorted_blocks, const vtr::vector<ClusterBlockId, t_block_score>& block_scores) { | ||
VTR_LOG("\nPrinting sorted blocks: \n"); | ||
for (unsigned int i = 0; i < sorted_blocks.size(); i++) { | ||
VTR_LOG("Block_Id: %zu, Macro size: %d, Num floorplan constraints: %d, Num equivalent tiles %d \n", sorted_blocks[i], block_scores[sorted_blocks[i]].macro_size, block_scores[sorted_blocks[i]].floorplan_constraints, block_scores[sorted_blocks[i]].num_equivalent_tiles); | ||
VTR_LOG("Block_Id: %zu, Macro size: %d, Num tiles outside floorplan constraints: %d\n", sorted_blocks[i], block_scores[sorted_blocks[i]].macro_size, block_scores[sorted_blocks[i]].tiles_outside_of_floorplan_constraints); | ||
} | ||
} | ||
|
||
|
@@ -421,15 +450,16 @@ void initial_placement(enum e_pad_loc_type pad_loc_type, const char* constraints | |
* array that gives every legal value of (x,y,z) that can accommodate a block. | ||
*/ | ||
|
||
//Sort blocks | ||
vtr::vector<ClusterBlockId, t_block_score> block_scores = assign_block_scores(); | ||
std::vector<ClusterBlockId> sorted_blocks = sort_blocks(block_scores); | ||
|
||
/* Go through cluster blocks to calculate the tightest placement | ||
* floorplan constraint for each constrained block | ||
*/ | ||
propagate_place_constraints(); | ||
|
||
//Sort blocks and placement macros according to how difficult they are to place | ||
vtr::vector<ClusterBlockId, t_block_score> block_scores = assign_block_scores(); | ||
std::vector<ClusterBlockId> sorted_blocks = sort_blocks(block_scores); | ||
std::vector<t_pl_macro> sorted_macros = sort_macros(block_scores); | ||
|
||
// Loading legal placement locations | ||
zero_initialize_grid_blocks(); | ||
alloc_and_load_legal_placement_locations(legal_pos); | ||
|
@@ -483,7 +513,7 @@ void initial_placement(enum e_pad_loc_type pad_loc_type, const char* constraints | |
* as fixed so they do not get moved during initial placement or during simulated annealing*/ | ||
mark_fixed_blocks(); | ||
|
||
initial_placement_pl_macros(MAX_NUM_TRIES_TO_PLACE_MACROS_RANDOMLY, free_locations); | ||
initial_placement_pl_macros(MAX_NUM_TRIES_TO_PLACE_MACROS_RANDOMLY, free_locations, sorted_macros); | ||
|
||
// All the macros are placed, update the legal_pos[][] array and free_locations[] array | ||
for (const auto& type : device_ctx.physical_tile_types) { | ||
|
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.