Skip to content

Deploy RRGraphBuilder in RRGraph Reader and Writer to replace the use of rr_node_indices #1800

New issue

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

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

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Jul 18, 2021
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
35 changes: 35 additions & 0 deletions vpr/src/device/rr_graph_builder.cpp
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#include "vtr_log.h"
#include "rr_graph_builder.h"

RRGraphBuilder::RRGraphBuilder(t_rr_graph_storage* node_storage,
Expand All @@ -13,3 +14,37 @@ t_rr_graph_storage& RRGraphBuilder::node_storage() {
RRSpatialLookup& RRGraphBuilder::node_lookup() {
return node_lookup_;
}

void RRGraphBuilder::add_node_to_all_locs(RRNodeId node) {
t_rr_type node_type = node_storage_.node_type(node);
short node_ptc_num = node_storage_.node_ptc_num(node);
for (int ix = node_storage_.node_xlow(node); ix <= node_storage_.node_xhigh(node); ix++) {
for (int iy = node_storage_.node_ylow(node); iy <= node_storage_.node_yhigh(node); iy++) {
switch (node_type) {
case SOURCE:
case SINK:
case CHANY:
node_lookup_.add_node(node, ix, iy, node_type, node_ptc_num, SIDES[0]);
break;
case CHANX:
/* Currently need to swap x and y for CHANX because of chan, seg convention
* TODO: Once the builders is reworked for use consistent (x, y) convention,
* the following swapping can be removed
*/
node_lookup_.add_node(node, iy, ix, node_type, node_ptc_num, SIDES[0]);
break;
case OPIN:
case IPIN:
for (const e_side& side : SIDES) {
if (node_storage_.is_node_on_specific_side(node, side)) {
node_lookup_.add_node(node, ix, iy, node_type, node_ptc_num, side);
}
}
break;
default:
VTR_LOG_ERROR("Invalid node type for node '%lu' in the routing resource graph file", size_t(node));
break;
}
}
}
}
9 changes: 9 additions & 0 deletions vpr/src/device/rr_graph_builder.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,15 @@ class RRGraphBuilder {
t_rr_graph_storage& node_storage();
/* Return a writable object for update the fast look-up of rr_node */
RRSpatialLookup& node_lookup();
/* Add an existing rr_node in the node storage to the node look-up
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this comment should also say that the node will be added to the lookup for every side it is on (for OPINs and IPINs) and for every (x,y) location at which it exists (for wires that span more than one (x,y).

* This function requires a valid node which has already been allocated in the node storage, with
* - a valid node id
* - valid geometry information: xlow/ylow/xhigh/yhigh
* - a valid node type
* - a valid node ptc number
* - a valid side (applicable to OPIN and IPIN nodes only
*/
void add_node_to_all_locs(RRNodeId node);

/* -- Internal data storage -- */
private:
Expand Down
2 changes: 1 addition & 1 deletion vpr/src/route/rr_graph_reader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,10 +59,10 @@ void load_rr_file(const t_graph_type graph_type,
read_edge_metadata,
&device_ctx.chan_width,
&device_ctx.rr_nodes,
&device_ctx.rr_graph_builder,
&device_ctx.rr_graph,
&device_ctx.rr_switch_inf,
&device_ctx.rr_indexed_data,
&device_ctx.rr_node_indices,
device_ctx.num_arch_switches,
device_ctx.arch_switch_inf,
device_ctx.rr_segments,
Expand Down
142 changes: 8 additions & 134 deletions vpr/src/route/rr_graph_uxsdcxx_serializer.h
Original file line number Diff line number Diff line change
Expand Up @@ -259,10 +259,10 @@ class RrGraphSerializer final : public uxsd::RrGraphBase<RrGraphContextTypes> {
bool read_edge_metadata,
t_chan_width* chan_width,
t_rr_graph_storage* rr_nodes,
RRGraphBuilder* rr_graph_builder,
RRGraphView* rr_graph,
std::vector<t_rr_switch_inf>* rr_switch_inf,
std::vector<t_rr_indexed_data>* rr_indexed_data,
t_rr_node_indices* rr_node_indices,
const size_t num_arch_switches,
const t_arch_switch_inf* arch_switch_inf,
const std::vector<t_segment_inf>& segment_inf,
Expand All @@ -274,10 +274,10 @@ class RrGraphSerializer final : public uxsd::RrGraphBase<RrGraphContextTypes> {
: wire_to_rr_ipin_switch_(wire_to_rr_ipin_switch)
, chan_width_(chan_width)
, rr_nodes_(rr_nodes)
, rr_graph_builder_(rr_graph_builder)
, rr_graph_(rr_graph)
, rr_switch_inf_(rr_switch_inf)
, rr_indexed_data_(rr_indexed_data)
, rr_node_indices_(rr_node_indices)
, read_rr_graph_filename_(read_rr_graph_filename)
, graph_type_(graph_type)
, base_cost_type_(base_cost_type)
Expand Down Expand Up @@ -1566,148 +1566,21 @@ class RrGraphSerializer final : public uxsd::RrGraphBase<RrGraphContextTypes> {
/*Allocates and load the rr_node look up table. SINK and SOURCE, IPIN and OPIN
*share the same look up table. CHANX and CHANY have individual look ups */
void process_rr_node_indices() {
const auto& rr_graph = (*rr_graph_);
/* Alloc the lookup table */
auto& indices = *rr_node_indices_;

typedef struct max_ptc {
short chanx_max_ptc = 0;
short chany_max_ptc = 0;
} t_max_ptc;

/*
* Local multi-dimensional vector to hold max_ptc for every coordinate.
* It has same height and width as CHANY and CHANX are inverted
*/
vtr::Matrix<t_max_ptc> coordinates_max_ptc; /* [x][y] */
size_t max_coord_size = std::max(grid_.width(), grid_.height());
coordinates_max_ptc.resize({max_coord_size, max_coord_size}, t_max_ptc());
auto& rr_graph_builder = (*rr_graph_builder_);

/* Alloc the lookup table */
for (t_rr_type rr_type : RR_TYPES) {
if (rr_type == CHANX) {
indices[rr_type].resize({grid_.height(), grid_.width(), NUM_SIDES});
rr_graph_builder.node_lookup().resize_nodes(grid_.height(), grid_.width(), rr_type, NUM_SIDES);
} else {
indices[rr_type].resize({grid_.width(), grid_.height(), NUM_SIDES});
rr_graph_builder.node_lookup().resize_nodes(grid_.width(), grid_.height(), rr_type, NUM_SIDES);
}
}

/*
* Add the correct node into the vector
* For CHANX and CHANY no node is added yet, but the maximum ptc is counted for each
* x/y location. This is needed later to add the correct node corresponding to CHANX
* and CHANY.
*
* Note that CHANX and CHANY 's x and y are swapped due to the chan and seg convention.
*/
/* Add the correct node into the vector */
for (size_t inode = 0; inode < rr_nodes_->size(); inode++) {
auto node = (*rr_nodes_)[inode];
if (rr_graph.node_type(node.id()) == SOURCE || rr_graph.node_type(node.id()) == SINK) {
for (int ix = node.xlow(); ix <= node.xhigh(); ix++) {
for (int iy = node.ylow(); iy <= node.yhigh(); iy++) {
if (node.ptc_num() >= (int)indices[SOURCE][ix][iy][0].size()) {
indices[SOURCE][ix][iy][0].resize(node.ptc_num() + 1, OPEN);
}
if (node.ptc_num() >= (int)indices[SINK][ix][iy][0].size()) {
indices[SINK][ix][iy][0].resize(node.ptc_num() + 1, OPEN);
}
indices[rr_graph.node_type(node.id())][ix][iy][0][node.ptc_num()] = inode;
}
}
} else if (rr_graph.node_type(node.id()) == IPIN || rr_graph.node_type(node.id()) == OPIN) {
for (int ix = node.xlow(); ix <= node.xhigh(); ix++) {
for (int iy = node.ylow(); iy <= node.yhigh(); iy++) {
for (const e_side& side : SIDES) {
if (!node.is_node_on_specific_side(side)) {
continue;
}
if (node.ptc_num() >= (int)indices[OPIN][ix][iy][side].size()) {
indices[OPIN][ix][iy][side].resize(node.ptc_num() + 1, OPEN);
}
if (node.ptc_num() >= (int)indices[IPIN][ix][iy][side].size()) {
indices[IPIN][ix][iy][side].resize(node.ptc_num() + 1, OPEN);
}
indices[rr_graph.node_type(node.id())][ix][iy][side][node.ptc_num()] = inode;
}
}
}
} else if (rr_graph.node_type(node.id()) == CHANX) {
for (int ix = node.xlow(); ix <= node.xhigh(); ix++) {
for (int iy = node.ylow(); iy <= node.yhigh(); iy++) {
coordinates_max_ptc[iy][ix].chanx_max_ptc = std::max(coordinates_max_ptc[iy][ix].chanx_max_ptc, node.ptc_num());
}
}
} else if (rr_graph.node_type(node.id()) == CHANY) {
for (int ix = node.xlow(); ix <= node.xhigh(); ix++) {
for (int iy = node.ylow(); iy <= node.yhigh(); iy++) {
coordinates_max_ptc[ix][iy].chany_max_ptc = std::max(coordinates_max_ptc[ix][iy].chany_max_ptc, node.ptc_num());
}
}
}
}

/* Alloc the lookup table */
for (t_rr_type rr_type : RR_TYPES) {
if (rr_type == CHANX) {
for (size_t y = 0; y < grid_.height(); ++y) {
for (size_t x = 0; x < grid_.width(); ++x) {
indices[CHANX][y][x][0].resize(coordinates_max_ptc[y][x].chanx_max_ptc + 1, OPEN);
}
}
} else if (rr_type == CHANY) {
for (size_t x = 0; x < grid_.width(); ++x) {
for (size_t y = 0; y < grid_.height(); ++y) {
indices[CHANY][x][y][0].resize(coordinates_max_ptc[x][y].chany_max_ptc + 1, OPEN);
}
}
}
}

int count;
/* CHANX and CHANY need to reevaluated with its ptc num as the correct index*/
for (size_t inode = 0; inode < rr_nodes_->size(); inode++) {
auto node = (*rr_nodes_)[inode];
if (rr_graph.node_type(node.id()) == CHANX) {
for (int iy = node.ylow(); iy <= node.yhigh(); iy++) {
for (int ix = node.xlow(); ix <= node.xhigh(); ix++) {
count = node.ptc_num();
if (count >= int(indices[CHANX][iy][ix][0].size())) {
report_error(
"Ptc index %d for CHANX (%d, %d) is out of bounds, size = %zu",
count, ix, iy, indices[CHANX][iy][ix][0].size());
}
indices[CHANX][iy][ix][0][count] = inode;
}
}
} else if (rr_graph.node_type(node.id()) == CHANY) {
for (int ix = node.xlow(); ix <= node.xhigh(); ix++) {
for (int iy = node.ylow(); iy <= node.yhigh(); iy++) {
count = node.ptc_num();
if (count >= int(indices[CHANY][ix][iy][0].size())) {
report_error(
"Ptc index %d for CHANY (%d, %d) is out of bounds, size = %zu",
count, ix, iy, indices[CHANY][ix][iy][0].size());
}
indices[CHANY][ix][iy][0][count] = inode;
}
}
}
}

//Copy the SOURCE/SINK nodes to all offset positions for blocks with width > 1 and/or height > 1
// This ensures that look-ups on non-root locations will still find the correct SOURCE/SINK
for (size_t x = 0; x < grid_.width(); x++) {
for (size_t y = 0; y < grid_.height(); y++) {
int width_offset = grid_[x][y].width_offset;
int height_offset = grid_[x][y].height_offset;
if (width_offset != 0 || height_offset != 0) {
int root_x = x - width_offset;
int root_y = y - height_offset;

indices[SOURCE][x][y][0] = indices[SOURCE][root_x][root_y][0];
indices[SINK][x][y][0] = indices[SINK][root_x][root_y][0];
}
}
rr_graph_builder.add_node_to_all_locs(node.id());
}
}

Expand Down Expand Up @@ -1976,6 +1849,7 @@ class RrGraphSerializer final : public uxsd::RrGraphBase<RrGraphContextTypes> {
int* wire_to_rr_ipin_switch_;
t_chan_width* chan_width_;
t_rr_graph_storage* rr_nodes_;
RRGraphBuilder* rr_graph_builder_;
RRGraphView* rr_graph_;
std::vector<t_rr_switch_inf>* rr_switch_inf_;
std::vector<t_rr_indexed_data>* rr_indexed_data_;
Expand Down
2 changes: 1 addition & 1 deletion vpr/src/route/rr_graph_writer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,10 @@ void write_rr_graph(const char* file_name) {
/*read_edge_metadata=*/false,
&device_ctx.chan_width,
&device_ctx.rr_nodes,
&device_ctx.rr_graph_builder,
&device_ctx.rr_graph,
&device_ctx.rr_switch_inf,
&device_ctx.rr_indexed_data,
&device_ctx.rr_node_indices,
device_ctx.num_arch_switches,
device_ctx.arch_switch_inf,
device_ctx.rr_segments,
Expand Down