Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Placement] Resolved Inconsistency with Placing at Root Tile Locs #2802

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 13 additions & 4 deletions vpr/src/base/vpr_api.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include <cmath>

#include "cluster_util.h"
#include "verify_placement.h"
#include "vpr_context.h"
#include "vtr_assert.h"
#include "vtr_math.h"
Expand Down Expand Up @@ -801,10 +802,6 @@ bool vpr_place_flow(const Netlist<>& net_list, t_vpr_setup& vpr_setup, const t_a
vpr_load_placement(vpr_setup, arch);
}

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

Expand Down Expand Up @@ -877,6 +874,18 @@ void vpr_load_placement(t_vpr_setup& vpr_setup, const t_arch& arch) {
place_ctx.placement_id = read_place(filename_opts.NetFile.c_str(), filename_opts.PlaceFile.c_str(),
blk_loc_registry,
filename_opts.verify_file_digests, device_ctx.grid);

// Verify that the placement invariants are met after reading the placement
// from a file.
unsigned num_errors = verify_placement(g_vpr_ctx);
if (num_errors == 0) {
VTR_LOG("Completed placement consistency check successfully.\n");
} else {
VPR_ERROR(VPR_ERROR_PLACE,
"Completed placement consistency check, %d errors found.\n"
"Aborting program.\n",
num_errors);
}
}

RouteStatus vpr_route_flow(const Netlist<>& net_list,
Expand Down
39 changes: 14 additions & 25 deletions vpr/src/pack/sync_netlists_to_routing_flat.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,19 +70,24 @@ inline ClusterBlockId get_cluster_block_from_rr_node(RRNodeId inode){
auto& place_ctx = g_vpr_ctx.placement();
auto& rr_graph = device_ctx.rr_graph;

auto physical_tile = device_ctx.grid.get_physical_type({
rr_graph.node_xlow(inode),
rr_graph.node_ylow(inode),
rr_graph.node_layer(inode)
});
t_physical_tile_loc node_phy_tile_loc(rr_graph.node_xlow(inode),
rr_graph.node_ylow(inode),
rr_graph.node_layer(inode));
auto physical_tile = device_ctx.grid.get_physical_type(node_phy_tile_loc);

int source_pin = rr_graph.node_pin_num(inode);

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

// The placer will only place Clusters at the root tile location. Need to
// offset to the root tile location to get the cluster block at this
// tile.
int width_offset = device_ctx.grid.get_width_offset(node_phy_tile_loc);
int height_offset = device_ctx.grid.get_height_offset(node_phy_tile_loc);

ClusterBlockId clb = place_ctx.grid_blocks().block_at_location({
rr_graph.node_xlow(inode),
rr_graph.node_ylow(inode),
rr_graph.node_xlow(inode) - width_offset,
rr_graph.node_ylow(inode) - height_offset,
subtile,
rr_graph.node_layer(inode)
});
Expand Down Expand Up @@ -185,7 +190,6 @@ static void sync_pb_routes_to_routing(void){
auto& device_ctx = g_vpr_ctx.device();
auto& atom_ctx = g_vpr_ctx.atom();
auto& cluster_ctx = g_vpr_ctx.mutable_clustering();
auto& place_ctx = g_vpr_ctx.placement();
auto& route_ctx = g_vpr_ctx.routing();
auto& rr_graph = device_ctx.rr_graph;

Expand Down Expand Up @@ -220,6 +224,7 @@ static void sync_pb_routes_to_routing(void){

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

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

ClusterBlockId clb = place_ctx.grid_blocks().block_at_location({
rr_graph.node_xlow(source_inode),
rr_graph.node_ylow(source_inode),
subtile,
rr_graph.node_layer(source_inode)
});

/* Look up pb graph pins from pb type if pin is not on tile, look up from block otherwise */
const t_pb_graph_pin* source_pb_graph_pin, *sink_pb_graph_pin;
if(is_pin_on_tile(physical_tile, sink_pin)){
Expand Down Expand Up @@ -361,14 +357,7 @@ static void sync_clustered_netlist_to_routing(void){

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

auto [_, subtile] = get_sub_tile_from_pin_physical_num(physical_tile, pin_index);

ClusterBlockId clb = place_ctx.grid_blocks().block_at_location({
rr_graph.node_xlow(rt_node.inode),
rr_graph.node_ylow(rt_node.inode),
subtile,
rr_graph.node_layer(rt_node.inode)
});
ClusterBlockId clb = get_cluster_block_from_rr_node(rt_node.inode);

if(!is_pin_on_tile(physical_tile, pin_index))
continue;
Expand Down
30 changes: 30 additions & 0 deletions vpr/src/place/verify_placement.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
* - The grid blocks matches the block locations.
* - Blocks are not in invalid grid locations.
* - All clusters are placed.
* - Clusters are only placed at the root tile location of large tiles.
*
* @param blk_loc_registry A registry containing the block locations and
* the blocks at each grid location.
Expand All @@ -57,6 +58,35 @@ static unsigned check_block_placement_consistency(const BlkLocRegistry& blk_loc_
for (int j = 0; j < (int)device_grid.height(); j++) {
const t_physical_tile_loc tile_loc(i, j, layer_num);
const auto& type = device_grid.get_physical_type(tile_loc);

// If this is not a root tile block, ensure that its usage is 0
// and that it has no valid clusters placed at this location.
// TODO: Eventually it should be made impossible to place blocks
// at these locations.
if (device_grid.get_width_offset(tile_loc) != 0 ||
device_grid.get_height_offset(tile_loc) != 0) {
// Usage must be 0
if (grid_blocks.get_usage(tile_loc) != 0) {
VTR_LOG_ERROR(
"%d blocks were placed at non-root tile location "
"(%d, %d, %d), but no blocks should be placed here.\n",
grid_blocks.get_usage(tile_loc), i, j, layer_num);
num_errors++;
}
// Check that all clusters at this tile location are invalid.
for (int k = 0; k < type->capacity; k++) {
ClusterBlockId bnum = grid_blocks.block_at_location({i, j, k, layer_num});
if (bnum.is_valid()) {
VTR_LOG_ERROR(
"Block %zu was placed at non-root tile location "
"(%d, %d, %d), but no blocks should be placed "
"here.\n",
size_t(bnum), i, j, layer_num);
num_errors++;
}
}
}

if (grid_blocks.get_usage(tile_loc) > type->capacity) {
VTR_LOG_ERROR(
"%d blocks were placed at grid location (%d,%d,%d), but location capacity is %d.\n",
Expand Down
78 changes: 1 addition & 77 deletions vpr/src/util/vpr_utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -88,82 +88,6 @@ void print_tabs(FILE* fpout, int num_tab) {
}
}

/* Points the place_ctx.grid_blocks structure back to the blocks list */
void sync_grid_to_blocks() {
auto& place_ctx = g_vpr_ctx.mutable_placement();
auto& device_ctx = g_vpr_ctx.device();
auto& device_grid = device_ctx.grid;

const int num_layers = device_ctx.grid.get_num_layers();

auto& grid_blocks = place_ctx.mutable_grid_blocks();
auto& block_locs = place_ctx.block_locs();

/* Reset usage and allocate blocks list if needed */
grid_blocks = GridBlock(device_grid.width(), device_grid.height(), device_ctx.grid.get_num_layers());


for (int layer_num = 0; layer_num < num_layers; layer_num++) {
for (int x = 0; x < (int)device_grid.width(); ++x) {
for (int y = 0; y < (int)device_grid.height(); ++y) {
const t_physical_tile_type_ptr type = device_ctx.grid.get_physical_type({x, y, layer_num});
grid_blocks.initialized_grid_block_at_location({x, y, layer_num}, type->capacity);
}
}
}

/* Go through each block */
auto& cluster_ctx = g_vpr_ctx.clustering();
for (ClusterBlockId blk_id : cluster_ctx.clb_nlist.blocks()) {
const auto& blk_loc = block_locs[blk_id].loc;
int blk_x = block_locs[blk_id].loc.x;
int blk_y = block_locs[blk_id].loc.y;
int blk_z = block_locs[blk_id].loc.sub_tile;
int blk_layer = block_locs[blk_id].loc.layer;

auto type = physical_tile_type(blk_loc);

/* Check range of block coords */
if (blk_x < 0 || blk_y < 0
|| (blk_x + type->width - 1) > int(device_ctx.grid.width() - 1)
|| (blk_y + type->height - 1) > int(device_ctx.grid.height() - 1)
|| blk_z < 0 || blk_z > (type->capacity)) {
VPR_FATAL_ERROR(VPR_ERROR_PLACE, "Block %zu is at invalid location (%d, %d, %d).\n",
size_t(blk_id), blk_x, blk_y, blk_z);
}

/* Check types match */
if (type != device_ctx.grid.get_physical_type({blk_x, blk_y, blk_layer})) {
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",
blk_x, blk_y, blk_layer,
type->name.c_str(),
device_ctx.grid.get_physical_type({blk_x, blk_y, blk_layer})->name.c_str());
}

/* Check already in use */
if (grid_blocks.block_at_location(blk_loc)) {
VPR_FATAL_ERROR(VPR_ERROR_PLACE, "Location (%d, %d, %d, %d) is used more than once.\n",
blk_x, blk_y, blk_z, blk_layer);
}

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) {
VPR_FATAL_ERROR(VPR_ERROR_PLACE, "Large block not aligned in placement for cluster_ctx.blocks %lu at (%d, %d, %d, %d).",
size_t(blk_id), blk_x, blk_y, blk_z, blk_layer);
}

/* Set the block */
for (int width = 0; width < type->width; ++width) {
for (int height = 0; height < type->height; ++height) {
grid_blocks.set_block_at_location({blk_x + width, blk_y + height, blk_z, blk_layer}, blk_id);
grid_blocks.increment_usage({blk_x + width, blk_y + height, blk_layer});

VTR_ASSERT(device_ctx.grid.get_width_offset({blk_x + width, blk_y + height, blk_layer}) == width);
VTR_ASSERT(device_ctx.grid.get_height_offset({blk_x + width, blk_y + height, blk_layer}) == height);
}
}
}
}

std::string rr_node_arch_name(RRNodeId inode, bool is_flat) {
auto& device_ctx = g_vpr_ctx.device();
const auto& rr_graph = device_ctx.rr_graph;
Expand Down Expand Up @@ -2134,4 +2058,4 @@ int PortPinToBlockPinConverter::get_blk_pin_from_port_pin(int blk_type_index, in
// Return the port and port_pin for the pin.
int blk_pin = blk_pin_from_port_pin_[blk_type_index][sub_tile][port][port_pin];
return blk_pin;
}
}
2 changes: 0 additions & 2 deletions vpr/src/util/vpr_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -126,8 +126,6 @@ inline ParentNetId get_cluster_net_parent_id(const AtomLookup& atom_look_up, Clu
return par_net_id;
}

void sync_grid_to_blocks();

//Returns a user-friendly architectural identifier for the specified RR node
std::string rr_node_arch_name(RRNodeId inode, bool is_flat);

Expand Down