From 6a2eb50264e8c36b846dec1064fc00667eb0d95d Mon Sep 17 00:00:00 2001 From: tangxifan Date: Wed, 24 Mar 2021 13:58:45 -0600 Subject: [PATCH 01/22] [VPR] Add an overlay RRGraph object; Different from t_rr_graph_view, this overlay aims to provide full featured RRGraph APIs. --- vpr/src/base/vpr_context.h | 2 + vpr/src/route/rr_graph_overlay.cpp | 22 +++++++++++ vpr/src/route/rr_graph_overlay.h | 63 ++++++++++++++++++++++++++++++ 3 files changed, 87 insertions(+) create mode 100644 vpr/src/route/rr_graph_overlay.cpp create mode 100644 vpr/src/route/rr_graph_overlay.h diff --git a/vpr/src/base/vpr_context.h b/vpr/src/base/vpr_context.h index 8128b6244a3..c84d6a7704c 100644 --- a/vpr/src/base/vpr_context.h +++ b/vpr/src/base/vpr_context.h @@ -9,6 +9,7 @@ #include "vtr_vector.h" #include "atom_netlist.h" #include "clustered_netlist.h" +#include "rr_graph_overlay.h" #include "rr_graph_storage.h" #include "rr_node.h" #include "rr_rc_data.h" @@ -145,6 +146,7 @@ struct DeviceContext : public Context { /* * Structures to define the routing architecture of the FPGA. */ + RRGraphOverlay rr_graph; // Currently an overlay of routing resource graph but in future will become an object grouping rr_nodes, rr_node_indices etc. t_rr_graph_storage rr_nodes; // autogenerated in build_rr_graph diff --git a/vpr/src/route/rr_graph_overlay.cpp b/vpr/src/route/rr_graph_overlay.cpp new file mode 100644 index 00000000000..d5de57eeb74 --- /dev/null +++ b/vpr/src/route/rr_graph_overlay.cpp @@ -0,0 +1,22 @@ +#include "rr_graph_overlay.h" + +/**************************** + * Constructors + ****************************/ +RRGraphOverlay::RRGraphOverlay() { + node_storage_ = nullptr; + rr_node_indices_ = nullptr; +} + +RRGraphOverlay::RRGraphOverlay(t_rr_graph_storage* node_storage, + t_rr_node_indices* rr_node_indices) { + node_storage_ = node_storage; + rr_node_indices_ = rr_node_indices; +} + +/**************************** + * Accessors + ****************************/ +t_rr_type RRGraphOverlay::node_type(const RRNodeId& id) const { + return (*node_storage_).node_type(id); +} diff --git a/vpr/src/route/rr_graph_overlay.h b/vpr/src/route/rr_graph_overlay.h new file mode 100644 index 00000000000..fe5295e0af1 --- /dev/null +++ b/vpr/src/route/rr_graph_overlay.h @@ -0,0 +1,63 @@ +#ifndef _RR_GRAPH_OVERLAY_ +#define _RR_GRAPH_OVERLAY_ + +#include + +#include "rr_graph_fwd.h" +#include "rr_node_fwd.h" +#include "rr_graph2.h" +#include "vtr_log.h" +#include "vtr_memory.h" +#include "vpr_utils.h" +#include "vtr_strong_id_range.h" +#include "vtr_array_view.h" +#include "rr_graph_storage.h" + +/* An overlay of routing resource graph + * which is an unified object including pointors to + * - node storage + * - edge_storage + * - node_ptc_storage + * - node_fan_in_storage + * - rr_node_indices + * + * Note that the overlay does not own the storage + * It serves a virtual protocol for + * - rr_graph builder + * - placer + * - router + * - timing analyzer + * - GUI + * + * Note that each client of rr_graph may get a frame view of the object + * - This helps to reduce the memory footprint for each client + * - This avoids massive changes for each client on using the APIs + * as each frame view provides adhoc APIs for each client + * + */ +class RRGraphOverlay { + /**************** + * Constructors + ****************/ + public: + RRGraphOverlay(); + RRGraphOverlay(t_rr_graph_storage* node_storage, + t_rr_node_indices* rr_node_indices); + + /**************** + * Node methods * + ****************/ + public: + t_rr_type node_type(const RRNodeId& id) const; + + /**************** + * internal data + ****************/ + private: + /* node-level storage including edge storages */ + t_rr_graph_storage* node_storage_; + /* Fast look-up */ + t_rr_node_indices* rr_node_indices_; +}; + +#endif From cb55accabf25598ab33d3db9b093c5b718fc673c Mon Sep 17 00:00:00 2001 From: tangxifan Date: Wed, 24 Mar 2021 14:16:07 -0600 Subject: [PATCH 02/22] [VPR] Update rr_graph overlay to enable its deployment in DeviceContext --- vpr/src/route/rr_graph.cpp | 5 +++++ vpr/src/route/rr_graph_overlay.cpp | 15 +++++++++------ vpr/src/route/rr_graph_overlay.h | 11 ++++++++--- 3 files changed, 22 insertions(+), 9 deletions(-) diff --git a/vpr/src/route/rr_graph.cpp b/vpr/src/route/rr_graph.cpp index b98103cf2c0..be34d6a9f69 100644 --- a/vpr/src/route/rr_graph.cpp +++ b/vpr/src/route/rr_graph.cpp @@ -369,6 +369,11 @@ void create_rr_graph(const t_graph_type graph_type, verify_rr_node_indices(grid, device_ctx.rr_node_indices, device_ctx.rr_nodes); + /* Update RRGraph overlay with new data pointers */ + DeviceContext& mutable_device_ctx = g_vpr_ctx.mutable_device(); + mutable_device_ctx.rr_graph.set_internal_data(&(mutable_device_ctx.rr_nodes), + &(mutable_device_ctx.rr_node_indices)); + print_rr_graph_stats(); //Write out rr graph file if needed diff --git a/vpr/src/route/rr_graph_overlay.cpp b/vpr/src/route/rr_graph_overlay.cpp index d5de57eeb74..db56aaa8fa3 100644 --- a/vpr/src/route/rr_graph_overlay.cpp +++ b/vpr/src/route/rr_graph_overlay.cpp @@ -8,15 +8,18 @@ RRGraphOverlay::RRGraphOverlay() { rr_node_indices_ = nullptr; } -RRGraphOverlay::RRGraphOverlay(t_rr_graph_storage* node_storage, - t_rr_node_indices* rr_node_indices) { - node_storage_ = node_storage; - rr_node_indices_ = rr_node_indices; -} - /**************************** * Accessors ****************************/ t_rr_type RRGraphOverlay::node_type(const RRNodeId& id) const { return (*node_storage_).node_type(id); } + +/**************************** + * Mutators + ****************************/ +void RRGraphOverlay::set_internal_data(t_rr_graph_storage* node_storage, + t_rr_node_indices* rr_node_indices) { + node_storage_ = node_storage; + rr_node_indices_ = rr_node_indices; +} diff --git a/vpr/src/route/rr_graph_overlay.h b/vpr/src/route/rr_graph_overlay.h index fe5295e0af1..e85a6b8d91b 100644 --- a/vpr/src/route/rr_graph_overlay.h +++ b/vpr/src/route/rr_graph_overlay.h @@ -41,15 +41,20 @@ class RRGraphOverlay { ****************/ public: RRGraphOverlay(); - RRGraphOverlay(t_rr_graph_storage* node_storage, - t_rr_node_indices* rr_node_indices); /**************** - * Node methods * + * Accessors ****************/ public: t_rr_type node_type(const RRNodeId& id) const; + /**************** + * Mutators + ****************/ + public: + void set_internal_data(t_rr_graph_storage* node_storage, + t_rr_node_indices* rr_node_indices); + /**************** * internal data ****************/ From 584f7fc01172817dcb6682451d6464f2782d03b2 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Wed, 24 Mar 2021 14:52:24 -0600 Subject: [PATCH 03/22] [VPR] Replace node type() API with overlay API in check_rr_graph.cpp --- vpr/src/route/check_rr_graph.cpp | 12 ++++++++---- vpr/src/route/rr_graph.cpp | 9 ++++----- vpr/src/route/rr_graph_overlay.cpp | 2 +- 3 files changed, 13 insertions(+), 10 deletions(-) diff --git a/vpr/src/route/check_rr_graph.cpp b/vpr/src/route/check_rr_graph.cpp index 1d19867fad0..6d4fa708d22 100644 --- a/vpr/src/route/check_rr_graph.cpp +++ b/vpr/src/route/check_rr_graph.cpp @@ -205,7 +205,7 @@ void check_rr_graph(const t_graph_type graph_type, bool is_fringe_warning_sent = false; for (size_t inode = 0; inode < device_ctx.rr_nodes.size(); inode++) { - t_rr_type rr_type = device_ctx.rr_nodes[inode].type(); + t_rr_type rr_type = device_ctx.rr_graph.node_type(RRNodeId(inode)); if (rr_type != SOURCE) { if (total_edges_to_node[inode] < 1 && !rr_node_is_global_clb_ipin(inode)) { @@ -224,16 +224,17 @@ void check_rr_graph(const t_graph_type graph_type, } const auto& node = device_ctx.rr_nodes[inode]; + const auto& rr_graph = device_ctx.rr_graph; bool is_fringe = ((device_ctx.rr_nodes[inode].xlow() == 1) || (device_ctx.rr_nodes[inode].ylow() == 1) || (device_ctx.rr_nodes[inode].xhigh() == int(grid.width()) - 2) || (device_ctx.rr_nodes[inode].yhigh() == int(grid.height()) - 2)); - bool is_wire = (device_ctx.rr_nodes[inode].type() == CHANX - || device_ctx.rr_nodes[inode].type() == CHANY); + bool is_wire = (rr_graph.node_type(RRNodeId(inode)) == CHANX + || rr_graph.node_type(RRNodeId(inode)) == CHANY); if (!is_chain && !is_fringe && !is_wire) { - if (node.type() == IPIN || node.type() == OPIN) { + if (rr_graph.node_type(RRNodeId(inode)) == IPIN || rr_graph.node_type(RRNodeId(inode)) == OPIN) { if (has_adjacent_channel(node, device_ctx.grid)) { auto block_type = device_ctx.grid[node.xlow()][node.ylow()].type; std::string pin_name = block_type_pin_index_to_name(block_type, node.pin_num()); @@ -573,6 +574,9 @@ static void check_unbuffered_edges(int from_node) { } static bool has_adjacent_channel(const t_rr_node& node, const DeviceGrid& grid) { + /* TODO: this function should be reworked later to adapt overlay interface + * once xlow(), ylow(), side() APIs are implemented in overlay interface + */ VTR_ASSERT(node.type() == IPIN || node.type() == OPIN); if ((node.xlow() == 0 && node.side() != RIGHT) //left device edge connects only along block's right side diff --git a/vpr/src/route/rr_graph.cpp b/vpr/src/route/rr_graph.cpp index be34d6a9f69..87f5b2e3295 100644 --- a/vpr/src/route/rr_graph.cpp +++ b/vpr/src/route/rr_graph.cpp @@ -369,11 +369,6 @@ void create_rr_graph(const t_graph_type graph_type, verify_rr_node_indices(grid, device_ctx.rr_node_indices, device_ctx.rr_nodes); - /* Update RRGraph overlay with new data pointers */ - DeviceContext& mutable_device_ctx = g_vpr_ctx.mutable_device(); - mutable_device_ctx.rr_graph.set_internal_data(&(mutable_device_ctx.rr_nodes), - &(mutable_device_ctx.rr_node_indices)); - print_rr_graph_stats(); //Write out rr graph file if needed @@ -739,6 +734,10 @@ static void build_rr_graph(const t_graph_type graph_type, rr_graph_externals(segment_inf, *wire_to_rr_ipin_switch, base_cost_type); + /* Update RRGraph overlay with new data pointers */ + device_ctx.rr_graph.set_internal_data(&(device_ctx.rr_nodes), + &(device_ctx.rr_node_indices)); + check_rr_graph(graph_type, grid, types); /* Free all temp structs */ diff --git a/vpr/src/route/rr_graph_overlay.cpp b/vpr/src/route/rr_graph_overlay.cpp index db56aaa8fa3..447427038db 100644 --- a/vpr/src/route/rr_graph_overlay.cpp +++ b/vpr/src/route/rr_graph_overlay.cpp @@ -12,7 +12,7 @@ RRGraphOverlay::RRGraphOverlay() { * Accessors ****************************/ t_rr_type RRGraphOverlay::node_type(const RRNodeId& id) const { - return (*node_storage_).node_type(id); + return node_storage_->node_type(id); } /**************************** From e927bb58274773861f9535dac0a5f09c2d337bdc Mon Sep 17 00:00:00 2001 From: tangxifan Date: Wed, 24 Mar 2021 15:34:12 -0600 Subject: [PATCH 04/22] [VPR] add overlay initialization for rr_graph loading from external files with minor code format fix --- vpr/src/route/rr_graph.cpp | 5 +++++ vpr/src/route/rr_graph_overlay.h | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/vpr/src/route/rr_graph.cpp b/vpr/src/route/rr_graph.cpp index 87f5b2e3295..679bd2b4a33 100644 --- a/vpr/src/route/rr_graph.cpp +++ b/vpr/src/route/rr_graph.cpp @@ -333,6 +333,11 @@ void create_rr_graph(const t_graph_type graph_type, router_opts.read_rr_edge_metadata, router_opts.do_check_rr_graph); reorder_rr_graph_nodes(router_opts); + + /* Update RRGraph overlay with new data pointers */ + DeviceContext& mutable_device_ctx = g_vpr_ctx.mutable_device(); + mutable_device_ctx.rr_graph.set_internal_data(&(mutable_device_ctx.rr_nodes), + &(mutable_device_ctx.rr_node_indices)); } } else { if (channel_widths_unchanged(device_ctx.chan_width, nodes_per_chan) && !device_ctx.rr_nodes.empty()) { diff --git a/vpr/src/route/rr_graph_overlay.h b/vpr/src/route/rr_graph_overlay.h index e85a6b8d91b..bababc18565 100644 --- a/vpr/src/route/rr_graph_overlay.h +++ b/vpr/src/route/rr_graph_overlay.h @@ -62,7 +62,7 @@ class RRGraphOverlay { /* node-level storage including edge storages */ t_rr_graph_storage* node_storage_; /* Fast look-up */ - t_rr_node_indices* rr_node_indices_; + t_rr_node_indices* rr_node_indices_; }; #endif From b25adaa2df9a51b76da7c24c4149812573b81239 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Wed, 24 Mar 2021 15:39:18 -0600 Subject: [PATCH 05/22] [VPR] Code format fix --- vpr/src/route/rr_graph_overlay.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/vpr/src/route/rr_graph_overlay.h b/vpr/src/route/rr_graph_overlay.h index bababc18565..730e05b6c0e 100644 --- a/vpr/src/route/rr_graph_overlay.h +++ b/vpr/src/route/rr_graph_overlay.h @@ -22,7 +22,7 @@ * - rr_node_indices * * Note that the overlay does not own the storage - * It serves a virtual protocol for + * It serves a virtual protocol for * - rr_graph builder * - placer * - router @@ -33,29 +33,29 @@ * - This helps to reduce the memory footprint for each client * - This avoids massive changes for each client on using the APIs * as each frame view provides adhoc APIs for each client - * + * */ class RRGraphOverlay { - /**************** + /**************** * Constructors ****************/ public: RRGraphOverlay(); - /**************** + /**************** * Accessors ****************/ public: t_rr_type node_type(const RRNodeId& id) const; - /**************** + /**************** * Mutators ****************/ public: void set_internal_data(t_rr_graph_storage* node_storage, t_rr_node_indices* rr_node_indices); - /**************** + /**************** * internal data ****************/ private: From 59b766c166c6d7aa9e0b9a9588742cee64fc135e Mon Sep 17 00:00:00 2001 From: tangxifan Date: Wed, 24 Mar 2021 15:40:03 -0600 Subject: [PATCH 06/22] [VPR] Code format fix --- vpr/src/route/rr_graph_overlay.h | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/vpr/src/route/rr_graph_overlay.h b/vpr/src/route/rr_graph_overlay.h index 730e05b6c0e..c8feb580498 100644 --- a/vpr/src/route/rr_graph_overlay.h +++ b/vpr/src/route/rr_graph_overlay.h @@ -37,27 +37,27 @@ */ class RRGraphOverlay { /**************** - * Constructors - ****************/ + * Constructors + ****************/ public: RRGraphOverlay(); /**************** - * Accessors - ****************/ + * Accessors + ****************/ public: t_rr_type node_type(const RRNodeId& id) const; /**************** - * Mutators - ****************/ + * Mutators + ****************/ public: void set_internal_data(t_rr_graph_storage* node_storage, t_rr_node_indices* rr_node_indices); /**************** - * internal data - ****************/ + * internal data + ****************/ private: /* node-level storage including edge storages */ t_rr_graph_storage* node_storage_; From 0d697c099cb6fe8edfb5e0320aa4ea2ba608d555 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Wed, 24 Mar 2021 17:15:49 -0600 Subject: [PATCH 07/22] [VPR] Add rr graph overlay to rr_graph reader and writer --- vpr/src/route/rr_graph.cpp | 6 +----- vpr/src/route/rr_graph_reader.cpp | 1 + vpr/src/route/rr_graph_uxsdcxx_serializer.h | 8 ++++++++ vpr/src/route/rr_graph_writer.cpp | 1 + 4 files changed, 11 insertions(+), 5 deletions(-) diff --git a/vpr/src/route/rr_graph.cpp b/vpr/src/route/rr_graph.cpp index 679bd2b4a33..37a3c2a614e 100644 --- a/vpr/src/route/rr_graph.cpp +++ b/vpr/src/route/rr_graph.cpp @@ -332,12 +332,8 @@ void create_rr_graph(const t_graph_type graph_type, det_routing_arch->read_rr_graph_filename.c_str(), router_opts.read_rr_edge_metadata, router_opts.do_check_rr_graph); - reorder_rr_graph_nodes(router_opts); - /* Update RRGraph overlay with new data pointers */ - DeviceContext& mutable_device_ctx = g_vpr_ctx.mutable_device(); - mutable_device_ctx.rr_graph.set_internal_data(&(mutable_device_ctx.rr_nodes), - &(mutable_device_ctx.rr_node_indices)); + reorder_rr_graph_nodes(router_opts); } } else { if (channel_widths_unchanged(device_ctx.chan_width, nodes_per_chan) && !device_ctx.rr_nodes.empty()) { diff --git a/vpr/src/route/rr_graph_reader.cpp b/vpr/src/route/rr_graph_reader.cpp index d76ca4fdcf9..1d47e4c156a 100644 --- a/vpr/src/route/rr_graph_reader.cpp +++ b/vpr/src/route/rr_graph_reader.cpp @@ -58,6 +58,7 @@ void load_rr_file(const t_graph_type graph_type, &device_ctx.read_rr_graph_filename, read_edge_metadata, &device_ctx.chan_width, + &device_ctx.rr_graph, &device_ctx.rr_nodes, &device_ctx.rr_switch_inf, &device_ctx.rr_indexed_data, diff --git a/vpr/src/route/rr_graph_uxsdcxx_serializer.h b/vpr/src/route/rr_graph_uxsdcxx_serializer.h index 85725581795..994cdb69999 100644 --- a/vpr/src/route/rr_graph_uxsdcxx_serializer.h +++ b/vpr/src/route/rr_graph_uxsdcxx_serializer.h @@ -16,6 +16,7 @@ #include "check_rr_graph.h" #include "rr_graph2.h" #include "rr_graph_indexed_data.h" +#include "rr_graph_overlay.h" class MetadataBind { public: @@ -258,6 +259,7 @@ class RrGraphSerializer final : public uxsd::RrGraphBase { std::string* read_rr_graph_filename, bool read_edge_metadata, t_chan_width* chan_width, + RRGraphOverlay* rr_graph, t_rr_graph_storage* rr_nodes, std::vector* rr_switch_inf, std::vector* rr_indexed_data, @@ -272,6 +274,7 @@ class RrGraphSerializer final : public uxsd::RrGraphBase { vtr::string_internment* strings) : wire_to_rr_ipin_switch_(wire_to_rr_ipin_switch) , chan_width_(chan_width) + , rr_graph_(rr_graph) , rr_nodes_(rr_nodes) , rr_switch_inf_(rr_switch_inf) , rr_indexed_data_(rr_indexed_data) @@ -1534,6 +1537,10 @@ class RrGraphSerializer final : public uxsd::RrGraphBase { VTR_ASSERT(read_rr_graph_name_ != nullptr); read_rr_graph_filename_->assign(read_rr_graph_name_); + /* Update RRGraph overlay with new data pointers */ + rr_graph_->set_internal_data(rr_nodes_, + rr_node_indices_); + if (do_check_rr_graph_) { check_rr_graph(graph_type_, grid_, physical_tile_types_); } @@ -1951,6 +1958,7 @@ class RrGraphSerializer final : public uxsd::RrGraphBase { // Output for loads, and constant data for writes. int* wire_to_rr_ipin_switch_; t_chan_width* chan_width_; + RRGraphOverlay* rr_graph_; t_rr_graph_storage* rr_nodes_; 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 86fed376c05..01b13659868 100644 --- a/vpr/src/route/rr_graph_writer.cpp +++ b/vpr/src/route/rr_graph_writer.cpp @@ -36,6 +36,7 @@ void write_rr_graph(const char* file_name) { /*read_rr_graph_filename=*/nullptr, /*read_edge_metadata=*/false, &device_ctx.chan_width, + &device_ctx.rr_graph, &device_ctx.rr_nodes, &device_ctx.rr_switch_inf, &device_ctx.rr_indexed_data, From ea1c0175f8d54ce3ea4dc4b38dccbe8a46884ca0 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Fri, 26 Mar 2021 13:27:53 -0600 Subject: [PATCH 08/22] [VPR] Add a prototype of RRGraphView (read-only) and its builder extension RRGraphBuilderView (mutable) --- vpr/src/base/vpr_context.h | 4 +- vpr/src/device/rr_graph_builder_view.cpp | 44 +++++++++ vpr/src/device/rr_graph_builder_view.h | 61 +++++++++++++ vpr/src/device/rr_graph_view.cpp | 87 ++++++++++++++++++ vpr/src/device/rr_graph_view.h | 99 +++++++++++++++++++++ vpr/src/route/check_rr_graph.cpp | 2 +- vpr/src/route/rr_graph_overlay.cpp | 25 ------ vpr/src/route/rr_graph_overlay.h | 68 -------------- vpr/src/route/rr_graph_uxsdcxx_serializer.h | 8 +- 9 files changed, 298 insertions(+), 100 deletions(-) create mode 100644 vpr/src/device/rr_graph_builder_view.cpp create mode 100644 vpr/src/device/rr_graph_builder_view.h create mode 100644 vpr/src/device/rr_graph_view.cpp create mode 100644 vpr/src/device/rr_graph_view.h delete mode 100644 vpr/src/route/rr_graph_overlay.cpp delete mode 100644 vpr/src/route/rr_graph_overlay.h diff --git a/vpr/src/base/vpr_context.h b/vpr/src/base/vpr_context.h index c84d6a7704c..7c8f23411f3 100644 --- a/vpr/src/base/vpr_context.h +++ b/vpr/src/base/vpr_context.h @@ -9,7 +9,7 @@ #include "vtr_vector.h" #include "atom_netlist.h" #include "clustered_netlist.h" -#include "rr_graph_overlay.h" +#include "rr_graph_view.h" #include "rr_graph_storage.h" #include "rr_node.h" #include "rr_rc_data.h" @@ -146,7 +146,7 @@ struct DeviceContext : public Context { /* * Structures to define the routing architecture of the FPGA. */ - RRGraphOverlay rr_graph; // Currently an overlay of routing resource graph but in future will become an object grouping rr_nodes, rr_node_indices etc. + RRGraphView rr_graph; // A read-only view of routing resource graph to be the ONLY database for client functions: GUI, placer, router, timing analyzer etc. t_rr_graph_storage rr_nodes; // autogenerated in build_rr_graph diff --git a/vpr/src/device/rr_graph_builder_view.cpp b/vpr/src/device/rr_graph_builder_view.cpp new file mode 100644 index 00000000000..d03c3b238bf --- /dev/null +++ b/vpr/src/device/rr_graph_builder_view.cpp @@ -0,0 +1,44 @@ +/*************************************** + * Methods for Object RRGraphBuilderView + ***************************************/ +#include "vtr_assert.h" +#include "rr_graph_builder_view.h" + +/**************************** + * Constructors + ****************************/ +RRGraphBuilderView::RRGraphBuilderView() { + node_storage_ = nullptr; + rr_node_indices_ = nullptr; +} + +/**************************** + * Mutators + ****************************/ +void RRGraphBuilderView::add_node_to_fast_lookup(const RRNodeId& node, + const int& x, + const int& y, + const t_rr_type& type, + const int& ptc, + const e_side& side) { + VTR_ASSERT_SAFE(3 == (*rr_node_indices_)[type].ndims()); + + /* Expand the fast look-up if the new node is out-of-range + * This may seldom happen because the rr_graph building function + * should ensure the fast look-up well organized + */ + VTR_ASSERT(type < (*rr_node_indices_).size()); + + if ((size_t(x) >= (*rr_node_indices_)[type].dim_size(1)) + || (size_t(y) >= (*rr_node_indices_)[type].dim_size(2)) + || (size_t(side) >= (*rr_node_indices_)[type].dim_size(3))) { + (*rr_node_indices_)[type].resize({size_t(x), size_t(y), size_t(side)}); + } + + if (size_t(ptc) >= (*rr_node_indices_)[type][x][y][side].size()) { + (*rr_node_indices_)[type][x][y][side].resize(ptc); + } + + /* Resize on demand finished; Register the node */ + (*rr_node_indices_)[type][x][y][side][ptc] = int(size_t(node)); +} diff --git a/vpr/src/device/rr_graph_builder_view.h b/vpr/src/device/rr_graph_builder_view.h new file mode 100644 index 00000000000..1adf26f16a2 --- /dev/null +++ b/vpr/src/device/rr_graph_builder_view.h @@ -0,0 +1,61 @@ +#ifndef _RR_GRAPH_BUILDER_VIEW_ +#define _RR_GRAPH_BUILDER_VIEW_ + +#include + +#include "rr_graph_fwd.h" +#include "rr_node_fwd.h" +#include "rr_graph2.h" +#include "vtr_log.h" +#include "vtr_memory.h" +#include "vpr_utils.h" +#include "vtr_strong_id_range.h" +#include "vtr_array_view.h" +#include "rr_graph_storage.h" +#include "rr_graph_view.h" + +/* An builder of routing resource graph which extends + * the read-only frame view RRGraphView + * + * Note that the builder does not own the storage + * It serves a virtual protocol for + * - rr_graph builder, which requires both mutators and accessors + * + * Note: + * - This is the only data structre allowed to modify a routing resource graph + * + */ +class RRGraphBuilderView : public RRGraphView { + /**************** + * Constructors + ****************/ + public: + RRGraphBuilderView(); + + /**************** + * Accessors all come from RRGraph View + ****************/ + + /**************** + * Mutators + ****************/ + public: + /* Register a node in the fast look-up */ + void add_node_to_fast_lookup(const RRNodeId& node, + const int& x, + const int& y, + const t_rr_type& type, + const int& ptc, + const e_side& side); + + /**************** + * internal data + ****************/ + protected: + /* node-level storage including edge storages */ + t_rr_graph_storage* node_storage_; + /* Fast look-up */ + t_rr_node_indices* rr_node_indices_; +}; + +#endif diff --git a/vpr/src/device/rr_graph_view.cpp b/vpr/src/device/rr_graph_view.cpp new file mode 100644 index 00000000000..fbef42b80e9 --- /dev/null +++ b/vpr/src/device/rr_graph_view.cpp @@ -0,0 +1,87 @@ +/*************************************** + * Methods for Object RRGraphView + ***************************************/ +#include "vtr_assert.h" +#include "rr_graph_view.h" + +/**************************** + * Constructors + ****************************/ +RRGraphView::RRGraphView() { + node_storage_ = nullptr; + rr_node_indices_ = nullptr; +} + +/**************************** + * Accessors + ****************************/ +t_rr_type RRGraphView::node_type(const RRNodeId& node) const { + return node_storage_->node_type(node); +} + +RRNodeId RRGraphView::find_node(const int& x, + const int& y, + const t_rr_type& type, + const int& ptc, + const e_side& side) const { + /* Find actual side to be used */ + e_side node_side = side; + if (type == IPIN || type == OPIN) { + VTR_ASSERT_MSG(side != NUM_SIDES, "IPIN/OPIN must specify desired side (can not be default NUM_SIDES)"); + } else { + VTR_ASSERT(type != IPIN && type != OPIN); + node_side = SIDES[0]; + } + + /* Currently need to swap x and y for CHANX because of chan, seg convention */ + size_t node_x = x; + size_t node_y = y; + if (CHANX == type) { + std::swap(node_x, node_y); + } + + VTR_ASSERT_SAFE(3 == (*rr_node_indices_)[type].ndims()); + + /* Sanity check to ensure the x, y, side and ptc are in range + * Data type of rr_node_indice: + * typedef std::array, 3>, NUM_RR_TYPES> t_rr_node_indices; + * Note that x, y and side are the 1st, 2nd and 3rd dimensions of the vtr::NdMatrix + * ptc is in the std::vector + */ + if (size_t(type) >= (*rr_node_indices_).size()) { + /* Node type is out of range, return an invalid index */ + return RRNodeId::INVALID(); + } + + if (node_x >= (*rr_node_indices_)[type].dim_size(1)) { + /* Node x is out of range, return an invalid index */ + return RRNodeId::INVALID(); + } + + if (node_y >= (*rr_node_indices_)[type].dim_size(2)) { + /* Node y is out of range, return an invalid index */ + return RRNodeId::INVALID(); + } + + if (node_side >= (*rr_node_indices_)[type].dim_size(3)) { + /* Node side is out of range, return an invalid index */ + return RRNodeId::INVALID(); + } + + if (ptc >= (*rr_node_indices_)[type][x][y][node_side].size()) { + /* Ptc is out of range, return an invalid index */ + return RRNodeId::INVALID(); + } + + /* Reaching here, it means that node exists in the look-up, return the id */ + return RRNodeId((*rr_node_indices_)[type][x][y][node_side][ptc]); +} + +/**************************** + * Mutators + ****************************/ +void RRGraphView::set_internal_data(t_rr_graph_storage* node_storage, + t_rr_node_indices* rr_node_indices) { + node_storage_ = node_storage; + rr_node_indices_ = rr_node_indices; +} diff --git a/vpr/src/device/rr_graph_view.h b/vpr/src/device/rr_graph_view.h new file mode 100644 index 00000000000..27cafd19cc4 --- /dev/null +++ b/vpr/src/device/rr_graph_view.h @@ -0,0 +1,99 @@ +#ifndef _RR_GRAPH_OVERLAY_ +#define _RR_GRAPH_OVERLAY_ + +#include + +#include "rr_graph_fwd.h" +#include "rr_node_fwd.h" +#include "rr_graph2.h" +#include "vtr_log.h" +#include "vtr_memory.h" +#include "vpr_utils.h" +#include "vtr_strong_id_range.h" +#include "vtr_array_view.h" +#include "rr_graph_storage.h" + +/* An read-only routing resource graph + * which is an unified object including pointors to + * - node storage + * - edge_storage + * - node_ptc_storage + * - node_fan_in_storage + * - rr_node_indices + * + * Note that the RRGraphView does not own the storage + * It serves a virtual read-only protocol for + * - placer + * - router + * - timing analyzer + * - GUI + * + * Note that each client of rr_graph may get a frame view of the object + * The RRGraphView is the complete frame view of the routing resource graph + * - This helps to reduce the memory footprint for each client + * - This avoids massive changes for each client on using the APIs + * as each frame view provides adhoc APIs for each client + * + * TODO: more compact frame views will be created, e.g., + * - a mini frame view: contains only node and edges, representing the connectivity of the graph + * - a geometry frame view: an extended mini frame view with node-level attributes, + * in particular geometry information (type, x, y etc). + * + */ +class RRGraphView { + /**************** + * Constructors + ****************/ + public: + RRGraphView(); + + /**************** + * Accessors + ****************/ + public: + /* Get the type of a routing resource node */ + t_rr_type node_type(const RRNodeId& node) const; + + /* Returns the index of the specified routing resource node. (x,y) are + * the location within the FPGA, rr_type specifies the type of resource, + * and ptc gives the number of this resource. ptc is the class number, + * pin number or track number, depending on what type of resource this + * is. All ptcs start at 0 and go up to pins_per_clb-1 or the equivalent. + * There are class_inf size SOURCEs + SINKs, type->num_pins IPINs + OPINs, + * and max_chan_width CHANX and CHANY (each). + * + * Note that for segments (CHANX and CHANY) of length > 1, the segment is + * given an rr_index based on the (x,y) location at which it starts (i.e. + * lowest (x,y) location at which this segment exists). + * This routine also performs error checking to make sure the node in + * question exists. + * + * The 'side' argument only applies to IPIN/OPIN types, and specifies which + * side of the grid tile the node should be located on. The value is ignored + * for non-IPIN/OPIN types + */ + RRNodeId find_node(const int& x, + const int& y, + const t_rr_type& type, + const int& ptc, + const e_side& side = NUM_SIDES) const; + + /**************** + * Mutators + ****************/ + public: + /* The ONLY mutators allowed */ + void set_internal_data(t_rr_graph_storage* node_storage, + t_rr_node_indices* rr_node_indices); + + /**************** + * internal data storage, can be accessed by parent class RRGraphBuilderView + ****************/ + protected: + /* node-level storage including edge storages */ + t_rr_graph_storage* node_storage_; + /* Fast look-up */ + t_rr_node_indices* rr_node_indices_; +}; + +#endif diff --git a/vpr/src/route/check_rr_graph.cpp b/vpr/src/route/check_rr_graph.cpp index cb58fd3dd60..6580da8a896 100644 --- a/vpr/src/route/check_rr_graph.cpp +++ b/vpr/src/route/check_rr_graph.cpp @@ -205,7 +205,7 @@ void check_rr_graph(const t_graph_type graph_type, bool is_fringe_warning_sent = false; for (size_t inode = 0; inode < device_ctx.rr_nodes.size(); inode++) { - t_rr_type rr_type = device_ctx.rr_graph.node_type(RRNodeId(inode)); + t_rr_type rr_type = device_ctx.rr_nodes.node_type(RRNodeId(inode)); if (rr_type != SOURCE) { if (total_edges_to_node[inode] < 1 && !rr_node_is_global_clb_ipin(inode)) { diff --git a/vpr/src/route/rr_graph_overlay.cpp b/vpr/src/route/rr_graph_overlay.cpp deleted file mode 100644 index 447427038db..00000000000 --- a/vpr/src/route/rr_graph_overlay.cpp +++ /dev/null @@ -1,25 +0,0 @@ -#include "rr_graph_overlay.h" - -/**************************** - * Constructors - ****************************/ -RRGraphOverlay::RRGraphOverlay() { - node_storage_ = nullptr; - rr_node_indices_ = nullptr; -} - -/**************************** - * Accessors - ****************************/ -t_rr_type RRGraphOverlay::node_type(const RRNodeId& id) const { - return node_storage_->node_type(id); -} - -/**************************** - * Mutators - ****************************/ -void RRGraphOverlay::set_internal_data(t_rr_graph_storage* node_storage, - t_rr_node_indices* rr_node_indices) { - node_storage_ = node_storage; - rr_node_indices_ = rr_node_indices; -} diff --git a/vpr/src/route/rr_graph_overlay.h b/vpr/src/route/rr_graph_overlay.h deleted file mode 100644 index c8feb580498..00000000000 --- a/vpr/src/route/rr_graph_overlay.h +++ /dev/null @@ -1,68 +0,0 @@ -#ifndef _RR_GRAPH_OVERLAY_ -#define _RR_GRAPH_OVERLAY_ - -#include - -#include "rr_graph_fwd.h" -#include "rr_node_fwd.h" -#include "rr_graph2.h" -#include "vtr_log.h" -#include "vtr_memory.h" -#include "vpr_utils.h" -#include "vtr_strong_id_range.h" -#include "vtr_array_view.h" -#include "rr_graph_storage.h" - -/* An overlay of routing resource graph - * which is an unified object including pointors to - * - node storage - * - edge_storage - * - node_ptc_storage - * - node_fan_in_storage - * - rr_node_indices - * - * Note that the overlay does not own the storage - * It serves a virtual protocol for - * - rr_graph builder - * - placer - * - router - * - timing analyzer - * - GUI - * - * Note that each client of rr_graph may get a frame view of the object - * - This helps to reduce the memory footprint for each client - * - This avoids massive changes for each client on using the APIs - * as each frame view provides adhoc APIs for each client - * - */ -class RRGraphOverlay { - /**************** - * Constructors - ****************/ - public: - RRGraphOverlay(); - - /**************** - * Accessors - ****************/ - public: - t_rr_type node_type(const RRNodeId& id) const; - - /**************** - * Mutators - ****************/ - public: - void set_internal_data(t_rr_graph_storage* node_storage, - t_rr_node_indices* rr_node_indices); - - /**************** - * internal data - ****************/ - private: - /* node-level storage including edge storages */ - t_rr_graph_storage* node_storage_; - /* Fast look-up */ - t_rr_node_indices* rr_node_indices_; -}; - -#endif diff --git a/vpr/src/route/rr_graph_uxsdcxx_serializer.h b/vpr/src/route/rr_graph_uxsdcxx_serializer.h index 994cdb69999..9d8a9dcfafc 100644 --- a/vpr/src/route/rr_graph_uxsdcxx_serializer.h +++ b/vpr/src/route/rr_graph_uxsdcxx_serializer.h @@ -16,7 +16,7 @@ #include "check_rr_graph.h" #include "rr_graph2.h" #include "rr_graph_indexed_data.h" -#include "rr_graph_overlay.h" +#include "rr_graph_view.h" class MetadataBind { public: @@ -259,7 +259,7 @@ class RrGraphSerializer final : public uxsd::RrGraphBase { std::string* read_rr_graph_filename, bool read_edge_metadata, t_chan_width* chan_width, - RRGraphOverlay* rr_graph, + RRGraphView* rr_graph, t_rr_graph_storage* rr_nodes, std::vector* rr_switch_inf, std::vector* rr_indexed_data, @@ -1537,7 +1537,7 @@ class RrGraphSerializer final : public uxsd::RrGraphBase { VTR_ASSERT(read_rr_graph_name_ != nullptr); read_rr_graph_filename_->assign(read_rr_graph_name_); - /* Update RRGraph overlay with new data pointers */ + /* Update RRGraph viewer with new data pointers */ rr_graph_->set_internal_data(rr_nodes_, rr_node_indices_); @@ -1958,7 +1958,7 @@ class RrGraphSerializer final : public uxsd::RrGraphBase { // Output for loads, and constant data for writes. int* wire_to_rr_ipin_switch_; t_chan_width* chan_width_; - RRGraphOverlay* rr_graph_; + RRGraphView* rr_graph_; t_rr_graph_storage* rr_nodes_; std::vector* rr_switch_inf_; std::vector* rr_indexed_data_; From 4c8238952ae21f2a9ea3bb00eb9d9b8def3a0de5 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Fri, 26 Mar 2021 14:03:40 -0600 Subject: [PATCH 09/22] [VPR] Bug fix in RRGraphView API and deploy to placer delay matrix computer --- vpr/src/device/rr_graph_builder_view.cpp | 6 ++-- vpr/src/device/rr_graph_view.cpp | 10 +++---- vpr/src/place/timing_place_lookup.cpp | 36 ++++++++++++------------ 3 files changed, 26 insertions(+), 26 deletions(-) diff --git a/vpr/src/device/rr_graph_builder_view.cpp b/vpr/src/device/rr_graph_builder_view.cpp index d03c3b238bf..f97715d302a 100644 --- a/vpr/src/device/rr_graph_builder_view.cpp +++ b/vpr/src/device/rr_graph_builder_view.cpp @@ -29,9 +29,9 @@ void RRGraphBuilderView::add_node_to_fast_lookup(const RRNodeId& node, */ VTR_ASSERT(type < (*rr_node_indices_).size()); - if ((size_t(x) >= (*rr_node_indices_)[type].dim_size(1)) - || (size_t(y) >= (*rr_node_indices_)[type].dim_size(2)) - || (size_t(side) >= (*rr_node_indices_)[type].dim_size(3))) { + if ((size_t(x) >= (*rr_node_indices_)[type].dim_size(0)) + || (size_t(y) >= (*rr_node_indices_)[type].dim_size(1)) + || (size_t(side) >= (*rr_node_indices_)[type].dim_size(2))) { (*rr_node_indices_)[type].resize({size_t(x), size_t(y), size_t(side)}); } diff --git a/vpr/src/device/rr_graph_view.cpp b/vpr/src/device/rr_graph_view.cpp index fbef42b80e9..ea60c35ea5f 100644 --- a/vpr/src/device/rr_graph_view.cpp +++ b/vpr/src/device/rr_graph_view.cpp @@ -53,28 +53,28 @@ RRNodeId RRGraphView::find_node(const int& x, return RRNodeId::INVALID(); } - if (node_x >= (*rr_node_indices_)[type].dim_size(1)) { + if (node_x >= (*rr_node_indices_)[type].dim_size(0)) { /* Node x is out of range, return an invalid index */ return RRNodeId::INVALID(); } - if (node_y >= (*rr_node_indices_)[type].dim_size(2)) { + if (node_y >= (*rr_node_indices_)[type].dim_size(1)) { /* Node y is out of range, return an invalid index */ return RRNodeId::INVALID(); } - if (node_side >= (*rr_node_indices_)[type].dim_size(3)) { + if (node_side >= (*rr_node_indices_)[type].dim_size(2)) { /* Node side is out of range, return an invalid index */ return RRNodeId::INVALID(); } - if (ptc >= (*rr_node_indices_)[type][x][y][node_side].size()) { + if (size_t(ptc) >= (*rr_node_indices_)[type][node_x][node_y][node_side].size()) { /* Ptc is out of range, return an invalid index */ return RRNodeId::INVALID(); } /* Reaching here, it means that node exists in the look-up, return the id */ - return RRNodeId((*rr_node_indices_)[type][x][y][node_side][ptc]); + return RRNodeId((*rr_node_indices_)[type][node_x][node_y][node_side][ptc]); } /**************************** diff --git a/vpr/src/place/timing_place_lookup.cpp b/vpr/src/place/timing_place_lookup.cpp index 65e3156b006..e3afc4a9b8a 100644 --- a/vpr/src/place/timing_place_lookup.cpp +++ b/vpr/src/place/timing_place_lookup.cpp @@ -350,25 +350,25 @@ static float route_connection_delay( for (int driver_ptc : best_driver_ptcs) { VTR_ASSERT(driver_ptc != OPEN); - int source_rr_node = get_rr_node_index(device_ctx.rr_node_indices, source_x, source_y, SOURCE, driver_ptc); + RRNodeId source_rr_node = device_ctx.rr_graph.find_node(source_x, source_y, SOURCE, driver_ptc); - VTR_ASSERT(source_rr_node != OPEN); + VTR_ASSERT(source_rr_node != RRNodeId::INVALID()); for (int sink_ptc : best_sink_ptcs) { VTR_ASSERT(sink_ptc != OPEN); - int sink_rr_node = get_rr_node_index(device_ctx.rr_node_indices, sink_x, sink_y, SINK, sink_ptc); + RRNodeId sink_rr_node = device_ctx.rr_graph.find_node(sink_x, sink_y, SINK, sink_ptc); - VTR_ASSERT(sink_rr_node != OPEN); + VTR_ASSERT(sink_rr_node != RRNodeId::INVALID()); - if (!measure_directconnect && directconnect_exists(source_rr_node, sink_rr_node)) { + if (!measure_directconnect && directconnect_exists(size_t(source_rr_node), size_t(sink_rr_node))) { //Skip if we shouldn't measure direct connects and a direct connect exists continue; } { successfully_routed = route_profiler.calculate_delay( - source_rr_node, sink_rr_node, + size_t(source_rr_node), size_t(sink_rr_node), router_opts, &net_delay_value); } @@ -444,10 +444,10 @@ static void generic_compute_matrix_dijkstra_expansion( auto best_driver_ptcs = get_best_classes(DRIVER, device_ctx.grid[source_x][source_y].type); for (int driver_ptc : best_driver_ptcs) { VTR_ASSERT(driver_ptc != OPEN); - int source_rr_node = get_rr_node_index(device_ctx.rr_node_indices, source_x, source_y, SOURCE, driver_ptc); + RRNodeId source_rr_node = device_ctx.rr_graph.find_node(source_x, source_y, SOURCE, driver_ptc); - VTR_ASSERT(source_rr_node != OPEN); - auto delays = calculate_all_path_delays_from_rr_node(source_rr_node, router_opts); + VTR_ASSERT(source_rr_node != RRNodeId::INVALID()); + auto delays = calculate_all_path_delays_from_rr_node(size_t(source_rr_node), router_opts); bool path_to_all_sinks = true; for (int sink_x = start_x; sink_x <= end_x; sink_x++) { @@ -479,16 +479,16 @@ static void generic_compute_matrix_dijkstra_expansion( for (int sink_ptc : best_sink_ptcs) { VTR_ASSERT(sink_ptc != OPEN); - int sink_rr_node = get_rr_node_index(device_ctx.rr_node_indices, sink_x, sink_y, SINK, sink_ptc); + RRNodeId sink_rr_node = device_ctx.rr_graph.find_node(sink_x, sink_y, SINK, sink_ptc); - VTR_ASSERT(sink_rr_node != OPEN); + VTR_ASSERT(sink_rr_node != RRNodeId::INVALID()); - if (!measure_directconnect && directconnect_exists(source_rr_node, sink_rr_node)) { + if (!measure_directconnect && directconnect_exists(size_t(source_rr_node), size_t(sink_rr_node))) { //Skip if we shouldn't measure direct connects and a direct connect exists continue; } - if (std::isnan(delays[sink_rr_node])) { + if (std::isnan(delays[size_t(sink_rr_node)])) { // This sink was not found continue; } @@ -502,7 +502,7 @@ static void generic_compute_matrix_dijkstra_expansion( #endif found_matrix[delta_x][delta_y] = true; - add_delay_to_matrix(&matrix, delta_x, delta_y, delays[sink_rr_node]); + add_delay_to_matrix(&matrix, delta_x, delta_y, delays[size_t(sink_rr_node)]); found_a_sink = true; break; @@ -979,8 +979,8 @@ static bool find_direct_connect_sample_locations(const t_direct_inf* direct, //(with multi-width/height blocks pins may not exist at all locations) bool from_pin_found = false; if (direct->from_side != NUM_SIDES) { - int from_pin_rr = get_rr_node_index(device_ctx.rr_node_indices, from_x, from_y, OPIN, from_pin, direct->from_side); - from_pin_found = (from_pin_rr != OPEN); + RRNodeId from_pin_rr = device_ctx.rr_graph.find_node(from_x, from_y, OPIN, from_pin, direct->from_side); + from_pin_found = (from_pin_rr != RRNodeId::INVALID()); } else { std::vector& from_pin_rrs = *scratch; get_rr_node_indices(device_ctx.rr_node_indices, from_x, from_y, OPIN, from_pin, &from_pin_rrs); @@ -997,8 +997,8 @@ static bool find_direct_connect_sample_locations(const t_direct_inf* direct, //(with multi-width/height blocks pins may not exist at all locations) bool to_pin_found = false; if (direct->to_side != NUM_SIDES) { - int to_pin_rr = get_rr_node_index(device_ctx.rr_node_indices, to_x, to_y, IPIN, to_pin, direct->to_side); - to_pin_found = (to_pin_rr != OPEN); + RRNodeId to_pin_rr = device_ctx.rr_graph.find_node(to_x, to_y, IPIN, to_pin, direct->to_side); + to_pin_found = (to_pin_rr != RRNodeId::INVALID()); } else { std::vector& to_pin_rrs = *scratch; get_rr_node_indices(device_ctx.rr_node_indices, to_x, to_y, IPIN, to_pin, &to_pin_rrs); From dcdb036b528d5463a9f65f3f43dc5e5127f28ab2 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Fri, 26 Mar 2021 14:13:37 -0600 Subject: [PATCH 10/22] [VPR] Code format fix --- vpr/src/device/rr_graph_builder_view.cpp | 2 +- vpr/src/device/rr_graph_view.cpp | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/vpr/src/device/rr_graph_builder_view.cpp b/vpr/src/device/rr_graph_builder_view.cpp index f97715d302a..d7d1a9cf5dc 100644 --- a/vpr/src/device/rr_graph_builder_view.cpp +++ b/vpr/src/device/rr_graph_builder_view.cpp @@ -34,7 +34,7 @@ void RRGraphBuilderView::add_node_to_fast_lookup(const RRNodeId& node, || (size_t(side) >= (*rr_node_indices_)[type].dim_size(2))) { (*rr_node_indices_)[type].resize({size_t(x), size_t(y), size_t(side)}); } - + if (size_t(ptc) >= (*rr_node_indices_)[type][x][y][side].size()) { (*rr_node_indices_)[type][x][y][side].resize(ptc); } diff --git a/vpr/src/device/rr_graph_view.cpp b/vpr/src/device/rr_graph_view.cpp index ea60c35ea5f..2f90c29dc19 100644 --- a/vpr/src/device/rr_graph_view.cpp +++ b/vpr/src/device/rr_graph_view.cpp @@ -16,7 +16,7 @@ RRGraphView::RRGraphView() { * Accessors ****************************/ t_rr_type RRGraphView::node_type(const RRNodeId& node) const { - return node_storage_->node_type(node); + return node_storage_->node_type(node); } RRNodeId RRGraphView::find_node(const int& x, @@ -69,8 +69,8 @@ RRNodeId RRGraphView::find_node(const int& x, } if (size_t(ptc) >= (*rr_node_indices_)[type][node_x][node_y][node_side].size()) { - /* Ptc is out of range, return an invalid index */ - return RRNodeId::INVALID(); + /* Ptc is out of range, return an invalid index */ + return RRNodeId::INVALID(); } /* Reaching here, it means that node exists in the look-up, return the id */ From 387eba78d9796e0e2b52b11b5891a6e043cc1a1f Mon Sep 17 00:00:00 2001 From: tangxifan Date: Fri, 26 Mar 2021 16:04:07 -0600 Subject: [PATCH 11/22] [VPR] Deploy mutator to rr_node_indice builder as an example --- vpr/src/device/rr_graph_builder_view.cpp | 13 ++++++++----- vpr/src/device/rr_graph_builder_view.h | 12 ++---------- vpr/src/route/rr_graph2.cpp | 20 ++++++++++++++------ 3 files changed, 24 insertions(+), 21 deletions(-) diff --git a/vpr/src/device/rr_graph_builder_view.cpp b/vpr/src/device/rr_graph_builder_view.cpp index d7d1a9cf5dc..7493a65f414 100644 --- a/vpr/src/device/rr_graph_builder_view.cpp +++ b/vpr/src/device/rr_graph_builder_view.cpp @@ -7,9 +7,10 @@ /**************************** * Constructors ****************************/ -RRGraphBuilderView::RRGraphBuilderView() { - node_storage_ = nullptr; - rr_node_indices_ = nullptr; +RRGraphBuilderView::RRGraphBuilderView(t_rr_graph_storage* node_storage, + t_rr_node_indices* rr_node_indices) { + node_storage_ = node_storage; + rr_node_indices_ = rr_node_indices; } /**************************** @@ -32,11 +33,13 @@ void RRGraphBuilderView::add_node_to_fast_lookup(const RRNodeId& node, if ((size_t(x) >= (*rr_node_indices_)[type].dim_size(0)) || (size_t(y) >= (*rr_node_indices_)[type].dim_size(1)) || (size_t(side) >= (*rr_node_indices_)[type].dim_size(2))) { - (*rr_node_indices_)[type].resize({size_t(x), size_t(y), size_t(side)}); + (*rr_node_indices_)[type].resize({std::max((*rr_node_indices_)[type].dim_size(0), size_t(x) + 1), + std::max((*rr_node_indices_)[type].dim_size(1), size_t(y) + 1), + std::max((*rr_node_indices_)[type].dim_size(2), size_t(side) + 1)}); } if (size_t(ptc) >= (*rr_node_indices_)[type][x][y][side].size()) { - (*rr_node_indices_)[type][x][y][side].resize(ptc); + (*rr_node_indices_)[type][x][y][side].resize(ptc + 1); } /* Resize on demand finished; Register the node */ diff --git a/vpr/src/device/rr_graph_builder_view.h b/vpr/src/device/rr_graph_builder_view.h index 1adf26f16a2..52bc69d52b9 100644 --- a/vpr/src/device/rr_graph_builder_view.h +++ b/vpr/src/device/rr_graph_builder_view.h @@ -30,7 +30,8 @@ class RRGraphBuilderView : public RRGraphView { * Constructors ****************/ public: - RRGraphBuilderView(); + RRGraphBuilderView(t_rr_graph_storage* node_storage, + t_rr_node_indices* rr_node_indices); /**************** * Accessors all come from RRGraph View @@ -47,15 +48,6 @@ class RRGraphBuilderView : public RRGraphView { const t_rr_type& type, const int& ptc, const e_side& side); - - /**************** - * internal data - ****************/ - protected: - /* node-level storage including edge storages */ - t_rr_graph_storage* node_storage_; - /* Fast look-up */ - t_rr_node_indices* rr_node_indices_; }; #endif diff --git a/vpr/src/route/rr_graph2.cpp b/vpr/src/route/rr_graph2.cpp index 330ede4b6fd..a4b03b4dd21 100644 --- a/vpr/src/route/rr_graph2.cpp +++ b/vpr/src/route/rr_graph2.cpp @@ -16,6 +16,8 @@ #include "read_xml_arch_file.h" #include "rr_types.h" +#include "rr_graph_builder_view.h" + constexpr short UN_SET = -1; /************************** Subroutines local to this module ****************/ @@ -973,6 +975,12 @@ static void load_chan_rr_indices(const int max_chan_width, static void load_block_rr_indices(const DeviceGrid& grid, t_rr_node_indices& indices, int* index) { + /* As the rr_indices builders modify a local copy of indices, use the local copy in the builder + * TODO: these building functions should only talk to a RRGraphBuilderView object + */ + RRGraphBuilderView rr_graph_builder_view(&(g_vpr_ctx.mutable_device().rr_nodes), + &indices); + //Walk through the grid assigning indices to SOURCE/SINK IPIN/OPIN for (size_t x = 0; x < grid.width(); x++) { for (size_t y = 0; y < grid.height(); y++) { @@ -982,15 +990,15 @@ static void load_block_rr_indices(const DeviceGrid& grid, //Assign indices for SINKs and SOURCEs // Note that SINKS/SOURCES have no side, so we always use side 0 - for (const auto& class_inf : type->class_inf) { - auto class_type = class_inf.type; + for (size_t iclass = 0; iclass < type->class_inf.size(); ++iclass) { + auto class_type = type->class_inf[iclass].type; if (class_type == DRIVER) { - indices[SOURCE][x][y][0].push_back(*index); - indices[SINK][x][y][0].push_back(OPEN); + rr_graph_builder_view.add_node_to_fast_lookup(RRNodeId(*index), x, y, SOURCE, iclass, SIDES[0]); + rr_graph_builder_view.add_node_to_fast_lookup(RRNodeId::INVALID(), x, y, SINK, iclass, SIDES[0]); } else { VTR_ASSERT(class_type == RECEIVER); - indices[SINK][x][y][0].push_back(*index); - indices[SOURCE][x][y][0].push_back(OPEN); + rr_graph_builder_view.add_node_to_fast_lookup(RRNodeId(*index), x, y, SINK, iclass, SIDES[0]); + rr_graph_builder_view.add_node_to_fast_lookup(RRNodeId::INVALID(), x, y, SOURCE, iclass, SIDES[0]); } ++(*index); } From 32225c8d524c670078099fda70b129b2c0b9de94 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Wed, 7 Apr 2021 17:44:18 -0600 Subject: [PATCH 12/22] [VPR] Reworked rr_graph_view and rr_graph_builder; Created rr_spatial_lookup as a sub data structure under rr_graph_view and rr_graph_builder --- vpr/src/base/vpr_context.h | 7 +- vpr/src/device/rr_graph_builder.cpp | 23 +++++ vpr/src/device/rr_graph_builder.h | 45 +++++++++ vpr/src/device/rr_graph_builder_view.cpp | 47 --------- vpr/src/device/rr_graph_builder_view.h | 53 ---------- vpr/src/device/rr_graph_view.cpp | 77 ++------------ vpr/src/device/rr_graph_view.h | 67 +++---------- vpr/src/device/rr_spatial_lookup.cpp | 106 ++++++++++++++++++++ vpr/src/device/rr_spatial_lookup.h | 69 +++++++++++++ vpr/src/place/timing_place_lookup.cpp | 12 +-- vpr/src/route/check_rr_graph.cpp | 4 +- vpr/src/route/rr_graph.cpp | 10 +- vpr/src/route/rr_graph2.cpp | 29 +++--- vpr/src/route/rr_graph2.h | 11 +- vpr/src/route/rr_graph_reader.cpp | 1 - vpr/src/route/rr_graph_uxsdcxx_serializer.h | 7 -- vpr/src/route/rr_graph_writer.cpp | 1 - 17 files changed, 302 insertions(+), 267 deletions(-) create mode 100644 vpr/src/device/rr_graph_builder.cpp create mode 100644 vpr/src/device/rr_graph_builder.h delete mode 100644 vpr/src/device/rr_graph_builder_view.cpp delete mode 100644 vpr/src/device/rr_graph_builder_view.h create mode 100644 vpr/src/device/rr_spatial_lookup.cpp create mode 100644 vpr/src/device/rr_spatial_lookup.h diff --git a/vpr/src/base/vpr_context.h b/vpr/src/base/vpr_context.h index 7c8f23411f3..a917c9725f6 100644 --- a/vpr/src/base/vpr_context.h +++ b/vpr/src/base/vpr_context.h @@ -146,7 +146,12 @@ struct DeviceContext : public Context { /* * Structures to define the routing architecture of the FPGA. */ - RRGraphView rr_graph; // A read-only view of routing resource graph to be the ONLY database for client functions: GUI, placer, router, timing analyzer etc. + RRGraphView rr_graph = RRGraphView(rr_nodes, rr_spatial_lookup); // A read-only view of routing resource graph to be the ONLY database for client functions: GUI, placer, router, timing analyzer etc. + + /* TODO: remove this interface from device_context once the code refactoring is completed + * because it should be part of the rr_graph view + */ + RRSpatialLookup rr_spatial_lookup = RRSpatialLookup(rr_node_indices); t_rr_graph_storage rr_nodes; // autogenerated in build_rr_graph diff --git a/vpr/src/device/rr_graph_builder.cpp b/vpr/src/device/rr_graph_builder.cpp new file mode 100644 index 00000000000..489d3226c12 --- /dev/null +++ b/vpr/src/device/rr_graph_builder.cpp @@ -0,0 +1,23 @@ +/*************************************** + * Methods for Object RRGraphBuilder + ***************************************/ +#include "rr_graph_builder.h" + +/**************************** + * Constructors + ****************************/ +RRGraphBuilder::RRGraphBuilder(t_rr_graph_storage& node_storage, + RRSpatialLookup& node_lookup) + : node_storage_(node_storage), node_lookup_(node_lookup) { +} + +/**************************** + * Mutators + ****************************/ +t_rr_graph_storage& RRGraphBuilder::node_storage() { + return node_storage_; +} + +RRSpatialLookup& RRGraphBuilder::node_lookup() { + return node_lookup_; +} diff --git a/vpr/src/device/rr_graph_builder.h b/vpr/src/device/rr_graph_builder.h new file mode 100644 index 00000000000..b19e034ca4e --- /dev/null +++ b/vpr/src/device/rr_graph_builder.h @@ -0,0 +1,45 @@ +#ifndef RR_GRAPH_BUILDER_H +#define RR_GRAPH_BUILDER_H + +#include "rr_graph_storage.h" +#include "rr_spatial_lookup.h" + +/* A data structure allows data modification on a routing resource graph + * + * Note that the builder does not own the storage + * It serves a virtual protocol for + * - node_storage: store the node list + * - node_lookup: store a fast look-up for the nodes + * + * Note: + * - This is the only data structre allowed to modify a routing resource graph + * + */ +class RRGraphBuilder { + /**************** + * Constructors + ****************/ + public: + RRGraphBuilder(t_rr_graph_storage& node_storage, + RRSpatialLookup& node_lookup); + + /**************** + * Mutators + ****************/ + public: + /* Return a writable object for rr_nodes */ + t_rr_graph_storage& node_storage(); + /* Return a writable object for update the fast look-up of rr_node */ + RRSpatialLookup& node_lookup(); + + /**************** + * internal data storage + ****************/ + private: + /* node-level storage including edge storages */ + t_rr_graph_storage& node_storage_; + /* Fast look-up for rr nodes */ + RRSpatialLookup& node_lookup_; +}; + +#endif diff --git a/vpr/src/device/rr_graph_builder_view.cpp b/vpr/src/device/rr_graph_builder_view.cpp deleted file mode 100644 index 7493a65f414..00000000000 --- a/vpr/src/device/rr_graph_builder_view.cpp +++ /dev/null @@ -1,47 +0,0 @@ -/*************************************** - * Methods for Object RRGraphBuilderView - ***************************************/ -#include "vtr_assert.h" -#include "rr_graph_builder_view.h" - -/**************************** - * Constructors - ****************************/ -RRGraphBuilderView::RRGraphBuilderView(t_rr_graph_storage* node_storage, - t_rr_node_indices* rr_node_indices) { - node_storage_ = node_storage; - rr_node_indices_ = rr_node_indices; -} - -/**************************** - * Mutators - ****************************/ -void RRGraphBuilderView::add_node_to_fast_lookup(const RRNodeId& node, - const int& x, - const int& y, - const t_rr_type& type, - const int& ptc, - const e_side& side) { - VTR_ASSERT_SAFE(3 == (*rr_node_indices_)[type].ndims()); - - /* Expand the fast look-up if the new node is out-of-range - * This may seldom happen because the rr_graph building function - * should ensure the fast look-up well organized - */ - VTR_ASSERT(type < (*rr_node_indices_).size()); - - if ((size_t(x) >= (*rr_node_indices_)[type].dim_size(0)) - || (size_t(y) >= (*rr_node_indices_)[type].dim_size(1)) - || (size_t(side) >= (*rr_node_indices_)[type].dim_size(2))) { - (*rr_node_indices_)[type].resize({std::max((*rr_node_indices_)[type].dim_size(0), size_t(x) + 1), - std::max((*rr_node_indices_)[type].dim_size(1), size_t(y) + 1), - std::max((*rr_node_indices_)[type].dim_size(2), size_t(side) + 1)}); - } - - if (size_t(ptc) >= (*rr_node_indices_)[type][x][y][side].size()) { - (*rr_node_indices_)[type][x][y][side].resize(ptc + 1); - } - - /* Resize on demand finished; Register the node */ - (*rr_node_indices_)[type][x][y][side][ptc] = int(size_t(node)); -} diff --git a/vpr/src/device/rr_graph_builder_view.h b/vpr/src/device/rr_graph_builder_view.h deleted file mode 100644 index 52bc69d52b9..00000000000 --- a/vpr/src/device/rr_graph_builder_view.h +++ /dev/null @@ -1,53 +0,0 @@ -#ifndef _RR_GRAPH_BUILDER_VIEW_ -#define _RR_GRAPH_BUILDER_VIEW_ - -#include - -#include "rr_graph_fwd.h" -#include "rr_node_fwd.h" -#include "rr_graph2.h" -#include "vtr_log.h" -#include "vtr_memory.h" -#include "vpr_utils.h" -#include "vtr_strong_id_range.h" -#include "vtr_array_view.h" -#include "rr_graph_storage.h" -#include "rr_graph_view.h" - -/* An builder of routing resource graph which extends - * the read-only frame view RRGraphView - * - * Note that the builder does not own the storage - * It serves a virtual protocol for - * - rr_graph builder, which requires both mutators and accessors - * - * Note: - * - This is the only data structre allowed to modify a routing resource graph - * - */ -class RRGraphBuilderView : public RRGraphView { - /**************** - * Constructors - ****************/ - public: - RRGraphBuilderView(t_rr_graph_storage* node_storage, - t_rr_node_indices* rr_node_indices); - - /**************** - * Accessors all come from RRGraph View - ****************/ - - /**************** - * Mutators - ****************/ - public: - /* Register a node in the fast look-up */ - void add_node_to_fast_lookup(const RRNodeId& node, - const int& x, - const int& y, - const t_rr_type& type, - const int& ptc, - const e_side& side); -}; - -#endif diff --git a/vpr/src/device/rr_graph_view.cpp b/vpr/src/device/rr_graph_view.cpp index 2f90c29dc19..1689ae523b3 100644 --- a/vpr/src/device/rr_graph_view.cpp +++ b/vpr/src/device/rr_graph_view.cpp @@ -1,87 +1,24 @@ /*************************************** * Methods for Object RRGraphView ***************************************/ -#include "vtr_assert.h" #include "rr_graph_view.h" /**************************** * Constructors ****************************/ -RRGraphView::RRGraphView() { - node_storage_ = nullptr; - rr_node_indices_ = nullptr; +RRGraphView::RRGraphView(t_rr_graph_storage& node_storage, + RRSpatialLookup& node_lookup) + : node_storage_(node_storage), node_lookup_(node_lookup) { } /**************************** * Accessors ****************************/ t_rr_type RRGraphView::node_type(const RRNodeId& node) const { - return node_storage_->node_type(node); + return node_storage_.node_type(node); } -RRNodeId RRGraphView::find_node(const int& x, - const int& y, - const t_rr_type& type, - const int& ptc, - const e_side& side) const { - /* Find actual side to be used */ - e_side node_side = side; - if (type == IPIN || type == OPIN) { - VTR_ASSERT_MSG(side != NUM_SIDES, "IPIN/OPIN must specify desired side (can not be default NUM_SIDES)"); - } else { - VTR_ASSERT(type != IPIN && type != OPIN); - node_side = SIDES[0]; - } - - /* Currently need to swap x and y for CHANX because of chan, seg convention */ - size_t node_x = x; - size_t node_y = y; - if (CHANX == type) { - std::swap(node_x, node_y); - } - - VTR_ASSERT_SAFE(3 == (*rr_node_indices_)[type].ndims()); - - /* Sanity check to ensure the x, y, side and ptc are in range - * Data type of rr_node_indice: - * typedef std::array, 3>, NUM_RR_TYPES> t_rr_node_indices; - * Note that x, y and side are the 1st, 2nd and 3rd dimensions of the vtr::NdMatrix - * ptc is in the std::vector - */ - if (size_t(type) >= (*rr_node_indices_).size()) { - /* Node type is out of range, return an invalid index */ - return RRNodeId::INVALID(); - } - - if (node_x >= (*rr_node_indices_)[type].dim_size(0)) { - /* Node x is out of range, return an invalid index */ - return RRNodeId::INVALID(); - } - - if (node_y >= (*rr_node_indices_)[type].dim_size(1)) { - /* Node y is out of range, return an invalid index */ - return RRNodeId::INVALID(); - } - - if (node_side >= (*rr_node_indices_)[type].dim_size(2)) { - /* Node side is out of range, return an invalid index */ - return RRNodeId::INVALID(); - } - - if (size_t(ptc) >= (*rr_node_indices_)[type][node_x][node_y][node_side].size()) { - /* Ptc is out of range, return an invalid index */ - return RRNodeId::INVALID(); - } - - /* Reaching here, it means that node exists in the look-up, return the id */ - return RRNodeId((*rr_node_indices_)[type][node_x][node_y][node_side][ptc]); -} - -/**************************** - * Mutators - ****************************/ -void RRGraphView::set_internal_data(t_rr_graph_storage* node_storage, - t_rr_node_indices* rr_node_indices) { - node_storage_ = node_storage; - rr_node_indices_ = rr_node_indices; +const RRSpatialLookup& RRGraphView::node_lookup() const { + /* Return a constant object rather than a writable one */ + return const_cast(node_lookup_); } diff --git a/vpr/src/device/rr_graph_view.h b/vpr/src/device/rr_graph_view.h index 27cafd19cc4..2de6b614b0a 100644 --- a/vpr/src/device/rr_graph_view.h +++ b/vpr/src/device/rr_graph_view.h @@ -1,24 +1,15 @@ -#ifndef _RR_GRAPH_OVERLAY_ -#define _RR_GRAPH_OVERLAY_ +#ifndef RR_GRAPH_VIEW_H +#define RR_GRAPH_VIEW_H -#include - -#include "rr_graph_fwd.h" -#include "rr_node_fwd.h" -#include "rr_graph2.h" -#include "vtr_log.h" -#include "vtr_memory.h" -#include "vpr_utils.h" -#include "vtr_strong_id_range.h" -#include "vtr_array_view.h" #include "rr_graph_storage.h" +#include "rr_spatial_lookup.h" /* An read-only routing resource graph * which is an unified object including pointors to * - node storage - * - edge_storage - * - node_ptc_storage - * - node_fan_in_storage + * - TODO: edge_storage + * - TODO: node_ptc_storage + * - TODO: node_fan_in_storage * - rr_node_indices * * Note that the RRGraphView does not own the storage @@ -45,7 +36,8 @@ class RRGraphView { * Constructors ****************/ public: - RRGraphView(); + RRGraphView(t_rr_graph_storage& node_storage, + RRSpatialLookup& node_lookup); /**************** * Accessors @@ -54,46 +46,17 @@ class RRGraphView { /* Get the type of a routing resource node */ t_rr_type node_type(const RRNodeId& node) const; - /* Returns the index of the specified routing resource node. (x,y) are - * the location within the FPGA, rr_type specifies the type of resource, - * and ptc gives the number of this resource. ptc is the class number, - * pin number or track number, depending on what type of resource this - * is. All ptcs start at 0 and go up to pins_per_clb-1 or the equivalent. - * There are class_inf size SOURCEs + SINKs, type->num_pins IPINs + OPINs, - * and max_chan_width CHANX and CHANY (each). - * - * Note that for segments (CHANX and CHANY) of length > 1, the segment is - * given an rr_index based on the (x,y) location at which it starts (i.e. - * lowest (x,y) location at which this segment exists). - * This routine also performs error checking to make sure the node in - * question exists. - * - * The 'side' argument only applies to IPIN/OPIN types, and specifies which - * side of the grid tile the node should be located on. The value is ignored - * for non-IPIN/OPIN types - */ - RRNodeId find_node(const int& x, - const int& y, - const t_rr_type& type, - const int& ptc, - const e_side& side = NUM_SIDES) const; - - /**************** - * Mutators - ****************/ - public: - /* The ONLY mutators allowed */ - void set_internal_data(t_rr_graph_storage* node_storage, - t_rr_node_indices* rr_node_indices); + /* Return a read-only object for performing fast look-up in rr_node */ + const RRSpatialLookup& node_lookup() const; /**************** - * internal data storage, can be accessed by parent class RRGraphBuilderView + * internal data storage ****************/ - protected: + private: /* node-level storage including edge storages */ - t_rr_graph_storage* node_storage_; - /* Fast look-up */ - t_rr_node_indices* rr_node_indices_; + t_rr_graph_storage& node_storage_; + /* Fast look-up for rr nodes */ + RRSpatialLookup& node_lookup_; }; #endif diff --git a/vpr/src/device/rr_spatial_lookup.cpp b/vpr/src/device/rr_spatial_lookup.cpp new file mode 100644 index 00000000000..32968cec5b5 --- /dev/null +++ b/vpr/src/device/rr_spatial_lookup.cpp @@ -0,0 +1,106 @@ +/*************************************** + * Methods for Object RRSpatialLookup + ***************************************/ +#include "vtr_assert.h" +#include "rr_spatial_lookup.h" + +/**************************** + * Constructors + ****************************/ +RRSpatialLookup::RRSpatialLookup(t_rr_node_indices& rr_node_indices) + : rr_node_indices_(rr_node_indices) { +} + +/**************************** + * Accessors + ****************************/ +RRNodeId RRSpatialLookup::find_node(int x, + int y, + t_rr_type type, + int ptc, + e_side side) const { + /* Find actual side to be used */ + e_side node_side = side; + if (type == IPIN || type == OPIN) { + VTR_ASSERT_MSG(side != NUM_SIDES, "IPIN/OPIN must specify desired side (can not be default NUM_SIDES)"); + } else { + VTR_ASSERT(type != IPIN && type != OPIN); + node_side = SIDES[0]; + } + + /* Currently need to swap x and y for CHANX because of chan, seg convention */ + size_t node_x = x; + size_t node_y = y; + if (CHANX == type) { + std::swap(node_x, node_y); + } + + VTR_ASSERT_SAFE(3 == rr_node_indices_[type].ndims()); + + /* Sanity check to ensure the x, y, side and ptc are in range + * Data type of rr_node_indice: + * typedef std::array, 3>, NUM_RR_TYPES> t_rr_node_indices; + * Note that x, y and side are the 1st, 2nd and 3rd dimensions of the vtr::NdMatrix + * ptc is in the std::vector + */ + if (size_t(type) >= rr_node_indices_.size()) { + /* Node type is out of range, return an invalid index */ + return RRNodeId::INVALID(); + } + + if (node_x >= rr_node_indices_[type].dim_size(0)) { + /* Node x is out of range, return an invalid index */ + return RRNodeId::INVALID(); + } + + if (node_y >= rr_node_indices_[type].dim_size(1)) { + /* Node y is out of range, return an invalid index */ + return RRNodeId::INVALID(); + } + + if (node_side >= rr_node_indices_[type].dim_size(2)) { + /* Node side is out of range, return an invalid index */ + return RRNodeId::INVALID(); + } + + if (size_t(ptc) >= rr_node_indices_[type][node_x][node_y][node_side].size()) { + /* Ptc is out of range, return an invalid index */ + return RRNodeId::INVALID(); + } + + /* Reaching here, it means that node exists in the look-up, return the id */ + return RRNodeId(rr_node_indices_[type][node_x][node_y][node_side][ptc]); +} + +/**************************** + * Mutators + ****************************/ +void RRSpatialLookup::add_node(RRNodeId node, + int x, + int y, + t_rr_type type, + int ptc, + e_side side) { + VTR_ASSERT_SAFE(3 == rr_node_indices_[type].ndims()); + + /* Expand the fast look-up if the new node is out-of-range + * This may seldom happen because the rr_graph building function + * should ensure the fast look-up well organized + */ + VTR_ASSERT(type < rr_node_indices_.size()); + + if ((size_t(x) >= rr_node_indices_[type].dim_size(0)) + || (size_t(y) >= rr_node_indices_[type].dim_size(1)) + || (size_t(side) >= rr_node_indices_[type].dim_size(2))) { + rr_node_indices_[type].resize({std::max(rr_node_indices_[type].dim_size(0), size_t(x) + 1), + std::max(rr_node_indices_[type].dim_size(1), size_t(y) + 1), + std::max(rr_node_indices_[type].dim_size(2), size_t(side) + 1)}); + } + + if (size_t(ptc) >= rr_node_indices_[type][x][y][side].size()) { + rr_node_indices_[type][x][y][side].resize(ptc + 1); + } + + /* Resize on demand finished; Register the node */ + rr_node_indices_[type][x][y][side][ptc] = int(size_t(node)); +} diff --git a/vpr/src/device/rr_spatial_lookup.h b/vpr/src/device/rr_spatial_lookup.h new file mode 100644 index 00000000000..7c717b7f4b4 --- /dev/null +++ b/vpr/src/device/rr_spatial_lookup.h @@ -0,0 +1,69 @@ +#ifndef RR_SPATIAL_LOOKUP_H +#define RR_SPATIAL_LOOKUP_H + +#include "vpr_types.h" + +/******************************************************************** + * A data structure storing the fast look-up for the nodes + * in a routing resource graph + * + * The data structure allows users to + * - Update the look-up with new nodes + * - Find the id of a node with given information, e.g., x, y, type etc. + ********************************************************************/ +class RRSpatialLookup { + /**************** + * Constructors + ****************/ + public: + RRSpatialLookup(t_rr_node_indices& rr_node_indices); + + /**************** + * Accessors + ****************/ + public: + /* Returns the index of the specified routing resource node. (x,y) are + * the location within the FPGA, rr_type specifies the type of resource, + * and ptc gives the number of this resource. ptc is the class number, + * pin number or track number, depending on what type of resource this + * is. All ptcs start at 0 and go up to pins_per_clb-1 or the equivalent. + * There are class_inf size SOURCEs + SINKs, type->num_pins IPINs + OPINs, + * and max_chan_width CHANX and CHANY (each). + * + * Note that for segments (CHANX and CHANY) of length > 1, the segment is + * given an rr_index based on the (x,y) location at which it starts (i.e. + * lowest (x,y) location at which this segment exists). + * This routine also performs error checking to make sure the node in + * question exists. + * + * The 'side' argument only applies to IPIN/OPIN types, and specifies which + * side of the grid tile the node should be located on. The value is ignored + * for non-IPIN/OPIN types + */ + RRNodeId find_node(int x, + int y, + t_rr_type type, + int ptc, + e_side side = NUM_SIDES) const; + + /**************** + * Mutators + ****************/ + public: + /* Register a node in the fast look-up */ + void add_node(RRNodeId node, + int x, + int y, + t_rr_type type, + int ptc, + e_side side); + + /**************** + * internal data storage + ****************/ + private: + /* Fast look-up */ + t_rr_node_indices& rr_node_indices_; +}; + +#endif diff --git a/vpr/src/place/timing_place_lookup.cpp b/vpr/src/place/timing_place_lookup.cpp index e3afc4a9b8a..102e5dd0f4f 100644 --- a/vpr/src/place/timing_place_lookup.cpp +++ b/vpr/src/place/timing_place_lookup.cpp @@ -350,14 +350,14 @@ static float route_connection_delay( for (int driver_ptc : best_driver_ptcs) { VTR_ASSERT(driver_ptc != OPEN); - RRNodeId source_rr_node = device_ctx.rr_graph.find_node(source_x, source_y, SOURCE, driver_ptc); + RRNodeId source_rr_node = device_ctx.rr_graph.node_lookup().find_node(source_x, source_y, SOURCE, driver_ptc); VTR_ASSERT(source_rr_node != RRNodeId::INVALID()); for (int sink_ptc : best_sink_ptcs) { VTR_ASSERT(sink_ptc != OPEN); - RRNodeId sink_rr_node = device_ctx.rr_graph.find_node(sink_x, sink_y, SINK, sink_ptc); + RRNodeId sink_rr_node = device_ctx.rr_graph.node_lookup().find_node(sink_x, sink_y, SINK, sink_ptc); VTR_ASSERT(sink_rr_node != RRNodeId::INVALID()); @@ -444,7 +444,7 @@ static void generic_compute_matrix_dijkstra_expansion( auto best_driver_ptcs = get_best_classes(DRIVER, device_ctx.grid[source_x][source_y].type); for (int driver_ptc : best_driver_ptcs) { VTR_ASSERT(driver_ptc != OPEN); - RRNodeId source_rr_node = device_ctx.rr_graph.find_node(source_x, source_y, SOURCE, driver_ptc); + RRNodeId source_rr_node = device_ctx.rr_graph.node_lookup().find_node(source_x, source_y, SOURCE, driver_ptc); VTR_ASSERT(source_rr_node != RRNodeId::INVALID()); auto delays = calculate_all_path_delays_from_rr_node(size_t(source_rr_node), router_opts); @@ -479,7 +479,7 @@ static void generic_compute_matrix_dijkstra_expansion( for (int sink_ptc : best_sink_ptcs) { VTR_ASSERT(sink_ptc != OPEN); - RRNodeId sink_rr_node = device_ctx.rr_graph.find_node(sink_x, sink_y, SINK, sink_ptc); + RRNodeId sink_rr_node = device_ctx.rr_graph.node_lookup().find_node(sink_x, sink_y, SINK, sink_ptc); VTR_ASSERT(sink_rr_node != RRNodeId::INVALID()); @@ -979,7 +979,7 @@ static bool find_direct_connect_sample_locations(const t_direct_inf* direct, //(with multi-width/height blocks pins may not exist at all locations) bool from_pin_found = false; if (direct->from_side != NUM_SIDES) { - RRNodeId from_pin_rr = device_ctx.rr_graph.find_node(from_x, from_y, OPIN, from_pin, direct->from_side); + RRNodeId from_pin_rr = device_ctx.rr_graph.node_lookup().find_node(from_x, from_y, OPIN, from_pin, direct->from_side); from_pin_found = (from_pin_rr != RRNodeId::INVALID()); } else { std::vector& from_pin_rrs = *scratch; @@ -997,7 +997,7 @@ static bool find_direct_connect_sample_locations(const t_direct_inf* direct, //(with multi-width/height blocks pins may not exist at all locations) bool to_pin_found = false; if (direct->to_side != NUM_SIDES) { - RRNodeId to_pin_rr = device_ctx.rr_graph.find_node(to_x, to_y, IPIN, to_pin, direct->to_side); + RRNodeId to_pin_rr = device_ctx.rr_graph.node_lookup().find_node(to_x, to_y, IPIN, to_pin, direct->to_side); to_pin_found = (to_pin_rr != RRNodeId::INVALID()); } else { std::vector& to_pin_rrs = *scratch; diff --git a/vpr/src/route/check_rr_graph.cpp b/vpr/src/route/check_rr_graph.cpp index 6580da8a896..582037dbcec 100644 --- a/vpr/src/route/check_rr_graph.cpp +++ b/vpr/src/route/check_rr_graph.cpp @@ -574,8 +574,8 @@ static void check_unbuffered_edges(int from_node) { } static bool has_adjacent_channel(const t_rr_node& node, const DeviceGrid& grid) { - /* TODO: this function should be reworked later to adapt overlay interface - * once xlow(), ylow(), side() APIs are implemented in overlay interface + /* TODO: this function should be reworked later to adapt RRGraphView interface + * once xlow(), ylow(), side() APIs are implemented */ VTR_ASSERT(node.type() == IPIN || node.type() == OPIN); diff --git a/vpr/src/route/rr_graph.cpp b/vpr/src/route/rr_graph.cpp index 37a3c2a614e..508604b74e3 100644 --- a/vpr/src/route/rr_graph.cpp +++ b/vpr/src/route/rr_graph.cpp @@ -573,8 +573,10 @@ static void build_rr_graph(const t_graph_type graph_type, /* Alloc node lookups, count nodes, alloc rr nodes */ int num_rr_nodes = 0; - device_ctx.rr_node_indices = alloc_and_load_rr_node_indices(max_chan_width, grid, - &num_rr_nodes, chan_details_x, chan_details_y); + alloc_and_load_rr_node_indices(device_ctx.rr_node_indices, + max_chan_width, grid, + &num_rr_nodes, chan_details_x, chan_details_y); + size_t expected_node_count = num_rr_nodes; if (clock_modeling == DEDICATED_NETWORK) { expected_node_count += ClockRRGraphBuilder::estimate_additional_nodes(grid); @@ -735,10 +737,6 @@ static void build_rr_graph(const t_graph_type graph_type, rr_graph_externals(segment_inf, *wire_to_rr_ipin_switch, base_cost_type); - /* Update RRGraph overlay with new data pointers */ - device_ctx.rr_graph.set_internal_data(&(device_ctx.rr_nodes), - &(device_ctx.rr_node_indices)); - check_rr_graph(graph_type, grid, types); /* Free all temp structs */ diff --git a/vpr/src/route/rr_graph2.cpp b/vpr/src/route/rr_graph2.cpp index a4b03b4dd21..422922b4078 100644 --- a/vpr/src/route/rr_graph2.cpp +++ b/vpr/src/route/rr_graph2.cpp @@ -16,7 +16,7 @@ #include "read_xml_arch_file.h" #include "rr_types.h" -#include "rr_graph_builder_view.h" +#include "rr_graph_builder.h" constexpr short UN_SET = -1; @@ -978,8 +978,8 @@ static void load_block_rr_indices(const DeviceGrid& grid, /* As the rr_indices builders modify a local copy of indices, use the local copy in the builder * TODO: these building functions should only talk to a RRGraphBuilderView object */ - RRGraphBuilderView rr_graph_builder_view(&(g_vpr_ctx.mutable_device().rr_nodes), - &indices); + RRGraphBuilder rr_graph_builder(g_vpr_ctx.mutable_device().rr_nodes, + g_vpr_ctx.mutable_device().rr_spatial_lookup); //Walk through the grid assigning indices to SOURCE/SINK IPIN/OPIN for (size_t x = 0; x < grid.width(); x++) { @@ -993,12 +993,12 @@ static void load_block_rr_indices(const DeviceGrid& grid, for (size_t iclass = 0; iclass < type->class_inf.size(); ++iclass) { auto class_type = type->class_inf[iclass].type; if (class_type == DRIVER) { - rr_graph_builder_view.add_node_to_fast_lookup(RRNodeId(*index), x, y, SOURCE, iclass, SIDES[0]); - rr_graph_builder_view.add_node_to_fast_lookup(RRNodeId::INVALID(), x, y, SINK, iclass, SIDES[0]); + rr_graph_builder.node_lookup().add_node(RRNodeId(*index), x, y, SOURCE, iclass, SIDES[0]); + rr_graph_builder.node_lookup().add_node(RRNodeId::INVALID(), x, y, SINK, iclass, SIDES[0]); } else { VTR_ASSERT(class_type == RECEIVER); - rr_graph_builder_view.add_node_to_fast_lookup(RRNodeId(*index), x, y, SINK, iclass, SIDES[0]); - rr_graph_builder_view.add_node_to_fast_lookup(RRNodeId::INVALID(), x, y, SOURCE, iclass, SIDES[0]); + rr_graph_builder.node_lookup().add_node(RRNodeId(*index), x, y, SINK, iclass, SIDES[0]); + rr_graph_builder.node_lookup().add_node(RRNodeId::INVALID(), x, y, SOURCE, iclass, SIDES[0]); } ++(*index); } @@ -1142,17 +1142,16 @@ static void load_block_rr_indices(const DeviceGrid& grid, } } -t_rr_node_indices alloc_and_load_rr_node_indices(const int max_chan_width, - const DeviceGrid& grid, - int* index, - const t_chan_details& chan_details_x, - const t_chan_details& chan_details_y) { +void alloc_and_load_rr_node_indices(t_rr_node_indices& indices, + const int max_chan_width, + const DeviceGrid& grid, + int* index, + const t_chan_details& chan_details_x, + const t_chan_details& chan_details_y) { /* Allocates and loads all the structures needed for fast lookups of the * * index of an rr_node. rr_node_indices is a matrix containing the index * * of the *first* rr_node at a given (i,j) location. */ - t_rr_node_indices indices; - /* Alloc the lookup table */ for (t_rr_type rr_type : RR_TYPES) { if (rr_type == CHANX) { @@ -1170,8 +1169,6 @@ t_rr_node_indices alloc_and_load_rr_node_indices(const int max_chan_width, CHANX, chan_details_x, indices, index); load_chan_rr_indices(max_chan_width, grid.height(), grid.width(), CHANY, chan_details_y, indices, index); - - return indices; } bool verify_rr_node_indices(const DeviceGrid& grid, const t_rr_node_indices& rr_node_indices, const t_rr_graph_storage& rr_nodes) { diff --git a/vpr/src/route/rr_graph2.h b/vpr/src/route/rr_graph2.h index 2b3bd22de25..09467afcdd3 100644 --- a/vpr/src/route/rr_graph2.h +++ b/vpr/src/route/rr_graph2.h @@ -44,11 +44,12 @@ struct t_opin_connections_scratchpad { /******************* Subroutines exported by rr_graph2.c *********************/ -t_rr_node_indices alloc_and_load_rr_node_indices(const int max_chan_width, - const DeviceGrid& grid, - int* index, - const t_chan_details& chan_details_x, - const t_chan_details& chan_details_y); +void alloc_and_load_rr_node_indices(t_rr_node_indices& indices, + const int max_chan_width, + const DeviceGrid& grid, + int* index, + const t_chan_details& chan_details_x, + const t_chan_details& chan_details_y); bool verify_rr_node_indices(const DeviceGrid& grid, const t_rr_node_indices& rr_node_indices, const t_rr_graph_storage& rr_nodes); diff --git a/vpr/src/route/rr_graph_reader.cpp b/vpr/src/route/rr_graph_reader.cpp index 1d47e4c156a..d76ca4fdcf9 100644 --- a/vpr/src/route/rr_graph_reader.cpp +++ b/vpr/src/route/rr_graph_reader.cpp @@ -58,7 +58,6 @@ void load_rr_file(const t_graph_type graph_type, &device_ctx.read_rr_graph_filename, read_edge_metadata, &device_ctx.chan_width, - &device_ctx.rr_graph, &device_ctx.rr_nodes, &device_ctx.rr_switch_inf, &device_ctx.rr_indexed_data, diff --git a/vpr/src/route/rr_graph_uxsdcxx_serializer.h b/vpr/src/route/rr_graph_uxsdcxx_serializer.h index 9d8a9dcfafc..958e9655bd5 100644 --- a/vpr/src/route/rr_graph_uxsdcxx_serializer.h +++ b/vpr/src/route/rr_graph_uxsdcxx_serializer.h @@ -16,7 +16,6 @@ #include "check_rr_graph.h" #include "rr_graph2.h" #include "rr_graph_indexed_data.h" -#include "rr_graph_view.h" class MetadataBind { public: @@ -259,7 +258,6 @@ class RrGraphSerializer final : public uxsd::RrGraphBase { std::string* read_rr_graph_filename, bool read_edge_metadata, t_chan_width* chan_width, - RRGraphView* rr_graph, t_rr_graph_storage* rr_nodes, std::vector* rr_switch_inf, std::vector* rr_indexed_data, @@ -274,7 +272,6 @@ class RrGraphSerializer final : public uxsd::RrGraphBase { vtr::string_internment* strings) : wire_to_rr_ipin_switch_(wire_to_rr_ipin_switch) , chan_width_(chan_width) - , rr_graph_(rr_graph) , rr_nodes_(rr_nodes) , rr_switch_inf_(rr_switch_inf) , rr_indexed_data_(rr_indexed_data) @@ -1537,10 +1534,6 @@ class RrGraphSerializer final : public uxsd::RrGraphBase { VTR_ASSERT(read_rr_graph_name_ != nullptr); read_rr_graph_filename_->assign(read_rr_graph_name_); - /* Update RRGraph viewer with new data pointers */ - rr_graph_->set_internal_data(rr_nodes_, - rr_node_indices_); - if (do_check_rr_graph_) { check_rr_graph(graph_type_, grid_, physical_tile_types_); } diff --git a/vpr/src/route/rr_graph_writer.cpp b/vpr/src/route/rr_graph_writer.cpp index 01b13659868..86fed376c05 100644 --- a/vpr/src/route/rr_graph_writer.cpp +++ b/vpr/src/route/rr_graph_writer.cpp @@ -36,7 +36,6 @@ void write_rr_graph(const char* file_name) { /*read_rr_graph_filename=*/nullptr, /*read_edge_metadata=*/false, &device_ctx.chan_width, - &device_ctx.rr_graph, &device_ctx.rr_nodes, &device_ctx.rr_switch_inf, &device_ctx.rr_indexed_data, From 6ae10164e3371145a6bfa2c7b83170d1d505f88e Mon Sep 17 00:00:00 2001 From: tangxifan Date: Wed, 7 Apr 2021 18:05:49 -0600 Subject: [PATCH 13/22] [VPR] code format fix; add comments to API --- vpr/src/base/vpr_context.h | 2 +- vpr/src/device/rr_graph_builder.cpp | 3 ++- vpr/src/device/rr_graph_view.cpp | 7 ++++--- vpr/src/device/rr_spatial_lookup.h | 10 +++++++++- 4 files changed, 16 insertions(+), 6 deletions(-) diff --git a/vpr/src/base/vpr_context.h b/vpr/src/base/vpr_context.h index a917c9725f6..02f4e9ed994 100644 --- a/vpr/src/base/vpr_context.h +++ b/vpr/src/base/vpr_context.h @@ -150,7 +150,7 @@ struct DeviceContext : public Context { /* TODO: remove this interface from device_context once the code refactoring is completed * because it should be part of the rr_graph view - */ + */ RRSpatialLookup rr_spatial_lookup = RRSpatialLookup(rr_node_indices); t_rr_graph_storage rr_nodes; // autogenerated in build_rr_graph diff --git a/vpr/src/device/rr_graph_builder.cpp b/vpr/src/device/rr_graph_builder.cpp index 489d3226c12..e2a59685aec 100644 --- a/vpr/src/device/rr_graph_builder.cpp +++ b/vpr/src/device/rr_graph_builder.cpp @@ -8,7 +8,8 @@ ****************************/ RRGraphBuilder::RRGraphBuilder(t_rr_graph_storage& node_storage, RRSpatialLookup& node_lookup) - : node_storage_(node_storage), node_lookup_(node_lookup) { + : node_storage_(node_storage) + , node_lookup_(node_lookup) { } /**************************** diff --git a/vpr/src/device/rr_graph_view.cpp b/vpr/src/device/rr_graph_view.cpp index 1689ae523b3..6367e98a3ca 100644 --- a/vpr/src/device/rr_graph_view.cpp +++ b/vpr/src/device/rr_graph_view.cpp @@ -8,7 +8,8 @@ ****************************/ RRGraphView::RRGraphView(t_rr_graph_storage& node_storage, RRSpatialLookup& node_lookup) - : node_storage_(node_storage), node_lookup_(node_lookup) { + : node_storage_(node_storage) + , node_lookup_(node_lookup) { } /**************************** @@ -19,6 +20,6 @@ t_rr_type RRGraphView::node_type(const RRNodeId& node) const { } const RRSpatialLookup& RRGraphView::node_lookup() const { - /* Return a constant object rather than a writable one */ - return const_cast(node_lookup_); + /* Return a constant object rather than a writable one */ + return const_cast(node_lookup_); } diff --git a/vpr/src/device/rr_spatial_lookup.h b/vpr/src/device/rr_spatial_lookup.h index 7c717b7f4b4..afeb86f54ec 100644 --- a/vpr/src/device/rr_spatial_lookup.h +++ b/vpr/src/device/rr_spatial_lookup.h @@ -50,7 +50,15 @@ class RRSpatialLookup { * Mutators ****************/ public: - /* Register a node in the fast look-up */ + /* Register a node in the fast look-up + * - You must have a node id + * - (x, y) are the coordinate of the node to be indexable in the fast look-up + * - type is the type of a node + * - ptc is a feature number of a node, which can be + * 1. pin index in a tile when type is OPIN/IPIN + * 2. track index in a routing channel when type is CHANX/CHANY + * - side is the side of node on the tile, applicable to OPIN/IPIN + */ void add_node(RRNodeId node, int x, int y, From 7c0169cc9872a9046847540007f4adfa884251eb Mon Sep 17 00:00:00 2001 From: tangxifan Date: Fri, 9 Apr 2021 17:28:58 -0600 Subject: [PATCH 14/22] [VPR] Add comments to explain why references are currently used in RRGraphBuilder/RRSpatialLookup --- vpr/src/device/rr_graph_builder.h | 9 +++++++++ vpr/src/device/rr_spatial_lookup.h | 14 ++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/vpr/src/device/rr_graph_builder.h b/vpr/src/device/rr_graph_builder.h index b19e034ca4e..f2c83ee5580 100644 --- a/vpr/src/device/rr_graph_builder.h +++ b/vpr/src/device/rr_graph_builder.h @@ -36,6 +36,15 @@ class RRGraphBuilder { * internal data storage ****************/ private: + /* TODO: When the refactoring effort finishes, + * the builder data structure will be the owner of the data storages. + * That is why the reference to storage/lookup is used here. + * It can avoid a lot of code changes once the refactoring is finished + * (there is no function get data directly through the node_storage in DeviceContext). + * If pointers are used, it may cause many codes in client functions + * or inside the data structures to be changed later. + * That explains why the reference is used here temporarily + */ /* node-level storage including edge storages */ t_rr_graph_storage& node_storage_; /* Fast look-up for rr nodes */ diff --git a/vpr/src/device/rr_spatial_lookup.h b/vpr/src/device/rr_spatial_lookup.h index afeb86f54ec..44e656e4bd1 100644 --- a/vpr/src/device/rr_spatial_lookup.h +++ b/vpr/src/device/rr_spatial_lookup.h @@ -52,12 +52,17 @@ class RRSpatialLookup { public: /* Register a node in the fast look-up * - You must have a node id + * 1. a valid one is to register a node in the lookup + * 2. an invalid id means the removal of a node from the lookup * - (x, y) are the coordinate of the node to be indexable in the fast look-up * - type is the type of a node * - ptc is a feature number of a node, which can be * 1. pin index in a tile when type is OPIN/IPIN * 2. track index in a routing channel when type is CHANX/CHANY * - side is the side of node on the tile, applicable to OPIN/IPIN + * + * Note that the add node here will not create a node in the node list + * You MUST add the node in the t_rr_node_storage so that the node is valid */ void add_node(RRNodeId node, int x, @@ -70,6 +75,15 @@ class RRSpatialLookup { * internal data storage ****************/ private: + /* TODO: When the refactoring effort finishes, + * the data structure will be the owner of the data storages. + * That is why the reference is used here. + * It can avoid a lot of code changes once the refactoring is finished + * (there is no function get data directly through the rr_node_indices in DeviceContext). + * If pointers are used, it may cause many codes in client functions + * or inside the data structures to be changed later. + * That explains why the reference is used here temporarily + */ /* Fast look-up */ t_rr_node_indices& rr_node_indices_; }; From 77f632eeedb3728c84c20e78bdbefe1e3ae15b7d Mon Sep 17 00:00:00 2001 From: tangxifan Date: Wed, 14 Apr 2021 20:05:44 -0600 Subject: [PATCH 15/22] [VPR] Add protection to RRGraphBuilder, RRGraphView and RRSpatial to avoid illegal copy/constructors --- vpr/src/base/vpr_context.h | 17 ++++++++++------- vpr/src/device/rr_graph_builder.cpp | 8 ++++---- vpr/src/device/rr_graph_builder.h | 13 +++++++++++-- vpr/src/device/rr_graph_view.cpp | 8 ++++---- vpr/src/device/rr_graph_view.h | 19 ++++++++++++++----- vpr/src/device/rr_spatial_lookup.cpp | 10 ++++++---- vpr/src/device/rr_spatial_lookup.h | 18 +++++++++++++++++- vpr/src/route/rr_graph2.cpp | 4 ++-- 8 files changed, 68 insertions(+), 29 deletions(-) diff --git a/vpr/src/base/vpr_context.h b/vpr/src/base/vpr_context.h index 02f4e9ed994..cd0efbd199e 100644 --- a/vpr/src/base/vpr_context.h +++ b/vpr/src/base/vpr_context.h @@ -146,13 +146,6 @@ struct DeviceContext : public Context { /* * Structures to define the routing architecture of the FPGA. */ - RRGraphView rr_graph = RRGraphView(rr_nodes, rr_spatial_lookup); // A read-only view of routing resource graph to be the ONLY database for client functions: GUI, placer, router, timing analyzer etc. - - /* TODO: remove this interface from device_context once the code refactoring is completed - * because it should be part of the rr_graph view - */ - RRSpatialLookup rr_spatial_lookup = RRSpatialLookup(rr_node_indices); - t_rr_graph_storage rr_nodes; // autogenerated in build_rr_graph std::vector rr_indexed_data; // [0 .. num_rr_indexed_data-1] @@ -169,6 +162,16 @@ struct DeviceContext : public Context { ///@brief The indicies of rr nodes of a given type at a specific x,y grid location t_rr_node_indices rr_node_indices; // [0..NUM_RR_TYPES-1][0..grid.width()-1][0..grid.width()-1][0..size-1] + /* A read-only view of routing resource graph to be the ONLY database + * for client functions: GUI, placer, router, timing analyzer etc. + */ + RRGraphView rr_graph{rr_nodes, rr_spatial_lookup}; + + /* TODO: remove this interface from device_context once the code refactoring is completed + * because it should be part of the rr_graph view + */ + RRSpatialLookup rr_spatial_lookup{rr_node_indices}; + ///@brief Autogenerated in build_rr_graph based on switch fan-in. [0..(num_rr_switches-1)] std::vector rr_switch_inf; diff --git a/vpr/src/device/rr_graph_builder.cpp b/vpr/src/device/rr_graph_builder.cpp index e2a59685aec..a5d74376e11 100644 --- a/vpr/src/device/rr_graph_builder.cpp +++ b/vpr/src/device/rr_graph_builder.cpp @@ -6,10 +6,10 @@ /**************************** * Constructors ****************************/ -RRGraphBuilder::RRGraphBuilder(t_rr_graph_storage& node_storage, - RRSpatialLookup& node_lookup) - : node_storage_(node_storage) - , node_lookup_(node_lookup) { +RRGraphBuilder::RRGraphBuilder(t_rr_graph_storage* node_storage, + RRSpatialLookup* node_lookup) + : node_storage_(*node_storage) + , node_lookup_(*node_lookup) { } /**************************** diff --git a/vpr/src/device/rr_graph_builder.h b/vpr/src/device/rr_graph_builder.h index f2c83ee5580..6876d17abdc 100644 --- a/vpr/src/device/rr_graph_builder.h +++ b/vpr/src/device/rr_graph_builder.h @@ -20,8 +20,17 @@ class RRGraphBuilder { * Constructors ****************/ public: - RRGraphBuilder(t_rr_graph_storage& node_storage, - RRSpatialLookup& node_lookup); + RRGraphBuilder(t_rr_graph_storage* node_storage, + RRSpatialLookup* node_lookup); + + /* Disable copy constructors + * This is to avoid any duplication of the object + * as it is only interface allowed to modify routing resource graph + */ + RRGraphBuilder(const RRGraphBuilder&) = delete; + + /* Disable copy assignment operator */ + void operator=(const RRGraphBuilder&) = delete; /**************** * Mutators diff --git a/vpr/src/device/rr_graph_view.cpp b/vpr/src/device/rr_graph_view.cpp index 6367e98a3ca..16e03585524 100644 --- a/vpr/src/device/rr_graph_view.cpp +++ b/vpr/src/device/rr_graph_view.cpp @@ -6,8 +6,8 @@ /**************************** * Constructors ****************************/ -RRGraphView::RRGraphView(t_rr_graph_storage& node_storage, - RRSpatialLookup& node_lookup) +RRGraphView::RRGraphView(const t_rr_graph_storage& node_storage, + const RRSpatialLookup& node_lookup) : node_storage_(node_storage) , node_lookup_(node_lookup) { } @@ -15,11 +15,11 @@ RRGraphView::RRGraphView(t_rr_graph_storage& node_storage, /**************************** * Accessors ****************************/ -t_rr_type RRGraphView::node_type(const RRNodeId& node) const { +t_rr_type RRGraphView::node_type(RRNodeId node) const { return node_storage_.node_type(node); } const RRSpatialLookup& RRGraphView::node_lookup() const { /* Return a constant object rather than a writable one */ - return const_cast(node_lookup_); + return node_lookup_; } diff --git a/vpr/src/device/rr_graph_view.h b/vpr/src/device/rr_graph_view.h index 2de6b614b0a..b620f58556c 100644 --- a/vpr/src/device/rr_graph_view.h +++ b/vpr/src/device/rr_graph_view.h @@ -36,15 +36,24 @@ class RRGraphView { * Constructors ****************/ public: - RRGraphView(t_rr_graph_storage& node_storage, - RRSpatialLookup& node_lookup); + RRGraphView(const t_rr_graph_storage& node_storage, + const RRSpatialLookup& node_lookup); + + /* Disable copy constructors + * This is to avoid any duplication of the object + * as it is only interface allowed to access routing resource graph + */ + RRGraphView(const RRGraphView&) = delete; + + /* Disable copy assignment operator */ + void operator=(const RRGraphView&) = delete; /**************** * Accessors ****************/ public: /* Get the type of a routing resource node */ - t_rr_type node_type(const RRNodeId& node) const; + t_rr_type node_type(RRNodeId node) const; /* Return a read-only object for performing fast look-up in rr_node */ const RRSpatialLookup& node_lookup() const; @@ -54,9 +63,9 @@ class RRGraphView { ****************/ private: /* node-level storage including edge storages */ - t_rr_graph_storage& node_storage_; + const t_rr_graph_storage& node_storage_; /* Fast look-up for rr nodes */ - RRSpatialLookup& node_lookup_; + const RRSpatialLookup& node_lookup_; }; #endif diff --git a/vpr/src/device/rr_spatial_lookup.cpp b/vpr/src/device/rr_spatial_lookup.cpp index 32968cec5b5..e44b26e36eb 100644 --- a/vpr/src/device/rr_spatial_lookup.cpp +++ b/vpr/src/device/rr_spatial_lookup.cpp @@ -88,12 +88,14 @@ void RRSpatialLookup::add_node(RRNodeId node, * should ensure the fast look-up well organized */ VTR_ASSERT(type < rr_node_indices_.size()); + VTR_ASSERT(0 <= x); + VTR_ASSERT(0 <= y); - if ((size_t(x) >= rr_node_indices_[type].dim_size(0)) - || (size_t(y) >= rr_node_indices_[type].dim_size(1)) + if ((x >= int(rr_node_indices_[type].dim_size(0))) + || (y >= int(rr_node_indices_[type].dim_size(1))) || (size_t(side) >= rr_node_indices_[type].dim_size(2))) { - rr_node_indices_[type].resize({std::max(rr_node_indices_[type].dim_size(0), size_t(x) + 1), - std::max(rr_node_indices_[type].dim_size(1), size_t(y) + 1), + rr_node_indices_[type].resize({std::max(int(rr_node_indices_[type].dim_size(0)), x + 1), + std::max(int(rr_node_indices_[type].dim_size(1)), y + 1), std::max(rr_node_indices_[type].dim_size(2), size_t(side) + 1)}); } diff --git a/vpr/src/device/rr_spatial_lookup.h b/vpr/src/device/rr_spatial_lookup.h index 44e656e4bd1..ad1ae18f8f7 100644 --- a/vpr/src/device/rr_spatial_lookup.h +++ b/vpr/src/device/rr_spatial_lookup.h @@ -16,7 +16,17 @@ class RRSpatialLookup { * Constructors ****************/ public: - RRSpatialLookup(t_rr_node_indices& rr_node_indices); + /* Explicitly define the only way to create an object */ + explicit RRSpatialLookup(t_rr_node_indices& rr_node_indices); + + /* Disable copy constructors + * This is to avoid any duplication of the object + * as it is only interface allowed to access node look-up of a routing resource graph + */ + RRSpatialLookup(const RRSpatialLookup&) = delete; + + /* Disable copy assignment operator */ + void operator=(const RRSpatialLookup&) = delete; /**************** * Accessors @@ -63,6 +73,12 @@ class RRSpatialLookup { * * Note that the add node here will not create a node in the node list * You MUST add the node in the t_rr_node_storage so that the node is valid + * + * TODO: Consider to try to return a reference to *this so that we can do chain calls + * - .add_node(...) + * - .add_node(...) + * - .add_node(...) + * As such, multiple node addition could be efficiently implemented */ void add_node(RRNodeId node, int x, diff --git a/vpr/src/route/rr_graph2.cpp b/vpr/src/route/rr_graph2.cpp index 422922b4078..26a338de8e3 100644 --- a/vpr/src/route/rr_graph2.cpp +++ b/vpr/src/route/rr_graph2.cpp @@ -978,8 +978,8 @@ static void load_block_rr_indices(const DeviceGrid& grid, /* As the rr_indices builders modify a local copy of indices, use the local copy in the builder * TODO: these building functions should only talk to a RRGraphBuilderView object */ - RRGraphBuilder rr_graph_builder(g_vpr_ctx.mutable_device().rr_nodes, - g_vpr_ctx.mutable_device().rr_spatial_lookup); + RRGraphBuilder rr_graph_builder(&(g_vpr_ctx.mutable_device().rr_nodes), + &(g_vpr_ctx.mutable_device().rr_spatial_lookup)); //Walk through the grid assigning indices to SOURCE/SINK IPIN/OPIN for (size_t x = 0; x < grid.width(); x++) { From 0410c26c1ad8d5690d88bee13382aaccb32706ca Mon Sep 17 00:00:00 2001 From: tangxifan Date: Wed, 14 Apr 2021 20:12:25 -0600 Subject: [PATCH 16/22] [VPR] Code format fix --- vpr/src/base/vpr_context.h | 2 +- vpr/src/device/rr_graph_builder.h | 2 +- vpr/src/device/rr_graph_view.h | 2 +- vpr/src/device/rr_spatial_lookup.h | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/vpr/src/base/vpr_context.h b/vpr/src/base/vpr_context.h index cd0efbd199e..260fa6924b8 100644 --- a/vpr/src/base/vpr_context.h +++ b/vpr/src/base/vpr_context.h @@ -165,7 +165,7 @@ struct DeviceContext : public Context { /* A read-only view of routing resource graph to be the ONLY database * for client functions: GUI, placer, router, timing analyzer etc. */ - RRGraphView rr_graph{rr_nodes, rr_spatial_lookup}; + RRGraphView rr_graph{rr_nodes, rr_spatial_lookup}; /* TODO: remove this interface from device_context once the code refactoring is completed * because it should be part of the rr_graph view diff --git a/vpr/src/device/rr_graph_builder.h b/vpr/src/device/rr_graph_builder.h index 6876d17abdc..5824b3eebf4 100644 --- a/vpr/src/device/rr_graph_builder.h +++ b/vpr/src/device/rr_graph_builder.h @@ -28,7 +28,7 @@ class RRGraphBuilder { * as it is only interface allowed to modify routing resource graph */ RRGraphBuilder(const RRGraphBuilder&) = delete; - + /* Disable copy assignment operator */ void operator=(const RRGraphBuilder&) = delete; diff --git a/vpr/src/device/rr_graph_view.h b/vpr/src/device/rr_graph_view.h index b620f58556c..c93f9a4ad47 100644 --- a/vpr/src/device/rr_graph_view.h +++ b/vpr/src/device/rr_graph_view.h @@ -44,7 +44,7 @@ class RRGraphView { * as it is only interface allowed to access routing resource graph */ RRGraphView(const RRGraphView&) = delete; - + /* Disable copy assignment operator */ void operator=(const RRGraphView&) = delete; diff --git a/vpr/src/device/rr_spatial_lookup.h b/vpr/src/device/rr_spatial_lookup.h index ad1ae18f8f7..99d9466d0e1 100644 --- a/vpr/src/device/rr_spatial_lookup.h +++ b/vpr/src/device/rr_spatial_lookup.h @@ -24,7 +24,7 @@ class RRSpatialLookup { * as it is only interface allowed to access node look-up of a routing resource graph */ RRSpatialLookup(const RRSpatialLookup&) = delete; - + /* Disable copy assignment operator */ void operator=(const RRSpatialLookup&) = delete; From baad50435d77879e2e2e7c62862ca6692bff6905 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Wed, 14 Apr 2021 20:56:11 -0600 Subject: [PATCH 17/22] [VPR] Compiler warning fix --- vpr/src/device/rr_spatial_lookup.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/vpr/src/device/rr_spatial_lookup.cpp b/vpr/src/device/rr_spatial_lookup.cpp index e44b26e36eb..a84d276e014 100644 --- a/vpr/src/device/rr_spatial_lookup.cpp +++ b/vpr/src/device/rr_spatial_lookup.cpp @@ -94,8 +94,8 @@ void RRSpatialLookup::add_node(RRNodeId node, if ((x >= int(rr_node_indices_[type].dim_size(0))) || (y >= int(rr_node_indices_[type].dim_size(1))) || (size_t(side) >= rr_node_indices_[type].dim_size(2))) { - rr_node_indices_[type].resize({std::max(int(rr_node_indices_[type].dim_size(0)), x + 1), - std::max(int(rr_node_indices_[type].dim_size(1)), y + 1), + rr_node_indices_[type].resize({std::max(rr_node_indices_[type].dim_size(0), size_t(x) + 1), + std::max(rr_node_indices_[type].dim_size(1), size_t(y) + 1), std::max(rr_node_indices_[type].dim_size(2), size_t(side) + 1)}); } From 3b5aab5bc5722654ee785c0aca1d145aa80e9fdf Mon Sep 17 00:00:00 2001 From: tangxifan Date: Thu, 15 Apr 2021 11:01:30 -0600 Subject: [PATCH 18/22] [VPR] Add RRGraphBuilder to DeviceContext; Identify a critical limitation on rr_graph_node_storage when moving forward! --- vpr/src/base/vpr_context.h | 12 +++++++++--- vpr/src/route/rr_graph2.cpp | 28 ++++++++++++++++++---------- 2 files changed, 27 insertions(+), 13 deletions(-) diff --git a/vpr/src/base/vpr_context.h b/vpr/src/base/vpr_context.h index 260fa6924b8..f531186d557 100644 --- a/vpr/src/base/vpr_context.h +++ b/vpr/src/base/vpr_context.h @@ -11,6 +11,7 @@ #include "clustered_netlist.h" #include "rr_graph_view.h" #include "rr_graph_storage.h" +#include "rr_graph_builder.h" #include "rr_node.h" #include "rr_rc_data.h" #include "tatum/TimingGraph.hpp" @@ -162,15 +163,20 @@ struct DeviceContext : public Context { ///@brief The indicies of rr nodes of a given type at a specific x,y grid location t_rr_node_indices rr_node_indices; // [0..NUM_RR_TYPES-1][0..grid.width()-1][0..grid.width()-1][0..size-1] + /* TODO: remove this interface from device_context once the code refactoring is completed + * because it should be part of the rr_graph view + */ + RRSpatialLookup rr_spatial_lookup{rr_node_indices}; + /* A read-only view of routing resource graph to be the ONLY database * for client functions: GUI, placer, router, timing analyzer etc. */ RRGraphView rr_graph{rr_nodes, rr_spatial_lookup}; - /* TODO: remove this interface from device_context once the code refactoring is completed - * because it should be part of the rr_graph view + /* A writeable view of routing resource graph to be the ONLY database + * for routing resource graph builder functions. */ - RRSpatialLookup rr_spatial_lookup{rr_node_indices}; + RRGraphBuilder rr_graph_builder{&rr_nodes, &rr_spatial_lookup}; ///@brief Autogenerated in build_rr_graph based on switch fan-in. [0..(num_rr_switches-1)] std::vector rr_switch_inf; diff --git a/vpr/src/route/rr_graph2.cpp b/vpr/src/route/rr_graph2.cpp index 26a338de8e3..2aed9eeee3c 100644 --- a/vpr/src/route/rr_graph2.cpp +++ b/vpr/src/route/rr_graph2.cpp @@ -16,8 +16,6 @@ #include "read_xml_arch_file.h" #include "rr_types.h" -#include "rr_graph_builder.h" - constexpr short UN_SET = -1; /************************** Subroutines local to this module ****************/ @@ -37,8 +35,9 @@ static void load_chan_rr_indices(const int max_chan_width, t_rr_node_indices& indices, int* index); -static void load_block_rr_indices(const DeviceGrid& grid, +static void load_block_rr_indices(RRGraphBuilder& rr_graph_builder, t_rr_node_indices& indices, + const DeviceGrid& grid, int* index); static int get_bidir_track_to_chan_seg(const std::vector conn_tracks, @@ -972,14 +971,13 @@ static void load_chan_rr_indices(const int max_chan_width, } } -static void load_block_rr_indices(const DeviceGrid& grid, +/* As the rr_indices builders modify a local copy of indices, use the local copy in the builder + * TODO: these building functions should only talk to a RRGraphBuilder object + */ +static void load_block_rr_indices(RRGraphBuilder& rr_graph_builder, t_rr_node_indices& indices, + const DeviceGrid& grid, int* index) { - /* As the rr_indices builders modify a local copy of indices, use the local copy in the builder - * TODO: these building functions should only talk to a RRGraphBuilderView object - */ - RRGraphBuilder rr_graph_builder(&(g_vpr_ctx.mutable_device().rr_nodes), - &(g_vpr_ctx.mutable_device().rr_spatial_lookup)); //Walk through the grid assigning indices to SOURCE/SINK IPIN/OPIN for (size_t x = 0; x < grid.width(); x++) { @@ -1142,6 +1140,16 @@ static void load_block_rr_indices(const DeviceGrid& grid, } } +/* As the rr_indices builders modify a local copy of indices, use the local copy in the builder + * TODO: these building functions should only talk to a RRGraphBuilder object + * The biggest and fatal issue is + * - the rr_graph2.h is included in the rr_graph_storage.h, + * which is included in the rr_graph_builder.h + * If we include rr_graph_builder.h in rr_graph2.h, this creates a loop + * for C++ compiler to identify data structures, which cannot be solved!!! + * This will block us when putting the RRGraphBuilder object as an input arguement + * of this function + */ void alloc_and_load_rr_node_indices(t_rr_node_indices& indices, const int max_chan_width, const DeviceGrid& grid, @@ -1162,7 +1170,7 @@ void alloc_and_load_rr_node_indices(t_rr_node_indices& indices, } /* Assign indices for block nodes */ - load_block_rr_indices(grid, indices, index); + load_block_rr_indices(g_vpr_ctx.mutable_device().rr_graph_builder, indices, grid, index); /* Load the data for x and y channels */ load_chan_rr_indices(max_chan_width, grid.width(), grid.height(), From 706a9656aa1d8e518818f3b02bc7256a5819f534 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Thu, 15 Apr 2021 16:34:15 -0600 Subject: [PATCH 19/22] [VPR] Reworked comments to emphasize on confusing codes while delete redundant codes to short the code view --- vpr/src/device/rr_graph_builder.cpp | 9 -------- vpr/src/device/rr_graph_builder.h | 17 +++++---------- vpr/src/device/rr_graph_view.cpp | 10 --------- vpr/src/device/rr_graph_view.h | 23 +++++++++------------ vpr/src/device/rr_spatial_lookup.cpp | 31 +++++++--------------------- vpr/src/device/rr_spatial_lookup.h | 20 +++++------------- vpr/src/route/rr_graph2.cpp | 1 - 7 files changed, 28 insertions(+), 83 deletions(-) diff --git a/vpr/src/device/rr_graph_builder.cpp b/vpr/src/device/rr_graph_builder.cpp index a5d74376e11..6279177570f 100644 --- a/vpr/src/device/rr_graph_builder.cpp +++ b/vpr/src/device/rr_graph_builder.cpp @@ -1,20 +1,11 @@ -/*************************************** - * Methods for Object RRGraphBuilder - ***************************************/ #include "rr_graph_builder.h" -/**************************** - * Constructors - ****************************/ RRGraphBuilder::RRGraphBuilder(t_rr_graph_storage* node_storage, RRSpatialLookup* node_lookup) : node_storage_(*node_storage) , node_lookup_(*node_lookup) { } -/**************************** - * Mutators - ****************************/ t_rr_graph_storage& RRGraphBuilder::node_storage() { return node_storage_; } diff --git a/vpr/src/device/rr_graph_builder.h b/vpr/src/device/rr_graph_builder.h index 5824b3eebf4..745995133f2 100644 --- a/vpr/src/device/rr_graph_builder.h +++ b/vpr/src/device/rr_graph_builder.h @@ -16,34 +16,27 @@ * */ class RRGraphBuilder { - /**************** - * Constructors - ****************/ + /* -- Constructors -- */ public: + /* See detailed comments about the data structures in the internal data storage section of this file */ RRGraphBuilder(t_rr_graph_storage* node_storage, RRSpatialLookup* node_lookup); - /* Disable copy constructors + /* Disable copy constructors and copy assignment operator * This is to avoid any duplication of the object * as it is only interface allowed to modify routing resource graph */ RRGraphBuilder(const RRGraphBuilder&) = delete; - - /* Disable copy assignment operator */ void operator=(const RRGraphBuilder&) = delete; - /**************** - * Mutators - ****************/ + /* -- Mutators -- */ public: /* Return a writable object for rr_nodes */ t_rr_graph_storage& node_storage(); /* Return a writable object for update the fast look-up of rr_node */ RRSpatialLookup& node_lookup(); - /**************** - * internal data storage - ****************/ + /* -- Internal data storage -- */ private: /* TODO: When the refactoring effort finishes, * the builder data structure will be the owner of the data storages. diff --git a/vpr/src/device/rr_graph_view.cpp b/vpr/src/device/rr_graph_view.cpp index 16e03585524..b6fb8941297 100644 --- a/vpr/src/device/rr_graph_view.cpp +++ b/vpr/src/device/rr_graph_view.cpp @@ -1,25 +1,15 @@ -/*************************************** - * Methods for Object RRGraphView - ***************************************/ #include "rr_graph_view.h" -/**************************** - * Constructors - ****************************/ RRGraphView::RRGraphView(const t_rr_graph_storage& node_storage, const RRSpatialLookup& node_lookup) : node_storage_(node_storage) , node_lookup_(node_lookup) { } -/**************************** - * Accessors - ****************************/ t_rr_type RRGraphView::node_type(RRNodeId node) const { return node_storage_.node_type(node); } const RRSpatialLookup& RRGraphView::node_lookup() const { - /* Return a constant object rather than a writable one */ return node_lookup_; } diff --git a/vpr/src/device/rr_graph_view.h b/vpr/src/device/rr_graph_view.h index c93f9a4ad47..65201f22547 100644 --- a/vpr/src/device/rr_graph_view.h +++ b/vpr/src/device/rr_graph_view.h @@ -32,35 +32,32 @@ * */ class RRGraphView { - /**************** - * Constructors - ****************/ + /* -- Constructors -- */ public: + /* See detailed comments about the data structures in the internal data storage section of this file */ RRGraphView(const t_rr_graph_storage& node_storage, const RRSpatialLookup& node_lookup); - /* Disable copy constructors + /* Disable copy constructors and copy assignment operator * This is to avoid any duplication of the object * as it is only interface allowed to access routing resource graph */ RRGraphView(const RRGraphView&) = delete; - - /* Disable copy assignment operator */ void operator=(const RRGraphView&) = delete; - /**************** - * Accessors - ****************/ + /* -- Accessors -- */ + /* TODO: The accessors may be turned into private later if they are replacable by 'questionin' + * kind of accessors + */ public: /* Get the type of a routing resource node */ t_rr_type node_type(RRNodeId node) const; - /* Return a read-only object for performing fast look-up in rr_node */ + /* Return the fast look-up data structure for queries from client functions */ const RRSpatialLookup& node_lookup() const; - /**************** - * internal data storage - ****************/ + /* -- Internal data storage -- */ + /* Note: only read-only object or data structures are allowed!!! */ private: /* node-level storage including edge storages */ const t_rr_graph_storage& node_storage_; diff --git a/vpr/src/device/rr_spatial_lookup.cpp b/vpr/src/device/rr_spatial_lookup.cpp index a84d276e014..e5179ba7b2a 100644 --- a/vpr/src/device/rr_spatial_lookup.cpp +++ b/vpr/src/device/rr_spatial_lookup.cpp @@ -1,19 +1,10 @@ -/*************************************** - * Methods for Object RRSpatialLookup - ***************************************/ #include "vtr_assert.h" #include "rr_spatial_lookup.h" -/**************************** - * Constructors - ****************************/ RRSpatialLookup::RRSpatialLookup(t_rr_node_indices& rr_node_indices) : rr_node_indices_(rr_node_indices) { } -/**************************** - * Accessors - ****************************/ RRNodeId RRSpatialLookup::find_node(int x, int y, t_rr_type type, @@ -28,7 +19,12 @@ RRNodeId RRSpatialLookup::find_node(int x, node_side = SIDES[0]; } - /* Currently need to swap x and y for CHANX because of chan, seg convention */ + /* Currently need to swap x and y for CHANX because of chan, seg convention + * This is due to that the fast look-up builders uses (y, x) coordinate when + * registering a CHANX node in the look-up + * TODO: Once the builders is reworked for use consistent (x, y) convention, + * the following swapping can be removed + */ size_t node_x = x; size_t node_y = y; if (CHANX == type) { @@ -38,43 +34,32 @@ RRNodeId RRSpatialLookup::find_node(int x, VTR_ASSERT_SAFE(3 == rr_node_indices_[type].ndims()); /* Sanity check to ensure the x, y, side and ptc are in range - * Data type of rr_node_indice: - * typedef std::array, 3>, NUM_RR_TYPES> t_rr_node_indices; - * Note that x, y and side are the 1st, 2nd and 3rd dimensions of the vtr::NdMatrix - * ptc is in the std::vector + * - Return an valid id by searching in look-up when all the parameters are in range + * - Return an invalid id if any out-of-range is detected */ if (size_t(type) >= rr_node_indices_.size()) { - /* Node type is out of range, return an invalid index */ return RRNodeId::INVALID(); } if (node_x >= rr_node_indices_[type].dim_size(0)) { - /* Node x is out of range, return an invalid index */ return RRNodeId::INVALID(); } if (node_y >= rr_node_indices_[type].dim_size(1)) { - /* Node y is out of range, return an invalid index */ return RRNodeId::INVALID(); } if (node_side >= rr_node_indices_[type].dim_size(2)) { - /* Node side is out of range, return an invalid index */ return RRNodeId::INVALID(); } if (size_t(ptc) >= rr_node_indices_[type][node_x][node_y][node_side].size()) { - /* Ptc is out of range, return an invalid index */ return RRNodeId::INVALID(); } - /* Reaching here, it means that node exists in the look-up, return the id */ return RRNodeId(rr_node_indices_[type][node_x][node_y][node_side][ptc]); } -/**************************** - * Mutators - ****************************/ void RRSpatialLookup::add_node(RRNodeId node, int x, int y, diff --git a/vpr/src/device/rr_spatial_lookup.h b/vpr/src/device/rr_spatial_lookup.h index 99d9466d0e1..9da329acc9b 100644 --- a/vpr/src/device/rr_spatial_lookup.h +++ b/vpr/src/device/rr_spatial_lookup.h @@ -12,25 +12,19 @@ * - Find the id of a node with given information, e.g., x, y, type etc. ********************************************************************/ class RRSpatialLookup { - /**************** - * Constructors - ****************/ + /* -- Constructors -- */ public: /* Explicitly define the only way to create an object */ explicit RRSpatialLookup(t_rr_node_indices& rr_node_indices); - /* Disable copy constructors + /* Disable copy constructors and copy assignment operator * This is to avoid any duplication of the object * as it is only interface allowed to access node look-up of a routing resource graph */ RRSpatialLookup(const RRSpatialLookup&) = delete; - - /* Disable copy assignment operator */ void operator=(const RRSpatialLookup&) = delete; - /**************** - * Accessors - ****************/ + /* -- Accessors -- */ public: /* Returns the index of the specified routing resource node. (x,y) are * the location within the FPGA, rr_type specifies the type of resource, @@ -56,9 +50,7 @@ class RRSpatialLookup { int ptc, e_side side = NUM_SIDES) const; - /**************** - * Mutators - ****************/ + /* -- Mutators -- */ public: /* Register a node in the fast look-up * - You must have a node id @@ -87,9 +79,7 @@ class RRSpatialLookup { int ptc, e_side side); - /**************** - * internal data storage - ****************/ + /* -- Internal data storage -- */ private: /* TODO: When the refactoring effort finishes, * the data structure will be the owner of the data storages. diff --git a/vpr/src/route/rr_graph2.cpp b/vpr/src/route/rr_graph2.cpp index 2aed9eeee3c..6f5567b2443 100644 --- a/vpr/src/route/rr_graph2.cpp +++ b/vpr/src/route/rr_graph2.cpp @@ -978,7 +978,6 @@ static void load_block_rr_indices(RRGraphBuilder& rr_graph_builder, t_rr_node_indices& indices, const DeviceGrid& grid, int* index) { - //Walk through the grid assigning indices to SOURCE/SINK IPIN/OPIN for (size_t x = 0; x < grid.width(); x++) { for (size_t y = 0; y < grid.height(); y++) { From 0297ce9cf3a7fc6d5a1af7bc9977636c033bab51 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Fri, 16 Apr 2021 10:44:54 -0600 Subject: [PATCH 20/22] [VPR] Reworked the comment about avoid copy contructors for RRGraphBuild, RRGraphView and RRSpatialLookup --- vpr/src/device/rr_graph_builder.h | 6 ++++-- vpr/src/device/rr_graph_view.h | 6 ++++-- vpr/src/device/rr_spatial_lookup.h | 6 ++++-- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/vpr/src/device/rr_graph_builder.h b/vpr/src/device/rr_graph_builder.h index 745995133f2..594beef45df 100644 --- a/vpr/src/device/rr_graph_builder.h +++ b/vpr/src/device/rr_graph_builder.h @@ -23,8 +23,10 @@ class RRGraphBuilder { RRSpatialLookup* node_lookup); /* Disable copy constructors and copy assignment operator - * This is to avoid any duplication of the object - * as it is only interface allowed to modify routing resource graph + * This is to avoid accidental copy because it could be an expensive operation considering that the + * memory footprint of the data structure could ~ Gb + * Using the following syntax, we prohibit accidental 'pass-by-value' which can be immediately caught + * by compiler */ RRGraphBuilder(const RRGraphBuilder&) = delete; void operator=(const RRGraphBuilder&) = delete; diff --git a/vpr/src/device/rr_graph_view.h b/vpr/src/device/rr_graph_view.h index 65201f22547..7d0853634e6 100644 --- a/vpr/src/device/rr_graph_view.h +++ b/vpr/src/device/rr_graph_view.h @@ -39,8 +39,10 @@ class RRGraphView { const RRSpatialLookup& node_lookup); /* Disable copy constructors and copy assignment operator - * This is to avoid any duplication of the object - * as it is only interface allowed to access routing resource graph + * This is to avoid accidental copy because it could be an expensive operation considering that the + * memory footprint of the data structure could ~ Gb + * Using the following syntax, we prohibit accidental 'pass-by-value' which can be immediately caught + * by compiler */ RRGraphView(const RRGraphView&) = delete; void operator=(const RRGraphView&) = delete; diff --git a/vpr/src/device/rr_spatial_lookup.h b/vpr/src/device/rr_spatial_lookup.h index 9da329acc9b..2d7fa641650 100644 --- a/vpr/src/device/rr_spatial_lookup.h +++ b/vpr/src/device/rr_spatial_lookup.h @@ -18,8 +18,10 @@ class RRSpatialLookup { explicit RRSpatialLookup(t_rr_node_indices& rr_node_indices); /* Disable copy constructors and copy assignment operator - * This is to avoid any duplication of the object - * as it is only interface allowed to access node look-up of a routing resource graph + * This is to avoid accidental copy because it could be an expensive operation considering that the + * memory footprint of the data structure could ~ Gb + * Using the following syntax, we prohibit accidental 'pass-by-value' which can be immediately caught + * by compiler */ RRSpatialLookup(const RRSpatialLookup&) = delete; void operator=(const RRSpatialLookup&) = delete; From e137b6dfad8f29ee61b90d6e32e3145dd20b887c Mon Sep 17 00:00:00 2001 From: tangxifan Date: Fri, 21 May 2021 15:25:47 -0600 Subject: [PATCH 21/22] [VPR] Update comments to avoid confusion and clarify --- vpr/src/device/rr_spatial_lookup.cpp | 19 ++++++++++-- vpr/src/device/rr_spatial_lookup.h | 46 +++++++++++++++++----------- 2 files changed, 45 insertions(+), 20 deletions(-) diff --git a/vpr/src/device/rr_spatial_lookup.cpp b/vpr/src/device/rr_spatial_lookup.cpp index e5179ba7b2a..e751fd80602 100644 --- a/vpr/src/device/rr_spatial_lookup.cpp +++ b/vpr/src/device/rr_spatial_lookup.cpp @@ -10,15 +10,29 @@ RRNodeId RRSpatialLookup::find_node(int x, t_rr_type type, int ptc, e_side side) const { - /* Find actual side to be used */ + /* Find actual side to be used + * - For the node which are input/outputs of a grid, there must be a specific side for them. + * Because they should have a specific pin location on the perimeter of a grid. + * - For other types of nodes, there is no need to define a side. However, a default value + * is needed when store the node in the fast look-up data structure. + * Here we just arbitrary use the first side of the SIDE vector as the default value. + * We may consider to use NUM_SIDES as the default value but it will cause an increase + * in the dimension of the fast look-up data structure. + * Please note that in the add_node function, we should keep the SAME convention! + */ e_side node_side = side; if (type == IPIN || type == OPIN) { VTR_ASSERT_MSG(side != NUM_SIDES, "IPIN/OPIN must specify desired side (can not be default NUM_SIDES)"); } else { - VTR_ASSERT(type != IPIN && type != OPIN); + VTR_ASSERT_SAFE(type != IPIN && type != OPIN); node_side = SIDES[0]; } + /* Pre-check: the x, y, side and ptc should be non negative numbers! Otherwise, return an invalid id */ + if ((0 > x) || (0 > y) || (NUM_SIDES == node_side) || (0 > ptc)) { + return RRNodeId::INVALID(); + } + /* Currently need to swap x and y for CHANX because of chan, seg convention * This is due to that the fast look-up builders uses (y, x) coordinate when * registering a CHANX node in the look-up @@ -66,6 +80,7 @@ void RRSpatialLookup::add_node(RRNodeId node, t_rr_type type, int ptc, e_side side) { + VTR_ASSERT(node); VTR_ASSERT_SAFE(3 == rr_node_indices_[type].ndims()); /* Expand the fast look-up if the new node is out-of-range diff --git a/vpr/src/device/rr_spatial_lookup.h b/vpr/src/device/rr_spatial_lookup.h index 2d7fa641650..f156384f88a 100644 --- a/vpr/src/device/rr_spatial_lookup.h +++ b/vpr/src/device/rr_spatial_lookup.h @@ -4,8 +4,9 @@ #include "vpr_types.h" /******************************************************************** - * A data structure storing the fast look-up for the nodes - * in a routing resource graph + * A data structure built to find the id of an routing resource node + * (rr_node) given information about its physical position and type. + * The data structure is mostly needed during rr_graph building * * The data structure allows users to * - Update the look-up with new nodes @@ -28,23 +29,29 @@ class RRSpatialLookup { /* -- Accessors -- */ public: - /* Returns the index of the specified routing resource node. (x,y) are - * the location within the FPGA, rr_type specifies the type of resource, - * and ptc gives the number of this resource. ptc is the class number, - * pin number or track number, depending on what type of resource this - * is. All ptcs start at 0 and go up to pins_per_clb-1 or the equivalent. - * There are class_inf size SOURCEs + SINKs, type->num_pins IPINs + OPINs, - * and max_chan_width CHANX and CHANY (each). + /* Returns the index of the specified routing resource node. + * - (x, y) are the grid location within the FPGA + * - rr_type specifies the type of resource, + * - ptc gives a unique number of resources of that type (e.g. CHANX) at that (x,y). + * All ptcs start at 0 and are positive. + * Depending on what type of resource this is, ptc can be + * - the class number of a common SINK/SOURCE node of grid, + * starting at 0 and go up to class_inf size - 1 of SOURCEs + SINKs in a grid + * - pin number of an input/output pin of a grid. They would normally start at 0 + * and go to the number of pins on a block at that (x, y) location + * - track number of a routing wire in a channel. They would normally go from 0 + * to channel_width - 1 at that (x,y) * * Note that for segments (CHANX and CHANY) of length > 1, the segment is * given an rr_index based on the (x,y) location at which it starts (i.e. * lowest (x,y) location at which this segment exists). - * This routine also performs error checking to make sure the node in - * question exists. * * The 'side' argument only applies to IPIN/OPIN types, and specifies which * side of the grid tile the node should be located on. The value is ignored * for non-IPIN/OPIN types + * + * This routine also performs error checking to make sure the node in + * question exists. */ RRNodeId find_node(int x, int y, @@ -55,18 +62,19 @@ class RRSpatialLookup { /* -- Mutators -- */ public: /* Register a node in the fast look-up - * - You must have a node id - * 1. a valid one is to register a node in the lookup - * 2. an invalid id means the removal of a node from the lookup + * - You must have a valid node id to register the node in the lookup * - (x, y) are the coordinate of the node to be indexable in the fast look-up * - type is the type of a node * - ptc is a feature number of a node, which can be - * 1. pin index in a tile when type is OPIN/IPIN - * 2. track index in a routing channel when type is CHANX/CHANY + * - the class number of a common SINK/SOURCE node of grid, + * - pin index in a tile when type is OPIN/IPIN + * - track index in a routing channel when type is CHANX/CHANY * - side is the side of node on the tile, applicable to OPIN/IPIN * - * Note that the add node here will not create a node in the node list - * You MUST add the node in the t_rr_node_storage so that the node is valid + * An invalid id will be returned if the node does not exist + * + * Note that a node added with this call will not create a node in the rr_graph_storage node list + * You MUST add the node in the rr_graph_storage so that the node is valid * * TODO: Consider to try to return a reference to *this so that we can do chain calls * - .add_node(...) @@ -81,6 +89,8 @@ class RRSpatialLookup { int ptc, e_side side); + /* TODO: Add an API remove_node() to unregister a node from the look-up */ + /* -- Internal data storage -- */ private: /* TODO: When the refactoring effort finishes, From 49e3339488e2f02a3b07df3ec53a6fa0b7f53a43 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Fri, 21 May 2021 16:41:33 -0600 Subject: [PATCH 22/22] [VPR] Patch comments and remove the inproper assert (which should be enabled later when remove_node() API is available in rr_spatial_lookup) --- vpr/src/base/vpr_context.h | 3 +++ vpr/src/device/rr_spatial_lookup.cpp | 1 - vpr/src/device/rr_spatial_lookup.h | 4 ++-- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/vpr/src/base/vpr_context.h b/vpr/src/base/vpr_context.h index f531186d557..c85aeb05245 100644 --- a/vpr/src/base/vpr_context.h +++ b/vpr/src/base/vpr_context.h @@ -165,6 +165,9 @@ struct DeviceContext : public Context { /* TODO: remove this interface from device_context once the code refactoring is completed * because it should be part of the rr_graph view + * TODO: Currently, we use reference pointers to ensure that the rr_spatial_lookup is always + * synchronized with the rr_node_indices but this causes a lot of confusion for developers + * The temporary fix should be patched as soon as possible. */ RRSpatialLookup rr_spatial_lookup{rr_node_indices}; diff --git a/vpr/src/device/rr_spatial_lookup.cpp b/vpr/src/device/rr_spatial_lookup.cpp index e751fd80602..0845e7a468c 100644 --- a/vpr/src/device/rr_spatial_lookup.cpp +++ b/vpr/src/device/rr_spatial_lookup.cpp @@ -80,7 +80,6 @@ void RRSpatialLookup::add_node(RRNodeId node, t_rr_type type, int ptc, e_side side) { - VTR_ASSERT(node); VTR_ASSERT_SAFE(3 == rr_node_indices_[type].ndims()); /* Expand the fast look-up if the new node is out-of-range diff --git a/vpr/src/device/rr_spatial_lookup.h b/vpr/src/device/rr_spatial_lookup.h index f156384f88a..44a413b5f90 100644 --- a/vpr/src/device/rr_spatial_lookup.h +++ b/vpr/src/device/rr_spatial_lookup.h @@ -42,6 +42,8 @@ class RRSpatialLookup { * - track number of a routing wire in a channel. They would normally go from 0 * to channel_width - 1 at that (x,y) * + * An invalid id will be returned if the node does not exist + * * Note that for segments (CHANX and CHANY) of length > 1, the segment is * given an rr_index based on the (x,y) location at which it starts (i.e. * lowest (x,y) location at which this segment exists). @@ -71,8 +73,6 @@ class RRSpatialLookup { * - track index in a routing channel when type is CHANX/CHANY * - side is the side of node on the tile, applicable to OPIN/IPIN * - * An invalid id will be returned if the node does not exist - * * Note that a node added with this call will not create a node in the rr_graph_storage node list * You MUST add the node in the rr_graph_storage so that the node is valid *