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 13 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_tile_counts.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 left 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_tile_counts[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_tile_counts[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");
}
}
38 changes: 38 additions & 0 deletions vpr/src/place/grid_tile_lookup.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*
* 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 left 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:
std::vector<vtr::NdMatrix<int, 2>> block_type_matrices;

std::vector<int> max_tile_counts;
};

#endif /* VPR_SRC_PLACE_GRID_TILE_LOOKUP_H_ */
Loading