Skip to content

Commit 5a062ba

Browse files
authored
Merge pull request #2802 from AlexandreSinger/feature-verify-placement
[Placement] Resolved Inconsistency with Placing at Root Tile Locs
2 parents fdf6d3c + afcb192 commit 5a062ba

File tree

5 files changed

+58
-108
lines changed

5 files changed

+58
-108
lines changed

vpr/src/base/vpr_api.cpp

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include <cmath>
1717

1818
#include "cluster_util.h"
19+
#include "verify_placement.h"
1920
#include "vpr_context.h"
2021
#include "vtr_assert.h"
2122
#include "vtr_math.h"
@@ -801,10 +802,6 @@ bool vpr_place_flow(const Netlist<>& net_list, t_vpr_setup& vpr_setup, const t_a
801802
vpr_load_placement(vpr_setup, arch);
802803
}
803804

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
807-
sync_grid_to_blocks();
808805
post_place_sync();
809806
}
810807

@@ -877,6 +874,18 @@ void vpr_load_placement(t_vpr_setup& vpr_setup, const t_arch& arch) {
877874
place_ctx.placement_id = read_place(filename_opts.NetFile.c_str(), filename_opts.PlaceFile.c_str(),
878875
blk_loc_registry,
879876
filename_opts.verify_file_digests, device_ctx.grid);
877+
878+
// Verify that the placement invariants are met after reading the placement
879+
// from a file.
880+
unsigned num_errors = verify_placement(g_vpr_ctx);
881+
if (num_errors == 0) {
882+
VTR_LOG("Completed placement consistency check successfully.\n");
883+
} else {
884+
VPR_ERROR(VPR_ERROR_PLACE,
885+
"Completed placement consistency check, %d errors found.\n"
886+
"Aborting program.\n",
887+
num_errors);
888+
}
880889
}
881890

882891
RouteStatus vpr_route_flow(const Netlist<>& net_list,

vpr/src/pack/sync_netlists_to_routing_flat.cpp

Lines changed: 14 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -70,19 +70,24 @@ inline ClusterBlockId get_cluster_block_from_rr_node(RRNodeId inode){
7070
auto& place_ctx = g_vpr_ctx.placement();
7171
auto& rr_graph = device_ctx.rr_graph;
7272

73-
auto physical_tile = device_ctx.grid.get_physical_type({
74-
rr_graph.node_xlow(inode),
75-
rr_graph.node_ylow(inode),
76-
rr_graph.node_layer(inode)
77-
});
73+
t_physical_tile_loc node_phy_tile_loc(rr_graph.node_xlow(inode),
74+
rr_graph.node_ylow(inode),
75+
rr_graph.node_layer(inode));
76+
auto physical_tile = device_ctx.grid.get_physical_type(node_phy_tile_loc);
7877

7978
int source_pin = rr_graph.node_pin_num(inode);
8079

8180
auto [_, subtile] = get_sub_tile_from_pin_physical_num(physical_tile, source_pin);
8281

82+
// The placer will only place Clusters at the root tile location. Need to
83+
// offset to the root tile location to get the cluster block at this
84+
// tile.
85+
int width_offset = device_ctx.grid.get_width_offset(node_phy_tile_loc);
86+
int height_offset = device_ctx.grid.get_height_offset(node_phy_tile_loc);
87+
8388
ClusterBlockId clb = place_ctx.grid_blocks().block_at_location({
84-
rr_graph.node_xlow(inode),
85-
rr_graph.node_ylow(inode),
89+
rr_graph.node_xlow(inode) - width_offset,
90+
rr_graph.node_ylow(inode) - height_offset,
8691
subtile,
8792
rr_graph.node_layer(inode)
8893
});
@@ -185,7 +190,6 @@ static void sync_pb_routes_to_routing(void){
185190
auto& device_ctx = g_vpr_ctx.device();
186191
auto& atom_ctx = g_vpr_ctx.atom();
187192
auto& cluster_ctx = g_vpr_ctx.mutable_clustering();
188-
auto& place_ctx = g_vpr_ctx.placement();
189193
auto& route_ctx = g_vpr_ctx.routing();
190194
auto& rr_graph = device_ctx.rr_graph;
191195

@@ -220,6 +224,7 @@ static void sync_pb_routes_to_routing(void){
220224

221225
/* Restore the connections */
222226
for(auto [source_inode, sink_inode]: conns_to_restore){
227+
ClusterBlockId clb = get_cluster_block_from_rr_node(source_inode);
223228
auto physical_tile = device_ctx.grid.get_physical_type({
224229
rr_graph.node_xlow(source_inode),
225230
rr_graph.node_ylow(source_inode),
@@ -228,15 +233,6 @@ static void sync_pb_routes_to_routing(void){
228233
int source_pin = rr_graph.node_pin_num(source_inode);
229234
int sink_pin = rr_graph.node_pin_num(sink_inode);
230235

231-
auto [_, subtile] = get_sub_tile_from_pin_physical_num(physical_tile, source_pin);
232-
233-
ClusterBlockId clb = place_ctx.grid_blocks().block_at_location({
234-
rr_graph.node_xlow(source_inode),
235-
rr_graph.node_ylow(source_inode),
236-
subtile,
237-
rr_graph.node_layer(source_inode)
238-
});
239-
240236
/* Look up pb graph pins from pb type if pin is not on tile, look up from block otherwise */
241237
const t_pb_graph_pin* source_pb_graph_pin, *sink_pb_graph_pin;
242238
if(is_pin_on_tile(physical_tile, sink_pin)){
@@ -361,14 +357,7 @@ static void sync_clustered_netlist_to_routing(void){
361357

362358
int pin_index = rr_graph.node_pin_num(rt_node.inode);
363359

364-
auto [_, subtile] = get_sub_tile_from_pin_physical_num(physical_tile, pin_index);
365-
366-
ClusterBlockId clb = place_ctx.grid_blocks().block_at_location({
367-
rr_graph.node_xlow(rt_node.inode),
368-
rr_graph.node_ylow(rt_node.inode),
369-
subtile,
370-
rr_graph.node_layer(rt_node.inode)
371-
});
360+
ClusterBlockId clb = get_cluster_block_from_rr_node(rt_node.inode);
372361

373362
if(!is_pin_on_tile(physical_tile, pin_index))
374363
continue;

vpr/src/place/verify_placement.cpp

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
* - The grid blocks matches the block locations.
3434
* - Blocks are not in invalid grid locations.
3535
* - All clusters are placed.
36+
* - Clusters are only placed at the root tile location of large tiles.
3637
*
3738
* @param blk_loc_registry A registry containing the block locations and
3839
* the blocks at each grid location.
@@ -57,6 +58,35 @@ static unsigned check_block_placement_consistency(const BlkLocRegistry& blk_loc_
5758
for (int j = 0; j < (int)device_grid.height(); j++) {
5859
const t_physical_tile_loc tile_loc(i, j, layer_num);
5960
const auto& type = device_grid.get_physical_type(tile_loc);
61+
62+
// If this is not a root tile block, ensure that its usage is 0
63+
// and that it has no valid clusters placed at this location.
64+
// TODO: Eventually it should be made impossible to place blocks
65+
// at these locations.
66+
if (device_grid.get_width_offset(tile_loc) != 0 ||
67+
device_grid.get_height_offset(tile_loc) != 0) {
68+
// Usage must be 0
69+
if (grid_blocks.get_usage(tile_loc) != 0) {
70+
VTR_LOG_ERROR(
71+
"%d blocks were placed at non-root tile location "
72+
"(%d, %d, %d), but no blocks should be placed here.\n",
73+
grid_blocks.get_usage(tile_loc), i, j, layer_num);
74+
num_errors++;
75+
}
76+
// Check that all clusters at this tile location are invalid.
77+
for (int k = 0; k < type->capacity; k++) {
78+
ClusterBlockId bnum = grid_blocks.block_at_location({i, j, k, layer_num});
79+
if (bnum.is_valid()) {
80+
VTR_LOG_ERROR(
81+
"Block %zu was placed at non-root tile location "
82+
"(%d, %d, %d), but no blocks should be placed "
83+
"here.\n",
84+
size_t(bnum), i, j, layer_num);
85+
num_errors++;
86+
}
87+
}
88+
}
89+
6090
if (grid_blocks.get_usage(tile_loc) > type->capacity) {
6191
VTR_LOG_ERROR(
6292
"%d blocks were placed at grid location (%d,%d,%d), but location capacity is %d.\n",

vpr/src/util/vpr_utils.cpp

Lines changed: 1 addition & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -88,82 +88,6 @@ void print_tabs(FILE* fpout, int num_tab) {
8888
}
8989
}
9090

91-
/* Points the place_ctx.grid_blocks structure back to the blocks list */
92-
void sync_grid_to_blocks() {
93-
auto& place_ctx = g_vpr_ctx.mutable_placement();
94-
auto& device_ctx = g_vpr_ctx.device();
95-
auto& device_grid = device_ctx.grid;
96-
97-
const int num_layers = device_ctx.grid.get_num_layers();
98-
99-
auto& grid_blocks = place_ctx.mutable_grid_blocks();
100-
auto& block_locs = place_ctx.block_locs();
101-
102-
/* Reset usage and allocate blocks list if needed */
103-
grid_blocks = GridBlock(device_grid.width(), device_grid.height(), device_ctx.grid.get_num_layers());
104-
105-
106-
for (int layer_num = 0; layer_num < num_layers; layer_num++) {
107-
for (int x = 0; x < (int)device_grid.width(); ++x) {
108-
for (int y = 0; y < (int)device_grid.height(); ++y) {
109-
const t_physical_tile_type_ptr type = device_ctx.grid.get_physical_type({x, y, layer_num});
110-
grid_blocks.initialized_grid_block_at_location({x, y, layer_num}, type->capacity);
111-
}
112-
}
113-
}
114-
115-
/* Go through each block */
116-
auto& cluster_ctx = g_vpr_ctx.clustering();
117-
for (ClusterBlockId blk_id : cluster_ctx.clb_nlist.blocks()) {
118-
const auto& blk_loc = block_locs[blk_id].loc;
119-
int blk_x = block_locs[blk_id].loc.x;
120-
int blk_y = block_locs[blk_id].loc.y;
121-
int blk_z = block_locs[blk_id].loc.sub_tile;
122-
int blk_layer = block_locs[blk_id].loc.layer;
123-
124-
auto type = physical_tile_type(blk_loc);
125-
126-
/* Check range of block coords */
127-
if (blk_x < 0 || blk_y < 0
128-
|| (blk_x + type->width - 1) > int(device_ctx.grid.width() - 1)
129-
|| (blk_y + type->height - 1) > int(device_ctx.grid.height() - 1)
130-
|| blk_z < 0 || blk_z > (type->capacity)) {
131-
VPR_FATAL_ERROR(VPR_ERROR_PLACE, "Block %zu is at invalid location (%d, %d, %d).\n",
132-
size_t(blk_id), blk_x, blk_y, blk_z);
133-
}
134-
135-
/* Check types match */
136-
if (type != device_ctx.grid.get_physical_type({blk_x, blk_y, blk_layer})) {
137-
VPR_FATAL_ERROR(VPR_ERROR_PLACE, "A block is in a grid location (%d x %d) layer (%d) with a conflicting types '%s' and '%s' .\n",
138-
blk_x, blk_y, blk_layer,
139-
type->name.c_str(),
140-
device_ctx.grid.get_physical_type({blk_x, blk_y, blk_layer})->name.c_str());
141-
}
142-
143-
/* Check already in use */
144-
if (grid_blocks.block_at_location(blk_loc)) {
145-
VPR_FATAL_ERROR(VPR_ERROR_PLACE, "Location (%d, %d, %d, %d) is used more than once.\n",
146-
blk_x, blk_y, blk_z, blk_layer);
147-
}
148-
149-
if (device_ctx.grid.get_width_offset({blk_x, blk_y, blk_layer}) != 0 || device_ctx.grid.get_height_offset({blk_x, blk_y, blk_layer}) != 0) {
150-
VPR_FATAL_ERROR(VPR_ERROR_PLACE, "Large block not aligned in placement for cluster_ctx.blocks %lu at (%d, %d, %d, %d).",
151-
size_t(blk_id), blk_x, blk_y, blk_z, blk_layer);
152-
}
153-
154-
/* Set the block */
155-
for (int width = 0; width < type->width; ++width) {
156-
for (int height = 0; height < type->height; ++height) {
157-
grid_blocks.set_block_at_location({blk_x + width, blk_y + height, blk_z, blk_layer}, blk_id);
158-
grid_blocks.increment_usage({blk_x + width, blk_y + height, blk_layer});
159-
160-
VTR_ASSERT(device_ctx.grid.get_width_offset({blk_x + width, blk_y + height, blk_layer}) == width);
161-
VTR_ASSERT(device_ctx.grid.get_height_offset({blk_x + width, blk_y + height, blk_layer}) == height);
162-
}
163-
}
164-
}
165-
}
166-
16791
std::string rr_node_arch_name(RRNodeId inode, bool is_flat) {
16892
auto& device_ctx = g_vpr_ctx.device();
16993
const auto& rr_graph = device_ctx.rr_graph;
@@ -2134,4 +2058,4 @@ int PortPinToBlockPinConverter::get_blk_pin_from_port_pin(int blk_type_index, in
21342058
// Return the port and port_pin for the pin.
21352059
int blk_pin = blk_pin_from_port_pin_[blk_type_index][sub_tile][port][port_pin];
21362060
return blk_pin;
2137-
}
2061+
}

vpr/src/util/vpr_utils.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -126,8 +126,6 @@ inline ParentNetId get_cluster_net_parent_id(const AtomLookup& atom_look_up, Clu
126126
return par_net_id;
127127
}
128128

129-
void sync_grid_to_blocks();
130-
131129
//Returns a user-friendly architectural identifier for the specified RR node
132130
std::string rr_node_arch_name(RRNodeId inode, bool is_flat);
133131

0 commit comments

Comments
 (0)