Skip to content

Commit 58ea2c0

Browse files
Merge branch 'master' into feature-verify-clustering
2 parents 88f581d + 045a9e8 commit 58ea2c0

File tree

8 files changed

+363
-160
lines changed

8 files changed

+363
-160
lines changed

vpr/src/analytical_place/full_legalizer.cpp

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77

88
#include "full_legalizer.h"
99

10-
#include <cmath>
1110
#include <list>
1211
#include <unordered_set>
1312
#include <vector>
@@ -28,6 +27,7 @@
2827
#include "place_constraints.h"
2928
#include "place_macro.h"
3029
#include "verify_clustering.h"
30+
#include "verify_placement.h"
3131
#include "vpr_api.h"
3232
#include "vpr_context.h"
3333
#include "vpr_error.h"
@@ -409,5 +409,16 @@ void FullLegalizer::legalize(const PartialPlacement& p_placement) {
409409

410410
// Place the clusters based on where the atoms want to be placed.
411411
place_clusters(clb_nlist, p_placement);
412+
413+
// Verify that the placement created by the full legalizer is valid.
414+
unsigned num_placement_errors = verify_placement(g_vpr_ctx);
415+
if (num_placement_errors == 0) {
416+
VTR_LOG("Completed placement consistency check successfully.\n");
417+
} else {
418+
VPR_ERROR(VPR_ERROR_AP,
419+
"Completed placement consistency check, %u errors found.\n"
420+
"Aborting program.\n",
421+
num_placement_errors);
422+
}
412423
}
413424

vpr/src/base/vpr_api.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -801,6 +801,9 @@ bool vpr_place_flow(const Netlist<>& net_list, t_vpr_setup& vpr_setup, const t_a
801801
vpr_load_placement(vpr_setup, arch);
802802
}
803803

804+
// FIXME: This synchronization is not consistent with the rest of
805+
// placement. This requires it to happen after the placement is
806+
// verified. See issue #2801
804807
sync_grid_to_blocks();
805808
post_place_sync();
806809
}

vpr/src/pack/verify_clustering.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@ static unsigned check_clustering_pb_consistency(const ClusteredNetlist& clb_nlis
165165
VTR_LOG_ERROR(
166166
"Cluster block %zu has a pb whose graph node does not match "
167167
"the pb_graph_head of its block type: %s.\n",
168-
size_t(clb_blk_id), clb_blk_type->name);
168+
size_t(clb_blk_id), clb_blk_type->name.c_str());
169169
num_errors++;
170170
}
171171
// TODO: Should check the pb_route. Tried checking that the pb_route

vpr/src/place/place.cpp

Lines changed: 12 additions & 134 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@
88
#include <optional>
99

1010
#include "NetPinTimingInvalidator.h"
11+
#include "clustered_netlist.h"
12+
#include "device_grid.h"
13+
#include "verify_placement.h"
1114
#include "vtr_assert.h"
1215
#include "vtr_log.h"
1316
#include "vtr_util.h"
@@ -228,11 +231,6 @@ static int check_placement_costs(const t_placer_costs& costs,
228231
PlacerState& placer_state,
229232
NetCostHandler& net_cost_handler);
230233

231-
232-
static int check_placement_consistency(const BlkLocRegistry& blk_loc_registry);
233-
static int check_block_placement_consistency(const BlkLocRegistry& blk_loc_registry);
234-
static int check_macro_placement_consistency(const BlkLocRegistry& blk_loc_registry);
235-
236234
static float starting_t(const t_annealing_state* state,
237235
t_placer_costs* costs,
238236
t_annealing_sched annealing_sched,
@@ -1943,12 +1941,19 @@ static void check_place(const t_placer_costs& costs,
19431941
* every block, blocks are in legal spots, etc. Also recomputes *
19441942
* the final placement cost from scratch and makes sure it is *
19451943
* within roundoff of what we think the cost is. */
1944+
const ClusteredNetlist& clb_nlist = g_vpr_ctx.clustering().clb_nlist;
1945+
const DeviceGrid& device_grid = g_vpr_ctx.device().grid;
1946+
const auto& cluster_constraints = g_vpr_ctx.floorplanning().cluster_constraints;
19461947

19471948
int error = 0;
19481949

1949-
error += check_placement_consistency(placer_state.blk_loc_registry());
1950+
// Verify the placement invariants independent to the placement flow.
1951+
error += verify_placement(placer_state.blk_loc_registry(),
1952+
clb_nlist,
1953+
device_grid,
1954+
cluster_constraints);
1955+
19501956
error += check_placement_costs(costs, delay_model, criticalities, place_algorithm, placer_state, net_cost_handler);
1951-
error += check_placement_floorplanning(placer_state.block_locs());
19521957

19531958
if (noc_opts.noc) {
19541959
// check the NoC costs during placement if the user is using the NoC supported flow
@@ -2000,133 +2005,6 @@ static int check_placement_costs(const t_placer_costs& costs,
20002005
return error;
20012006
}
20022007

2003-
static int check_placement_consistency(const BlkLocRegistry& blk_loc_registry) {
2004-
return check_block_placement_consistency(blk_loc_registry) + check_macro_placement_consistency(blk_loc_registry);
2005-
}
2006-
2007-
static int check_block_placement_consistency(const BlkLocRegistry& blk_loc_registry) {
2008-
auto& cluster_ctx = g_vpr_ctx.clustering();
2009-
auto& device_ctx = g_vpr_ctx.device();
2010-
const auto& block_locs = blk_loc_registry.block_locs();
2011-
const auto& grid_blocks = blk_loc_registry.grid_blocks();
2012-
2013-
int error = 0;
2014-
2015-
vtr::vector<ClusterBlockId, int> bdone(cluster_ctx.clb_nlist.blocks().size(), 0);
2016-
2017-
/* Step through device grid and placement. Check it against blocks */
2018-
for (int layer_num = 0; layer_num < (int)device_ctx.grid.get_num_layers(); layer_num++) {
2019-
for (int i = 0; i < (int)device_ctx.grid.width(); i++) {
2020-
for (int j = 0; j < (int)device_ctx.grid.height(); j++) {
2021-
const t_physical_tile_loc tile_loc(i, j, layer_num);
2022-
const auto& type = device_ctx.grid.get_physical_type(tile_loc);
2023-
if (grid_blocks.get_usage(tile_loc) > type->capacity) {
2024-
VTR_LOG_ERROR(
2025-
"%d blocks were placed at grid location (%d,%d,%d), but location capacity is %d.\n",
2026-
grid_blocks.get_usage(tile_loc), i, j, layer_num, type->capacity);
2027-
error++;
2028-
}
2029-
int usage_check = 0;
2030-
for (int k = 0; k < type->capacity; k++) {
2031-
ClusterBlockId bnum = grid_blocks.block_at_location({i, j, k, layer_num});
2032-
if (bnum == ClusterBlockId::INVALID()) {
2033-
continue;
2034-
}
2035-
2036-
auto logical_block = cluster_ctx.clb_nlist.block_type(bnum);
2037-
auto physical_tile = type;
2038-
t_pl_loc block_loc = block_locs[bnum].loc;
2039-
2040-
if (physical_tile_type(block_loc) != physical_tile) {
2041-
VTR_LOG_ERROR(
2042-
"Block %zu type (%s) does not match grid location (%zu,%zu, %d) type (%s).\n",
2043-
size_t(bnum), logical_block->name.c_str(), i, j, layer_num, physical_tile->name.c_str());
2044-
error++;
2045-
}
2046-
2047-
auto& loc = block_locs[bnum].loc;
2048-
if (loc.x != i || loc.y != j || loc.layer != layer_num
2049-
|| !is_sub_tile_compatible(physical_tile, logical_block,
2050-
loc.sub_tile)) {
2051-
VTR_LOG_ERROR(
2052-
"Block %zu's location is (%d,%d,%d,%d) but found in grid at (%d,%d,%d,%d).\n",
2053-
size_t(bnum),
2054-
loc.x,
2055-
loc.y,
2056-
loc.sub_tile,
2057-
loc.layer,
2058-
i,
2059-
j,
2060-
k,
2061-
layer_num);
2062-
error++;
2063-
}
2064-
++usage_check;
2065-
bdone[bnum]++;
2066-
}
2067-
if (usage_check != grid_blocks.get_usage(tile_loc)) {
2068-
VTR_LOG_ERROR(
2069-
"%d block(s) were placed at location (%d,%d,%d), but location contains %d block(s).\n",
2070-
grid_blocks.get_usage(tile_loc),
2071-
tile_loc.x,
2072-
tile_loc.y,
2073-
tile_loc.layer_num,
2074-
usage_check);
2075-
error++;
2076-
}
2077-
}
2078-
}
2079-
}
2080-
2081-
/* Check that every block exists in the device_ctx.grid and cluster_ctx.blocks arrays somewhere. */
2082-
for (ClusterBlockId blk_id : cluster_ctx.clb_nlist.blocks())
2083-
if (bdone[blk_id] != 1) {
2084-
VTR_LOG_ERROR("Block %zu listed %d times in device context grid.\n",
2085-
size_t(blk_id), bdone[blk_id]);
2086-
error++;
2087-
}
2088-
2089-
return error;
2090-
}
2091-
2092-
int check_macro_placement_consistency(const BlkLocRegistry& blk_loc_registry) {
2093-
const auto& pl_macros = blk_loc_registry.place_macros().macros();
2094-
const auto& block_locs = blk_loc_registry.block_locs();
2095-
const auto& grid_blocks = blk_loc_registry.grid_blocks();
2096-
2097-
int error = 0;
2098-
2099-
/* Check the pl_macro placement are legal - blocks are in the proper relative position. */
2100-
for (size_t imacro = 0; imacro < pl_macros.size(); imacro++) {
2101-
auto head_iblk = pl_macros[imacro].members[0].blk_index;
2102-
2103-
for (size_t imember = 0; imember < pl_macros[imacro].members.size(); imember++) {
2104-
auto member_iblk = pl_macros[imacro].members[imember].blk_index;
2105-
2106-
// Compute the supposed member's x,y,z location
2107-
t_pl_loc member_pos = block_locs[head_iblk].loc + pl_macros[imacro].members[imember].offset;
2108-
2109-
// Check the blk_loc_registry.block_locs data structure first
2110-
if (block_locs[member_iblk].loc != member_pos) {
2111-
VTR_LOG_ERROR(
2112-
"Block %zu in pl_macro #%zu is not placed in the proper orientation.\n",
2113-
size_t(member_iblk), imacro);
2114-
error++;
2115-
}
2116-
2117-
// Then check the blk_loc_registry.grid data structure
2118-
if (grid_blocks.block_at_location(member_pos) != member_iblk) {
2119-
VTR_LOG_ERROR(
2120-
"Block %zu in pl_macro #%zu is not placed in the proper orientation.\n",
2121-
size_t(member_iblk), imacro);
2122-
error++;
2123-
}
2124-
} // Finish going through all the members
2125-
} // Finish going through all the macros
2126-
2127-
return error;
2128-
}
2129-
21302008
#ifdef VERBOSE
21312009
void print_clb_placement(const char* fname) {
21322010
/* Prints out the clb placements to a file. */

vpr/src/place/place_constraints.cpp

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -13,21 +13,6 @@
1313
#include "place_util.h"
1414
#include "vpr_context.h"
1515

16-
int check_placement_floorplanning(const vtr::vector_map<ClusterBlockId, t_block_loc>& block_locs) {
17-
int error = 0;
18-
auto& cluster_ctx = g_vpr_ctx.clustering();
19-
20-
for (ClusterBlockId blk_id : cluster_ctx.clb_nlist.blocks()) {
21-
t_pl_loc loc = block_locs[blk_id].loc;
22-
if (!cluster_floorplanning_legal(blk_id, loc)) {
23-
error++;
24-
VTR_LOG_ERROR("Block %zu is not in correct floorplanning region.\n", size_t(blk_id));
25-
}
26-
}
27-
28-
return error;
29-
}
30-
3116
bool is_cluster_constrained(ClusterBlockId blk_id) {
3217
auto& floorplanning_ctx = g_vpr_ctx.floorplanning();
3318
const PartitionRegion& pr = floorplanning_ctx.cluster_constraints[blk_id];

vpr/src/place/place_constraints.h

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,6 @@
1515
#include "place_macro.h"
1616
#include "grid_tile_lookup.h"
1717

18-
/**
19-
* @brief Check that placement of each block is within the floorplan constraint region
20-
* of that block (if the block has any constraints).
21-
*
22-
* @param block_locs Contains the location where each clustered block is placed.
23-
* @return int The number of errors (inconsistencies in adherence to floorplanning constraints).
24-
*/
25-
int check_placement_floorplanning(const vtr::vector_map<ClusterBlockId, t_block_loc>& block_locs);
26-
2718
/**
2819
* @brief Check if the block has floorplanning constraints.
2920
*

0 commit comments

Comments
 (0)