diff --git a/utils/route_diag/src/main.cpp b/utils/route_diag/src/main.cpp index a601beb13e3..866e837b574 100644 --- a/utils/route_diag/src/main.cpp +++ b/utils/route_diag/src/main.cpp @@ -101,7 +101,7 @@ static void do_one_route(int source_node, int sink_node, ConnectionRouter router( device_ctx.grid, *router_lookahead, - device_ctx.rr_nodes, + device_ctx.rr_graph.rr_nodes(), &device_ctx.rr_graph, device_ctx.rr_rc_data, device_ctx.rr_graph.rr_switch(), diff --git a/vpr/src/base/read_route.cpp b/vpr/src/base/read_route.cpp index af56c55f9cb..3f0e0cf8605 100644 --- a/vpr/src/base/read_route.cpp +++ b/vpr/src/base/read_route.cpp @@ -126,7 +126,7 @@ bool read_route(const char* route_file, const t_router_opts& router_opts, bool v recompute_occupancy_from_scratch(); /* Note: This pres_fac is not necessarily correct since it isn't the first routing iteration*/ - OveruseInfo overuse_info(device_ctx.rr_nodes.size()); + OveruseInfo overuse_info(device_ctx.rr_graph.num_nodes()); pathfinder_update_acc_cost_and_overuse_info(router_opts.acc_fac, overuse_info); reserve_locally_used_opins(&small_heap, router_opts.initial_pres_fac, @@ -505,21 +505,19 @@ static bool check_rr_graph_connectivity(RRNodeId prev_node, RRNodeId node) { if (prev_node == node) return false; auto& device_ctx = g_vpr_ctx.device(); - const auto& rr_graph = device_ctx.rr_nodes; - /*TODO We need to remove temp_rr_graph once rr_graph is resolved*/ - const auto& temp_rr_graph = device_ctx.rr_graph; + const auto& rr_graph = device_ctx.rr_graph; // If it's starting a new sub branch this is ok - if (device_ctx.rr_graph.node_type(prev_node) == SINK) return true; + if (rr_graph.node_type(prev_node) == SINK) return true; for (RREdgeId edge : rr_graph.edge_range(prev_node)) { //If the sink node is reachable by previous node return true - if (rr_graph.edge_sink_node(edge) == node) { + if (rr_graph.rr_nodes().edge_sink_node(edge) == node) { return true; } // If there are any non-configurable branches return true - short edge_switch = rr_graph.edge_switch(edge); - if (!(temp_rr_graph.rr_switch_inf(RRSwitchId(edge_switch)).configurable())) return true; + short edge_switch = rr_graph.rr_nodes().edge_switch(edge); + if (!(rr_graph.rr_switch_inf(RRSwitchId(edge_switch)).configurable())) return true; } // If it's part of a non configurable node list, return true diff --git a/vpr/src/base/vpr_context.h b/vpr/src/base/vpr_context.h index bde685331c9..b741952990c 100644 --- a/vpr/src/base/vpr_context.h +++ b/vpr/src/base/vpr_context.h @@ -147,7 +147,6 @@ struct DeviceContext : public Context { /* * Structures to define the routing architecture of the FPGA. */ - t_rr_graph_storage rr_nodes; // autogenerated in build_rr_graph vtr::vector rr_indexed_data; // [0 .. num_rr_indexed_data-1] @@ -163,19 +162,12 @@ struct DeviceContext : public Context { /* A writeable view of routing resource graph to be the ONLY database * for routing resource graph builder functions. */ - RRGraphBuilder rr_graph_builder{&rr_nodes}; + RRGraphBuilder rr_graph_builder{}; /* 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_graph_builder.node_lookup(), - rr_graph_builder.rr_node_metadata(), - rr_graph_builder.rr_edge_metadata(), - rr_indexed_data, - rr_graph_builder.rr_segments(), - rr_graph_builder.rr_switch()}; - + RRGraphView rr_graph{rr_graph_builder.rr_nodes(), rr_graph_builder.node_lookup(), rr_graph_builder.rr_node_metadata(), rr_graph_builder.rr_edge_metadata(), rr_indexed_data, rr_graph_builder.rr_segments(), rr_graph_builder.rr_switch()}; int num_arch_switches; t_arch_switch_inf* arch_switch_inf; // [0..(num_arch_switches-1)] @@ -194,7 +186,6 @@ struct DeviceContext : public Context { * a single value */ int virtual_clock_network_root_idx; - /** * @brief switch_fanin_remap is only used for printing out switch fanin stats * (the -switch_stats option) diff --git a/vpr/src/device/rr_graph_builder.cpp b/vpr/src/device/rr_graph_builder.cpp index 2b2b02bb7bb..3f2a3e7fa45 100644 --- a/vpr/src/device/rr_graph_builder.cpp +++ b/vpr/src/device/rr_graph_builder.cpp @@ -7,11 +7,9 @@ //#include "globals.h" -RRGraphBuilder::RRGraphBuilder(t_rr_graph_storage* node_storage) - : node_storage_(*node_storage) { -} +RRGraphBuilder::RRGraphBuilder() {} -t_rr_graph_storage& RRGraphBuilder::node_storage() { +t_rr_graph_storage& RRGraphBuilder::rr_nodes() { return node_storage_; } @@ -63,6 +61,7 @@ void RRGraphBuilder::add_node_to_all_locs(RRNodeId node) { void RRGraphBuilder::clear() { node_lookup_.clear(); + node_storage_.clear(); rr_node_metadata_.clear(); rr_edge_metadata_.clear(); rr_segments_.clear(); diff --git a/vpr/src/device/rr_graph_builder.h b/vpr/src/device/rr_graph_builder.h index f7fca5e15fa..60a30a7f4ed 100644 --- a/vpr/src/device/rr_graph_builder.h +++ b/vpr/src/device/rr_graph_builder.h @@ -21,7 +21,7 @@ class RRGraphBuilder { /* -- 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); + RRGraphBuilder(); /* Disable copy constructors and copy assignment operator * This is to avoid accidental copy because it could be an expensive operation considering that the @@ -35,7 +35,7 @@ class RRGraphBuilder { /* -- Mutators -- */ public: /** @brief Return a writable object for rr_nodes */ - t_rr_graph_storage& node_storage(); + t_rr_graph_storage& rr_nodes(); /** @brief Return a writable object for update the fast look-up of rr_node */ RRSpatialLookup& node_lookup(); /** .. warning:: The Metadata should stay as an independent data structure than rest of the internal data, @@ -212,6 +212,11 @@ class RRGraphBuilder { inline void emplace_back_edge(RRNodeId src, RRNodeId dest, short edge_switch) { node_storage_.emplace_back_edge(src, dest, edge_switch); } + /** @brief Append 1 more RR node to the RR graph. */ + inline void emplace_back() { + // No edges can be assigned if mutating the rr node array. + node_storage_.emplace_back(); + } /** @brief alloc_and_load_edges; It adds a batch of edges. */ inline void alloc_and_load_edges(const t_rr_edge_info_set* rr_edges_to_create) { @@ -316,7 +321,7 @@ class RRGraphBuilder { * That explains why the reference is used here temporarily */ /* node-level storage including edge storages */ - t_rr_graph_storage& node_storage_; + t_rr_graph_storage node_storage_; /* Fast look-up for rr nodes */ RRSpatialLookup node_lookup_; diff --git a/vpr/src/device/rr_graph_view.h b/vpr/src/device/rr_graph_view.h index 31ae233c38b..de12a827630 100644 --- a/vpr/src/device/rr_graph_view.h +++ b/vpr/src/device/rr_graph_view.h @@ -69,13 +69,23 @@ class RRGraphView { * } */ inline vtr::StrongIdRange nodes() const { - return vtr::StrongIdRange(RRNodeId(0), RRNodeId(size())); + return vtr::StrongIdRange(RRNodeId(0), RRNodeId(num_nodes())); } /** @brief Return number of nodes. This function is inlined for runtime optimization. */ - inline size_t size() const { + inline size_t num_nodes() const { return node_storage_.size(); } + /** @brief Is the RR graph currently empty? */ + inline bool empty() const { + return node_storage_.empty(); + } + + /** @brief Returns a range of RREdgeId's belonging to RRNodeId id. + * If this range is empty, then RRNodeId id has no edges.*/ + inline vtr::StrongIdRange edge_range(RRNodeId id) const { + return vtr::StrongIdRange(node_storage_.first_edge(id), node_storage_.last_edge(id)); + } /** @brief Get the type of a routing resource node. This function is inlined for runtime optimization. */ inline t_rr_type node_type(RRNodeId node) const { @@ -421,6 +431,11 @@ class RRGraphView { const RRSpatialLookup& node_lookup() const { return node_lookup_; } + /** @brief Return the node-level storage structure for queries from client functions */ + inline const t_rr_graph_storage& rr_nodes() const { + return node_storage_; + } + /** .. warning:: The Metadata should stay as an independent data structure than rest of the internal data, * e.g., node_lookup! */ MetadataStorage rr_node_metadata_data() const { @@ -464,6 +479,7 @@ class RRGraphView { const MetadataStorage>& rr_edge_metadata_; /* rr_indexed_data_ and rr_segments_ are needed to lookup the segment information in node_coordinate_to_string() */ const vtr::vector& rr_indexed_data_; + /* Segment info for rr nodes */ const vtr::vector& rr_segments_; /* switch info for rr nodes */ diff --git a/vpr/src/draw/draw.cpp b/vpr/src/draw/draw.cpp index 8d190a286e3..bf594218b7f 100644 --- a/vpr/src/draw/draw.cpp +++ b/vpr/src/draw/draw.cpp @@ -929,7 +929,7 @@ void alloc_draw_structs(const t_arch* arch) { /* Space is allocated for draw_rr_node but not initialized because we do * * not yet know information about the routing resources. */ draw_state->draw_rr_node = (t_draw_rr_node*)vtr::malloc( - device_ctx.rr_nodes.size() * sizeof(t_draw_rr_node)); + device_ctx.rr_graph.num_nodes() * sizeof(t_draw_rr_node)); draw_state->arch_info = arch; @@ -980,10 +980,10 @@ void init_draw_coords(float width_val) { return; //do not initialize only if --disp off and --save_graphics off /* Each time routing is on screen, need to reallocate the color of each * * rr_node, as the number of rr_nodes may change. */ - if (device_ctx.rr_nodes.size() != 0) { + if (rr_graph.num_nodes() != 0) { draw_state->draw_rr_node = (t_draw_rr_node*)vtr::realloc( draw_state->draw_rr_node, - (device_ctx.rr_nodes.size()) * sizeof(t_draw_rr_node)); + (rr_graph.num_nodes()) * sizeof(t_draw_rr_node)); /*FIXME: the type cast should be eliminated by making draw_rr_node adapt RRNodeId */ for (const RRNodeId& rr_id : rr_graph.nodes()) { draw_state->draw_rr_node[(size_t)rr_id].color = DEFAULT_RR_NODE_COLOR; @@ -1310,7 +1310,7 @@ static void draw_routing_costs(ezgl::renderer* g) { float min_cost = std::numeric_limits::infinity(); float max_cost = -min_cost; - std::vector rr_node_costs(device_ctx.rr_nodes.size(), 0.); + std::vector rr_node_costs(device_ctx.rr_graph.num_nodes(), 0.); for (const RRNodeId& rr_id : device_ctx.rr_graph.nodes()) { float cost = 0.; @@ -1694,7 +1694,7 @@ static void draw_rr_edges(int inode, ezgl::renderer* g) { to_node = size_t(rr_graph.edge_sink_node(rr_node, iedge)); to_type = rr_graph.node_type(RRNodeId(to_node)); to_ptc_num = rr_graph.node_ptc_num(RRNodeId(to_node)); - bool edge_configurable = device_ctx.rr_nodes[inode].edge_is_configurable(iedge); + bool edge_configurable = rr_graph.rr_nodes()[inode].edge_is_configurable(iedge); switch (from_type) { case OPIN: @@ -2288,7 +2288,7 @@ static void draw_rr_pin(int inode, const ezgl::color& color, ezgl::renderer* g) * the physical pin is on. */ void draw_get_rr_pin_coords(int inode, float* xcen, float* ycen, const e_side& pin_side) { auto& device_ctx = g_vpr_ctx.device(); - draw_get_rr_pin_coords(device_ctx.rr_nodes[inode], xcen, ycen, pin_side); + draw_get_rr_pin_coords(device_ctx.rr_graph.rr_nodes()[inode], xcen, ycen, pin_side); } void draw_get_rr_pin_coords(const t_rr_node& node, float* xcen, float* ycen, const e_side& pin_side) { @@ -2357,7 +2357,7 @@ static void draw_rr_src_sink(int inode, ezgl::color color, ezgl::renderer* g) { const auto& rr_graph = device_ctx.rr_graph; float xcen, ycen; - draw_get_rr_src_sink_coords(device_ctx.rr_nodes[inode], &xcen, &ycen); + draw_get_rr_src_sink_coords(rr_graph.rr_nodes()[inode], &xcen, &ycen); g->set_color(color); @@ -2786,7 +2786,7 @@ static int draw_check_rr_node_hit(float click_x, float click_y) { case SOURCE: case SINK: { float xcen, ycen; - draw_get_rr_src_sink_coords(device_ctx.rr_nodes[inode], &xcen, &ycen); + draw_get_rr_src_sink_coords(rr_graph.rr_nodes()[inode], &xcen, &ycen); // Now check if we clicked on this pin if (click_x >= xcen - draw_coords->pin_size && click_x <= xcen + draw_coords->pin_size && click_y >= ycen - draw_coords->pin_size && click_y <= ycen + draw_coords->pin_size) { @@ -2829,7 +2829,7 @@ void draw_expand_non_configurable_rr_nodes_recurr(int from_node, for (t_edge_size iedge = 0; iedge < rr_graph.num_edges(RRNodeId(from_node)); ++iedge) { - bool edge_configurable = device_ctx.rr_nodes[from_node].edge_is_configurable(iedge); + bool edge_configurable = rr_graph.rr_nodes()[from_node].edge_is_configurable(iedge); int to_node = size_t(rr_graph.edge_sink_node(RRNodeId(from_node), iedge)); if (!edge_configurable && !expanded_nodes.count(to_node)) { @@ -3355,7 +3355,7 @@ static void draw_pin_to_sink(int ipin_node, int sink_node, ezgl::renderer* g) { draw_get_rr_pin_coords(ipin_node, &x1, &y1, pin_side); float x2 = 0, y2 = 0; - draw_get_rr_src_sink_coords(device_ctx.rr_nodes[sink_node], &x2, &y2); + draw_get_rr_src_sink_coords(rr_graph.rr_nodes()[sink_node], &x2, &y2); g->draw_line({x1, y1}, {x2, y2}); @@ -3370,7 +3370,7 @@ static void draw_source_to_pin(int source_node, int opin_node, ezgl::renderer* g const auto& rr_graph = device_ctx.rr_graph; float x1 = 0, y1 = 0; - draw_get_rr_src_sink_coords(device_ctx.rr_nodes[source_node], &x1, &y1); + draw_get_rr_src_sink_coords(rr_graph.rr_nodes()[source_node], &x1, &y1); /* Draw the line for each ipin on different sides */ for (const e_side& pin_side : SIDES) { @@ -4141,7 +4141,7 @@ static void draw_router_expansion_costs(ezgl::renderer* g) { auto& device_ctx = g_vpr_ctx.device(); auto& routing_ctx = g_vpr_ctx.routing(); - std::vector rr_costs(device_ctx.rr_nodes.size()); + std::vector rr_costs(device_ctx.rr_graph.num_nodes()); for (const RRNodeId& rr_id : device_ctx.rr_graph.nodes()) { float cost = get_router_expansion_cost( @@ -4198,11 +4198,11 @@ static void draw_rr_costs(ezgl::renderer* g, const std::vector& rr_costs, || draw_state->show_router_expansion_cost == DRAW_ROUTER_EXPANSION_COST_KNOWN_WITH_EDGES || draw_state->show_router_expansion_cost == DRAW_ROUTER_EXPANSION_COST_EXPECTED_WITH_EDGES); - VTR_ASSERT(rr_costs.size() == device_ctx.rr_nodes.size()); + VTR_ASSERT(rr_costs.size() == rr_graph.num_nodes()); float min_cost = std::numeric_limits::infinity(); float max_cost = -min_cost; - for (const RRNodeId& rr_id : device_ctx.rr_graph.nodes()) { + for (const RRNodeId& rr_id : rr_graph.nodes()) { if (std::isnan(rr_costs[(size_t)rr_id])) continue; min_cost = std::min(min_cost, rr_costs[(size_t)rr_id]); @@ -4214,7 +4214,7 @@ static void draw_rr_costs(ezgl::renderer* g, const std::vector& rr_costs, //Draw the nodes in ascending order of value, this ensures high valued nodes //are not overdrawn by lower value ones (e.g-> when zoomed-out far) - std::vector nodes(device_ctx.rr_nodes.size()); + std::vector nodes(rr_graph.num_nodes()); std::iota(nodes.begin(), nodes.end(), 0); auto cmp_ascending_cost = [&](int lhs_node, int rhs_node) { if (lowest_cost_first) { diff --git a/vpr/src/draw/search_bar.cpp b/vpr/src/draw/search_bar.cpp index 44df449e099..df0698d4919 100644 --- a/vpr/src/draw/search_bar.cpp +++ b/vpr/src/draw/search_bar.cpp @@ -68,7 +68,7 @@ void search_and_highlight(GtkWidget* /*widget*/, ezgl::application* app) { ss >> rr_node_id; // valid rr node id check - if (rr_node_id < 0 || rr_node_id >= int(device_ctx.rr_nodes.size())) { + if (rr_node_id < 0 || rr_node_id >= int(device_ctx.rr_graph.num_nodes())) { warning_dialog_box("Invalid RR Node ID"); app->refresh_drawing(); return; diff --git a/vpr/src/pack/post_routing_pb_pin_fixup.cpp b/vpr/src/pack/post_routing_pb_pin_fixup.cpp index a0c6e2d44af..d10302c9121 100644 --- a/vpr/src/pack/post_routing_pb_pin_fixup.cpp +++ b/vpr/src/pack/post_routing_pb_pin_fixup.cpp @@ -159,7 +159,7 @@ static void update_cluster_pin_with_post_routing_results(const DeviceContext& de if (!rr_node) { continue; } - VTR_ASSERT((size_t)rr_node < device_ctx.rr_nodes.size()); + VTR_ASSERT((size_t)rr_node < device_ctx.rr_graph.num_nodes()); /* If the node has been visited on the other side, we just skip it */ if (visited_rr_nodes.end() != std::find(visited_rr_nodes.begin(), visited_rr_nodes.end(), RRNodeId(rr_node))) { diff --git a/vpr/src/power/power.cpp b/vpr/src/power/power.cpp index 838c387f599..0a609c14a89 100644 --- a/vpr/src/power/power.cpp +++ b/vpr/src/power/power.cpp @@ -1192,7 +1192,7 @@ void power_routing_init(const t_det_routing_arch* routing_arch) { } /* Initialize RR Graph Structures */ - rr_node_power = (t_rr_node_power*)vtr::calloc(device_ctx.rr_nodes.size(), + rr_node_power = (t_rr_node_power*)vtr::calloc(rr_graph.num_nodes(), sizeof(t_rr_node_power)); for (const RRNodeId& rr_id : device_ctx.rr_graph.nodes()) { rr_node_power[(size_t)rr_id].driver_switch_type = OPEN; diff --git a/vpr/src/route/annotate_routing.cpp b/vpr/src/route/annotate_routing.cpp index cf78fe1bc07..6a1b8b95e75 100644 --- a/vpr/src/route/annotate_routing.cpp +++ b/vpr/src/route/annotate_routing.cpp @@ -28,7 +28,7 @@ vtr::vector annotate_rr_node_nets(const DeviceContext& d const auto& rr_graph = device_ctx.rr_graph; vtr::vector rr_node_nets; - rr_node_nets.resize(device_ctx.rr_nodes.size(), ClusterNetId::INVALID()); + rr_node_nets.resize(rr_graph.num_nodes(), ClusterNetId::INVALID()); for (auto net_id : clustering_ctx.clb_nlist.nets()) { if (clustering_ctx.clb_nlist.net_is_ignored(net_id)) { @@ -52,7 +52,7 @@ vtr::vector annotate_rr_node_nets(const DeviceContext& d * whose capacity is 1 */ if ((rr_node_nets[rr_node]) - && (1 == device_ctx.rr_nodes.node_capacity(rr_node)) + && (1 == rr_graph.node_capacity(rr_node)) && (net_id != rr_node_nets[rr_node])) { VPR_FATAL_ERROR(VPR_ERROR_ANALYSIS, "Detect two nets '%s' and '%s' that are mapped to the same rr_node '%ld'!\n%s\n", diff --git a/vpr/src/route/check_route.cpp b/vpr/src/route/check_route.cpp index 49df0a45ebd..d3e6d3c10a2 100644 --- a/vpr/src/route/check_route.cpp +++ b/vpr/src/route/check_route.cpp @@ -74,8 +74,8 @@ void check_route(enum e_route_type route_type, e_check_route_option check_route_ check_locally_used_clb_opins(route_ctx.clb_opins_used_locally, route_type); - auto connected_to_route = std::make_unique(device_ctx.rr_nodes.size()); - std::fill_n(connected_to_route.get(), device_ctx.rr_nodes.size(), false); + auto connected_to_route = std::make_unique(rr_graph.num_nodes()); + std::fill_n(connected_to_route.get(), rr_graph.num_nodes(), false); max_pins = 0; for (auto net_id : cluster_ctx.clb_nlist.nets()) @@ -536,7 +536,7 @@ void recompute_occupancy_from_scratch() { /* Will always be 0 for pads or SINK classes. */ for (ipin = 0; ipin < num_local_opins; ipin++) { inode = route_ctx.clb_opins_used_locally[blk_id][iclass][ipin]; - VTR_ASSERT(inode >= 0 && inode < (ssize_t)device_ctx.rr_nodes.size()); + VTR_ASSERT(inode >= 0 && inode < (ssize_t)device_ctx.rr_graph.num_nodes()); route_ctx.rr_node_route_inf[inode].set_occ(route_ctx.rr_node_route_inf[inode].occ() + 1); } } @@ -592,9 +592,9 @@ static void check_node_and_range(int inode, enum e_route_type route_type) { auto& device_ctx = g_vpr_ctx.device(); - if (inode < 0 || inode >= (int)device_ctx.rr_nodes.size()) { + if (inode < 0 || inode >= (int)device_ctx.rr_graph.num_nodes()) { VPR_FATAL_ERROR(VPR_ERROR_ROUTE, - "in check_node_and_range: rr_node #%d is out of legal, range (0 to %d).\n", inode, device_ctx.rr_nodes.size() - 1); + "in check_node_and_range: rr_node #%d is out of legal, range (0 to %d).\n", inode, device_ctx.rr_graph.num_nodes() - 1); } check_rr_node(inode, route_type, device_ctx); } diff --git a/vpr/src/route/check_rr_graph.cpp b/vpr/src/route/check_rr_graph.cpp index ef9a9cdc048..d97163ecff8 100644 --- a/vpr/src/route/check_rr_graph.cpp +++ b/vpr/src/route/check_rr_graph.cpp @@ -50,15 +50,15 @@ void check_rr_graph(const t_graph_type graph_type, auto& device_ctx = g_vpr_ctx.device(); const auto& rr_graph = device_ctx.rr_graph; - auto total_edges_to_node = std::vector(device_ctx.rr_nodes.size()); - auto switch_types_from_current_to_node = std::vector(device_ctx.rr_nodes.size()); + auto total_edges_to_node = std::vector(rr_graph.num_nodes()); + auto switch_types_from_current_to_node = std::vector(rr_graph.num_nodes()); const int num_rr_switches = rr_graph.num_rr_switches(); std::vector> edges; - for (const RRNodeId& rr_node : device_ctx.rr_graph.nodes()) { + for (const RRNodeId& rr_node : rr_graph.nodes()) { size_t inode = (size_t)rr_node; - device_ctx.rr_nodes[inode].validate(); + rr_graph.rr_nodes()[inode].validate(); /* Ignore any uninitialized rr_graph nodes */ if (!rr_graph.node_is_initialized(rr_node)) { @@ -82,7 +82,7 @@ void check_rr_graph(const t_graph_type graph_type, for (int iedge = 0; iedge < num_edges; iedge++) { int to_node = size_t(rr_graph.edge_sink_node(rr_node, iedge)); - if (to_node < 0 || to_node >= (int)device_ctx.rr_nodes.size()) { + if (to_node < 0 || to_node >= (int)rr_graph.num_nodes()) { VPR_FATAL_ERROR(VPR_ERROR_ROUTE, "in check_rr_graph: node %d has an edge %d.\n" "\tEdge is out of range.\n", @@ -185,14 +185,14 @@ void check_rr_graph(const t_graph_type graph_type, //Check that all config/non-config edges are appropriately organized for (auto edge : rr_graph.configurable_edges(RRNodeId(inode))) { - if (!device_ctx.rr_nodes[inode].edge_is_configurable(edge)) { + if (!rr_graph.rr_nodes()[inode].edge_is_configurable(edge)) { VPR_FATAL_ERROR(VPR_ERROR_ROUTE, "in check_rr_graph: node %d edge %d is non-configurable, but in configurable edges", inode, edge); } } for (auto edge : rr_graph.non_configurable_edges(RRNodeId(inode))) { - if (device_ctx.rr_nodes[inode].edge_is_configurable(edge)) { + if (rr_graph.rr_nodes()[inode].edge_is_configurable(edge)) { VPR_FATAL_ERROR(VPR_ERROR_ROUTE, "in check_rr_graph: node %d edge %d is configurable, but in non-configurable edges", inode, edge); } @@ -224,7 +224,7 @@ void check_rr_graph(const t_graph_type graph_type, } } - const auto& node = device_ctx.rr_nodes[inode]; + const auto& node = rr_graph.rr_nodes()[inode]; bool is_fringe = ((rr_graph.node_xlow(rr_node) == 1) || (rr_graph.node_ylow(rr_node) == 1) @@ -494,7 +494,7 @@ void check_rr_node(int inode, enum e_route_type route_type, const DeviceContext& //Don't worry about disconnect PINs which have no adjacent channels (i.e. on the device perimeter) bool check_for_out_edges = true; if (rr_type == IPIN || rr_type == OPIN) { - if (!has_adjacent_channel(device_ctx.rr_nodes[inode], device_ctx.grid)) { + if (!has_adjacent_channel(rr_graph.rr_nodes()[inode], device_ctx.grid)) { check_for_out_edges = false; } } diff --git a/vpr/src/route/clock_connection_builders.cpp b/vpr/src/route/clock_connection_builders.cpp index 8045dcf19cf..b47fe782d7a 100644 --- a/vpr/src/route/clock_connection_builders.cpp +++ b/vpr/src/route/clock_connection_builders.cpp @@ -91,19 +91,18 @@ void RoutingToClockConnection::create_switches(const ClockRRGraphBuilder& clock_ RRNodeId RoutingToClockConnection::create_virtual_clock_network_sink_node(int x, int y) { auto& device_ctx = g_vpr_ctx.mutable_device(); - auto& rr_graph = device_ctx.rr_nodes; - auto& temp_rr_graph = device_ctx.rr_graph; // replace this with rr_graph once device_ctx.rr_nodes is unused + auto& rr_graph = device_ctx.rr_graph; auto& rr_graph_builder = device_ctx.rr_graph_builder; auto& node_lookup = device_ctx.rr_graph_builder.node_lookup(); - rr_graph.emplace_back(); - RRNodeId node_index = RRNodeId(rr_graph.size() - 1); + rr_graph_builder.emplace_back(); + RRNodeId node_index = RRNodeId(rr_graph.num_nodes() - 1); //Determine the a valid PTC std::vector nodes_at_loc = node_lookup.find_grid_nodes_at_all_sides(x, y, SINK); int max_ptc = 0; for (RRNodeId inode : nodes_at_loc) { - max_ptc = std::max(max_ptc, temp_rr_graph.node_class_num(inode)); + max_ptc = std::max(max_ptc, rr_graph.node_class_num(inode)); } int ptc = max_ptc + 1; @@ -121,7 +120,7 @@ RRNodeId RoutingToClockConnection::create_virtual_clock_network_sink_node(int x, // However, since the SINK node has the same xhigh/xlow as well as yhigh/ylow, we can probably use a shortcut for (int ix = rr_graph.node_xlow(node_index); ix <= rr_graph.node_xhigh(node_index); ++ix) { for (int iy = rr_graph.node_ylow(node_index); iy <= rr_graph.node_yhigh(node_index); ++iy) { - node_lookup.add_node(node_index, ix, iy, rr_graph.node_type(node_index), temp_rr_graph.node_class_num(node_index)); + node_lookup.add_node(node_index, ix, iy, rr_graph.node_type(node_index), rr_graph.node_class_num(node_index)); } } diff --git a/vpr/src/route/route_breadth_first.cpp b/vpr/src/route/route_breadth_first.cpp index 46ae3b9adbb..d041d736e97 100644 --- a/vpr/src/route/route_breadth_first.cpp +++ b/vpr/src/route/route_breadth_first.cpp @@ -72,7 +72,7 @@ bool try_breadth_first_route(const t_router_opts& router_opts) { BinaryHeap heap; heap.init_heap(device_ctx.grid); - OveruseInfo overuse_info(device_ctx.rr_nodes.size()); + OveruseInfo overuse_info(device_ctx.rr_graph.num_nodes()); for (itry = 1; itry <= router_opts.max_router_iterations; itry++) { VTR_LOG("Routing Iteration %d\n", itry); @@ -387,8 +387,8 @@ static void breadth_first_expand_neighbours(BinaryHeap& heap, int inode, float p const auto& rr_graph = device_ctx.rr_graph; auto& route_ctx = g_vpr_ctx.routing(); - for (RREdgeId from_edge : device_ctx.rr_nodes.edge_range(RRNodeId(inode))) { - RRNodeId to_node = device_ctx.rr_nodes.edge_sink_node(from_edge); + for (RREdgeId from_edge : rr_graph.edge_range(RRNodeId(inode))) { + RRNodeId to_node = device_ctx.rr_graph.rr_nodes().edge_sink_node(from_edge); vtr::Point lower_left(route_ctx.route_bb[net_id].xmin, route_ctx.route_bb[net_id].ymin); vtr::Point upper_right(route_ctx.route_bb[net_id].xmax, route_ctx.route_bb[net_id].ymax); diff --git a/vpr/src/route/route_common.cpp b/vpr/src/route/route_common.cpp index cfa6025f007..2a4e38b6f4f 100644 --- a/vpr/src/route/route_common.cpp +++ b/vpr/src/route/route_common.cpp @@ -369,7 +369,7 @@ std::vector> collect_rr_node_nets() { auto& route_ctx = g_vpr_ctx.routing(); auto& cluster_ctx = g_vpr_ctx.clustering(); - std::vector> rr_node_nets(device_ctx.rr_nodes.size()); + std::vector> rr_node_nets(device_ctx.rr_graph.num_nodes()); for (ClusterNetId inet : cluster_ctx.clb_nlist.nets()) { t_trace* trace_elem = route_ctx.trace[inet].head; while (trace_elem) { @@ -568,7 +568,8 @@ static t_trace_branch traceback_branch(int node, int target_net_pin_index, std:: t_trace* prev_ptr = alloc_trace_data(); prev_ptr->index = inode; prev_ptr->net_pin_index = OPEN; //Net pin index is invalid for Non-SINK nodes - prev_ptr->iswitch = device_ctx.rr_nodes.edge_switch(iedge); + prev_ptr->iswitch = rr_graph.rr_nodes().edge_switch(iedge); + prev_ptr->next = branch_head; branch_head = prev_ptr; @@ -630,7 +631,7 @@ static std::pair add_trace_non_configurable_recurr(int node, auto& device_ctx = g_vpr_ctx.device(); const auto& rr_graph = device_ctx.rr_graph; for (auto iedge : rr_graph.non_configurable_edges(RRNodeId(node))) { - VTR_ASSERT_SAFE(!device_ctx.rr_nodes[node].edge_is_configurable(iedge)); + VTR_ASSERT_SAFE(!rr_graph.rr_nodes()[node].edge_is_configurable(iedge)); int to_node = size_t(rr_graph.edge_sink_node(RRNodeId(node), iedge)); @@ -941,8 +942,8 @@ void alloc_and_load_rr_node_route_structs() { auto& route_ctx = g_vpr_ctx.mutable_routing(); auto& device_ctx = g_vpr_ctx.device(); - route_ctx.rr_node_route_inf.resize(device_ctx.rr_nodes.size()); - route_ctx.non_configurable_bitset.resize(device_ctx.rr_nodes.size()); + route_ctx.rr_node_route_inf.resize(device_ctx.rr_graph.num_nodes()); + route_ctx.non_configurable_bitset.resize(device_ctx.rr_graph.num_nodes()); route_ctx.non_configurable_bitset.fill(false); reset_rr_node_route_structs(); @@ -959,7 +960,7 @@ void reset_rr_node_route_structs() { auto& route_ctx = g_vpr_ctx.mutable_routing(); auto& device_ctx = g_vpr_ctx.device(); - VTR_ASSERT(route_ctx.rr_node_route_inf.size() == size_t(device_ctx.rr_nodes.size())); + VTR_ASSERT(route_ctx.rr_node_route_inf.size() == size_t(device_ctx.rr_graph.num_nodes())); for (const RRNodeId& rr_id : device_ctx.rr_graph.nodes()) { auto& node_inf = route_ctx.rr_node_route_inf[(size_t)rr_id]; @@ -1401,7 +1402,7 @@ void reserve_locally_used_opins(HeapInterface* heap, float pres_fac, float acc_f /* Always 0 for pads and for RECEIVER (IPIN) classes */ for (ipin = 0; ipin < num_local_opin; ipin++) { inode = route_ctx.clb_opins_used_locally[blk_id][iclass][ipin]; - VTR_ASSERT(inode >= 0 && inode < (ssize_t)device_ctx.rr_nodes.size()); + VTR_ASSERT(inode >= 0 && inode < (ssize_t)rr_graph.num_nodes()); adjust_one_rr_occ_and_acc_cost(inode, -1, acc_fac); } } @@ -1638,7 +1639,7 @@ void print_rr_node_route_inf() { if (!std::isinf(route_ctx.rr_node_route_inf[inode].path_cost)) { int prev_node = route_ctx.rr_node_route_inf[inode].prev_node; RREdgeId prev_edge = route_ctx.rr_node_route_inf[inode].prev_edge; - auto switch_id = device_ctx.rr_nodes.edge_switch(prev_edge); + auto switch_id = rr_graph.rr_nodes().edge_switch(prev_edge); VTR_LOG("rr_node: %d prev_node: %d prev_edge: %zu", inode, prev_node, (size_t)prev_edge); @@ -1672,7 +1673,7 @@ void print_rr_node_route_inf_dot() { if (!std::isinf(route_ctx.rr_node_route_inf[inode].path_cost)) { int prev_node = route_ctx.rr_node_route_inf[inode].prev_node; RREdgeId prev_edge = route_ctx.rr_node_route_inf[inode].prev_edge; - auto switch_id = device_ctx.rr_nodes.edge_switch(prev_edge); + auto switch_id = rr_graph.rr_nodes().edge_switch(prev_edge); if (prev_node != OPEN && bool(prev_edge)) { VTR_LOG("\tnode%d -> node%zu [", prev_node, inode); diff --git a/vpr/src/route/route_timing.cpp b/vpr/src/route/route_timing.cpp index b758c278182..b2ebaa43791 100644 --- a/vpr/src/route/route_timing.cpp +++ b/vpr/src/route/route_timing.cpp @@ -322,7 +322,7 @@ bool try_timing_driven_route_tmpl(const t_router_opts& router_opts, */ bool routing_is_successful = false; WirelengthInfo wirelength_info; - OveruseInfo overuse_info(device_ctx.rr_nodes.size()); + OveruseInfo overuse_info(device_ctx.rr_graph.num_nodes()); tatum::TimingPathInfo critical_path; int itry; //Routing iteration number int itry_conflicted_mode = 0; @@ -339,7 +339,7 @@ bool try_timing_driven_route_tmpl(const t_router_opts& router_opts, ConnectionRouter router( device_ctx.grid, *router_lookahead, - device_ctx.rr_nodes, + device_ctx.rr_graph.rr_nodes(), &device_ctx.rr_graph, device_ctx.rr_rc_data, device_ctx.rr_graph.rr_switch(), @@ -1944,7 +1944,7 @@ static t_bb calc_current_bb(const t_trace* head) { bb.ymax = 0; for (const t_trace* elem = head; elem != nullptr; elem = elem->next) { - const t_rr_node& node = device_ctx.rr_nodes[elem->index]; + const t_rr_node& node = device_ctx.rr_graph.rr_nodes()[elem->index]; //The router interprets RR nodes which cross the boundary as being //'within' of the BB. Only those which are *strictly* out side the //box are excluded, hence we use the nodes xhigh/yhigh for xmin/xmax, diff --git a/vpr/src/route/route_tree_timing.cpp b/vpr/src/route/route_tree_timing.cpp index a216e3f1a8e..2f2b369221b 100644 --- a/vpr/src/route/route_tree_timing.cpp +++ b/vpr/src/route/route_tree_timing.cpp @@ -80,7 +80,7 @@ bool alloc_route_tree_timing_structs(bool exists_ok) { /* Allocates any structures needed to build the routing trees. */ auto& device_ctx = g_vpr_ctx.device(); - bool route_tree_structs_are_allocated = (rr_node_to_rt_node.size() == size_t(device_ctx.rr_nodes.size()) + bool route_tree_structs_are_allocated = (rr_node_to_rt_node.size() == size_t(device_ctx.rr_graph.num_nodes()) || rt_node_free_list != nullptr); if (route_tree_structs_are_allocated) { if (exists_ok) { @@ -91,7 +91,7 @@ bool alloc_route_tree_timing_structs(bool exists_ok) { } } - rr_node_to_rt_node = std::vector(device_ctx.rr_nodes.size(), nullptr); + rr_node_to_rt_node = std::vector(device_ctx.rr_graph.num_nodes(), nullptr); return true; } @@ -322,7 +322,7 @@ add_subtree_to_route_tree(t_heap* hptr, int target_net_pin_index, t_rt_node** si std::unordered_set all_visited; //does not include sink inode = hptr->prev_node(); RREdgeId edge = hptr->prev_edge(); - short iswitch = device_ctx.rr_nodes.edge_switch(edge); + short iswitch = rr_graph.rr_nodes().edge_switch(edge); /* For all "new" nodes in the main path */ // inode is node index of previous node @@ -361,7 +361,7 @@ add_subtree_to_route_tree(t_heap* hptr, int target_net_pin_index, t_rt_node** si downstream_rt_node = rt_node; edge = route_ctx.rr_node_route_inf[inode].prev_edge; inode = route_ctx.rr_node_route_inf[inode].prev_node; - iswitch = device_ctx.rr_nodes.edge_switch(edge); + iswitch = rr_graph.rr_nodes().edge_switch(edge); } //Inode is now the branch point to the old routing; do not need @@ -422,7 +422,7 @@ static t_rt_node* add_non_configurable_to_route_tree(const int rr_node, const bo } for (int iedge : rr_graph.non_configurable_edges(RRNodeId(rr_node))) { //Recursive case: expand children - VTR_ASSERT(!device_ctx.rr_nodes[rr_node].edge_is_configurable(iedge)); + VTR_ASSERT(!rr_graph.rr_nodes()[rr_node].edge_is_configurable(iedge)); int to_rr_node = size_t(rr_graph.edge_sink_node(RRNodeId(rr_node), iedge)); //Recurse diff --git a/vpr/src/route/router_delay_profiling.cpp b/vpr/src/route/router_delay_profiling.cpp index e37f414de04..53025596120 100644 --- a/vpr/src/route/router_delay_profiling.cpp +++ b/vpr/src/route/router_delay_profiling.cpp @@ -16,7 +16,7 @@ RouterDelayProfiler::RouterDelayProfiler( : router_( g_vpr_ctx.device().grid, *lookahead, - g_vpr_ctx.device().rr_nodes, + g_vpr_ctx.device().rr_graph.rr_nodes(), &g_vpr_ctx.device().rr_graph, g_vpr_ctx.device().rr_rc_data, g_vpr_ctx.device().rr_graph.rr_switch(), @@ -100,7 +100,7 @@ std::vector calculate_all_path_delays_from_rr_node(int src_rr_node, const auto& device_ctx = g_vpr_ctx.device(); auto& routing_ctx = g_vpr_ctx.mutable_routing(); - std::vector path_delays_to(device_ctx.rr_nodes.size(), std::numeric_limits::quiet_NaN()); + std::vector path_delays_to(device_ctx.rr_graph.num_nodes(), std::numeric_limits::quiet_NaN()); t_rt_node* rt_root = setup_routing_resources_no_net(src_rr_node); @@ -121,7 +121,7 @@ std::vector calculate_all_path_delays_from_rr_node(int src_rr_node, const ConnectionRouter router( device_ctx.grid, *router_lookahead, - device_ctx.rr_nodes, + device_ctx.rr_graph.rr_nodes(), &g_vpr_ctx.device().rr_graph, device_ctx.rr_rc_data, device_ctx.rr_graph.rr_switch(), @@ -135,8 +135,8 @@ std::vector calculate_all_path_delays_from_rr_node(int src_rr_node, const free_route_tree(rt_root); - VTR_ASSERT(shortest_paths.size() == device_ctx.rr_nodes.size()); - for (int sink_rr_node = 0; sink_rr_node < (int)device_ctx.rr_nodes.size(); ++sink_rr_node) { + VTR_ASSERT(shortest_paths.size() == device_ctx.rr_graph.num_nodes()); + for (int sink_rr_node = 0; sink_rr_node < (int)device_ctx.rr_graph.num_nodes(); ++sink_rr_node) { if (sink_rr_node == src_rr_node) { path_delays_to[sink_rr_node] = 0.; } else { diff --git a/vpr/src/route/router_lookahead_extended_map.cpp b/vpr/src/route/router_lookahead_extended_map.cpp index 258de89050b..beb954d6cea 100644 --- a/vpr/src/route/router_lookahead_extended_map.cpp +++ b/vpr/src/route/router_lookahead_extended_map.cpp @@ -438,8 +438,8 @@ void ExtendedMapLookahead::compute(const std::vector& segment_inf util::RoutingCosts delay_costs; util::RoutingCosts base_costs; int total_path_count = 0; - std::vector node_expanded(device_ctx.rr_nodes.size()); - std::vector paths(device_ctx.rr_nodes.size()); + std::vector node_expanded(device_ctx.rr_graph.num_nodes()); + std::vector paths(device_ctx.rr_graph.num_nodes()); // Each point in a sample region contains a set of nodes. Each node becomes a starting node // for the dijkstra expansions, and different paths are explored to reach different locations. diff --git a/vpr/src/route/router_lookahead_map.cpp b/vpr/src/route/router_lookahead_map.cpp index c46e213633b..213f4a04b15 100644 --- a/vpr/src/route/router_lookahead_map.cpp +++ b/vpr/src/route/router_lookahead_map.cpp @@ -588,11 +588,11 @@ static void run_dijkstra(RRNodeId start_node, int start_x, int start_y, t_routin const auto& rr_graph = device_ctx.rr_graph; auto& node_expanded = data->node_expanded; - node_expanded.resize(device_ctx.rr_nodes.size()); + node_expanded.resize(rr_graph.num_nodes()); std::fill(node_expanded.begin(), node_expanded.end(), false); auto& node_visited_costs = data->node_visited_costs; - node_visited_costs.resize(device_ctx.rr_nodes.size()); + node_visited_costs.resize(rr_graph.num_nodes()); std::fill(node_visited_costs.begin(), node_visited_costs.end(), -1.0); /* a priority queue for expansion */ diff --git a/vpr/src/route/router_lookahead_map_utils.cpp b/vpr/src/route/router_lookahead_map_utils.cpp index a65054a0a63..47cbcb2bb48 100644 --- a/vpr/src/route/router_lookahead_map_utils.cpp +++ b/vpr/src/route/router_lookahead_map_utils.cpp @@ -415,8 +415,7 @@ t_chan_ipins_delays compute_router_chan_ipin_lookahead() { static void dijkstra_flood_to_wires(int itile, RRNodeId node, util::t_src_opin_delays& src_opin_delays) { auto& device_ctx = g_vpr_ctx.device(); - const auto& temp_rr_graph = device_ctx.rr_graph; //TODO rename to rr_graph once the variable on the next line is unneeded - auto& rr_graph = device_ctx.rr_nodes; + const auto& rr_graph = device_ctx.rr_graph; struct t_pq_entry { float delay; @@ -435,7 +434,7 @@ static void dijkstra_flood_to_wires(int itile, RRNodeId node, util::t_src_opin_d root.delay = 0.; root.node = node; - int ptc = temp_rr_graph.node_ptc_num(node); + int ptc = rr_graph.node_ptc_num(node); /* * Perform Djikstra from the SOURCE/OPIN of interest, stopping at the the first @@ -462,13 +461,13 @@ static void dijkstra_flood_to_wires(int itile, RRNodeId node, util::t_src_opin_d t_pq_entry curr = pq.top(); pq.pop(); - e_rr_type curr_rr_type = temp_rr_graph.node_type(curr.node); + e_rr_type curr_rr_type = rr_graph.node_type(curr.node); if (curr_rr_type == CHANX || curr_rr_type == CHANY || curr_rr_type == SINK) { //We stop expansion at any CHANX/CHANY/SINK int seg_index; if (curr_rr_type != SINK) { //It's a wire, figure out its type - auto cost_index = temp_rr_graph.node_cost_index(curr.node); + auto cost_index = rr_graph.node_cost_index(curr.node); seg_index = device_ctx.rr_indexed_data[cost_index].seg_index; } else { //This is a direct-connect path between an IPIN and OPIN, @@ -492,14 +491,14 @@ static void dijkstra_flood_to_wires(int itile, RRNodeId node, util::t_src_opin_d } else if (curr_rr_type == SOURCE || curr_rr_type == OPIN || curr_rr_type == IPIN) { //We allow expansion through SOURCE/OPIN/IPIN types - auto cost_index = temp_rr_graph.node_cost_index(curr.node); + auto cost_index = rr_graph.node_cost_index(curr.node); float incr_cong = device_ctx.rr_indexed_data[cost_index].base_cost; //Current nodes congestion cost for (RREdgeId edge : rr_graph.edge_range(curr.node)) { - int iswitch = rr_graph.edge_switch(edge); - float incr_delay = temp_rr_graph.rr_switch_inf(RRSwitchId(iswitch)).Tdel; + int iswitch = rr_graph.rr_nodes().edge_switch(edge); + float incr_delay = rr_graph.rr_switch_inf(RRSwitchId(iswitch)).Tdel; - RRNodeId next_node = rr_graph.edge_sink_node(edge); + RRNodeId next_node = rr_graph.rr_nodes().edge_sink_node(edge); t_pq_entry next; next.congestion = curr.congestion + incr_cong; //Of current node @@ -516,8 +515,7 @@ static void dijkstra_flood_to_wires(int itile, RRNodeId node, util::t_src_opin_d static void dijkstra_flood_to_ipins(RRNodeId node, util::t_chan_ipins_delays& chan_ipins_delays) { auto& device_ctx = g_vpr_ctx.device(); - const auto& temp_rr_graph = device_ctx.rr_graph; //TODO rename to rr_graph once the variable on the next line is unneeded - auto& rr_graph = device_ctx.rr_nodes; + auto& rr_graph = device_ctx.rr_graph; struct t_pq_entry { float delay; @@ -562,15 +560,15 @@ static void dijkstra_flood_to_ipins(RRNodeId node, util::t_chan_ipins_delays& ch t_pq_entry curr = pq.top(); pq.pop(); - e_rr_type curr_rr_type = temp_rr_graph.node_type(curr.node); + e_rr_type curr_rr_type = rr_graph.node_type(curr.node); if (curr_rr_type == IPIN) { - int node_x = temp_rr_graph.node_xlow(curr.node); - int node_y = temp_rr_graph.node_ylow(curr.node); + int node_x = rr_graph.node_xlow(curr.node); + int node_y = rr_graph.node_ylow(curr.node); auto tile_type = device_ctx.grid[node_x][node_y].type; int itile = tile_type->index; - int ptc = temp_rr_graph.node_ptc_num(curr.node); + int ptc = rr_graph.node_ptc_num(curr.node); if (ptc >= int(chan_ipins_delays[itile].size())) { chan_ipins_delays[itile].resize(ptc + 1); //Inefficient but functional... @@ -587,14 +585,14 @@ static void dijkstra_flood_to_ipins(RRNodeId node, util::t_chan_ipins_delays& ch } //We allow expansion through SOURCE/OPIN/IPIN types - auto cost_index = temp_rr_graph.node_cost_index(curr.node); + auto cost_index = rr_graph.node_cost_index(curr.node); float new_cong = device_ctx.rr_indexed_data[cost_index].base_cost; //Current nodes congestion cost for (RREdgeId edge : rr_graph.edge_range(curr.node)) { - int iswitch = rr_graph.edge_switch(edge); - float new_delay = temp_rr_graph.rr_switch_inf(RRSwitchId(iswitch)).Tdel; + int iswitch = rr_graph.rr_nodes().edge_switch(edge); + float new_delay = rr_graph.rr_switch_inf(RRSwitchId(iswitch)).Tdel; - RRNodeId next_node = rr_graph.edge_sink_node(edge); + RRNodeId next_node = rr_graph.rr_nodes().edge_sink_node(edge); t_pq_entry next; next.congestion = new_cong; //Of current node diff --git a/vpr/src/route/router_lookahead_sampling.cpp b/vpr/src/route/router_lookahead_sampling.cpp index 1cafebacfae..8060e8e7f0b 100644 --- a/vpr/src/route/router_lookahead_sampling.cpp +++ b/vpr/src/route/router_lookahead_sampling.cpp @@ -24,7 +24,7 @@ static int manhattan_distance(const vtr::Point& a, const vtr::Point& b // This builds a rectangle from (x, y) to (x+1, y+1) static vtr::Rect bounding_box_for_node(RRNodeId node) { auto& device_ctx = g_vpr_ctx.device(); - auto& rr_graph = device_ctx.rr_nodes; + auto& rr_graph = device_ctx.rr_graph; int x = rr_graph.node_xlow(node); int y = rr_graph.node_ylow(node); @@ -198,12 +198,11 @@ std::vector find_sample_regions(int num_segments) { std::vector sample_regions; auto& device_ctx = g_vpr_ctx.device(); const auto& rr_graph = device_ctx.rr_graph; - auto& rr_nodes = device_ctx.rr_nodes; std::vector> segment_counts(num_segments); // compute bounding boxes for each segment type std::vector> bounding_box_for_segment(num_segments, vtr::Rect()); - for (auto& node : rr_nodes) { + for (auto& node : rr_graph.rr_nodes()) { if (rr_graph.node_type(node.id()) != CHANX && rr_graph.node_type(node.id()) != CHANY) continue; if (rr_graph.node_capacity(node.id()) == 0 || rr_graph.num_edges(node.id()) == 0) continue; int seg_index = device_ctx.rr_indexed_data[rr_graph.node_cost_index(node.id())].seg_index; @@ -221,7 +220,7 @@ std::vector find_sample_regions(int num_segments) { } // count sample points - for (const auto& node : rr_nodes) { + for (const auto& node : rr_graph.rr_nodes()) { int seg_index, x, y; std::tie(seg_index, x, y) = get_node_info(node, num_segments); @@ -247,7 +246,7 @@ std::vector find_sample_regions(int num_segments) { } // collect the node indices for each segment type at the selected sample points - for (const auto& node : rr_nodes) { + for (const auto& node : rr_graph.rr_nodes()) { int seg_index, x, y; std::tie(seg_index, x, y) = get_node_info(node, num_segments); diff --git a/vpr/src/route/rr_graph.cpp b/vpr/src/route/rr_graph.cpp index c373836ba13..5172a66e2be 100644 --- a/vpr/src/route/rr_graph.cpp +++ b/vpr/src/route/rr_graph.cpp @@ -334,7 +334,7 @@ void create_rr_graph(const t_graph_type graph_type, } } } else { - if (channel_widths_unchanged(device_ctx.chan_width, nodes_per_chan) && !device_ctx.rr_nodes.empty()) { + if (channel_widths_unchanged(device_ctx.chan_width, nodes_per_chan) && !device_ctx.rr_graph.empty()) { //No change in channel width, so skip re-building RR graph VTR_LOG("RR graph channel widths unchanged, skipping RR graph rebuild\n"); return; @@ -370,7 +370,7 @@ void create_rr_graph(const t_graph_type graph_type, process_non_config_sets(); - verify_rr_node_indices(grid, device_ctx.rr_graph, device_ctx.rr_nodes); + verify_rr_node_indices(grid, device_ctx.rr_graph, device_ctx.rr_graph.rr_nodes()); print_rr_graph_stats(); @@ -386,11 +386,11 @@ void print_rr_graph_stats() { const auto& rr_graph = device_ctx.rr_graph; size_t num_rr_edges = 0; - for (auto& rr_node : device_ctx.rr_nodes) { + for (auto& rr_node : rr_graph.rr_nodes()) { num_rr_edges += rr_graph.edges(rr_node.id()).size(); } - VTR_LOG(" RR Graph Nodes: %zu\n", device_ctx.rr_nodes.size()); + VTR_LOG(" RR Graph Nodes: %zu\n", rr_graph.num_nodes()); VTR_LOG(" RR Graph Edges: %zu\n", num_rr_edges); } @@ -705,7 +705,7 @@ static void build_rr_graph(const t_graph_type graph_type, auto update_chan_width = alloc_and_load_rr_graph( device_ctx.rr_graph_builder, - device_ctx.rr_nodes, device_ctx.rr_graph, segment_inf.size(), + device_ctx.rr_graph_builder.rr_nodes(), device_ctx.rr_graph, segment_inf.size(), chan_details_x, chan_details_y, track_to_pin_lookup, opin_to_track_map, switch_block_conn, sb_conn_map, grid, Fs, unidir_sb_pattern, @@ -721,9 +721,9 @@ static void build_rr_graph(const t_graph_type graph_type, clock_modeling); // Verify no incremental node allocation. - if (device_ctx.rr_nodes.size() > expected_node_count) { + if (rr_graph.num_nodes() > expected_node_count) { VTR_LOG_ERROR("Expected no more than %zu nodes, have %zu nodes\n", - expected_node_count, device_ctx.rr_nodes.size()); + expected_node_count, rr_graph.num_nodes()); } /* Update rr_nodes capacities if global routing */ @@ -1405,8 +1405,6 @@ void free_rr_graph() { device_ctx.read_rr_graph_filename.clear(); - device_ctx.rr_nodes.clear(); - device_ctx.rr_graph_builder.clear(); device_ctx.rr_indexed_data.clear(); @@ -2485,8 +2483,6 @@ std::string describe_rr_node(int inode) { std::string msg = vtr::string_fmt("RR node: %d", inode); - auto rr_node = device_ctx.rr_nodes[inode]; - if (rr_graph.node_type(RRNodeId(inode)) == CHANX || rr_graph.node_type(RRNodeId(inode)) == CHANY) { auto cost_index = rr_graph.node_cost_index(RRNodeId(inode)); @@ -2503,11 +2499,11 @@ std::string describe_rr_node(int inode) { seg_index); } } else if (rr_graph.node_type(RRNodeId(inode)) == IPIN || rr_graph.node_type(RRNodeId(inode)) == OPIN) { - auto type = device_ctx.grid[rr_graph.node_xlow(rr_node.id())][rr_graph.node_ylow(rr_node.id())].type; - std::string pin_name = block_type_pin_index_to_name(type, rr_graph.node_pin_num(rr_node.id())); + auto type = device_ctx.grid[rr_graph.node_xlow(RRNodeId(inode))][rr_graph.node_ylow(RRNodeId(inode))].type; + std::string pin_name = block_type_pin_index_to_name(type, rr_graph.node_pin_num(RRNodeId(inode))); msg += vtr::string_fmt(" pin: %d pin_name: %s", - rr_graph.node_pin_num(rr_node.id()), + rr_graph.node_pin_num(RRNodeId(inode)), pin_name.c_str()); } else { VTR_ASSERT(rr_graph.node_type(RRNodeId(inode)) == SOURCE || rr_graph.node_type(RRNodeId(inode)) == SINK); @@ -3024,11 +3020,10 @@ static RRNodeId pick_best_direct_connect_target_rr_node(const RRGraphView& rr_gr //Collects the sets of connected non-configurable edges in the RR graph static void create_edge_groups(EdgeGroups* groups) { auto& device_ctx = g_vpr_ctx.device(); - auto& rr_nodes = device_ctx.rr_nodes; const auto& rr_graph = device_ctx.rr_graph; - rr_nodes.for_each_edge( + rr_graph.rr_nodes().for_each_edge( [&](RREdgeId edge, RRNodeId src, RRNodeId sink) { - if (!rr_graph.rr_switch_inf(RRSwitchId(rr_nodes.edge_switch(edge))).configurable()) { + if (!rr_graph.rr_switch_inf(RRSwitchId(rr_graph.rr_nodes().edge_switch(edge))).configurable()) { groups->add_non_config_edge(size_t(src), size_t(sink)); } }); diff --git a/vpr/src/route/rr_graph_area.cpp b/vpr/src/route/rr_graph_area.cpp index 078f7e35cdb..48f6ce08e16 100644 --- a/vpr/src/route/rr_graph_area.cpp +++ b/vpr/src/route/rr_graph_area.cpp @@ -145,7 +145,7 @@ void count_bidir_routing_transistors(int num_switch, int wire_to_ipin_switch, fl trans_track_to_cblock_buf = 0; } - num_inputs_to_cblock = (int*)vtr::calloc(device_ctx.rr_nodes.size(), sizeof(int)); + num_inputs_to_cblock = (int*)vtr::calloc(rr_graph.num_nodes(), sizeof(int)); maxlen = std::max(device_ctx.grid.width(), device_ctx.grid.height()); cblock_counted = (bool*)vtr::calloc(maxlen, sizeof(bool)); @@ -319,7 +319,7 @@ void count_unidir_routing_transistors(std::vector& /*segment_inf* * switches of all rr nodes. Thus we keep track of which muxes we have already * counted via the variable below. */ bool* chan_node_switch_done; - chan_node_switch_done = (bool*)vtr::calloc(device_ctx.rr_nodes.size(), sizeof(bool)); + chan_node_switch_done = (bool*)vtr::calloc(rr_graph.num_nodes(), sizeof(bool)); /* The variable below is an accumulator variable that will add up all the * * transistors in the routing. Make double so that it doesn't stop * @@ -349,7 +349,7 @@ void count_unidir_routing_transistors(std::vector& /*segment_inf* trans_track_to_cblock_buf = 0; } - num_inputs_to_cblock = (int*)vtr::calloc(device_ctx.rr_nodes.size(), sizeof(int)); + num_inputs_to_cblock = (int*)vtr::calloc(rr_graph.num_nodes(), sizeof(int)); maxlen = std::max(device_ctx.grid.width(), device_ctx.grid.height()); cblock_counted = (bool*)vtr::calloc(maxlen, sizeof(bool)); diff --git a/vpr/src/route/rr_graph_indexed_data.cpp b/vpr/src/route/rr_graph_indexed_data.cpp index c0cba045629..aaedd4e7d5d 100644 --- a/vpr/src/route/rr_graph_indexed_data.cpp +++ b/vpr/src/route/rr_graph_indexed_data.cpp @@ -451,7 +451,6 @@ static void load_rr_indexed_data_T_values() { static void calculate_average_switch(int inode, double& avg_switch_R, double& avg_switch_T, double& avg_switch_Cinternal, int& num_switches, short& buffered, vtr::vector>& fan_in_list) { auto& device_ctx = g_vpr_ctx.device(); const auto& rr_graph = device_ctx.rr_graph; - const auto& rr_nodes = device_ctx.rr_nodes.view(); auto node = RRNodeId(inode); @@ -463,7 +462,7 @@ static void calculate_average_switch(int inode, double& avg_switch_R, double& av for (const auto& edge : fan_in_list[node]) { /* want to get C/R/Tdel/Cinternal of switches that connect this track segment to other track segments */ if (rr_graph.node_type(node) == CHANX || rr_graph.node_type(node) == CHANY) { - int switch_index = rr_nodes.edge_switch(edge); + int switch_index = rr_graph.rr_nodes().edge_switch(edge); if (rr_graph.rr_switch_inf(RRSwitchId(switch_index)).type() == SwitchType::SHORT) continue; diff --git a/vpr/src/route/rr_graph_reader.cpp b/vpr/src/route/rr_graph_reader.cpp index df3688e1323..f2c6faf6a37 100644 --- a/vpr/src/route/rr_graph_reader.cpp +++ b/vpr/src/route/rr_graph_reader.cpp @@ -62,7 +62,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_nodes, + &device_ctx.rr_graph_builder.rr_nodes(), &device_ctx.rr_graph_builder, &device_ctx.rr_graph, &device_ctx.rr_graph_builder.rr_switch(), diff --git a/vpr/src/route/rr_graph_timing_params.cpp b/vpr/src/route/rr_graph_timing_params.cpp index dcf50499334..b3a2766639f 100644 --- a/vpr/src/route/rr_graph_timing_params.cpp +++ b/vpr/src/route/rr_graph_timing_params.cpp @@ -45,9 +45,9 @@ void add_rr_graph_C_from_switches(float C_ipin_cblock) { cblock_counted = (bool*)vtr::calloc(maxlen, sizeof(bool)); buffer_Cin = (float*)vtr::calloc(maxlen, sizeof(float)); - std::vector rr_node_C(device_ctx.rr_nodes.size(), 0.); //Stores the final C + std::vector rr_node_C(rr_graph.num_nodes(), 0.); //Stores the final C - for (const RRNodeId& rr_id : device_ctx.rr_graph.nodes()) { + for (const RRNodeId& rr_id : rr_graph.nodes()) { size_t inode = (size_t)rr_id; //The C may have already been partly initialized (e.g. with metal capacitance) rr_node_C[inode] += rr_graph.node_C(rr_id); @@ -172,8 +172,8 @@ void add_rr_graph_C_from_switches(float C_ipin_cblock) { * Current structures only keep switch information from a node to the next node and * not the reverse. Therefore I need to go through all the possible edges to figure * out what the Cout's should be */ - Couts_to_add = (float*)vtr::calloc(device_ctx.rr_nodes.size(), sizeof(float)); - for (const RRNodeId& inode : device_ctx.rr_graph.nodes()) { + Couts_to_add = (float*)vtr::calloc(rr_graph.num_nodes(), sizeof(float)); + for (const RRNodeId& inode : rr_graph.nodes()) { for (t_edge_size iedge = 0; iedge < rr_graph.num_edges(inode); iedge++) { switch_index = rr_graph.edge_switch(inode, iedge); to_node = size_t(rr_graph.edge_sink_node(inode, iedge)); diff --git a/vpr/src/route/rr_graph_util.cpp b/vpr/src/route/rr_graph_util.cpp index b1b23194353..06aaf1e2612 100644 --- a/vpr/src/route/rr_graph_util.cpp +++ b/vpr/src/route/rr_graph_util.cpp @@ -84,15 +84,15 @@ int seg_index_of_sblock(int from_node, int to_node) { } vtr::vector> get_fan_in_list() { - auto& rr_nodes = g_vpr_ctx.device().rr_nodes; + auto& rr_graph = g_vpr_ctx.device().rr_graph; vtr::vector> node_fan_in_list; - node_fan_in_list.resize(rr_nodes.size(), std::vector(0)); + node_fan_in_list.resize(rr_graph.num_nodes(), std::vector(0)); node_fan_in_list.shrink_to_fit(); //Walk the graph and increment fanin on all dwnstream nodes - rr_nodes.for_each_edge( + rr_graph.rr_nodes().for_each_edge( [&](RREdgeId edge, __attribute__((unused)) RRNodeId src, RRNodeId sink) { node_fan_in_list[sink].push_back(edge); }); diff --git a/vpr/src/route/rr_graph_writer.cpp b/vpr/src/route/rr_graph_writer.cpp index 61504faf3c6..d06d24c5c45 100644 --- a/vpr/src/route/rr_graph_writer.cpp +++ b/vpr/src/route/rr_graph_writer.cpp @@ -35,7 +35,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_nodes, + &device_ctx.rr_graph_builder.rr_nodes(), &device_ctx.rr_graph_builder, &device_ctx.rr_graph, &device_ctx.rr_graph_builder.rr_switch(), diff --git a/vpr/src/route/spatial_route_tree_lookup.cpp b/vpr/src/route/spatial_route_tree_lookup.cpp index 96159237224..3f6052dbdc8 100644 --- a/vpr/src/route/spatial_route_tree_lookup.cpp +++ b/vpr/src/route/spatial_route_tree_lookup.cpp @@ -33,12 +33,12 @@ void update_route_tree_spatial_lookup_recur(t_rt_node* rt_node, SpatialRouteTree auto& device_ctx = g_vpr_ctx.device(); const auto& rr_graph = device_ctx.rr_graph; - auto& rr_node = device_ctx.rr_nodes[rt_node->inode]; + RRNodeId rr_node = (RRNodeId)rt_node->inode; - int bin_xlow = grid_to_bin_x(rr_graph.node_xlow(rr_node.id()), spatial_lookup); - int bin_ylow = grid_to_bin_y(rr_graph.node_ylow(rr_node.id()), spatial_lookup); - int bin_xhigh = grid_to_bin_x(rr_graph.node_xhigh(rr_node.id()), spatial_lookup); - int bin_yhigh = grid_to_bin_y(rr_graph.node_yhigh(rr_node.id()), spatial_lookup); + int bin_xlow = grid_to_bin_x(rr_graph.node_xlow(rr_node), spatial_lookup); + int bin_ylow = grid_to_bin_y(rr_graph.node_ylow(rr_node), spatial_lookup); + int bin_xhigh = grid_to_bin_x(rr_graph.node_xhigh(rr_node), spatial_lookup); + int bin_yhigh = grid_to_bin_y(rr_graph.node_yhigh(rr_node), spatial_lookup); spatial_lookup[bin_xlow][bin_ylow].push_back(rt_node); @@ -78,12 +78,12 @@ size_t grid_to_bin_y(size_t grid_y, const SpatialRouteTreeLookup& spatial_lookup bool validate_route_tree_spatial_lookup(t_rt_node* rt_node, const SpatialRouteTreeLookup& spatial_lookup) { auto& device_ctx = g_vpr_ctx.device(); const auto& rr_graph = device_ctx.rr_graph; - auto& rr_node = device_ctx.rr_nodes[rt_node->inode]; + RRNodeId rr_node = (RRNodeId)rt_node->inode; - int bin_xlow = grid_to_bin_x(rr_graph.node_xlow(rr_node.id()), spatial_lookup); - int bin_ylow = grid_to_bin_y(rr_graph.node_ylow(rr_node.id()), spatial_lookup); - int bin_xhigh = grid_to_bin_x(rr_graph.node_xhigh(rr_node.id()), spatial_lookup); - int bin_yhigh = grid_to_bin_y(rr_graph.node_yhigh(rr_node.id()), spatial_lookup); + int bin_xlow = grid_to_bin_x(rr_graph.node_xlow(rr_node), spatial_lookup); + int bin_ylow = grid_to_bin_y(rr_graph.node_ylow(rr_node), spatial_lookup); + int bin_xhigh = grid_to_bin_x(rr_graph.node_xhigh(rr_node), spatial_lookup); + int bin_yhigh = grid_to_bin_y(rr_graph.node_yhigh(rr_node), spatial_lookup); bool valid = true; @@ -91,14 +91,14 @@ bool validate_route_tree_spatial_lookup(t_rt_node* rt_node, const SpatialRouteTr if (std::find(low_bin_rt_nodes.begin(), low_bin_rt_nodes.end(), rt_node) == low_bin_rt_nodes.end()) { valid = false; VPR_FATAL_ERROR(VPR_ERROR_ROUTE, "Failed to find route tree node %d at (low coord %d,%d) in spatial lookup [bin %d,%d]", - rt_node->inode, rr_graph.node_xlow(rr_node.id()), rr_graph.node_ylow(rr_node.id()), bin_xlow, bin_ylow); + rt_node->inode, rr_graph.node_xlow(rr_node), rr_graph.node_ylow(rr_node), bin_xlow, bin_ylow); } auto& high_bin_rt_nodes = spatial_lookup[bin_xhigh][bin_yhigh]; if (std::find(high_bin_rt_nodes.begin(), high_bin_rt_nodes.end(), rt_node) == high_bin_rt_nodes.end()) { valid = false; VPR_FATAL_ERROR(VPR_ERROR_ROUTE, "Failed to find route tree node %d at (high coord %d,%d) in spatial lookup [bin %d,%d]", - rt_node->inode, rr_graph.node_xhigh(rr_node.id()), rr_graph.node_yhigh(rr_node.id()), bin_xhigh, bin_yhigh); + rt_node->inode, rr_graph.node_xhigh(rr_node), rr_graph.node_yhigh(rr_node), bin_xhigh, bin_yhigh); } //Recurse diff --git a/vpr/src/util/vpr_utils.cpp b/vpr/src/util/vpr_utils.cpp index 196f1f3603f..4f3cbf8cda9 100644 --- a/vpr/src/util/vpr_utils.cpp +++ b/vpr/src/util/vpr_utils.cpp @@ -1799,8 +1799,8 @@ void print_switch_usage() { switch_fanin_delay = new std::map[device_ctx.num_arch_switches]; // a node can have multiple inward switches, so // map key: switch index; map value: count (fanin) - std::map* inward_switch_inf = new std::map[device_ctx.rr_nodes.size()]; - for (const RRNodeId& inode : device_ctx.rr_graph.nodes()) { + std::map* inward_switch_inf = new std::map[rr_graph.num_nodes()]; + for (const RRNodeId& inode : rr_graph.nodes()) { int num_edges = rr_graph.num_edges(inode); for (int iedge = 0; iedge < num_edges; iedge++) { int switch_index = rr_graph.edge_switch(inode, iedge); diff --git a/vpr/test/test_connection_router.cpp b/vpr/test/test_connection_router.cpp index 14f016c1678..7b0e3688cd9 100644 --- a/vpr/test/test_connection_router.cpp +++ b/vpr/test/test_connection_router.cpp @@ -46,7 +46,7 @@ static float do_one_route(int source_node, int sink_node, const t_router_opts& r ConnectionRouter router( device_ctx.grid, *router_lookahead, - device_ctx.rr_nodes, + device_ctx.rr_graph.rr_nodes(), &device_ctx.rr_graph, device_ctx.rr_rc_data, device_ctx.rr_graph.rr_switch(), @@ -79,21 +79,21 @@ static float do_one_route(int source_node, int sink_node, const t_router_opts& r // Find a source and a sink by walking edges. std::tuple find_source_and_sink() { auto& device_ctx = g_vpr_ctx.device(); - auto& rr_graph = device_ctx.rr_nodes; + auto& rr_graph = device_ctx.rr_graph; // Current longest walk std::tuple longest = std::make_tuple(0, 0, 0); // Start from each RR node - for (size_t id = 0; id < rr_graph.size(); id++) { + for (size_t id = 0; id < rr_graph.num_nodes(); id++) { RRNodeId source(id), sink = source; for (int hops = 0; hops < kMaxHops; hops++) { // Take the first edge, if there is one. - auto edge = rr_graph.first_edge(sink); - if (edge == rr_graph.last_edge(sink)) { + auto edge = rr_graph.node_first_edge(sink); + if (edge == rr_graph.node_last_edge(sink)) { break; } - sink = rr_graph.edge_sink_node(edge); + sink = rr_graph.rr_nodes().edge_sink_node(edge); // If this is the new longest walk, store it. if (hops > std::get<2>(longest)) { diff --git a/vpr/test/test_vpr.cpp b/vpr/test/test_vpr.cpp index dd983c8f04d..f19fd9c9f74 100644 --- a/vpr/test/test_vpr.cpp +++ b/vpr/test/test_vpr.cpp @@ -183,8 +183,8 @@ TEST_CASE("read_rr_graph_metadata", "[vpr]") { const auto& device_ctx = g_vpr_ctx.device(); // recompute ordering from 'random_shuffle' - std::vector src_order(device_ctx.rr_nodes.size()); // new id -> old id - std::iota(src_order.begin(), src_order.end(), 0); // Initialize to [0, 1, 2 ...] + std::vector src_order(device_ctx.rr_graph.num_nodes()); // new id -> old id + std::iota(src_order.begin(), src_order.end(), 0); // Initialize to [0, 1, 2 ...] std::mt19937 g(1); std::shuffle(src_order.begin(), src_order.end(), g);