Skip to content

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 15 commits into from
Aug 31, 2021
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
143 changes: 143 additions & 0 deletions vpr/src/place/grid_tile_lookup.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
#include "grid_tile_lookup.h"

void GridTileLookup::initialize_grid_tile_matrices() {
auto& device_ctx = g_vpr_ctx.device();

//Will store the max number of tile locations for each logical block type
max_placement_locations.resize(device_ctx.logical_block_types.size());

for (const auto& type : device_ctx.logical_block_types) {
vtr::NdMatrix<int, 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<int, 2>& type_count) {
auto& device_ctx = g_vpr_ctx.device();

int num_rows = device_ctx.grid.height();
int num_cols = device_ctx.grid.width();

/*
* Iterating through every location on the grid to store the number of subtiles of
* the correct type at each location. For each location, we store the cumulative
* number of tiles of the type up to that location - meaning we store the number of
* subtiles at the location, plus the number of subtiles at the locations above and to
* the right of it.
*/
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] = 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] = sub_tile.capacity.total();
}
}
}

if (i_col < num_cols - 1) {
type_count[i_col][j_row] += type_count[i_col + 1][j_row];
}
if (j_row < num_rows - 1) {
type_count[i_col][j_row] += type_count[i_col][j_row + 1];
}
if (i_col < (num_cols - 1) && j_row < (num_rows - 1)) {
type_count[i_col][j_row] -= type_count[i_col + 1][j_row + 1];
}
}
}

//The total number of subtiles for the block type will be at [0][0]
max_placement_locations[block_type->index] = type_count[0][0];
}

vtr::NdMatrix<int, 2>& GridTileLookup::get_type_grid(t_logical_block_type_ptr block_type) {
return block_type_matrices[block_type->index];
}

int GridTileLookup::total_type_tiles(t_logical_block_type_ptr block_type) {
return max_placement_locations[block_type->index];
}

/*
* This routine uses pre-computed values from the grids for each block type to get the number of grid tiles
* covered by a region.
* For a region with no subtiles specified, the number of grid tiles can be calculated by adding
* and subtracting four values from within/at the edge of the region.
* The region with subtile case is taken care of by a helper routine, region_with_subtile_count().
*/
int GridTileLookup::region_tile_count(const Region& reg, t_logical_block_type_ptr block_type) {
vtr::Rect<int> reg_rect = reg.get_region_rect();
int subtile = reg.get_sub_tile();

int xmin = reg_rect.xmin();
int ymin = reg_rect.ymin();
int xmax = reg_rect.xmax();
int ymax = reg_rect.ymax();
auto& type_grid = block_type_matrices[block_type->index];

int xdim = type_grid.dim_size(0);
int ydim = type_grid.dim_size(1);

int num_tiles = 0;

if (subtile == NO_SUBTILE) {
num_tiles = type_grid[xmin][ymin];

if ((ymax + 1) < ydim) {
num_tiles -= type_grid[xmin][ymax + 1];
}

if ((xmax + 1) < xdim) {
num_tiles -= type_grid[xmax + 1][ymin];
}

if ((xmax + 1) < xdim && (ymax + 1) < ydim) {
num_tiles += type_grid[xmax + 1][ymax + 1];
}
} else {
num_tiles = region_with_subtile_count(reg, block_type);
}

return num_tiles;
}

/*
* This routine is for the subtile specified case; an O(region_size) scan needs to be done to check whether each grid
* location in the region is compatible for the block at the subtile specified.
*/
int GridTileLookup::region_with_subtile_count(const Region& reg, t_logical_block_type_ptr block_type) {
auto& device_ctx = g_vpr_ctx.device();
int num_sub_tiles = 0;
vtr::Rect<int> reg_rect = reg.get_region_rect();
int subtile = reg.get_sub_tile();

int xmin = reg_rect.xmin();
int ymin = reg_rect.ymin();
int xmax = reg_rect.xmax();
int ymax = reg_rect.ymax();

for (int i = xmax; i >= xmin; i--) {
for (int j = ymax; j >= ymin; j--) {
auto& tile = device_ctx.grid[i][j].type;
if (is_sub_tile_compatible(tile, block_type, subtile)) {
num_sub_tiles++;
}
}
}

return num_sub_tiles;
}

void GridTileLookup::print_type_matrix(vtr::NdMatrix<int, 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]);
}
VTR_LOG("\n");
}
}
49 changes: 49 additions & 0 deletions vpr/src/place/grid_tile_lookup.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/*
* This class is used to store a grid for each logical block type that stores the cumulative number of subtiles
* for that type available at each location in the grid. The cumulative number of subtiles is the subtiles at the
* location plus the subtiles available at the grid locations above and to the right of the locations.
* Having these grids allows for O(1) lookups about the number of subtiles available for a given type of block
* in a rectangular region.
* 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"

class GridTileLookup {
public:
vtr::NdMatrix<int, 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<int, 2>& type_count);

void print_type_matrix(vtr::NdMatrix<int, 2>& type_count);

int region_tile_count(const Region& reg, t_logical_block_type_ptr block_type);

int region_with_subtile_count(const Region& reg, t_logical_block_type_ptr block_type);

int total_type_tiles(t_logical_block_type_ptr block_type);

private:
/*
* Stores the cumulative total of subtiles available at each location in the grid for each block type.
* Therefore, the length of the vector will be the number of logical block types. To access the cumulative
* number of subtiles at a location, you would use block_type_matrices[iblock_type][x][y] - this would
* give the number of placement locations that are at, or above and to the right of the given [x,y] for
* the given block type.
*/
std::vector<vtr::NdMatrix<int, 2>> block_type_matrices;

/*
* Stores the total number of placement locations (i.e. compatible subtiles) for each block type.
* To access the max_placement locations for a particular block type, use max_placement_locations[block_type->index]
*/
std::vector<int> max_placement_locations;
};

#endif /* VPR_SRC_PLACE_GRID_TILE_LOOKUP_H_ */
Loading