From 649e215082a92c1468f2a634eae290ed63b98f7d Mon Sep 17 00:00:00 2001 From: tangxifan Date: Wed, 14 Jul 2021 11:19:11 -0600 Subject: [PATCH 1/5] [VPR] Update rr_graph reader and writer functions to remove the use of rr_node_indices and deploy RRSpatialLookup API --- vpr/src/route/rr_graph_reader.cpp | 2 +- vpr/src/route/rr_graph_uxsdcxx_serializer.h | 147 +++++--------------- vpr/src/route/rr_graph_writer.cpp | 2 +- 3 files changed, 36 insertions(+), 115 deletions(-) diff --git a/vpr/src/route/rr_graph_reader.cpp b/vpr/src/route/rr_graph_reader.cpp index 82d29dbbffb..8f37d52c3d5 100644 --- a/vpr/src/route/rr_graph_reader.cpp +++ b/vpr/src/route/rr_graph_reader.cpp @@ -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, diff --git a/vpr/src/route/rr_graph_uxsdcxx_serializer.h b/vpr/src/route/rr_graph_uxsdcxx_serializer.h index 1428ca1d317..6e0e9e3ce8c 100644 --- a/vpr/src/route/rr_graph_uxsdcxx_serializer.h +++ b/vpr/src/route/rr_graph_uxsdcxx_serializer.h @@ -259,10 +259,10 @@ class RrGraphSerializer final : public uxsd::RrGraphBase { bool read_edge_metadata, t_chan_width* chan_width, t_rr_graph_storage* rr_nodes, + RRGraphBuilder* rr_graph_builder, RRGraphView* rr_graph, std::vector* rr_switch_inf, std::vector* 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& segment_inf, @@ -274,10 +274,10 @@ class RrGraphSerializer final : public uxsd::RrGraphBase { : 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) @@ -1567,133 +1567,47 @@ class RrGraphSerializer final : public uxsd::RrGraphBase { *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 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 (int ix = node.xlow(); ix <= node.xhigh(); ix++) { + for (int iy = node.ylow(); iy <= node.yhigh(); iy++) { + switch (rr_graph.node_type(node.id())) { + case SOURCE: + case SINK: + case CHANX: + case CHANY: + rr_graph_builder.node_lookup().add_node(node.id(), ix, iy, rr_graph.node_type(node.id()), node.ptc_num(), SIDES[0]); + break; + case OPIN: + case IPIN: 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.is_node_on_specific_side(side)) { + rr_graph_builder.node_lookup().add_node(node.id(), ix, iy, rr_graph.node_type(node.id()), node.ptc_num(), side); } - 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; + break; + default: + report_error("Invalid node type for node '%lu' in the routing resource graph file", size_t(node.id())); + break; } } } } + // Xifan: The following codes may be redundant! The coordinates (xlow/ylow/xhigh/yhigh) are already + // bounded to the grid bounding box if the rr_graph file follows the standards! //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++) { @@ -1704,8 +1618,14 @@ class RrGraphSerializer final : public uxsd::RrGraphBase { 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.node_lookup().mirror_nodes(vtr::Point(root_x, root_y), + vtr::Point(x, y), + SOURCE, + SIDES[0]); + rr_graph_builder.node_lookup().mirror_nodes(vtr::Point(root_x, root_y), + vtr::Point(x, y), + SINK, + SIDES[0]); } } } @@ -1976,6 +1896,7 @@ class RrGraphSerializer final : public uxsd::RrGraphBase { 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* rr_switch_inf_; std::vector* rr_indexed_data_; diff --git a/vpr/src/route/rr_graph_writer.cpp b/vpr/src/route/rr_graph_writer.cpp index a37f052299e..1450157ad16 100644 --- a/vpr/src/route/rr_graph_writer.cpp +++ b/vpr/src/route/rr_graph_writer.cpp @@ -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, From f2de5e9070278c1be36e9f0b66b825d4e3ab7e83 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Wed, 14 Jul 2021 11:41:50 -0600 Subject: [PATCH 2/5] [VPR] Fix CHANX (x,y) convention and apply code format fix --- vpr/src/route/rr_graph_uxsdcxx_serializer.h | 40 ++++++++++++--------- 1 file changed, 23 insertions(+), 17 deletions(-) diff --git a/vpr/src/route/rr_graph_uxsdcxx_serializer.h b/vpr/src/route/rr_graph_uxsdcxx_serializer.h index 6e0e9e3ce8c..867323c53e5 100644 --- a/vpr/src/route/rr_graph_uxsdcxx_serializer.h +++ b/vpr/src/route/rr_graph_uxsdcxx_serializer.h @@ -1584,29 +1584,35 @@ class RrGraphSerializer final : public uxsd::RrGraphBase { for (int ix = node.xlow(); ix <= node.xhigh(); ix++) { for (int iy = node.ylow(); iy <= node.yhigh(); iy++) { switch (rr_graph.node_type(node.id())) { - case SOURCE: - case SINK: - case CHANX: - case CHANY: - rr_graph_builder.node_lookup().add_node(node.id(), ix, iy, rr_graph.node_type(node.id()), node.ptc_num(), SIDES[0]); - break; - case OPIN: - case IPIN: - for (const e_side& side : SIDES) { - if (node.is_node_on_specific_side(side)) { - rr_graph_builder.node_lookup().add_node(node.id(), ix, iy, rr_graph.node_type(node.id()), node.ptc_num(), side); + case SOURCE: + case SINK: + 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 + */ + rr_graph_builder.node_lookup().add_node(node.id(), iy, ix, rr_graph.node_type(node.id()), node.ptc_num(), SIDES[0]); + break; + case CHANY: + rr_graph_builder.node_lookup().add_node(node.id(), ix, iy, rr_graph.node_type(node.id()), node.ptc_num(), SIDES[0]); + break; + case OPIN: + case IPIN: + for (const e_side& side : SIDES) { + if (node.is_node_on_specific_side(side)) { + rr_graph_builder.node_lookup().add_node(node.id(), ix, iy, rr_graph.node_type(node.id()), node.ptc_num(), side); + } } - } - break; - default: - report_error("Invalid node type for node '%lu' in the routing resource graph file", size_t(node.id())); - break; + break; + default: + report_error("Invalid node type for node '%lu' in the routing resource graph file", size_t(node.id())); + break; } } } } - // Xifan: The following codes may be redundant! The coordinates (xlow/ylow/xhigh/yhigh) are already + // Xifan: The following codes may be redundant! The coordinates (xlow/ylow/xhigh/yhigh) are already // bounded to the grid bounding box if the rr_graph file follows the standards! //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 From 840f27693060ea45bd1ae0e84c15d0a1892d68b3 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Wed, 14 Jul 2021 11:51:52 -0600 Subject: [PATCH 3/5] [VPR] Fixed the bug in rr_graph reader due to misuse the new API --- vpr/src/route/rr_graph_uxsdcxx_serializer.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/vpr/src/route/rr_graph_uxsdcxx_serializer.h b/vpr/src/route/rr_graph_uxsdcxx_serializer.h index 867323c53e5..f0fcbb681b7 100644 --- a/vpr/src/route/rr_graph_uxsdcxx_serializer.h +++ b/vpr/src/route/rr_graph_uxsdcxx_serializer.h @@ -1586,6 +1586,9 @@ class RrGraphSerializer final : public uxsd::RrGraphBase { switch (rr_graph.node_type(node.id())) { case SOURCE: case SINK: + case CHANY: + rr_graph_builder.node_lookup().add_node(node.id(), ix, iy, rr_graph.node_type(node.id()), 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, @@ -1593,9 +1596,6 @@ class RrGraphSerializer final : public uxsd::RrGraphBase { */ rr_graph_builder.node_lookup().add_node(node.id(), iy, ix, rr_graph.node_type(node.id()), node.ptc_num(), SIDES[0]); break; - case CHANY: - rr_graph_builder.node_lookup().add_node(node.id(), ix, iy, rr_graph.node_type(node.id()), node.ptc_num(), SIDES[0]); - break; case OPIN: case IPIN: for (const e_side& side : SIDES) { From b661ceb4d4f282d80acf750b318c35cdddb2c8f2 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Wed, 14 Jul 2021 12:16:55 -0600 Subject: [PATCH 4/5] [VPR] Remove redundant codes in RRGraph reader --- vpr/src/route/rr_graph_uxsdcxx_serializer.h | 24 --------------------- 1 file changed, 24 deletions(-) diff --git a/vpr/src/route/rr_graph_uxsdcxx_serializer.h b/vpr/src/route/rr_graph_uxsdcxx_serializer.h index f0fcbb681b7..2d3781eb359 100644 --- a/vpr/src/route/rr_graph_uxsdcxx_serializer.h +++ b/vpr/src/route/rr_graph_uxsdcxx_serializer.h @@ -1611,30 +1611,6 @@ class RrGraphSerializer final : public uxsd::RrGraphBase { } } } - - // Xifan: The following codes may be redundant! The coordinates (xlow/ylow/xhigh/yhigh) are already - // bounded to the grid bounding box if the rr_graph file follows the standards! - //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; - - rr_graph_builder.node_lookup().mirror_nodes(vtr::Point(root_x, root_y), - vtr::Point(x, y), - SOURCE, - SIDES[0]); - rr_graph_builder.node_lookup().mirror_nodes(vtr::Point(root_x, root_y), - vtr::Point(x, y), - SINK, - SIDES[0]); - } - } - } } // Enum converters from/to uxsd types From 0845c14da86fb2e6b101e1e661881381621e34f6 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Sat, 17 Jul 2021 15:45:30 -0600 Subject: [PATCH 5/5] [VPR] Added a new API ``add_node_to_all_locs`` to RRGraphBuilder --- vpr/src/device/rr_graph_builder.cpp | 35 +++++++++++++++++++++ vpr/src/device/rr_graph_builder.h | 9 ++++++ vpr/src/route/rr_graph_uxsdcxx_serializer.h | 31 +----------------- 3 files changed, 45 insertions(+), 30 deletions(-) diff --git a/vpr/src/device/rr_graph_builder.cpp b/vpr/src/device/rr_graph_builder.cpp index 6279177570f..f663e6f7551 100644 --- a/vpr/src/device/rr_graph_builder.cpp +++ b/vpr/src/device/rr_graph_builder.cpp @@ -1,3 +1,4 @@ +#include "vtr_log.h" #include "rr_graph_builder.h" RRGraphBuilder::RRGraphBuilder(t_rr_graph_storage* node_storage, @@ -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; + } + } + } +} diff --git a/vpr/src/device/rr_graph_builder.h b/vpr/src/device/rr_graph_builder.h index 594beef45df..9020fa5bf1c 100644 --- a/vpr/src/device/rr_graph_builder.h +++ b/vpr/src/device/rr_graph_builder.h @@ -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 + * 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: diff --git a/vpr/src/route/rr_graph_uxsdcxx_serializer.h b/vpr/src/route/rr_graph_uxsdcxx_serializer.h index 2d3781eb359..313efcd20a7 100644 --- a/vpr/src/route/rr_graph_uxsdcxx_serializer.h +++ b/vpr/src/route/rr_graph_uxsdcxx_serializer.h @@ -1566,7 +1566,6 @@ class RrGraphSerializer final : public uxsd::RrGraphBase { /*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_); auto& rr_graph_builder = (*rr_graph_builder_); /* Alloc the lookup table */ @@ -1581,35 +1580,7 @@ class RrGraphSerializer final : public uxsd::RrGraphBase { /* Add the correct node into the vector */ for (size_t inode = 0; inode < rr_nodes_->size(); inode++) { auto node = (*rr_nodes_)[inode]; - for (int ix = node.xlow(); ix <= node.xhigh(); ix++) { - for (int iy = node.ylow(); iy <= node.yhigh(); iy++) { - switch (rr_graph.node_type(node.id())) { - case SOURCE: - case SINK: - case CHANY: - rr_graph_builder.node_lookup().add_node(node.id(), ix, iy, rr_graph.node_type(node.id()), 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 - */ - rr_graph_builder.node_lookup().add_node(node.id(), iy, ix, rr_graph.node_type(node.id()), node.ptc_num(), SIDES[0]); - break; - case OPIN: - case IPIN: - for (const e_side& side : SIDES) { - if (node.is_node_on_specific_side(side)) { - rr_graph_builder.node_lookup().add_node(node.id(), ix, iy, rr_graph.node_type(node.id()), node.ptc_num(), side); - } - } - break; - default: - report_error("Invalid node type for node '%lu' in the routing resource graph file", size_t(node.id())); - break; - } - } - } + rr_graph_builder.add_node_to_all_locs(node.id()); } }