From cd289a228d9dccff8c8abd816269fd32b554166d Mon Sep 17 00:00:00 2001 From: Sarah Khalid Date: Wed, 2 Jun 2021 12:14:02 -0400 Subject: [PATCH 01/24] Added code for marking down blocks that constrained to one location on the grid as fixed and changed definition of Region::empty() to show false for a region that contains one grid location --- vpr/src/base/region.cpp | 2 +- vpr/src/place/initial_placement.cpp | 3 +++ vpr/src/place/place_constraints.cpp | 33 +++++++++++++++++++++++++++++ vpr/src/place/place_constraints.h | 6 ++++++ 4 files changed, 43 insertions(+), 1 deletion(-) diff --git a/vpr/src/base/region.cpp b/vpr/src/base/region.cpp index 2035a57e717..fdcaea9d7c1 100644 --- a/vpr/src/base/region.cpp +++ b/vpr/src/base/region.cpp @@ -35,7 +35,7 @@ bool Region::locked() { } bool Region::empty() { - return region_bounds.empty(); + return region_bounds.xmax() < region_bounds.xmin() || region_bounds.ymax() < region_bounds.ymin(); } bool Region::is_loc_in_reg(t_pl_loc loc) { diff --git a/vpr/src/place/initial_placement.cpp b/vpr/src/place/initial_placement.cpp index 45784d6e698..e158f2ef07b 100644 --- a/vpr/src/place/initial_placement.cpp +++ b/vpr/src/place/initial_placement.cpp @@ -466,6 +466,9 @@ void initial_placement(enum e_pad_loc_type pad_loc_type, const char* constraints read_constraints(constraints_file); } + /*Mark fixed blocks*/ + mark_fixed_blocks(); + initial_placement_pl_macros(MAX_NUM_TRIES_TO_PLACE_MACROS_RANDOMLY, free_locations); // All the macros are placed, update the legal_pos[][] array and free_locations[] array diff --git a/vpr/src/place/place_constraints.cpp b/vpr/src/place/place_constraints.cpp index 5f6014a835f..a08845f71b6 100644 --- a/vpr/src/place/place_constraints.cpp +++ b/vpr/src/place/place_constraints.cpp @@ -180,3 +180,36 @@ void load_cluster_constraints() { } } } + +void mark_fixed_blocks() { + auto& cluster_ctx = g_vpr_ctx.clustering(); + auto& place_ctx = g_vpr_ctx.mutable_placement(); + auto& floorplanning_ctx = g_vpr_ctx.floorplanning(); + + for (auto blk_id : cluster_ctx.clb_nlist.blocks()) { + PartitionRegion pr = floorplanning_ctx.cluster_constraints[blk_id]; + std::vector part_region = pr.get_partition_region(); + if (part_region.size() == 1) { + int subtile = part_region[0].get_sub_tile(); + vtr::Rect rect = part_region[0].get_region_rect(); + + if (part_region[0].locked()) { + //Set the location of the block + place_ctx.block_locs[blk_id].loc.x = rect.xmin(); + place_ctx.block_locs[blk_id].loc.y = rect.ymin(); + place_ctx.block_locs[blk_id].loc.sub_tile = subtile; + + //Mark the grid location of the block + place_ctx.grid_blocks[rect.xmin()][rect.ymin()].blocks[subtile] = blk_id; + + //Set as fixed + place_ctx.block_locs[blk_id].is_fixed = true; + + //Mark grid location usage + place_ctx.grid_blocks[rect.xmin()][rect.ymin()].usage++; + + std::string block_name = cluster_ctx.clb_nlist.block_name(blk_id); + } + } + } +} diff --git a/vpr/src/place/place_constraints.h b/vpr/src/place/place_constraints.h index b9121ebdcd7..f12027707cc 100644 --- a/vpr/src/place/place_constraints.h +++ b/vpr/src/place/place_constraints.h @@ -64,4 +64,10 @@ inline bool floorplan_legal(const t_pl_blocks_to_be_moved& blocks_affected) { */ void load_cluster_constraints(); +/* + * Marks blocks with a region with xlow = xhigh, ylow = yhigh, and subtile specified as fixed + * Marking them as fixed indicates that they cannot be moved during simulated annealing + */ +void mark_fixed_blocks(); + #endif /* VPR_SRC_PLACE_PLACE_CONSTRAINTS_H_ */ From 8ad3c1bd170861778ab4f6a0863305d090b7e3e3 Mon Sep 17 00:00:00 2001 From: Sarah Khalid Date: Wed, 2 Jun 2021 15:08:10 -0400 Subject: [PATCH 02/24] Region empty function now returns true if the rectangle either has impossible dimensions, or it is uninitialized. This change was needed because previously, the default uninitialized values would be seen as impossible dimensions (and therefore empty) and now they are not because of the recent change to the empty routine --- vpr/src/base/region.cpp | 3 ++- vpr/src/base/region.h | 3 ++- vpr/src/place/place_constraints.cpp | 20 ++++++++++---------- 3 files changed, 14 insertions(+), 12 deletions(-) diff --git a/vpr/src/base/region.cpp b/vpr/src/base/region.cpp index fdcaea9d7c1..23fb0f848a7 100644 --- a/vpr/src/base/region.cpp +++ b/vpr/src/base/region.cpp @@ -35,7 +35,8 @@ bool Region::locked() { } bool Region::empty() { - return region_bounds.xmax() < region_bounds.xmin() || region_bounds.ymax() < region_bounds.ymin(); + return region_bounds.xmax() < region_bounds.xmin() || region_bounds.ymax() < region_bounds.ymin() || + (region_bounds.xmin() == -1 && region_bounds.ymin() == -1 && region_bounds.xmax() == -1 && region_bounds.ymax() == -1); } bool Region::is_loc_in_reg(t_pl_loc loc) { diff --git a/vpr/src/base/region.h b/vpr/src/base/region.h index 9069ba180f6..79b56de9311 100644 --- a/vpr/src/base/region.h +++ b/vpr/src/base/region.h @@ -44,7 +44,8 @@ class Region { void set_sub_tile(int _sub_tile); /** - * @brief Return whether the region is empty, based on whether the region rectangle is empty + * @brief Return whether the region is empty, meaning the rectangle has impossible dimensions + * or has the default values (-1, -1, -1, -1), indicating that it is uninitialized. */ bool empty(); diff --git a/vpr/src/place/place_constraints.cpp b/vpr/src/place/place_constraints.cpp index a08845f71b6..22cb7f5b54d 100644 --- a/vpr/src/place/place_constraints.cpp +++ b/vpr/src/place/place_constraints.cpp @@ -187,14 +187,14 @@ void mark_fixed_blocks() { auto& floorplanning_ctx = g_vpr_ctx.floorplanning(); for (auto blk_id : cluster_ctx.clb_nlist.blocks()) { - PartitionRegion pr = floorplanning_ctx.cluster_constraints[blk_id]; - std::vector part_region = pr.get_partition_region(); - if (part_region.size() == 1) { - int subtile = part_region[0].get_sub_tile(); - vtr::Rect rect = part_region[0].get_region_rect(); - - if (part_region[0].locked()) { - //Set the location of the block + PartitionRegion pr = floorplanning_ctx.cluster_constraints[blk_id]; + std::vector part_region = pr.get_partition_region(); + if (part_region.size() == 1) { + int subtile = part_region[0].get_sub_tile(); + vtr::Rect rect = part_region[0].get_region_rect(); + + if (part_region[0].locked()) { + //Set the location of the block place_ctx.block_locs[blk_id].loc.x = rect.xmin(); place_ctx.block_locs[blk_id].loc.y = rect.ymin(); place_ctx.block_locs[blk_id].loc.sub_tile = subtile; @@ -209,7 +209,7 @@ void mark_fixed_blocks() { place_ctx.grid_blocks[rect.xmin()][rect.ymin()].usage++; std::string block_name = cluster_ctx.clb_nlist.block_name(blk_id); - } - } + } + } } } From 77786c8c18aed2ec003252643b8913f9a8ca4f9d Mon Sep 17 00:00:00 2001 From: Sarah Khalid Date: Wed, 2 Jun 2021 15:15:50 -0400 Subject: [PATCH 03/24] Ran make format --- vpr/src/base/region.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/vpr/src/base/region.cpp b/vpr/src/base/region.cpp index 23fb0f848a7..d33fa7946fc 100644 --- a/vpr/src/base/region.cpp +++ b/vpr/src/base/region.cpp @@ -35,8 +35,7 @@ bool Region::locked() { } bool Region::empty() { - return region_bounds.xmax() < region_bounds.xmin() || region_bounds.ymax() < region_bounds.ymin() || - (region_bounds.xmin() == -1 && region_bounds.ymin() == -1 && region_bounds.xmax() == -1 && region_bounds.ymax() == -1); + return region_bounds.xmax() < region_bounds.xmin() || region_bounds.ymax() < region_bounds.ymin() || (region_bounds.xmin() == -1 && region_bounds.ymin() == -1 && region_bounds.xmax() == -1 && region_bounds.ymax() == -1); } bool Region::is_loc_in_reg(t_pl_loc loc) { From 25a5b7fc975daa7aa3a13399b945e09743313ee7 Mon Sep 17 00:00:00 2001 From: Sarah Khalid Date: Wed, 9 Jun 2021 12:30:36 -0400 Subject: [PATCH 04/24] Changed default empty region values --- vpr/src/base/region.cpp | 8 ++++---- vpr/src/place/initial_placement.cpp | 3 ++- vpr/test/test_vpr_constraints.cpp | 4 ++-- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/vpr/src/base/region.cpp b/vpr/src/base/region.cpp index d33fa7946fc..923b2e0e904 100644 --- a/vpr/src/base/region.cpp +++ b/vpr/src/base/region.cpp @@ -3,10 +3,10 @@ Region::Region() { sub_tile = NO_SUBTILE; - //default rect for a region is (-1, -1, -1, -1) + //default rect for a region is (999, 999, -1, -1) //these values indicate an empty rectangle, they are set as default values to help catch uninitialized use - region_bounds.set_xmin(-1); - region_bounds.set_ymin(-1); + region_bounds.set_xmin(999); + region_bounds.set_ymin(999); region_bounds.set_xmax(-1); region_bounds.set_ymax(-1); } @@ -35,7 +35,7 @@ bool Region::locked() { } bool Region::empty() { - return region_bounds.xmax() < region_bounds.xmin() || region_bounds.ymax() < region_bounds.ymin() || (region_bounds.xmin() == -1 && region_bounds.ymin() == -1 && region_bounds.xmax() == -1 && region_bounds.ymax() == -1); + return (region_bounds.xmax() < region_bounds.xmin() || region_bounds.ymax() < region_bounds.ymin()); } bool Region::is_loc_in_reg(t_pl_loc loc) { diff --git a/vpr/src/place/initial_placement.cpp b/vpr/src/place/initial_placement.cpp index e158f2ef07b..26fbe74fba7 100644 --- a/vpr/src/place/initial_placement.cpp +++ b/vpr/src/place/initial_placement.cpp @@ -466,7 +466,8 @@ void initial_placement(enum e_pad_loc_type pad_loc_type, const char* constraints read_constraints(constraints_file); } - /*Mark fixed blocks*/ + /*Mark the blocks that have already been locked to one spot via floorplan 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); diff --git a/vpr/test/test_vpr_constraints.cpp b/vpr/test/test_vpr_constraints.cpp index c6dbb9a81e4..74866f669a5 100644 --- a/vpr/test/test_vpr_constraints.cpp +++ b/vpr/test/test_vpr_constraints.cpp @@ -28,14 +28,14 @@ TEST_CASE("Region", "[vpr]") { REQUIRE(rect.ymax() == 4); REQUIRE(r1.get_sub_tile() == 2); - //checking that default constructor creates an empty rectangle (-1,-1,-1,-1) + //checking that default constructor creates an empty rectangle (999, 999,-1,-1) Region def_region; bool is_def_empty = false; vtr::Rect def_rect = def_region.get_region_rect(); is_def_empty = def_rect.empty(); REQUIRE(is_def_empty == true); - REQUIRE(def_rect.xmin() == -1); + REQUIRE(def_rect.xmin() == 999); REQUIRE(def_region.get_sub_tile() == -1); } From 6c6772dc52b197c3317ea8309ac4de677e1e528c Mon Sep 17 00:00:00 2001 From: Sarah Khalid Date: Wed, 9 Jun 2021 17:21:26 -0400 Subject: [PATCH 05/24] Added helper function for marking block locations and grid usage with extra checks --- vpr/src/base/read_place.cpp | 2 +- vpr/src/base/region.h | 4 ++-- vpr/src/place/place_constraints.cpp | 15 ++++--------- vpr/src/place/place_util.cpp | 35 +++++++++++++++++++++++++++++ vpr/src/place/place_util.h | 3 +++ 5 files changed, 45 insertions(+), 14 deletions(-) diff --git a/vpr/src/base/read_place.cpp b/vpr/src/base/read_place.cpp index b4a8b972d71..9f623095641 100644 --- a/vpr/src/base/read_place.cpp +++ b/vpr/src/base/read_place.cpp @@ -268,7 +268,7 @@ void read_place_body(std::ifstream& placement_file, } //need to lock down blocks and mark grid block usage if it is a constraints file - //for a place file, grid usage is marked during initial placement instead + //for a place file, grid usage is marked elsewhere if (!is_place_file) { place_ctx.block_locs[blk_id].is_fixed = true; place_ctx.grid_blocks[block_x][block_y].blocks[sub_tile_index] = blk_id; diff --git a/vpr/src/base/region.h b/vpr/src/base/region.h index 79b56de9311..fa550d89a73 100644 --- a/vpr/src/base/region.h +++ b/vpr/src/base/region.h @@ -44,8 +44,8 @@ class Region { void set_sub_tile(int _sub_tile); /** - * @brief Return whether the region is empty, meaning the rectangle has impossible dimensions - * or has the default values (-1, -1, -1, -1), indicating that it is uninitialized. + * @brief Return whether the region is empty (i. e. the region bounds rectangle + * covers no area) */ bool empty(); diff --git a/vpr/src/place/place_constraints.cpp b/vpr/src/place/place_constraints.cpp index 22cb7f5b54d..958a8fbfa40 100644 --- a/vpr/src/place/place_constraints.cpp +++ b/vpr/src/place/place_constraints.cpp @@ -10,6 +10,7 @@ #include "globals.h" #include "place_constraints.h" +#include "place_util.h" /*checks that each block's location is compatible with its floorplanning constraints if it has any*/ int check_placement_floorplanning() { @@ -194,21 +195,13 @@ void mark_fixed_blocks() { vtr::Rect rect = part_region[0].get_region_rect(); if (part_region[0].locked()) { - //Set the location of the block - place_ctx.block_locs[blk_id].loc.x = rect.xmin(); - place_ctx.block_locs[blk_id].loc.y = rect.ymin(); - place_ctx.block_locs[blk_id].loc.sub_tile = subtile; + t_pl_loc loc(rect.xmin(), rect.ymin(), subtile); - //Mark the grid location of the block - place_ctx.grid_blocks[rect.xmin()][rect.ymin()].blocks[subtile] = blk_id; + //Mark block location and grid usage + mark_block_location(blk_id, loc); //Set as fixed place_ctx.block_locs[blk_id].is_fixed = true; - - //Mark grid location usage - place_ctx.grid_blocks[rect.xmin()][rect.ymin()].usage++; - - std::string block_name = cluster_ctx.clb_nlist.block_name(blk_id); } } } diff --git a/vpr/src/place/place_util.cpp b/vpr/src/place/place_util.cpp index 74805f3d96e..a410e5e6aa0 100644 --- a/vpr/src/place/place_util.cpp +++ b/vpr/src/place/place_util.cpp @@ -427,3 +427,38 @@ void alloc_and_load_legal_placement_locations(std::vector int(device_ctx.grid.width() - 1) + || location.y < 0 || location.y > int(device_ctx.grid.height() - 1)) { + VPR_THROW(VPR_ERROR_PLACE, "Block %s with ID %d is out of range at location (%d, %d). \n", block_name.c_str(), blk_id, location.x, location.y); + } + + //Set the location of the block + place_ctx.block_locs[blk_id].loc.x = location.x; + place_ctx.block_locs[blk_id].loc.y = location.y; + place_ctx.block_locs[blk_id].loc.sub_tile = location.sub_tile; + + //Check if block is at an illegal location + auto physical_tile = device_ctx.grid[location.x][location.y].type; + auto logical_block = cluster_ctx.clb_nlist.block_type(blk_id); + + if (location.sub_tile >= physical_tile->capacity || location.sub_tile < 0) { + VPR_THROW(VPR_ERROR_PLACE, "Block %s subtile number (%d) is out of range. \n", block_name.c_str(), location.sub_tile); + } + + if (!is_sub_tile_compatible(physical_tile, logical_block, place_ctx.block_locs[blk_id].loc.sub_tile)) { + VPR_THROW(VPR_ERROR_PLACE, "Attempt to place block %s with ID %d at illegal location (%d, %d). \n", block_name.c_str(), blk_id, location.x, location.y); + } + + //Mark the grid location and usage of the block + place_ctx.grid_blocks[location.x][location.y].blocks[location.sub_tile] = blk_id; + place_ctx.grid_blocks[location.x][location.y].usage++; +} diff --git a/vpr/src/place/place_util.h b/vpr/src/place/place_util.h index 2ed0bf2e714..57271e28510 100644 --- a/vpr/src/place/place_util.h +++ b/vpr/src/place/place_util.h @@ -218,4 +218,7 @@ void load_grid_blocks_from_block_locs(); ///@brief Builds legal_pos structure. legal_pos[type->index] is an array that gives every legal value of (x,y,z) that can accommodate a block. void alloc_and_load_legal_placement_locations(std::vector>>& legal_pos); + +///@brief Marks the location and grid usage for a block that is set at a location +void mark_block_location(ClusterBlockId blk_id, const t_pl_loc& location); #endif From bf766f0858f6e2feca7a23eab67e0aa166b95c6a Mon Sep 17 00:00:00 2001 From: Sarah Khalid Date: Wed, 9 Jun 2021 18:25:55 -0400 Subject: [PATCH 06/24] Changed placement consistency error messages to improve clarity --- vpr/src/place/place.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/vpr/src/place/place.cpp b/vpr/src/place/place.cpp index aabd02c95a9..f6a2fa9762b 100644 --- a/vpr/src/place/place.cpp +++ b/vpr/src/place/place.cpp @@ -2644,8 +2644,8 @@ static int check_block_placement_consistency() { for (size_t i = 0; i < device_ctx.grid.width(); i++) for (size_t j = 0; j < device_ctx.grid.height(); j++) { if (place_ctx.grid_blocks[i][j].usage > device_ctx.grid[i][j].type->capacity) { - VTR_LOG_ERROR("Block at grid location (%zu,%zu) overused. Usage is %d.\n", - i, j, place_ctx.grid_blocks[i][j].usage); + VTR_LOG_ERROR("%d blocks were placed at grid location (%zu,%zu), but location capacity is %d.\n", + place_ctx.grid_blocks[i][j].usage, i, j, device_ctx.grid[i][j].type->capacity); error++; } int usage_check = 0; @@ -2674,8 +2674,8 @@ static int check_block_placement_consistency() { bdone[bnum]++; } if (usage_check != place_ctx.grid_blocks[i][j].usage) { - VTR_LOG_ERROR("Location (%zu,%zu) usage is %d, but has actual usage %d.\n", - i, j, place_ctx.grid_blocks[i][j].usage, usage_check); + VTR_LOG_ERROR("%d block(s) were placed at location (%zu,%zu), but location contains %d block(s).\n", + place_ctx.grid_blocks[i][j].usage, i, j, usage_check); error++; } } @@ -2683,7 +2683,7 @@ static int check_block_placement_consistency() { /* Check that every block exists in the device_ctx.grid and cluster_ctx.blocks arrays somewhere. */ for (auto blk_id : cluster_ctx.clb_nlist.blocks()) if (bdone[blk_id] != 1) { - VTR_LOG_ERROR("Block %zu listed %d times in data structures.\n", + VTR_LOG_ERROR("Block %zu listed %d times in device context grid.\n", size_t(blk_id), bdone[blk_id]); error++; } From c9151299ad17f356a68156f920be9d6ffce87836 Mon Sep 17 00:00:00 2001 From: Sarah Khalid Date: Thu, 10 Jun 2021 10:38:11 -0400 Subject: [PATCH 07/24] Add function to count number of tiles covered by a floorplan region --- vpr/src/place/place_constraints.cpp | 19 +++++++++++++++++++ vpr/src/place/place_constraints.h | 5 +++++ 2 files changed, 24 insertions(+) diff --git a/vpr/src/place/place_constraints.cpp b/vpr/src/place/place_constraints.cpp index 958a8fbfa40..0c4b5a1e765 100644 --- a/vpr/src/place/place_constraints.cpp +++ b/vpr/src/place/place_constraints.cpp @@ -205,4 +205,23 @@ void mark_fixed_blocks() { } } } + Region reg; t_logical_block_type_ptr block_type; + int i = num_tiles_covered(reg, block_type); +} + +int num_tiles_covered(const Region& reg, t_logical_block_type_ptr block_type) { + + auto& device_ctx = g_vpr_ctx.device(); + int num_tiles = 1; + + vtr::Rect rb = reg.get_region_rect(); + int x = rb.xmin(); + int y = rb.ymin(); + auto tile = device_ctx.grid[x][y].type; + if (is_tile_compatible(tile, block_type)) { + num_tiles++; + } + + return num_tiles; + } diff --git a/vpr/src/place/place_constraints.h b/vpr/src/place/place_constraints.h index f12027707cc..32b31d33dc9 100644 --- a/vpr/src/place/place_constraints.h +++ b/vpr/src/place/place_constraints.h @@ -70,4 +70,9 @@ void load_cluster_constraints(); */ void mark_fixed_blocks(); +/* + * Number of tiles covered by a region + */ +int num_tiles_covered(const Region& reg, t_logical_block_type_ptr block_type); + #endif /* VPR_SRC_PLACE_PLACE_CONSTRAINTS_H_ */ From 2f0dbf6a689f5e05a81e36914b2897ad2ce8cf6a Mon Sep 17 00:00:00 2001 From: Sarah Khalid Date: Mon, 14 Jun 2021 11:08:11 -0400 Subject: [PATCH 08/24] Changed comment --- vpr/src/place/place_constraints.cpp | 9 +++++---- vpr/src/place/place_constraints.h | 2 +- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/vpr/src/place/place_constraints.cpp b/vpr/src/place/place_constraints.cpp index 0c4b5a1e765..23abd0b3a39 100644 --- a/vpr/src/place/place_constraints.cpp +++ b/vpr/src/place/place_constraints.cpp @@ -205,11 +205,11 @@ void mark_fixed_blocks() { } } } - Region reg; t_logical_block_type_ptr block_type; - int i = num_tiles_covered(reg, block_type); + //Region reg; t_logical_block_type_ptr block_type; + //int i = num_tiles_covered(reg, block_type); } -int num_tiles_covered(const Region& reg, t_logical_block_type_ptr block_type) { +/*int num_tiles_covered(const Region& reg, t_logical_block_type_ptr block_type) { auto& device_ctx = g_vpr_ctx.device(); int num_tiles = 1; @@ -218,10 +218,11 @@ int num_tiles_covered(const Region& reg, t_logical_block_type_ptr block_type) { int x = rb.xmin(); int y = rb.ymin(); auto tile = device_ctx.grid[x][y].type; + auto cap = tile->capacity; if (is_tile_compatible(tile, block_type)) { num_tiles++; } return num_tiles; -} +}*/ diff --git a/vpr/src/place/place_constraints.h b/vpr/src/place/place_constraints.h index 32b31d33dc9..5474e2842fe 100644 --- a/vpr/src/place/place_constraints.h +++ b/vpr/src/place/place_constraints.h @@ -73,6 +73,6 @@ void mark_fixed_blocks(); /* * Number of tiles covered by a region */ -int num_tiles_covered(const Region& reg, t_logical_block_type_ptr block_type); +//int num_tiles_covered(const Region& reg, t_logical_block_type_ptr block_type); #endif /* VPR_SRC_PLACE_PLACE_CONSTRAINTS_H_ */ From 8165a5d91b4e0b80d3b21371701255e693e8d879 Mon Sep 17 00:00:00 2001 From: Sarah Khalid Date: Mon, 14 Jun 2021 21:57:32 -0400 Subject: [PATCH 09/24] Changed name of function mark_block_location->set_block_location --- vpr/src/place/place_constraints.cpp | 2 +- vpr/src/place/place_constraints.h | 5 +++-- vpr/src/place/place_util.cpp | 2 +- vpr/src/place/place_util.h | 2 +- 4 files changed, 6 insertions(+), 5 deletions(-) diff --git a/vpr/src/place/place_constraints.cpp b/vpr/src/place/place_constraints.cpp index 23abd0b3a39..c17d02b34bb 100644 --- a/vpr/src/place/place_constraints.cpp +++ b/vpr/src/place/place_constraints.cpp @@ -198,7 +198,7 @@ void mark_fixed_blocks() { t_pl_loc loc(rect.xmin(), rect.ymin(), subtile); //Mark block location and grid usage - mark_block_location(blk_id, loc); + set_block_location(blk_id, loc); //Set as fixed place_ctx.block_locs[blk_id].is_fixed = true; diff --git a/vpr/src/place/place_constraints.h b/vpr/src/place/place_constraints.h index 5474e2842fe..a648b9f2baf 100644 --- a/vpr/src/place/place_constraints.h +++ b/vpr/src/place/place_constraints.h @@ -65,8 +65,9 @@ inline bool floorplan_legal(const t_pl_blocks_to_be_moved& blocks_affected) { void load_cluster_constraints(); /* - * Marks blocks with a region with xlow = xhigh, ylow = yhigh, and subtile specified as fixed - * Marking them as fixed indicates that they cannot be moved during simulated annealing + * Marks blocks as fixed if they have a constraint region that specifies exactly one x, y, + * subtile location as legal. + * Marking them as fixed indicates that they cannot be moved during initial placement and simulated annealing */ void mark_fixed_blocks(); diff --git a/vpr/src/place/place_util.cpp b/vpr/src/place/place_util.cpp index a410e5e6aa0..d37342a781b 100644 --- a/vpr/src/place/place_util.cpp +++ b/vpr/src/place/place_util.cpp @@ -428,7 +428,7 @@ void alloc_and_load_legal_placement_locations(std::vector>>& legal_pos); ///@brief Marks the location and grid usage for a block that is set at a location -void mark_block_location(ClusterBlockId blk_id, const t_pl_loc& location); +void set_block_location(ClusterBlockId blk_id, const t_pl_loc& location); #endif From 8a900162c016c0e44faa21db9f49eadc2fe722c3 Mon Sep 17 00:00:00 2001 From: Sarah Khalid Date: Wed, 16 Jun 2021 12:09:27 -0400 Subject: [PATCH 10/24] Added functions to check whether the PartitionRegion of a cluster block covers one tile or more than one tile. This was needed to decide which blocks to mark as fixed --- vpr/src/place/place_constraints.cpp | 105 +++++++++++++++++++++------- vpr/src/place/place_constraints.h | 4 +- 2 files changed, 83 insertions(+), 26 deletions(-) diff --git a/vpr/src/place/place_constraints.cpp b/vpr/src/place/place_constraints.cpp index c17d02b34bb..c62140f9bfb 100644 --- a/vpr/src/place/place_constraints.cpp +++ b/vpr/src/place/place_constraints.cpp @@ -188,41 +188,96 @@ void mark_fixed_blocks() { auto& floorplanning_ctx = g_vpr_ctx.floorplanning(); for (auto blk_id : cluster_ctx.clb_nlist.blocks()) { + if (!is_cluster_constrained(blk_id)) { + continue; + } PartitionRegion pr = floorplanning_ctx.cluster_constraints[blk_id]; - std::vector part_region = pr.get_partition_region(); - if (part_region.size() == 1) { - int subtile = part_region[0].get_sub_tile(); - vtr::Rect rect = part_region[0].get_region_rect(); + auto block_type = cluster_ctx.clb_nlist.block_type(blk_id); + auto block_name = cluster_ctx.clb_nlist.block_name(blk_id); + t_pl_loc loc; - if (part_region[0].locked()) { - t_pl_loc loc(rect.xmin(), rect.ymin(), subtile); + if(is_pr_size_one(pr, block_type, loc)) { - //Mark block location and grid usage - set_block_location(blk_id, loc); + //Set block location and grid usage + set_block_location(blk_id, loc); - //Set as fixed - place_ctx.block_locs[blk_id].is_fixed = true; - } - } + //Set as fixed + place_ctx.block_locs[blk_id].is_fixed = true; + + VTR_LOG("Block %s marked as fixed \n", block_name.c_str()); + } } - //Region reg; t_logical_block_type_ptr block_type; - //int i = num_tiles_covered(reg, block_type); + } -/*int num_tiles_covered(const Region& reg, t_logical_block_type_ptr block_type) { - auto& device_ctx = g_vpr_ctx.device(); - int num_tiles = 1; +bool is_region_size_one(const Region& reg, t_logical_block_type_ptr block_type) { + auto& device_ctx = g_vpr_ctx.device(); vtr::Rect rb = reg.get_region_rect(); - int x = rb.xmin(); - int y = rb.ymin(); - auto tile = device_ctx.grid[x][y].type; - auto cap = tile->capacity; - if (is_tile_compatible(tile, block_type)) { - num_tiles++; + bool size_one = false; + + if (rb.xmin() == rb.xmax() && rb.ymin() == rb.ymax()) { + if (reg.get_sub_tile() != NO_SUBTILE) { + size_one = true; + } else { + int x = rb.xmin(); int y = rb.ymin(); + auto tile = device_ctx.grid[x][y].type; + if(is_tile_compatible(tile, block_type)) { + auto cap = tile->capacity; + if (cap == 1) { + size_one = true; + } else { + size_one = false; + } + } else { + return false; + //give an error because somehow tile and block type not compatible; + } + } + } else { + size_one = false; + } + + return size_one; +} + + +bool is_pr_size_one(PartitionRegion& pr, t_logical_block_type_ptr block_type, t_pl_loc& loc) { + std::vector regions = pr.get_partition_region(); + bool pr_size_one; + bool reg_size_one; + Region intersect_reg; + + for (unsigned int i = 0; i < regions.size(); i++) { + reg_size_one = is_region_size_one(regions[i], block_type); + if (!reg_size_one) { + pr_size_one = false; + break; + } else { + if (i == 0) { + intersect_reg = regions[0]; + } else { + intersect_reg = intersection(intersect_reg, regions[i]); + } + if (intersect_reg.empty()) { + pr_size_one = false; + break; + } else { + pr_size_one = true; + } + } + } - return num_tiles; + vtr::Rect rect = intersect_reg.get_region_rect(); + loc.x = rect.xmin(); + loc.y = rect.ymin(); + if (intersect_reg.get_sub_tile() == NO_SUBTILE) { + loc.sub_tile = 0; + } else { + loc.sub_tile = intersect_reg.get_sub_tile(); + } -}*/ + return pr_size_one; +} diff --git a/vpr/src/place/place_constraints.h b/vpr/src/place/place_constraints.h index a648b9f2baf..833da18bdaa 100644 --- a/vpr/src/place/place_constraints.h +++ b/vpr/src/place/place_constraints.h @@ -74,6 +74,8 @@ void mark_fixed_blocks(); /* * Number of tiles covered by a region */ -//int num_tiles_covered(const Region& reg, t_logical_block_type_ptr block_type); +bool is_region_size_one(const Region& reg, t_logical_block_type_ptr block_type); + +bool is_pr_size_one(PartitionRegion& pr, t_logical_block_type_ptr block_type, t_pl_loc& loc); #endif /* VPR_SRC_PLACE_PLACE_CONSTRAINTS_H_ */ From 2cc056b6d69519aafcc7eb93d88e2f0a2c1415c0 Mon Sep 17 00:00:00 2001 From: Sarah Khalid Date: Wed, 16 Jun 2021 12:10:52 -0400 Subject: [PATCH 11/24] Ran make format --- vpr/src/place/place_constraints.cpp | 155 ++++++++++++++-------------- 1 file changed, 75 insertions(+), 80 deletions(-) diff --git a/vpr/src/place/place_constraints.cpp b/vpr/src/place/place_constraints.cpp index c62140f9bfb..6d4e92e232c 100644 --- a/vpr/src/place/place_constraints.cpp +++ b/vpr/src/place/place_constraints.cpp @@ -188,96 +188,91 @@ void mark_fixed_blocks() { auto& floorplanning_ctx = g_vpr_ctx.floorplanning(); for (auto blk_id : cluster_ctx.clb_nlist.blocks()) { - if (!is_cluster_constrained(blk_id)) { - continue; - } + if (!is_cluster_constrained(blk_id)) { + continue; + } PartitionRegion pr = floorplanning_ctx.cluster_constraints[blk_id]; - auto block_type = cluster_ctx.clb_nlist.block_type(blk_id); - auto block_name = cluster_ctx.clb_nlist.block_name(blk_id); - t_pl_loc loc; - - if(is_pr_size_one(pr, block_type, loc)) { + auto block_type = cluster_ctx.clb_nlist.block_type(blk_id); + auto block_name = cluster_ctx.clb_nlist.block_name(blk_id); + t_pl_loc loc; - //Set block location and grid usage - set_block_location(blk_id, loc); + if (is_pr_size_one(pr, block_type, loc)) { + //Set block location and grid usage + set_block_location(blk_id, loc); - //Set as fixed - place_ctx.block_locs[blk_id].is_fixed = true; + //Set as fixed + place_ctx.block_locs[blk_id].is_fixed = true; - VTR_LOG("Block %s marked as fixed \n", block_name.c_str()); - } + VTR_LOG("Block %s marked as fixed \n", block_name.c_str()); + } } - } - bool is_region_size_one(const Region& reg, t_logical_block_type_ptr block_type) { + auto& device_ctx = g_vpr_ctx.device(); + vtr::Rect rb = reg.get_region_rect(); + bool size_one = false; - auto& device_ctx = g_vpr_ctx.device(); - vtr::Rect rb = reg.get_region_rect(); - bool size_one = false; - - if (rb.xmin() == rb.xmax() && rb.ymin() == rb.ymax()) { - if (reg.get_sub_tile() != NO_SUBTILE) { - size_one = true; - } else { - int x = rb.xmin(); int y = rb.ymin(); - auto tile = device_ctx.grid[x][y].type; - if(is_tile_compatible(tile, block_type)) { - auto cap = tile->capacity; - if (cap == 1) { - size_one = true; - } else { - size_one = false; - } - } else { - return false; - //give an error because somehow tile and block type not compatible; - } - } - } else { - size_one = false; - } - - return size_one; -} + if (rb.xmin() == rb.xmax() && rb.ymin() == rb.ymax()) { + if (reg.get_sub_tile() != NO_SUBTILE) { + size_one = true; + } else { + int x = rb.xmin(); + int y = rb.ymin(); + auto tile = device_ctx.grid[x][y].type; + if (is_tile_compatible(tile, block_type)) { + auto cap = tile->capacity; + if (cap == 1) { + size_one = true; + } else { + size_one = false; + } + } else { + return false; + //give an error because somehow tile and block type not compatible; + } + } + } else { + size_one = false; + } + return size_one; +} bool is_pr_size_one(PartitionRegion& pr, t_logical_block_type_ptr block_type, t_pl_loc& loc) { - std::vector regions = pr.get_partition_region(); - bool pr_size_one; - bool reg_size_one; - Region intersect_reg; - - for (unsigned int i = 0; i < regions.size(); i++) { - reg_size_one = is_region_size_one(regions[i], block_type); - if (!reg_size_one) { - pr_size_one = false; - break; - } else { - if (i == 0) { - intersect_reg = regions[0]; - } else { - intersect_reg = intersection(intersect_reg, regions[i]); - } - if (intersect_reg.empty()) { - pr_size_one = false; - break; - } else { - pr_size_one = true; - } - } - - } - - vtr::Rect rect = intersect_reg.get_region_rect(); - loc.x = rect.xmin(); - loc.y = rect.ymin(); - if (intersect_reg.get_sub_tile() == NO_SUBTILE) { - loc.sub_tile = 0; - } else { - loc.sub_tile = intersect_reg.get_sub_tile(); - } - - return pr_size_one; + std::vector regions = pr.get_partition_region(); + bool pr_size_one; + bool reg_size_one; + Region intersect_reg; + + for (unsigned int i = 0; i < regions.size(); i++) { + reg_size_one = is_region_size_one(regions[i], block_type); + if (!reg_size_one) { + pr_size_one = false; + break; + } else { + if (i == 0) { + intersect_reg = regions[0]; + } else { + intersect_reg = intersection(intersect_reg, regions[i]); + } + if (intersect_reg.empty()) { + pr_size_one = false; + break; + } else { + pr_size_one = true; + } + } + } + + vtr::Rect rect = intersect_reg.get_region_rect(); + loc.x = rect.xmin(); + loc.y = rect.ymin(); + if (intersect_reg.get_sub_tile() == NO_SUBTILE) { + loc.sub_tile = 0; + } else { + loc.sub_tile = intersect_reg.get_sub_tile(); + } + + return pr_size_one; } From 904db4723a051d8e647cb4bb8889c97b4ac58b90 Mon Sep 17 00:00:00 2001 From: Sarah Khalid Date: Wed, 16 Jun 2021 12:25:10 -0400 Subject: [PATCH 12/24] Removed locked member function from Region class - was no longer needed after function to check number of tiles was written --- vpr/src/base/region.cpp | 4 ---- vpr/src/base/region.h | 5 ----- vpr/test/test_vpr_constraints.cpp | 32 ------------------------------- 3 files changed, 41 deletions(-) diff --git a/vpr/src/base/region.cpp b/vpr/src/base/region.cpp index 923b2e0e904..104c9a47b3b 100644 --- a/vpr/src/base/region.cpp +++ b/vpr/src/base/region.cpp @@ -30,10 +30,6 @@ void Region::set_sub_tile(int _sub_tile) { sub_tile = _sub_tile; } -bool Region::locked() { - return region_bounds.xmin() == region_bounds.xmax() && region_bounds.ymin() == region_bounds.ymax() && sub_tile != NO_SUBTILE; -} - bool Region::empty() { return (region_bounds.xmax() < region_bounds.xmin() || region_bounds.ymax() < region_bounds.ymin()); } diff --git a/vpr/src/base/region.h b/vpr/src/base/region.h index fa550d89a73..415060ada6a 100644 --- a/vpr/src/base/region.h +++ b/vpr/src/base/region.h @@ -49,11 +49,6 @@ class Region { */ bool empty(); - /** - * @brief Checks whether a block is locked down to a specific x, y, subtile location - */ - bool locked(); - /** * @brief Check if the location is in the region (at a valid x, y, subtile location within the region bounds, inclusive) * If the region has no subtile specified, then the location subtile does not have to match. If it does, the location diff --git a/vpr/test/test_vpr_constraints.cpp b/vpr/test/test_vpr_constraints.cpp index 74866f669a5..1277d61b4b3 100644 --- a/vpr/test/test_vpr_constraints.cpp +++ b/vpr/test/test_vpr_constraints.cpp @@ -393,38 +393,6 @@ TEST_CASE("PartRegionIntersect6", "[vpr]") { REQUIRE(regions[3].get_region_rect() == int_r2r4); } -//Test the locked member function of the Region class -TEST_CASE("RegionLocked", "[vpr]") { - Region r1; - bool is_r1_locked = false; - - //set the region to a specific x, y, subtile location - region is locked - r1.set_region_rect(2, 3, 2, 3); //point (2,3) to point (2,3) - locking to specific x, y location - r1.set_sub_tile(3); //locking down to subtile 3 - - is_r1_locked = r1.locked(); - - REQUIRE(is_r1_locked == true); - - //do not set region to specific x, y location - region is not locked even if a subtile is specified - r1.set_region_rect(2, 3, 5, 6); //point (2,3) to point (5,6) - not locking to specific x, y location - r1.set_sub_tile(3); //locking down to subtile 3 - - is_r1_locked = r1.locked(); - - REQUIRE(is_r1_locked == false); - - //do not specify a subtile for the region - region is not locked even if it is set at specific x, y location - Region r2; - bool is_r2_locked = true; - - r2.set_region_rect(2, 3, 2, 3); - - is_r2_locked = r2.locked(); - - REQUIRE(is_r2_locked == false); -} - static constexpr const char kArchFile[] = "test_read_arch_metadata.xml"; // Test that place constraints are not changed during placement From 3a9096bfdda6c46fe2b4b92d43f95d8d5a5fd62e Mon Sep 17 00:00:00 2001 From: Sarah Khalid Date: Wed, 16 Jun 2021 12:34:41 -0400 Subject: [PATCH 13/24] Got rid of unnecessary lines in mark_fixed_blocks --- vpr/src/place/place_constraints.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/vpr/src/place/place_constraints.cpp b/vpr/src/place/place_constraints.cpp index 6d4e92e232c..31267b5d774 100644 --- a/vpr/src/place/place_constraints.cpp +++ b/vpr/src/place/place_constraints.cpp @@ -193,7 +193,6 @@ void mark_fixed_blocks() { } PartitionRegion pr = floorplanning_ctx.cluster_constraints[blk_id]; auto block_type = cluster_ctx.clb_nlist.block_type(blk_id); - auto block_name = cluster_ctx.clb_nlist.block_name(blk_id); t_pl_loc loc; if (is_pr_size_one(pr, block_type, loc)) { @@ -202,8 +201,6 @@ void mark_fixed_blocks() { //Set as fixed place_ctx.block_locs[blk_id].is_fixed = true; - - VTR_LOG("Block %s marked as fixed \n", block_name.c_str()); } } } From 3c9c93a0e3a2204dc769d2e12599401405dff432 Mon Sep 17 00:00:00 2001 From: Sarah Khalid Date: Wed, 16 Jun 2021 14:39:39 -0400 Subject: [PATCH 14/24] Ran make format --- vpr/test/test_vpr_constraints.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/vpr/test/test_vpr_constraints.cpp b/vpr/test/test_vpr_constraints.cpp index 0822c9b12e6..c687c5f6b7e 100644 --- a/vpr/test/test_vpr_constraints.cpp +++ b/vpr/test/test_vpr_constraints.cpp @@ -394,7 +394,6 @@ TEST_CASE("PartRegionIntersect6", "[vpr]") { REQUIRE(regions[3].get_region_rect() == int_r2r4); } - //Test calculation of macro constraints /* Checks that the PartitionRegion of a macro member is updated properly according * to the head member's PartitionRegion that is passed in. @@ -426,7 +425,6 @@ TEST_CASE("MacroConstraints", "[vpr]") { REQUIRE(mac_rect.ymax() == 7); } - static constexpr const char kArchFile[] = "test_read_arch_metadata.xml"; // Test that place constraints are not changed during placement From e1fa745d0f7fe7158d1f1ed2097698237abd9ea2 Mon Sep 17 00:00:00 2001 From: Sarah Khalid Date: Thu, 17 Jun 2021 12:53:33 -0400 Subject: [PATCH 15/24] Initialized grid blocks earlier in flow of reading in place file --- vpr/src/base/read_place.cpp | 32 ++++++++++++++++++++++++++++---- 1 file changed, 28 insertions(+), 4 deletions(-) diff --git a/vpr/src/base/read_place.cpp b/vpr/src/base/read_place.cpp index 9f623095641..fb1c56e8a76 100644 --- a/vpr/src/base/read_place.cpp +++ b/vpr/src/base/read_place.cpp @@ -185,6 +185,25 @@ void read_place_body(std::ifstream& placement_file, place_ctx.block_locs.resize(cluster_ctx.clb_nlist.blocks().size()); } + /* + * If place file, initialize grid blocks + */ + if (is_place_file) { + auto& grid_blocks = place_ctx.grid_blocks; + auto& device_grid = device_ctx.grid; + grid_blocks.resize({device_grid.width(), device_grid.height()}); + for (size_t x = 0; x < device_grid.width(); ++x) { + for (size_t y = 0; y < device_grid.height(); ++y) { + auto& grid_block = grid_blocks[x][y]; + grid_block.blocks.resize(device_ctx.grid[x][y].type->capacity); + + for (int z = 0; z < device_ctx.grid[x][y].type->capacity; ++z) { + grid_block.blocks[z] = EMPTY_BLOCK_ID; + } + } + } + } + //used to count how many times a block has been seen in the place/constraints file so duplicate blocks can be detected vtr::vector_map seen_blocks; @@ -271,10 +290,15 @@ void read_place_body(std::ifstream& placement_file, //for a place file, grid usage is marked elsewhere if (!is_place_file) { place_ctx.block_locs[blk_id].is_fixed = true; - place_ctx.grid_blocks[block_x][block_y].blocks[sub_tile_index] = blk_id; - if (seen_blocks[blk_id] == 0) { - place_ctx.grid_blocks[block_x][block_y].usage++; - } + /*place_ctx.grid_blocks[block_x][block_y].blocks[sub_tile_index] = blk_id; + * if (seen_blocks[blk_id] == 0) { + * place_ctx.grid_blocks[block_x][block_y].usage++; + * }*/ + } + + place_ctx.grid_blocks[block_x][block_y].blocks[sub_tile_index] = blk_id; + if (seen_blocks[blk_id] == 0) { + place_ctx.grid_blocks[block_x][block_y].usage++; } //mark the block as seen From f2305df188343707f295561825fea16d050e6f90 Mon Sep 17 00:00:00 2001 From: Sarah Khalid Date: Thu, 17 Jun 2021 14:25:20 -0400 Subject: [PATCH 16/24] Refactored read_place to make use of set_block_location utility function --- vpr/src/base/read_place.cpp | 40 ++++++++----------------------------- 1 file changed, 8 insertions(+), 32 deletions(-) diff --git a/vpr/src/base/read_place.cpp b/vpr/src/base/read_place.cpp index fb1c56e8a76..0b1a3b58583 100644 --- a/vpr/src/base/read_place.cpp +++ b/vpr/src/base/read_place.cpp @@ -15,6 +15,7 @@ #include "hash.h" #include "read_place.h" #include "read_xml_arch_file.h" +#include "place_util.h" void read_place_header( std::ifstream& placement_file, @@ -262,43 +263,18 @@ void read_place_body(std::ifstream& placement_file, } } - //Check if block location is out of range of grid dimensions - if (block_x < 0 || block_x > int(device_ctx.grid.width() - 1) - || block_y < 0 || block_y > int(device_ctx.grid.height() - 1)) { - VPR_THROW(VPR_ERROR_PLACE, "Block %s with ID %d is out of range at location (%d, %d). \n", c_block_name, blk_id, block_x, block_y); - } - - //Set the location - place_ctx.block_locs[blk_id].loc.x = block_x; - place_ctx.block_locs[blk_id].loc.y = block_y; - place_ctx.block_locs[blk_id].loc.sub_tile = sub_tile_index; - - //Check if block is at an illegal location - - auto physical_tile = device_ctx.grid[block_x][block_y].type; - auto logical_block = cluster_ctx.clb_nlist.block_type(blk_id); - - if (sub_tile_index >= physical_tile->capacity || sub_tile_index < 0) { - VPR_THROW(VPR_ERROR_PLACE, "Block %s subtile number (%d) is out of range. \n", c_block_name, sub_tile_index); - } + t_pl_loc loc; + loc.x = block_x; + loc.y = block_y; + loc.sub_tile = sub_tile_index; - if (!is_sub_tile_compatible(physical_tile, logical_block, place_ctx.block_locs[blk_id].loc.sub_tile)) { - VPR_THROW(VPR_ERROR_PLACE, "Attempt to place block %s with ID %d at illegal location (%d, %d). \n", c_block_name, blk_id, block_x, block_y); + if (seen_blocks[blk_id] == 0) { + set_block_location(blk_id, loc); } - //need to lock down blocks and mark grid block usage if it is a constraints file - //for a place file, grid usage is marked elsewhere + //need to lock down blocks if it is a constraints file if (!is_place_file) { place_ctx.block_locs[blk_id].is_fixed = true; - /*place_ctx.grid_blocks[block_x][block_y].blocks[sub_tile_index] = blk_id; - * if (seen_blocks[blk_id] == 0) { - * place_ctx.grid_blocks[block_x][block_y].usage++; - * }*/ - } - - place_ctx.grid_blocks[block_x][block_y].blocks[sub_tile_index] = blk_id; - if (seen_blocks[blk_id] == 0) { - place_ctx.grid_blocks[block_x][block_y].usage++; } //mark the block as seen From 7e0fe5885ebb76c88169cd0669850687c0f7bf41 Mon Sep 17 00:00:00 2001 From: Sarah Khalid Date: Thu, 17 Jun 2021 15:07:25 -0400 Subject: [PATCH 17/24] Improved error messaging during read place --- vpr/src/base/read_place.cpp | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/vpr/src/base/read_place.cpp b/vpr/src/base/read_place.cpp index 0b1a3b58583..e432e625918 100644 --- a/vpr/src/base/read_place.cpp +++ b/vpr/src/base/read_place.cpp @@ -187,7 +187,9 @@ void read_place_body(std::ifstream& placement_file, } /* - * If place file, initialize grid blocks + * If placement is being loaded (i.e. reading in a place file), + * the grid_blocks data structure has not been initialized yet, + * so it is initialized here. */ if (is_place_file) { auto& grid_blocks = place_ctx.grid_blocks; @@ -197,10 +199,6 @@ void read_place_body(std::ifstream& placement_file, for (size_t y = 0; y < device_grid.height(); ++y) { auto& grid_block = grid_blocks[x][y]; grid_block.blocks.resize(device_ctx.grid[x][y].type->capacity); - - for (int z = 0; z < device_ctx.grid[x][y].type->capacity; ++z) { - grid_block.blocks[z] = EMPTY_BLOCK_ID; - } } } } @@ -256,10 +254,11 @@ void read_place_body(std::ifstream& placement_file, //Check if block is listed multiple times with conflicting locations in constraints file if (seen_blocks[blk_id] > 0) { if (block_x != place_ctx.block_locs[blk_id].loc.x || block_y != place_ctx.block_locs[blk_id].loc.y || sub_tile_index != place_ctx.block_locs[blk_id].loc.sub_tile) { + std::string cluster_name = cluster_ctx.clb_nlist.block_name(blk_id); VPR_THROW(VPR_ERROR_PLACE, - "The location of cluster %d is specified %d times in the constraints file with conflicting locations. \n" + "The location of cluster %s (#%d) is specified %d times in the constraints file with conflicting locations. \n" "Its location was last specified with block %s. \n", - blk_id, seen_blocks[blk_id] + 1, c_block_name); + cluster_name.c_str(), blk_id, seen_blocks[blk_id] + 1, c_block_name); } } From 0504d8c8bf0f680948319db54dc8731fa4b66a5e Mon Sep 17 00:00:00 2001 From: Sarah Khalid Date: Thu, 17 Jun 2021 18:33:49 -0400 Subject: [PATCH 18/24] Refactored region size routine to return an int instead of a bool --- vpr/src/base/read_place.cpp | 2 +- vpr/src/place/place_constraints.cpp | 94 +++++++++++++++-------------- vpr/src/place/place_constraints.h | 2 +- 3 files changed, 51 insertions(+), 47 deletions(-) diff --git a/vpr/src/base/read_place.cpp b/vpr/src/base/read_place.cpp index e432e625918..d835dd0c8ef 100644 --- a/vpr/src/base/read_place.cpp +++ b/vpr/src/base/read_place.cpp @@ -254,7 +254,7 @@ void read_place_body(std::ifstream& placement_file, //Check if block is listed multiple times with conflicting locations in constraints file if (seen_blocks[blk_id] > 0) { if (block_x != place_ctx.block_locs[blk_id].loc.x || block_y != place_ctx.block_locs[blk_id].loc.y || sub_tile_index != place_ctx.block_locs[blk_id].loc.sub_tile) { - std::string cluster_name = cluster_ctx.clb_nlist.block_name(blk_id); + std::string cluster_name = cluster_ctx.clb_nlist.block_name(blk_id); VPR_THROW(VPR_ERROR_PLACE, "The location of cluster %s (#%d) is specified %d times in the constraints file with conflicting locations. \n" "Its location was last specified with block %s. \n", diff --git a/vpr/src/place/place_constraints.cpp b/vpr/src/place/place_constraints.cpp index 4d687069ca5..f75a0d9224f 100644 --- a/vpr/src/place/place_constraints.cpp +++ b/vpr/src/place/place_constraints.cpp @@ -270,82 +270,86 @@ void mark_fixed_blocks() { } PartitionRegion pr = floorplanning_ctx.cluster_constraints[blk_id]; auto block_type = cluster_ctx.clb_nlist.block_type(blk_id); + auto block_name = cluster_ctx.clb_nlist.block_name(blk_id); t_pl_loc loc; + VTR_LOG("Checking block %s \n", block_name.c_str()); if (is_pr_size_one(pr, block_type, loc)) { //Set block location and grid usage set_block_location(blk_id, loc); //Set as fixed place_ctx.block_locs[blk_id].is_fixed = true; + VTR_LOG("Block %s marked as fixed at %d, %d, %d. \n", block_name.c_str(), loc.x, loc.y, loc.sub_tile); } } } -bool is_region_size_one(const Region& reg, t_logical_block_type_ptr block_type) { +int region_size(const Region& reg, t_logical_block_type_ptr block_type, t_pl_loc& loc) { auto& device_ctx = g_vpr_ctx.device(); vtr::Rect rb = reg.get_region_rect(); - bool size_one = false; + int num_tiles = 0; + + for (int x = rb.xmin(); x <= rb.xmax(); x++) { + for (int y = rb.ymin(); y <= rb.ymax(); y++) { + auto& tile = device_ctx.grid[x][y].type; + VTR_LOG("At tile (%d, %d) \n", x, y); + if (!is_tile_compatible(tile, block_type)) { + //VTR_LOG("Tile not compatible, skip block %d \n"); + continue; + } - if (rb.xmin() == rb.xmax() && rb.ymin() == rb.ymax()) { - if (reg.get_sub_tile() != NO_SUBTILE) { - size_one = true; - } else { - int x = rb.xmin(); - int y = rb.ymin(); - auto tile = device_ctx.grid[x][y].type; - if (is_tile_compatible(tile, block_type)) { - auto cap = tile->capacity; - if (cap == 1) { - size_one = true; - } else { - size_one = false; + if (reg.get_sub_tile() != NO_SUBTILE) { + num_tiles++; + loc.x = x; + loc.y = y; + loc.sub_tile = reg.get_sub_tile(); + //VTR_LOG("Number of tiles incremented, num_tiles is %d \n", num_tiles); + if (num_tiles > 1) { + return num_tiles; + } + } else if (reg.get_sub_tile() == NO_SUBTILE) { + auto& cap = tile->capacity; + for (int z = 0; z < cap; z++) { + num_tiles++; + loc.x = x; + loc.y = y; + loc.sub_tile = 0; + //VTR_LOG("Number of tiles incremented, num_tiles is %d \n", num_tiles); + if (num_tiles > 1) { + return num_tiles; + } } - } else { - return false; - //give an error because somehow tile and block type not compatible; } } - } else { - size_one = false; } - return size_one; + return num_tiles; } bool is_pr_size_one(PartitionRegion& pr, t_logical_block_type_ptr block_type, t_pl_loc& loc) { std::vector regions = pr.get_partition_region(); bool pr_size_one; - bool reg_size_one; - Region intersect_reg; + + int pr_size = 0; + int reg_size; for (unsigned int i = 0; i < regions.size(); i++) { - reg_size_one = is_region_size_one(regions[i], block_type); - if (!reg_size_one) { + reg_size = region_size(regions[i], block_type, loc); + pr_size = pr_size + reg_size; + //VTR_LOG("Region size is %d \n", reg_size); + //VTR_LOG("Partition Region size is %d \n", pr_size); + if (pr_size > 1) { pr_size_one = false; - break; - } else { - if (i == 0) { - intersect_reg = regions[0]; - } else { - intersect_reg = intersection(intersect_reg, regions[i]); - } - if (intersect_reg.empty()) { - pr_size_one = false; - break; - } else { - pr_size_one = true; - } + return pr_size_one; } } - vtr::Rect rect = intersect_reg.get_region_rect(); - loc.x = rect.xmin(); - loc.y = rect.ymin(); - if (intersect_reg.get_sub_tile() == NO_SUBTILE) { - loc.sub_tile = 0; - } else { - loc.sub_tile = intersect_reg.get_sub_tile(); + if (pr_size == 0) { + pr_size_one = false; + return pr_size_one; + } else if (pr_size == 1) { + pr_size_one = true; } return pr_size_one; diff --git a/vpr/src/place/place_constraints.h b/vpr/src/place/place_constraints.h index 42f5a46ac17..6634f3f8ca7 100644 --- a/vpr/src/place/place_constraints.h +++ b/vpr/src/place/place_constraints.h @@ -98,7 +98,7 @@ void mark_fixed_blocks(); /* * Number of tiles covered by a region */ -bool is_region_size_one(const Region& reg, t_logical_block_type_ptr block_type); +int region_size(const Region& reg, t_logical_block_type_ptr block_type, t_pl_loc& loc); bool is_pr_size_one(PartitionRegion& pr, t_logical_block_type_ptr block_type, t_pl_loc& loc); From 8c3c1633d7d2cd53e2eb3d5dc44ad738c76538ca Mon Sep 17 00:00:00 2001 From: Sarah Khalid Date: Fri, 18 Jun 2021 00:44:05 -0400 Subject: [PATCH 19/24] Refactored region tile cover routine to return int instead of bool --- vpr/src/place/place_constraints.cpp | 53 +++++++++++++++++++++-------- vpr/src/place/place_constraints.h | 13 +++++-- 2 files changed, 49 insertions(+), 17 deletions(-) diff --git a/vpr/src/place/place_constraints.cpp b/vpr/src/place/place_constraints.cpp index f75a0d9224f..b2818cd74b0 100644 --- a/vpr/src/place/place_constraints.cpp +++ b/vpr/src/place/place_constraints.cpp @@ -270,22 +270,28 @@ void mark_fixed_blocks() { } PartitionRegion pr = floorplanning_ctx.cluster_constraints[blk_id]; auto block_type = cluster_ctx.clb_nlist.block_type(blk_id); - auto block_name = cluster_ctx.clb_nlist.block_name(blk_id); t_pl_loc loc; - VTR_LOG("Checking block %s \n", block_name.c_str()); if (is_pr_size_one(pr, block_type, loc)) { //Set block location and grid usage set_block_location(blk_id, loc); //Set as fixed place_ctx.block_locs[blk_id].is_fixed = true; - VTR_LOG("Block %s marked as fixed at %d, %d, %d. \n", block_name.c_str(), loc.x, loc.y, loc.sub_tile); } } } -int region_size(const Region& reg, t_logical_block_type_ptr block_type, t_pl_loc& loc) { +/* + * Returns 0, 1, or 2 depending on the number of tiles covered. + * Will not return a value above 2 because as soon as num_tiles is above 1, + * it is known that the block that is assigned to this region will not be fixed, and so + * num_tiles is immediately returned. + * Updates the location passed in because if num_tiles turns out to be 1 after checking the + * region, the location that was set will be used as the location to which the block + * will be fixed. + */ +int region_tile_cover(const Region& reg, t_logical_block_type_ptr block_type, t_pl_loc& loc) { auto& device_ctx = g_vpr_ctx.device(); vtr::Rect rb = reg.get_region_rect(); int num_tiles = 0; @@ -293,21 +299,36 @@ int region_size(const Region& reg, t_logical_block_type_ptr block_type, t_pl_loc for (int x = rb.xmin(); x <= rb.xmax(); x++) { for (int y = rb.ymin(); y <= rb.ymax(); y++) { auto& tile = device_ctx.grid[x][y].type; - VTR_LOG("At tile (%d, %d) \n", x, y); + + /* + * If the tile at the grid location is not compatible with the cluster block + * type, do not count this tile for num_tiles + */ if (!is_tile_compatible(tile, block_type)) { - //VTR_LOG("Tile not compatible, skip block %d \n"); continue; } + /* + * If the region passed has a specific subtile set, increment + * the number of tiles set the location using the x, y, subtile + * values + */ if (reg.get_sub_tile() != NO_SUBTILE) { num_tiles++; loc.x = x; loc.y = y; loc.sub_tile = reg.get_sub_tile(); - //VTR_LOG("Number of tiles incremented, num_tiles is %d \n", num_tiles); if (num_tiles > 1) { return num_tiles; } + + /* + * If the region passed does not have a subtile set, set the + * subtile to zero. The loc that is set will only be used in the + * event that num_tiles is 1, and num_tiles will only be 1 if the + * capacity of the tile type turns out to be zero, thus implying + * that the location subtile will be zero. + */ } else if (reg.get_sub_tile() == NO_SUBTILE) { auto& cap = tile->capacity; for (int z = 0; z < cap; z++) { @@ -315,7 +336,6 @@ int region_size(const Region& reg, t_logical_block_type_ptr block_type, t_pl_loc loc.x = x; loc.y = y; loc.sub_tile = 0; - //VTR_LOG("Number of tiles incremented, num_tiles is %d \n", num_tiles); if (num_tiles > 1) { return num_tiles; } @@ -327,6 +347,13 @@ int region_size(const Region& reg, t_logical_block_type_ptr block_type, t_pl_loc return num_tiles; } +/* + * Used when marking fixed blocks to check whether the ParitionRegion associated with a block + * covers one tile. If it covers one tile, it is marked as fixed. If it covers 0 tiles or + * more than one tile, it will not be marked as fixed. As soon as it is known that the + * PartitionRegion covers more than one tile, there is no need to check further regions + * and the routine will return false. + */ bool is_pr_size_one(PartitionRegion& pr, t_logical_block_type_ptr block_type, t_pl_loc& loc) { std::vector regions = pr.get_partition_region(); bool pr_size_one; @@ -335,19 +362,15 @@ bool is_pr_size_one(PartitionRegion& pr, t_logical_block_type_ptr block_type, t_ int reg_size; for (unsigned int i = 0; i < regions.size(); i++) { - reg_size = region_size(regions[i], block_type, loc); + reg_size = region_tile_cover(regions[i], block_type, loc); pr_size = pr_size + reg_size; - //VTR_LOG("Region size is %d \n", reg_size); - //VTR_LOG("Partition Region size is %d \n", pr_size); if (pr_size > 1) { - pr_size_one = false; - return pr_size_one; + break; } } - if (pr_size == 0) { + if (pr_size == 0 || pr_size > 1) { pr_size_one = false; - return pr_size_one; } else if (pr_size == 1) { pr_size_one = true; } diff --git a/vpr/src/place/place_constraints.h b/vpr/src/place/place_constraints.h index 6634f3f8ca7..f0d20debf12 100644 --- a/vpr/src/place/place_constraints.h +++ b/vpr/src/place/place_constraints.h @@ -96,10 +96,19 @@ void load_cluster_constraints(); void mark_fixed_blocks(); /* - * Number of tiles covered by a region + * Returns the number of tiles covered by a floorplan region. + * The return value of this routine will either be 0, 1, or 2. This + * is because this routine is used to check whether the region covers no tile, + * one tile, or more than one tile, and so as soon as it is seen that the number of tiles + * covered is 2, no further information is needed. */ -int region_size(const Region& reg, t_logical_block_type_ptr block_type, t_pl_loc& loc); +int region_tile_cover(const Region& reg, t_logical_block_type_ptr block_type, t_pl_loc& loc); +/* + * Returns whether the PartitionRegion covers no tiles, 1 tile, or more than 1 tile. + * Used to decide whether to mark a block with the .is_fixed flag based on its floorplan + * region. + */ bool is_pr_size_one(PartitionRegion& pr, t_logical_block_type_ptr block_type, t_pl_loc& loc); #endif /* VPR_SRC_PLACE_PLACE_CONSTRAINTS_H_ */ From c3ad3b68973b27d85793ad0905b84216bfc8b3c6 Mon Sep 17 00:00:00 2001 From: Sarah Khalid Date: Fri, 18 Jun 2021 01:34:06 -0400 Subject: [PATCH 20/24] Modified is_pr_size_one to get rid of compiler warning --- vpr/src/place/place_constraints.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/vpr/src/place/place_constraints.cpp b/vpr/src/place/place_constraints.cpp index b2818cd74b0..6bbc697cd01 100644 --- a/vpr/src/place/place_constraints.cpp +++ b/vpr/src/place/place_constraints.cpp @@ -369,10 +369,10 @@ bool is_pr_size_one(PartitionRegion& pr, t_logical_block_type_ptr block_type, t_ } } - if (pr_size == 0 || pr_size > 1) { - pr_size_one = false; - } else if (pr_size == 1) { + if (pr_size == 1) { pr_size_one = true; + } else { //pr_size = 0 or pr_size > 1 + pr_size_one = false; } return pr_size_one; From 6ad75c3abe048668a9c6d8d394afc41bb505c4d8 Mon Sep 17 00:00:00 2001 From: Sarah Khalid Date: Fri, 18 Jun 2021 10:53:07 -0400 Subject: [PATCH 21/24] Added check to partition region size check to see whether multiple regions cover the same tile --- vpr/src/place/place_constraints.cpp | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/vpr/src/place/place_constraints.cpp b/vpr/src/place/place_constraints.cpp index 6bbc697cd01..c850381ffe5 100644 --- a/vpr/src/place/place_constraints.cpp +++ b/vpr/src/place/place_constraints.cpp @@ -357,12 +357,39 @@ int region_tile_cover(const Region& reg, t_logical_block_type_ptr block_type, t_ bool is_pr_size_one(PartitionRegion& pr, t_logical_block_type_ptr block_type, t_pl_loc& loc) { std::vector regions = pr.get_partition_region(); bool pr_size_one; - + Region intersect_reg; int pr_size = 0; int reg_size; for (unsigned int i = 0; i < regions.size(); i++) { reg_size = region_tile_cover(regions[i], block_type, loc); + + /* + * If multiple regions in the PartitionRegion all have size 1, + * the block may still be marked as locked, in the case that + * they all cover the exact same tile. To check whether this + * is the case, whenever there is a size 1 region, it is intersected + * with the previous size 1 regions to see whether it covers the same tile. + * If there is an intersection, it does cover the same tile, and so pr_size is + * not incremented (unless this is the first size 1 region encountered). + */ + if (reg_size == 1) { + if (i == 0) { + intersect_reg = regions[0]; + pr_size = pr_size + reg_size; + } else { + intersect_reg = intersection(intersect_reg, regions[i]); + } + if (intersect_reg.empty()) { + pr_size = pr_size + reg_size; + if (pr_size > 1) { + break; + } + } else { + continue; + } + } + pr_size = pr_size + reg_size; if (pr_size > 1) { break; From 8887b6cec7b1c3d1bd0de1a171cf948be85d8d34 Mon Sep 17 00:00:00 2001 From: Sarah Khalid Date: Mon, 21 Jun 2021 11:37:58 -0400 Subject: [PATCH 22/24] Added checks for whether subtile location is valid when marking fixed blocks --- vpr/src/place/place_constraints.cpp | 80 ++++++++++++++++------------- 1 file changed, 45 insertions(+), 35 deletions(-) diff --git a/vpr/src/place/place_constraints.cpp b/vpr/src/place/place_constraints.cpp index c850381ffe5..581fd5c4397 100644 --- a/vpr/src/place/place_constraints.cpp +++ b/vpr/src/place/place_constraints.cpp @@ -11,6 +11,7 @@ #include "globals.h" #include "place_constraints.h" #include "place_util.h" +#include "initial_placement.cpp" /*checks that each block's location is compatible with its floorplanning constraints if it has any*/ int check_placement_floorplanning() { @@ -272,12 +273,17 @@ void mark_fixed_blocks() { auto block_type = cluster_ctx.clb_nlist.block_type(blk_id); t_pl_loc loc; + /* + * If the block can be placed in exactly one + * legal (x, y, subtile) location, place it now + * and mark it as fixed. + */ if (is_pr_size_one(pr, block_type, loc)) { - //Set block location and grid usage set_block_location(blk_id, loc); - //Set as fixed place_ctx.block_locs[blk_id].is_fixed = true; + + VTR_LOG("Marked block %d as fixed at location %d, %d, %d \n", blk_id, loc.x, loc.y, loc.sub_tile); } } } @@ -308,34 +314,36 @@ int region_tile_cover(const Region& reg, t_logical_block_type_ptr block_type, t_ continue; } + auto possible_sub_tiles = get_possible_sub_tile_indices(tile, block_type); + /* * If the region passed has a specific subtile set, increment * the number of tiles set the location using the x, y, subtile - * values + * values if the subtile is valid at this location */ if (reg.get_sub_tile() != NO_SUBTILE) { - num_tiles++; - loc.x = x; - loc.y = y; - loc.sub_tile = reg.get_sub_tile(); - if (num_tiles > 1) { - return num_tiles; - } + //Check if the user-specified subtile is in the range of possible subtile values + auto st = std::find(possible_sub_tiles.begin(), possible_sub_tiles.end(), reg.get_sub_tile()); + if (st != possible_sub_tiles.end()) { + num_tiles++; + loc.x = x; + loc.y = y; + loc.sub_tile = reg.get_sub_tile(); + if (num_tiles > 1) { + return num_tiles; + } + } /* * If the region passed does not have a subtile set, set the - * subtile to zero. The loc that is set will only be used in the - * event that num_tiles is 1, and num_tiles will only be 1 if the - * capacity of the tile type turns out to be zero, thus implying - * that the location subtile will be zero. + * subtile to the first possible slot at this location. */ } else if (reg.get_sub_tile() == NO_SUBTILE) { - auto& cap = tile->capacity; - for (int z = 0; z < cap; z++) { + for (int z = 0; z < possible_sub_tiles.size(); z++) { num_tiles++; loc.x = x; loc.y = y; - loc.sub_tile = 0; + loc.sub_tile = possible_sub_tiles[z]; if (num_tiles > 1) { return num_tiles; } @@ -355,44 +363,46 @@ int region_tile_cover(const Region& reg, t_logical_block_type_ptr block_type, t_ * and the routine will return false. */ bool is_pr_size_one(PartitionRegion& pr, t_logical_block_type_ptr block_type, t_pl_loc& loc) { + auto& device_ctx = g_vpr_ctx.device(); std::vector regions = pr.get_partition_region(); bool pr_size_one; - Region intersect_reg; int pr_size = 0; int reg_size; + Region intersect_reg; + intersect_reg.set_region_rect(0, 0, device_ctx.grid.width() - 1, device_ctx.grid.height() - 1); + Region new_reg; + for (unsigned int i = 0; i < regions.size(); i++) { reg_size = region_tile_cover(regions[i], block_type, loc); /* * If multiple regions in the PartitionRegion all have size 1, * the block may still be marked as locked, in the case that - * they all cover the exact same tile. To check whether this + * they all cover the exact same x, y, subtile location. To check whether this * is the case, whenever there is a size 1 region, it is intersected - * with the previous size 1 regions to see whether it covers the same tile. - * If there is an intersection, it does cover the same tile, and so pr_size is + * with the previous size 1 regions to see whether it covers the same location. + * If there is an intersection, it does cover the same location, and so pr_size is * not incremented (unless this is the first size 1 region encountered). */ if (reg_size == 1) { - if (i == 0) { - intersect_reg = regions[0]; - pr_size = pr_size + reg_size; - } else { - intersect_reg = intersection(intersect_reg, regions[i]); - } - if (intersect_reg.empty()) { + //get the exact x, y, subtile location covered by regions[i] + new_reg.set_region_rect(loc.x, loc.y, loc.x, loc.y); + new_reg.set_sub_tile(loc.sub_tile); + + intersect_reg = intersection(intersect_reg, new_reg); + + if (i == 0 || intersect_reg.empty()) { pr_size = pr_size + reg_size; if (pr_size > 1) { break; } - } else { - continue; } - } - - pr_size = pr_size + reg_size; - if (pr_size > 1) { - break; + } else { + pr_size = pr_size + reg_size; + if (pr_size > 1) { + break; + } } } From 58e268316d1a24e3d8a1d6ad3d8c8a74d3c40cc3 Mon Sep 17 00:00:00 2001 From: Sarah Khalid Date: Mon, 21 Jun 2021 14:45:42 -0400 Subject: [PATCH 23/24] Check whether subtile is compatible when adding fixed blocks --- vpr/src/place/place_constraints.cpp | 49 ++++++++++++++--------------- vpr/src/place/place_constraints.h | 4 ++- vpr/src/place/place_util.cpp | 2 +- vpr/src/place/place_util.h | 2 +- 4 files changed, 29 insertions(+), 28 deletions(-) diff --git a/vpr/src/place/place_constraints.cpp b/vpr/src/place/place_constraints.cpp index 581fd5c4397..43a8231fe3c 100644 --- a/vpr/src/place/place_constraints.cpp +++ b/vpr/src/place/place_constraints.cpp @@ -11,7 +11,6 @@ #include "globals.h" #include "place_constraints.h" #include "place_util.h" -#include "initial_placement.cpp" /*checks that each block's location is compatible with its floorplanning constraints if it has any*/ int check_placement_floorplanning() { @@ -282,8 +281,6 @@ void mark_fixed_blocks() { set_block_location(blk_id, loc); place_ctx.block_locs[blk_id].is_fixed = true; - - VTR_LOG("Marked block %d as fixed at location %d, %d, %d \n", blk_id, loc.x, loc.y, loc.sub_tile); } } } @@ -314,18 +311,13 @@ int region_tile_cover(const Region& reg, t_logical_block_type_ptr block_type, t_ continue; } - auto possible_sub_tiles = get_possible_sub_tile_indices(tile, block_type); - /* * If the region passed has a specific subtile set, increment * the number of tiles set the location using the x, y, subtile - * values if the subtile is valid at this location + * values if the subtile is compatible at this location */ if (reg.get_sub_tile() != NO_SUBTILE) { - //Check if the user-specified subtile is in the range of possible subtile values - auto st = std::find(possible_sub_tiles.begin(), possible_sub_tiles.end(), reg.get_sub_tile()); - - if (st != possible_sub_tiles.end()) { + if (is_sub_tile_compatible(tile, block_type, reg.get_sub_tile())) { num_tiles++; loc.x = x; loc.y = y; @@ -334,18 +326,26 @@ int region_tile_cover(const Region& reg, t_logical_block_type_ptr block_type, t_ return num_tiles; } } + /* - * If the region passed does not have a subtile set, set the - * subtile to the first possible slot at this location. + * If the region passed in does not have a subtile set, set the + * subtile to the first possible slot found at this location. */ } else if (reg.get_sub_tile() == NO_SUBTILE) { - for (int z = 0; z < possible_sub_tiles.size(); z++) { - num_tiles++; - loc.x = x; - loc.y = y; - loc.sub_tile = possible_sub_tiles[z]; - if (num_tiles > 1) { - return num_tiles; + int num_compatible_st = 0; + + for (int z = 0; z < tile->capacity; z++) { + if (is_sub_tile_compatible(tile, block_type, z)) { + num_tiles++; + num_compatible_st++; + if (num_compatible_st == 1) { //set loc.sub_tile to the first compatible subtile value found + loc.x = x; + loc.y = y; + loc.sub_tile = z; + } + if (num_tiles > 1) { + return num_tiles; + } } } } @@ -371,7 +371,7 @@ bool is_pr_size_one(PartitionRegion& pr, t_logical_block_type_ptr block_type, t_ Region intersect_reg; intersect_reg.set_region_rect(0, 0, device_ctx.grid.width() - 1, device_ctx.grid.height() - 1); - Region new_reg; + Region current_reg; for (unsigned int i = 0; i < regions.size(); i++) { reg_size = region_tile_cover(regions[i], block_type, loc); @@ -386,11 +386,10 @@ bool is_pr_size_one(PartitionRegion& pr, t_logical_block_type_ptr block_type, t_ * not incremented (unless this is the first size 1 region encountered). */ if (reg_size == 1) { - //get the exact x, y, subtile location covered by regions[i] - new_reg.set_region_rect(loc.x, loc.y, loc.x, loc.y); - new_reg.set_sub_tile(loc.sub_tile); - - intersect_reg = intersection(intersect_reg, new_reg); + //get the exact x, y, subtile location covered by the current region (regions[i]) + current_reg.set_region_rect(loc.x, loc.y, loc.x, loc.y); + current_reg.set_sub_tile(loc.sub_tile); + intersect_reg = intersection(intersect_reg, current_reg); if (i == 0 || intersect_reg.empty()) { pr_size = pr_size + reg_size; diff --git a/vpr/src/place/place_constraints.h b/vpr/src/place/place_constraints.h index f0d20debf12..ccbe4c9f64e 100644 --- a/vpr/src/place/place_constraints.h +++ b/vpr/src/place/place_constraints.h @@ -105,9 +105,11 @@ void mark_fixed_blocks(); int region_tile_cover(const Region& reg, t_logical_block_type_ptr block_type, t_pl_loc& loc); /* - * Returns whether the PartitionRegion covers no tiles, 1 tile, or more than 1 tile. + * Returns a bool that indicates if the PartitionRegion covers exactly one compatible location. * Used to decide whether to mark a block with the .is_fixed flag based on its floorplan * region. + * block_type is used to determine whether the PartitionRegion is compatible with the cluster block type + * and loc is updated with the location covered by the PartitionRegion */ bool is_pr_size_one(PartitionRegion& pr, t_logical_block_type_ptr block_type, t_pl_loc& loc); diff --git a/vpr/src/place/place_util.cpp b/vpr/src/place/place_util.cpp index d37342a781b..e6e0ab6cad1 100644 --- a/vpr/src/place/place_util.cpp +++ b/vpr/src/place/place_util.cpp @@ -433,7 +433,7 @@ void set_block_location(ClusterBlockId blk_id, const t_pl_loc& location) { auto& device_ctx = g_vpr_ctx.device(); auto& cluster_ctx = g_vpr_ctx.clustering(); - std::string block_name = cluster_ctx.clb_nlist.block_name(blk_id); + const std::string& block_name = cluster_ctx.clb_nlist.block_name(blk_id); //Check if block location is out of range of grid dimensions if (location.x < 0 || location.x > int(device_ctx.grid.width() - 1) diff --git a/vpr/src/place/place_util.h b/vpr/src/place/place_util.h index e977d5a2617..30648dc895e 100644 --- a/vpr/src/place/place_util.h +++ b/vpr/src/place/place_util.h @@ -219,6 +219,6 @@ void load_grid_blocks_from_block_locs(); ///@brief Builds legal_pos structure. legal_pos[type->index] is an array that gives every legal value of (x,y,z) that can accommodate a block. void alloc_and_load_legal_placement_locations(std::vector>>& legal_pos); -///@brief Marks the location and grid usage for a block that is set at a location +///@brief Performs error checking to see if location is legal for block type, and sets the location and grid usage of the block if it is legal. void set_block_location(ClusterBlockId blk_id, const t_pl_loc& location); #endif From 57ae843129522aca59f5622924512592f51813f0 Mon Sep 17 00:00:00 2001 From: Sarah Khalid Date: Mon, 21 Jun 2021 15:05:40 -0400 Subject: [PATCH 24/24] Moved initialization of placement structures during load place flow. Initialize the structures using utility function init_placement_context, which is also used during the do place flow --- vpr/src/base/read_place.cpp | 23 ----------------------- vpr/src/base/vpr_api.cpp | 4 ++++ 2 files changed, 4 insertions(+), 23 deletions(-) diff --git a/vpr/src/base/read_place.cpp b/vpr/src/base/read_place.cpp index d835dd0c8ef..68b51ef5b02 100644 --- a/vpr/src/base/read_place.cpp +++ b/vpr/src/base/read_place.cpp @@ -174,35 +174,12 @@ void read_place_body(std::ifstream& placement_file, const char* place_file, bool is_place_file) { auto& cluster_ctx = g_vpr_ctx.clustering(); - auto& device_ctx = g_vpr_ctx.device(); auto& place_ctx = g_vpr_ctx.mutable_placement(); auto& atom_ctx = g_vpr_ctx.atom(); std::string line; int lineno = 0; - if (place_ctx.block_locs.size() != cluster_ctx.clb_nlist.blocks().size()) { - //Resize if needed - place_ctx.block_locs.resize(cluster_ctx.clb_nlist.blocks().size()); - } - - /* - * If placement is being loaded (i.e. reading in a place file), - * the grid_blocks data structure has not been initialized yet, - * so it is initialized here. - */ - if (is_place_file) { - auto& grid_blocks = place_ctx.grid_blocks; - auto& device_grid = device_ctx.grid; - grid_blocks.resize({device_grid.width(), device_grid.height()}); - for (size_t x = 0; x < device_grid.width(); ++x) { - for (size_t y = 0; y < device_grid.height(); ++y) { - auto& grid_block = grid_blocks[x][y]; - grid_block.blocks.resize(device_ctx.grid[x][y].type->capacity); - } - } - } - //used to count how many times a block has been seen in the place/constraints file so duplicate blocks can be detected vtr::vector_map seen_blocks; diff --git a/vpr/src/base/vpr_api.cpp b/vpr/src/base/vpr_api.cpp index 5c1587d9c91..54f053ec6a7 100644 --- a/vpr/src/base/vpr_api.cpp +++ b/vpr/src/base/vpr_api.cpp @@ -70,6 +70,7 @@ #include "output_clustering.h" #include "vpr_constraints_reader.h" #include "place_constraints.h" +#include "place_util.h" #include "vpr_constraints_writer.h" @@ -684,6 +685,9 @@ void vpr_load_placement(t_vpr_setup& vpr_setup, const t_arch& arch) { auto& place_ctx = g_vpr_ctx.mutable_placement(); const auto& filename_opts = vpr_setup.FileNameOpts; + //Initialize placement data structures, which will be filled when loading placement + init_placement_context(); + //Load an existing placement from a file read_place(filename_opts.NetFile.c_str(), filename_opts.PlaceFile.c_str(), filename_opts.verify_file_digests, device_ctx.grid);