From 1b306c0a8dc50812580ae3c3f3a03b65e059a8f1 Mon Sep 17 00:00:00 2001 From: soheilshahrouz Date: Wed, 29 Jan 2025 13:18:16 -0500 Subject: [PATCH 01/23] fix some typos in comments --- libs/librrgraph/src/base/rr_graph_storage.cpp | 2 +- libs/librrgraph/src/base/rr_graph_storage.h | 28 +++++++++---------- libs/librrgraph/src/base/rr_graph_view.h | 21 +++++++++----- libs/librrgraph/src/base/rr_node_types.h | 4 +-- libs/libvtrutil/src/vtr_strong_id_range.h | 8 +++--- 5 files changed, 35 insertions(+), 28 deletions(-) diff --git a/libs/librrgraph/src/base/rr_graph_storage.cpp b/libs/librrgraph/src/base/rr_graph_storage.cpp index 8d8dcd5ac20..b36887c9d4d 100644 --- a/libs/librrgraph/src/base/rr_graph_storage.cpp +++ b/libs/librrgraph/src/base/rr_graph_storage.cpp @@ -720,7 +720,7 @@ void t_rr_graph_storage::set_node_type(RRNodeId id, t_rr_type new_type) { node_storage_[id].type_ = new_type; } -void t_rr_graph_storage::set_node_name(RRNodeId id, std::string new_name) { +void t_rr_graph_storage::set_node_name(RRNodeId id, const std::string& new_name) { node_name_.insert(std::make_pair(id, new_name)); } void t_rr_graph_storage::set_node_coordinates(RRNodeId id, short x1, short y1, short x2, short y2) { diff --git a/libs/librrgraph/src/base/rr_graph_storage.h b/libs/librrgraph/src/base/rr_graph_storage.h index 82c8f0b2326..bd80ffa13d5 100644 --- a/libs/librrgraph/src/base/rr_graph_storage.h +++ b/libs/librrgraph/src/base/rr_graph_storage.h @@ -25,10 +25,10 @@ * parallel rr_node_* structures. * * * * This structure should **only** contain data used in the inner loop of the * - * router. This data is consider "hot" and the router performance is * + * router. This data is considered "hot" and the router performance is * * sensitive to layout and size of this "hot" data. * - * Cold data should be stored seperately in t_rr_graph_storage. * + * Cold data should be stored separately in t_rr_graph_storage. * * * * xlow, xhigh, ylow, yhigh: Integer coordinates (see route.c for * * coordinate system) of the ends of this routing resource. * @@ -43,7 +43,7 @@ * changes of rr base costs, and some memory storage savings for * * fields that have only a few distinct values). * * rc_index: An integer index into a deduplicated table of R and C values. - * For example, two nodes that have identifical R/C values will + * For example, two nodes that have identical R/C values will * have the same rc_index. * capacity: Capacity of this node (number of routes that can use it). * * * @@ -89,7 +89,7 @@ struct alignas(16) t_rr_node_data { static_assert(sizeof(t_rr_node_data) == 16, "Check t_rr_node_data size"); static_assert(alignof(t_rr_node_data) == 16, "Check t_rr_node_data size"); -/* t_rr_node_ptc_data is cold data is therefore kept seperate from +/* t_rr_node_ptc_data is cold data is therefore kept separate from * t_rr_node_data. * * ptc_num: Pin, track or class number, depending on rr_node type. * @@ -401,7 +401,7 @@ class t_rr_graph_storage { } /** @brief Get the source node for the specified edge. */ - RRNodeId edge_src_node(const RREdgeId& edge) const { + RRNodeId edge_src_node(const RREdgeId edge) const { VTR_ASSERT_DEBUG(edge.is_valid()); return edge_src_node_[edge]; } @@ -425,12 +425,12 @@ class t_rr_graph_storage { * This method should generally not be used, and instead first_edge and * last_edge should be used. */ - RRNodeId edge_sink_node(const RRNodeId& id, t_edge_size iedge) const { + RRNodeId edge_sink_node(const RRNodeId id, t_edge_size iedge) const { return edge_sink_node(edge_id(id, iedge)); } /** @brief Get the switch used for the specified edge. */ - short edge_switch(const RREdgeId& edge) const { + short edge_switch(const RREdgeId edge) const { return edge_switch_[edge]; } @@ -439,7 +439,7 @@ class t_rr_graph_storage { * This method should generally not be used, and instead first_edge and * last_edge should be used. */ - short edge_switch(const RRNodeId& id, t_edge_size iedge) const { + short edge_switch(const RRNodeId id, t_edge_size iedge) const { return edge_switch(edge_id(id, iedge)); } @@ -448,7 +448,7 @@ class t_rr_graph_storage { * * The following methods implement an interface that appears to be * equivalent to the interface exposed by std::vector. - * This was done for backwards compability. See t_rr_node for more details. + * This was done for backwards compatibility. See t_rr_node for more details. * * Proxy methods: * @@ -483,8 +483,8 @@ class t_rr_graph_storage { ***************************/ /** @brief - * Makes room in storage for RRNodeId in amoritized O(1) fashion. - * This results in an allocation pattern similiar to what would happen + * Makes room in storage for RRNodeId in amortized O(1) fashion. + * This results in an allocation pattern similar to what would happen * if push_back(x) / emplace_back() were used if underlying storage * was not pre-allocated. */ @@ -505,7 +505,7 @@ class t_rr_graph_storage { node_layer_.reserve(size); } - /** @brief Resize node storage to accomidate size RR nodes. */ + /** @brief Resize node storage to accommodate size RR nodes. */ void resize(size_t size) { // No edges can be assigned if mutating the rr node array. VTR_ASSERT(!edges_read_); @@ -606,7 +606,7 @@ class t_rr_graph_storage { void set_node_class_num(RRNodeId id, int); //Same as set_ptc_num() by checks type() is consistent void set_node_type(RRNodeId id, t_rr_type new_type); - void set_node_name(RRNodeId id, std::string new_name); + void set_node_name(RRNodeId id, const std::string& new_name); void set_node_coordinates(RRNodeId id, short x1, short y1, short x2, short y2); void set_node_layer(RRNodeId id, short layer); void set_node_ptc_twist_incr(RRNodeId id, short twist); @@ -617,7 +617,7 @@ class t_rr_graph_storage { /** @brief * Add a side to the node abbributes - * This is the function to use when you just add a new side WITHOUT reseting side attributes + * This is the function to use when you just add a new side WITHOUT resetting side attributes */ void add_node_side(RRNodeId, e_side new_side); diff --git a/libs/librrgraph/src/base/rr_graph_view.h b/libs/librrgraph/src/base/rr_graph_view.h index d0fffc04307..4032422bfb2 100644 --- a/libs/librrgraph/src/base/rr_graph_view.h +++ b/libs/librrgraph/src/base/rr_graph_view.h @@ -27,7 +27,10 @@ * 5. A short (metal connection). * * - * @note Despite the RRGraph containing millions of edges, there are only a few switch types. Therefore, all switch details, including R and C, are stored using a flyweight pattern (rr_switch_inf) rather than being directly embedded in the edge-related data of the RRGraph. Each edge stores the ID of its associated switch for easy lookup. + * @note Despite the RRGraph containing millions of edges, there are only a few switch types. + * Therefore, all switch details, including R and C, are stored using a flyweight pattern (rr_switch_inf) + * rather than being directly embedded in the edge-related data of the RRGraph. + * Each edge stores the ID of its associated switch for easy lookup. * * * \internal @@ -82,7 +85,7 @@ class RRGraphView { void operator=(const RRGraphView&) = delete; /* -- Accessors -- */ - /* TODO: The accessors may be turned into private later if they are replacable by 'questionin' + /* TODO: The accessors may be turned into private later if they are replacable by 'questionin' * kind of accessors */ public: @@ -94,7 +97,7 @@ class RRGraphView { * @code * * // Strongly suggest using a read-only rr_graph object const RRGraph& rr_graph; - * for (const RRNodeId& node : rr_graph.nodes()) { + * for (const RRNodeId node : rr_graph.nodes()) { * // Do something with each node * } * @endcode @@ -262,7 +265,9 @@ class RRGraphView { } /** @brief Check if two routing resource nodes are adjacent (must be a CHANX and a CHANY). - * @note This function performs error checking by determining whether two nodes are physically adjacent based on their geometry. It does not verify the routing edges to confirm if a connection is feasible within the current routing graph. + * @note This function performs error checking by determining whether two nodes are physically adjacent + * based on their geometry. It does not verify the routing edges to confirm if a connection is feasible + * within the current routing graph. */ inline bool nodes_are_adjacent(RRNodeId chanx_node, RRNodeId chany_node) const { VTR_ASSERT(node_type(chanx_node) == CHANX && node_type(chany_node) == CHANY); @@ -477,7 +482,7 @@ class RRGraphView { * // Do something with the edge * } */ - inline edge_idx_range edges(const RRNodeId& id) const { + inline edge_idx_range edges(const RRNodeId id) const { return vtr::make_range(edge_idx_iterator(0), edge_idx_iterator(num_edges(id))); } @@ -489,7 +494,10 @@ class RRGraphView { /** * @brief Retrieve the `ptc_num` of a routing resource node. - * @note ptc_num (Pin, Track, or Class Number) allows for distinguishing overlapping routing elements that occupy the same (x, y) coordinate, ensuring they can be uniquely identified and managed without confusion. For instance, several routing wires or pins might overlap physically, but their ptc_num differentiates them. + * @note ptc_num (Pin, Track, or Class Number) allows for distinguishing overlapping routing elements + * that occupy the same (x, y) coordinate, ensuring they can be uniquely identified and managed + * without confusion. For instance, several routing wires or pins might overlap physically, + * but their ptc_num differentiates them. * @note The meaning of `ptc_num` varies depending on the node type (relevant to VPR RRG, may not apply to custom RRGs): * - **CHANX/CHANY**: Represents the track ID in routing channels. * - **OPIN/IPIN**: Refers to the pin index within the logic block data structure. @@ -560,7 +568,6 @@ class RRGraphView { * If you wish to create a new data structure to represent switches between routing resources, * please follow the flyweight pattern by linking your switch ids to edges only! */ - inline const t_rr_switch_inf& rr_switch_inf(RRSwitchId switch_id) const { return rr_switch_inf_[switch_id]; } diff --git a/libs/librrgraph/src/base/rr_node_types.h b/libs/librrgraph/src/base/rr_node_types.h index 3c3c3f91953..cba27f6a911 100644 --- a/libs/librrgraph/src/base/rr_node_types.h +++ b/libs/librrgraph/src/base/rr_node_types.h @@ -65,7 +65,7 @@ typedef uint16_t t_edge_size; /** * @brief An iterator that dereferences to an edge index * - * Used inconjunction with vtr::Range to return ranges of edge indices + * Used in conjunction with vtr::Range to return ranges of edge indices */ class edge_idx_iterator { public: @@ -100,7 +100,7 @@ typedef vtr::Range edge_idx_range; typedef std::vector> t_arch_switch_fanin; /* - * Reistance/Capacitance data for an RR Nodes + * Resistance/Capacitance data for an RR Nodes * * In practice many RR nodes have the same values, so they are fly-weighted * to keep t_rr_node small. Each RR node holds an rc_index which allows diff --git a/libs/libvtrutil/src/vtr_strong_id_range.h b/libs/libvtrutil/src/vtr_strong_id_range.h index 66628d9e5ed..c369b025c5a 100644 --- a/libs/libvtrutil/src/vtr_strong_id_range.h +++ b/libs/libvtrutil/src/vtr_strong_id_range.h @@ -12,7 +12,7 @@ namespace vtr { * * StrongId's are described in vtr_strong_id.h. In some cases, StrongId's be considered * like random access iterators, but not all StrongId's have this property. - * In addition, there is utility in refering to a range of id's, and being able + * In addition, there is utility in referring to a range of id's, and being able * to iterator over that range. */ @@ -83,7 +83,7 @@ class StrongIdIterator { return temp; // Return the copy } - ///@brief Decremment operator + ///@brief Decrement operator StrongIdIterator& operator--() { VTR_ASSERT_SAFE(bool(id_)); *this -= 1; @@ -152,7 +152,7 @@ inline StrongIdIterator operator-( /** * @brief StrongIdRange class * - * StrongIdRange allows a pair of StrongId's to defines a continguous range of + * StrongIdRange allows a pair of StrongId's to defines a contiguous range of * ids. The "end" StrongId is excluded from this range. */ template @@ -176,7 +176,7 @@ class StrongIdRange { ///@brief Returns true if the range is empty bool empty() { return begin_ == end_; } - ///@brief Reurns the size of the range + ///@brief Returns the size of the range size_t size() { return std::distance(begin(), end()); } From 967784846a5be96e980df59ad2b54d0415e53521 Mon Sep 17 00:00:00 2001 From: soheilshahrouz Date: Wed, 29 Jan 2025 13:43:29 -0500 Subject: [PATCH 02/23] cleaned print_switch_usage a little bit to use std::vector instead of new --- vpr/src/util/vpr_utils.cpp | 36 ++++++++++++++++-------------------- 1 file changed, 16 insertions(+), 20 deletions(-) diff --git a/vpr/src/util/vpr_utils.cpp b/vpr/src/util/vpr_utils.cpp index 37b485158c0..c59ad7af89c 100644 --- a/vpr/src/util/vpr_utils.cpp +++ b/vpr/src/util/vpr_utils.cpp @@ -1563,20 +1563,20 @@ static int convert_switch_index(int* switch_index, int* fanin) { * we have to use an extra loop to setup the information of inward switch first. */ void print_switch_usage() { - auto& device_ctx = g_vpr_ctx.device(); + const auto& device_ctx = g_vpr_ctx.device(); const auto& rr_graph = device_ctx.rr_graph; + if (device_ctx.switch_fanin_remap.empty()) { VTR_LOG_WARN("Cannot print switch usage stats: device_ctx.switch_fanin_remap is empty\n"); return; } - std::map* switch_fanin_count; - std::map* switch_fanin_delay; - switch_fanin_count = new std::map[device_ctx.all_sw_inf.size()]; - switch_fanin_delay = new std::map[device_ctx.all_sw_inf.size()]; - // a node can have multiple inward switches, so - // map key: switch index; map value: count (fanin) - std::map* inward_switch_inf = new std::map[rr_graph.num_nodes()]; - for (const RRNodeId& inode : rr_graph.nodes()) { + + std::vector> switch_fanin_count(device_ctx.all_sw_inf.size()); + std::vector> switch_fanin_delay(device_ctx.all_sw_inf.size()); + // a node can have multiple inward switches, so map key: switch index; map value: count (fanin) + std::vector> inward_switch_inf(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); @@ -1584,23 +1584,21 @@ void print_switch_usage() { // Assumption: suppose for a L4 wire (bi-directional): ----+----+----+----, it can be driven from any point (0, 1, 2, 3). // physically, the switch driving from point 1 & 3 should be the same. But we will assign then different switch // index; or there is no way to differentiate them after abstracting a 2D wire into a 1D node - if (inward_switch_inf[to_node_index].count(switch_index) == 0) + if (inward_switch_inf[to_node_index].count(switch_index) == 0) { inward_switch_inf[to_node_index][switch_index] = 0; + } //VTR_ASSERT(from_node.type != OPIN); inward_switch_inf[to_node_index][switch_index]++; } } - for (const RRNodeId& rr_id : device_ctx.rr_graph.nodes()) { - std::map::iterator itr; - for (itr = inward_switch_inf[(size_t)rr_id].begin(); itr != inward_switch_inf[(size_t)rr_id].end(); itr++) { + + for (const RRNodeId rr_id : device_ctx.rr_graph.nodes()) { + for (auto itr = inward_switch_inf[(size_t)rr_id].begin(); itr != inward_switch_inf[(size_t)rr_id].end(); itr++) { int switch_index = itr->first; int fanin = itr->second; float Tdel = rr_graph.rr_switch_inf(RRSwitchId(switch_index)).Tdel; int status = convert_switch_index(&switch_index, &fanin); if (status == -1) { - delete[] switch_fanin_count; - delete[] switch_fanin_delay; - delete[] inward_switch_inf; return; } if (switch_fanin_count[switch_index].count(fanin) == 0) { @@ -1610,9 +1608,10 @@ void print_switch_usage() { switch_fanin_delay[switch_index][fanin] = Tdel; } } + VTR_LOG("\n=============== switch usage stats ===============\n"); for (int iswitch = 0; iswitch < (int)device_ctx.all_sw_inf.size(); iswitch++) { - std::string s_name = device_ctx.all_sw_inf.at(iswitch).name; + const std::string& s_name = device_ctx.all_sw_inf.at(iswitch).name; float s_area = device_ctx.all_sw_inf.at(iswitch).mux_trans_size; VTR_LOG(">>>>> switch index: %d, name: %s, mux trans size: %g\n", iswitch, s_name.c_str(), s_area); @@ -1624,9 +1623,6 @@ void print_switch_usage() { } } VTR_LOG("\n==================================================\n\n"); - delete[] switch_fanin_count; - delete[] switch_fanin_delay; - delete[] inward_switch_inf; } int max_pins_per_grid_tile() { From 5bd113131b4518ca485ac327307598166fb8aab8 Mon Sep 17 00:00:00 2001 From: soheilshahrouz Date: Wed, 29 Jan 2025 14:22:31 -0500 Subject: [PATCH 03/23] add RRGraphView::edge_delay --- libs/librrgraph/src/base/rr_graph_view.h | 9 +++++++++ vpr/src/base/vpr_context.h | 8 +++++++- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/libs/librrgraph/src/base/rr_graph_view.h b/libs/librrgraph/src/base/rr_graph_view.h index 4032422bfb2..5f59d03a342 100644 --- a/libs/librrgraph/src/base/rr_graph_view.h +++ b/libs/librrgraph/src/base/rr_graph_view.h @@ -418,6 +418,15 @@ class RRGraphView { return node_storage_.edge_switch(id, iedge); } + inline float edge_delay(RRNodeId id, t_edge_size iedge) const { + auto switch_idx = node_storage_.edge_switch(id, iedge); + const t_rr_switch_inf& rr_switch_info = rr_switch_inf((RRSwitchId)switch_idx); + float nominal_delay = rr_switch_info.Tdel; + float delay_offset = 0.f; + //TODO: find delay offset + return nominal_delay + delay_offset; + } + /** @brief Return the source node for the specified edge. */ inline RRNodeId edge_src_node(const RREdgeId edge_id) const { diff --git a/vpr/src/base/vpr_context.h b/vpr/src/base/vpr_context.h index 0c297f93ac1..6c7c70ceef9 100644 --- a/vpr/src/base/vpr_context.h +++ b/vpr/src/base/vpr_context.h @@ -206,7 +206,13 @@ 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_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_rc_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_rc_data, + rr_graph_builder.rr_segments(), + rr_graph_builder.rr_switch()}; std::vector arch_switch_inf; // [0..(num_arch_switches-1)] std::map all_sw_inf; From af5a56e91ea6fe821f2f933b898c8040deffa151 Mon Sep 17 00:00:00 2001 From: soheilshahrouz Date: Wed, 29 Jan 2025 15:29:33 -0500 Subject: [PATCH 04/23] added t_rr_switch_offset_inf struct --- libs/libarchfpga/src/physical_types.h | 8 ++++++++ libs/librrgraph/src/base/rr_graph_builder.h | 4 +++- libs/librrgraph/src/base/rr_graph_fwd.h | 1 + libs/librrgraph/src/base/rr_graph_storage.h | 11 +++++++++++ libs/librrgraph/src/base/rr_graph_view.h | 4 +++- vpr/src/route/route_tree.cpp | 2 +- 6 files changed, 27 insertions(+), 3 deletions(-) diff --git a/libs/libarchfpga/src/physical_types.h b/libs/libarchfpga/src/physical_types.h index f1851a91214..f8ae1d6a4fd 100644 --- a/libs/libarchfpga/src/physical_types.h +++ b/libs/libarchfpga/src/physical_types.h @@ -1872,6 +1872,14 @@ struct t_rr_switch_inf { SwitchType type_ = SwitchType::INVALID; }; +struct t_rr_switch_offset_inf { + float R = 0.f; + float Cin = 0.; + float Cout = 0.; + float Cinternal = 0.; + float Tdel = 0.; +}; + /** * @struct t_direct_inf * @brief Lists all the important information about a direct chain connection. diff --git a/libs/librrgraph/src/base/rr_graph_builder.h b/libs/librrgraph/src/base/rr_graph_builder.h index cc367395bc6..faa24e2c3f1 100644 --- a/libs/librrgraph/src/base/rr_graph_builder.h +++ b/libs/librrgraph/src/base/rr_graph_builder.h @@ -124,7 +124,7 @@ class RRGraphBuilder { } /** @brief Set the node name with a given valid id */ - inline void set_node_name(RRNodeId id, std::string name) { + inline void set_node_name(RRNodeId id, const std::string& name) { node_storage_.set_node_name(id, name); } /** @@ -396,6 +396,8 @@ class RRGraphBuilder { /* Detailed information about the switches, which are used in the RRGraph */ vtr::vector rr_switch_inf_; + vtr::vector rr_switch_offset_inf_; + /** @warning The Metadata should stay as an independent data structure from the rest of the internal data, * e.g., node_lookup! */ /* Metadata is an extra data on rr-nodes and edges, respectively, that is not used by vpr diff --git a/libs/librrgraph/src/base/rr_graph_fwd.h b/libs/librrgraph/src/base/rr_graph_fwd.h index 41d0b8f3d58..fbbb4629e62 100644 --- a/libs/librrgraph/src/base/rr_graph_fwd.h +++ b/libs/librrgraph/src/base/rr_graph_fwd.h @@ -27,6 +27,7 @@ typedef vtr::StrongId RRNodeId; typedef vtr::StrongId RREdgeId; typedef vtr::StrongId RRIndexedDataId; typedef vtr::StrongId RRSwitchId; +typedef vtr::StrongId RRSwitchOffsetInfoId; typedef vtr::StrongId RRSegmentId; typedef vtr::StrongId NodeRCIndex; diff --git a/libs/librrgraph/src/base/rr_graph_storage.h b/libs/librrgraph/src/base/rr_graph_storage.h index bd80ffa13d5..bc041e1f110 100644 --- a/libs/librrgraph/src/base/rr_graph_storage.h +++ b/libs/librrgraph/src/base/rr_graph_storage.h @@ -434,6 +434,11 @@ class t_rr_graph_storage { return edge_switch_[edge]; } + /** @brief Get the switch offset info index used for the specified edge. */ + RRSwitchOffsetInfoId edge_switch_offset_inf(const RREdgeId edge) const { + return edge_switch_offset_inf_[edge]; + } + /** @brief Get the switch used for the iedge'th edge from specified RRNodeId. * * This method should generally not be used, and instead first_edge and @@ -443,6 +448,11 @@ class t_rr_graph_storage { return edge_switch(edge_id(id, iedge)); } + /** @brief Get the switch offset info id used for the iedge'th edge from specified RRNodeId. */ + RRSwitchOffsetInfoId edge_switch_offset_inf(const RRNodeId id, t_edge_size iedge) const { + return edge_switch_offset_inf(edge_id(id, iedge)); + } + /** @brief * Node proxy methods * @@ -871,6 +881,7 @@ class t_rr_graph_storage { vtr::vector edge_src_node_; vtr::vector edge_dest_node_; vtr::vector edge_switch_; + vtr::vector edge_switch_offset_inf_; /** @brief * The delay of certain switches specified in the architecture file depends on the number of inputs of the edge's sink node (pins or tracks). diff --git a/libs/librrgraph/src/base/rr_graph_view.h b/libs/librrgraph/src/base/rr_graph_view.h index 5f59d03a342..6b6c89563ad 100644 --- a/libs/librrgraph/src/base/rr_graph_view.h +++ b/libs/librrgraph/src/base/rr_graph_view.h @@ -659,8 +659,10 @@ class RRGraphView { /// Segment info for rr nodes const vtr::vector& rr_segments_; - /// switch info for rr nodes + /// switch info for rr edges const vtr::vector& rr_switch_inf_; + /// switch offset info for edges + const vtr::vector& rr_switch_offset_inf_; }; #endif diff --git a/vpr/src/route/route_tree.cpp b/vpr/src/route/route_tree.cpp index 799fa185fbd..1ac8d8c13ff 100644 --- a/vpr/src/route/route_tree.cpp +++ b/vpr/src/route/route_tree.cpp @@ -290,7 +290,7 @@ RouteTree::update_unbuffered_ancestors_C_downstream(RouteTreeNode& from_node) { /* Having set the value of C_downstream_addition, we must check whether the parent switch * is a buffered or unbuffered switch with the if statement below. If the parent switch is - * a buffered switch, then the parent node's downsteam capacitance is increased by the + * a buffered switch, then the parent node's downstream capacitance is increased by the * value of the parent switch's internal capacitance in the if statement below. * Correspondingly, the ancestors' downstream capacitance will be updated by the same * value through the while loop. Otherwise, if the parent switch is unbuffered, then From ea06ff48adb2aaf0aaa82dc310d2f225b38b0eba Mon Sep 17 00:00:00 2001 From: soheilshahrouz Date: Wed, 29 Jan 2025 15:41:31 -0500 Subject: [PATCH 05/23] finished the implementation of RRGraphView::edge_delay() --- libs/librrgraph/src/base/rr_graph_storage.cpp | 2 +- libs/librrgraph/src/base/rr_graph_storage.h | 2 +- libs/librrgraph/src/base/rr_graph_view.h | 8 ++++++-- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/libs/librrgraph/src/base/rr_graph_storage.cpp b/libs/librrgraph/src/base/rr_graph_storage.cpp index b36887c9d4d..45c3cc990c5 100644 --- a/libs/librrgraph/src/base/rr_graph_storage.cpp +++ b/libs/librrgraph/src/base/rr_graph_storage.cpp @@ -618,7 +618,7 @@ const std::string& t_rr_graph_storage::node_direction_string(RRNodeId id) const } const char* t_rr_graph_storage::node_side_string(RRNodeId id) const { - for (const e_side& side : TOTAL_2D_SIDES) { + for (const e_side side : TOTAL_2D_SIDES) { if (is_node_on_specific_side(id, side)) { return TOTAL_2D_SIDE_STRINGS[side]; } diff --git a/libs/librrgraph/src/base/rr_graph_storage.h b/libs/librrgraph/src/base/rr_graph_storage.h index bc041e1f110..6f52633ca68 100644 --- a/libs/librrgraph/src/base/rr_graph_storage.h +++ b/libs/librrgraph/src/base/rr_graph_storage.h @@ -393,7 +393,7 @@ class t_rr_graph_storage { * This method should generally not be used, and instead first_edge and * last_edge should be used. */ - RREdgeId edge_id(const RRNodeId& id, t_edge_size iedge) const { + RREdgeId edge_id(const RRNodeId id, t_edge_size iedge) const { RREdgeId first_edge = this->first_edge(id); RREdgeId ret(size_t(first_edge) + iedge); VTR_ASSERT_SAFE(ret < last_edge(id)); diff --git a/libs/librrgraph/src/base/rr_graph_view.h b/libs/librrgraph/src/base/rr_graph_view.h index 6b6c89563ad..f788bb7bf74 100644 --- a/libs/librrgraph/src/base/rr_graph_view.h +++ b/libs/librrgraph/src/base/rr_graph_view.h @@ -419,10 +419,14 @@ class RRGraphView { } inline float edge_delay(RRNodeId id, t_edge_size iedge) const { - auto switch_idx = node_storage_.edge_switch(id, iedge); + RREdgeId edge_id = node_storage_.edge_id(id, iedge); + auto switch_idx = node_storage_.edge_switch(edge_id); const t_rr_switch_inf& rr_switch_info = rr_switch_inf((RRSwitchId)switch_idx); float nominal_delay = rr_switch_info.Tdel; - float delay_offset = 0.f; + + RRSwitchOffsetInfoId switch_offset_inf_id = node_storage_.edge_switch_offset_inf(edge_id); + + float delay_offset = rr_switch_offset_inf_[switch_offset_inf_id].Tdel; //TODO: find delay offset return nominal_delay + delay_offset; } From e2321b565cfe75f7826f0708e3a0066657dd6afe Mon Sep 17 00:00:00 2001 From: soheilshahrouz Date: Wed, 29 Jan 2025 15:51:21 -0500 Subject: [PATCH 06/23] add methods to RRGraphBuilder for modifying rr_switch_offset_inf_ --- libs/libarchfpga/src/physical_types.h | 8 ++++---- libs/librrgraph/src/base/rr_graph_builder.h | 20 +++++++++++++++++++- 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/libs/libarchfpga/src/physical_types.h b/libs/libarchfpga/src/physical_types.h index f8ae1d6a4fd..72bb9efe38f 100644 --- a/libs/libarchfpga/src/physical_types.h +++ b/libs/libarchfpga/src/physical_types.h @@ -1873,10 +1873,10 @@ struct t_rr_switch_inf { }; struct t_rr_switch_offset_inf { - float R = 0.f; - float Cin = 0.; - float Cout = 0.; - float Cinternal = 0.; +// float R = 0.f; +// float Cin = 0.; +// float Cout = 0.; +// float Cinternal = 0.; float Tdel = 0.; }; diff --git a/libs/librrgraph/src/base/rr_graph_builder.h b/libs/librrgraph/src/base/rr_graph_builder.h index faa24e2c3f1..2a6a07dd439 100644 --- a/libs/librrgraph/src/base/rr_graph_builder.h +++ b/libs/librrgraph/src/base/rr_graph_builder.h @@ -118,6 +118,17 @@ class RRGraphBuilder { return rr_switch_inf_; } + inline RRSwitchOffsetInfoId add_rr_switch_offset_info(const t_rr_switch_offset_inf& switch_offset_info) { + // Allocate an ID + RRSwitchOffsetInfoId switch_offset_info_id = RRSwitchOffsetInfoId(rr_switch_offset_inf_.size()); + rr_switch_offset_inf_.push_back(switch_offset_info); + return switch_offset_info_id; + } + + inline vtr::vector& rr_switch_offset_inf() { + return rr_switch_offset_inf_; + } + /** @brief Set the type of a node with a given valid id */ inline void set_node_type(RRNodeId id, t_rr_type type) { node_storage_.set_node_type(id, type); @@ -315,6 +326,9 @@ class RRGraphBuilder { inline void reserve_switches(size_t num_switches) { this->rr_switch_inf_.reserve(num_switches); } + inline void reserve_switch_offse_info(size_t num_offsets) { + this->rr_switch_offset_inf_.resize(num_offsets); + } /** @brief This function resize node storage to accomidate size RR nodes. */ inline void resize_nodes(size_t size) { node_storage_.resize(size); @@ -330,6 +344,10 @@ class RRGraphBuilder { rr_switch_inf_.resize(size); } + inline void resize_switch_offset_info(size_t size) { + rr_switch_offset_inf_.resize(size); + } + /** @brief Validate that edge data is partitioned correctly * @note This function is used to validate the correctness of the routing resource graph in terms * of graph attributes. Strongly recommend to call it when you finish the building a routing resource @@ -357,7 +375,7 @@ class RRGraphBuilder { /** @brief Disable the flags which would prevent adding adding extra-resources, when flat-routing * is enabled, to the RR Graph * @note - * When flat-routing is enabled, intra-cluster resources are added to the RR Graph after global rosources + * When flat-routing is enabled, intra-cluster resources are added to the RR Graph after global resources * are already added. This function disables the flags which would prevent adding extra-resources to the RR Graph */ inline void reset_rr_graph_flags() { From a03bfc005b08da31cd48f97809524f7d6cb5c5c5 Mon Sep 17 00:00:00 2001 From: soheilshahrouz Date: Wed, 29 Jan 2025 15:56:14 -0500 Subject: [PATCH 07/23] add rr_switch_offset_inf argument to RRGraphView constructor --- libs/librrgraph/src/base/rr_graph_view.cpp | 6 ++++-- libs/librrgraph/src/base/rr_graph_view.h | 3 ++- vpr/src/base/vpr_context.h | 3 ++- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/libs/librrgraph/src/base/rr_graph_view.cpp b/libs/librrgraph/src/base/rr_graph_view.cpp index 0ddc5445d42..9d07fb51d0c 100644 --- a/libs/librrgraph/src/base/rr_graph_view.cpp +++ b/libs/librrgraph/src/base/rr_graph_view.cpp @@ -9,7 +9,8 @@ RRGraphView::RRGraphView(const t_rr_graph_storage& node_storage, const vtr::vector& rr_indexed_data, const std::vector& rr_rc_data, const vtr::vector& rr_segments, - const vtr::vector& rr_switch_inf) + const vtr::vector& rr_switch_inf, + const vtr::vector& rr_switch_offset_inf) : node_storage_(node_storage) , node_lookup_(node_lookup) , rr_node_metadata_(rr_node_metadata) @@ -17,5 +18,6 @@ RRGraphView::RRGraphView(const t_rr_graph_storage& node_storage, , rr_indexed_data_(rr_indexed_data) , rr_rc_data_(rr_rc_data) , rr_segments_(rr_segments) - , rr_switch_inf_(rr_switch_inf) { + , rr_switch_inf_(rr_switch_inf) + , rr_switch_offset_inf_(rr_switch_offset_inf) { } diff --git a/libs/librrgraph/src/base/rr_graph_view.h b/libs/librrgraph/src/base/rr_graph_view.h index f788bb7bf74..c078304f56e 100644 --- a/libs/librrgraph/src/base/rr_graph_view.h +++ b/libs/librrgraph/src/base/rr_graph_view.h @@ -73,7 +73,8 @@ class RRGraphView { const vtr::vector& rr_indexed_data, const std::vector& rr_rc_data, const vtr::vector& rr_segments, - const vtr::vector& rr_switch_inf); + const vtr::vector& rr_switch_inf, + const vtr::vector& rr_switch_offset_inf); /* Disable copy constructors and copy assignment operator * This is to avoid accidental copy because it could be an expensive operation considering that the diff --git a/vpr/src/base/vpr_context.h b/vpr/src/base/vpr_context.h index 6c7c70ceef9..a8e5207e47b 100644 --- a/vpr/src/base/vpr_context.h +++ b/vpr/src/base/vpr_context.h @@ -212,7 +212,8 @@ struct DeviceContext : public Context { rr_graph_builder.rr_edge_metadata(), rr_indexed_data, rr_rc_data, rr_graph_builder.rr_segments(), - rr_graph_builder.rr_switch()}; + rr_graph_builder.rr_switch(), + rr_graph_builder.rr_switch_offset_inf()}; std::vector arch_switch_inf; // [0..(num_arch_switches-1)] std::map all_sw_inf; From d4973a84b199d0a27e06c5dd74164bb685e8ef39 Mon Sep 17 00:00:00 2001 From: soheilshahrouz Date: Thu, 30 Jan 2025 10:38:25 -0500 Subject: [PATCH 08/23] partially implemented load_rr_edge_attribute_offset_file() --- libs/libarchfpga/src/physical_types.h | 4 ++ libs/librrgraph/src/base/rr_graph_storage.cpp | 3 ++ libs/librrgraph/src/base/rr_graph_storage.h | 2 +- libs/librrgraph/src/io/rr_graph_reader.cpp | 48 +++++++++++++++++++ libs/librrgraph/src/io/rr_graph_reader.h | 4 ++ vpr/src/base/vpr_types.h | 1 + vpr/src/route/rr_graph.cpp | 18 ------- 7 files changed, 61 insertions(+), 19 deletions(-) diff --git a/libs/libarchfpga/src/physical_types.h b/libs/libarchfpga/src/physical_types.h index 72bb9efe38f..24e41f24349 100644 --- a/libs/libarchfpga/src/physical_types.h +++ b/libs/libarchfpga/src/physical_types.h @@ -1878,6 +1878,10 @@ struct t_rr_switch_offset_inf { // float Cout = 0.; // float Cinternal = 0.; float Tdel = 0.; + + bool operator<(const t_rr_switch_offset_inf& other) const { + return std::tie(Tdel) < std::tie(other.Tdel); + } }; /** diff --git a/libs/librrgraph/src/base/rr_graph_storage.cpp b/libs/librrgraph/src/base/rr_graph_storage.cpp index 45c3cc990c5..5ddf63cc8f1 100644 --- a/libs/librrgraph/src/base/rr_graph_storage.cpp +++ b/libs/librrgraph/src/base/rr_graph_storage.cpp @@ -10,6 +10,7 @@ void t_rr_graph_storage::reserve_edges(size_t num_edges) { edge_src_node_.reserve(num_edges); edge_dest_node_.reserve(num_edges); edge_switch_.reserve(num_edges); + edge_switch_offset_inf_.reserve(num_edges); edge_remapped_.reserve(num_edges); } @@ -19,6 +20,7 @@ void t_rr_graph_storage::emplace_back_edge(RRNodeId src, RRNodeId dest, short ed edge_src_node_.emplace_back(src); edge_dest_node_.emplace_back(dest); edge_switch_.emplace_back(edge_switch); + edge_switch_offset_inf_.emplace_back(); edge_remapped_.emplace_back(remapped); } @@ -123,6 +125,7 @@ struct edge_swapper { std::swap(a.storage_->edge_src_node_[a_edge], a.storage_->edge_src_node_[b_edge]); std::swap(a.storage_->edge_dest_node_[a_edge], a.storage_->edge_dest_node_[b_edge]); std::swap(a.storage_->edge_switch_[a_edge], a.storage_->edge_switch_[b_edge]); + std::swap(a.storage_->edge_switch_offset_inf_[a_edge], a.storage_->edge_switch_offset_inf_[b_edge]); std::vector::swap(a.storage_->edge_remapped_[a_edge], a.storage_->edge_remapped_[b_edge]); } diff --git a/libs/librrgraph/src/base/rr_graph_storage.h b/libs/librrgraph/src/base/rr_graph_storage.h index 6f52633ca68..b8bd046a14c 100644 --- a/libs/librrgraph/src/base/rr_graph_storage.h +++ b/libs/librrgraph/src/base/rr_graph_storage.h @@ -353,7 +353,7 @@ class t_rr_graph_storage { return vtr::make_range(edge_idx_iterator(num_edges(id) - num_non_configurable_edges(id, rr_switches)), edge_idx_iterator(num_edges(id))); } - t_edge_size num_edges(const RRNodeId& id) const { + t_edge_size num_edges(const RRNodeId id) const { return size_t(last_edge(id)) - size_t(first_edge(id)); } bool edge_is_configurable(RRNodeId id, t_edge_size iedge, const vtr::vector& rr_switches) const; diff --git a/libs/librrgraph/src/io/rr_graph_reader.cpp b/libs/librrgraph/src/io/rr_graph_reader.cpp index ec574080dba..f540742a7ac 100644 --- a/libs/librrgraph/src/io/rr_graph_reader.cpp +++ b/libs/librrgraph/src/io/rr_graph_reader.cpp @@ -115,3 +115,51 @@ void load_rr_file(RRGraphBuilder* rr_graph_builder, read_rr_graph_name); } } + +void load_rr_edge_attribute_offset_file(RRGraphBuilder& rr_graph_builder, + RRGraphView& rr_graph, + std::string_view rr_edge_attribute_offset_filename) { + std::ifstream file(rr_edge_attribute_offset_filename.data()); + + if (!file) { + VTR_LOG_ERROR("Failed to open RR edge offset file: %s ", rr_edge_attribute_offset_filename.data()); + } + + std::map unique_edge_offsets; + std::string line; + bool first_line = true; + while (std::getline(file, line)) { + // Ignore first line if it starts with # + if (first_line && !line.empty() && line[0] == '#') { + first_line = false; + continue; + } + first_line = false; + + std::istringstream iss(line); + int edge_id; + t_rr_switch_offset_inf rr_switch_offset_inf; + + if (!(iss >> edge_id >> rr_switch_offset_inf.Tdel)) { + throw std::runtime_error("Invalid line format: " + line); + } + + if (edge_id < 0) { + throw std::runtime_error("Negative integer found: " + std::to_string(edge_id)); + } + + auto it = unique_edge_offsets.find(rr_switch_offset_inf); + + RRSwitchOffsetInfoId rr_switch_offset_id; + if (it == unique_edge_offsets.end()) { + rr_switch_offset_id = rr_graph_builder.add_rr_switch_offset_info(rr_switch_offset_inf); + } else { // rr_switch_offset_inf is already added to the RRGraphBuilder object + rr_switch_offset_id = it->second; + } + // TODO: update edge information to point to this info + } +} + + + +} diff --git a/libs/librrgraph/src/io/rr_graph_reader.h b/libs/librrgraph/src/io/rr_graph_reader.h index 8549b712bdf..fa2e97fa04e 100644 --- a/libs/librrgraph/src/io/rr_graph_reader.h +++ b/libs/librrgraph/src/io/rr_graph_reader.h @@ -35,4 +35,8 @@ void load_rr_file(RRGraphBuilder* rr_graph_builder, const char* echo_file_name, bool is_flat); +void load_rr_edge_attribute_offset_file(RRGraphBuilder& rr_graph_builder, + RRGraphView& rr_graph, + std::string_view rr_edge_attribute_offset_filename); + #endif /* RR_GRAPH_READER_H */ diff --git a/vpr/src/base/vpr_types.h b/vpr/src/base/vpr_types.h index abea66f8d6b..5ffeb0e2f63 100644 --- a/vpr/src/base/vpr_types.h +++ b/vpr/src/base/vpr_types.h @@ -1416,6 +1416,7 @@ struct t_det_routing_arch { float R_minW_pmos; std::string read_rr_graph_filename; + std::string read_rr_edge_attribute_offset_filename; std::string write_rr_graph_filename; }; diff --git a/vpr/src/route/rr_graph.cpp b/vpr/src/route/rr_graph.cpp index 0b2073555de..f9a5ae5838b 100644 --- a/vpr/src/route/rr_graph.cpp +++ b/vpr/src/route/rr_graph.cpp @@ -44,18 +44,6 @@ //#define VERBOSE //used for getting the exact count of each edge type and printing it to std out. -struct t_mux { - int size; - t_mux* next; -}; - -struct t_mux_size_distribution { - int mux_count; - int max_index; - int* distr; - t_mux_size_distribution* next; -}; - struct t_clb_to_clb_directs { t_physical_tile_type_ptr from_clb_type; int from_clb_pin_start_index; @@ -74,12 +62,6 @@ struct t_pin_loc { e_side side; }; -struct t_pin_spec { - t_rr_type pin_type; - int pin_ptc; - RRNodeId pin_rr_node_id; -}; - /******************* Variables local to this module. ***********************/ /********************* Subroutines local to this module. *******************/ From 8de3b3c132c5ef1184e6a9bb3dae73c953983b0b Mon Sep 17 00:00:00 2001 From: soheilshahrouz Date: Thu, 30 Jan 2025 11:26:13 -0500 Subject: [PATCH 09/23] add RRGraphBuilder::set_edge_offset_id() method and call it in load_rr_edge_attribute_offset_file() --- libs/librrgraph/src/base/rr_graph_builder.h | 4 ++++ libs/librrgraph/src/base/rr_graph_storage.cpp | 18 +++++++++++++++--- libs/librrgraph/src/base/rr_graph_storage.h | 15 ++++++++------- libs/librrgraph/src/io/rr_graph_reader.cpp | 7 ++----- libs/librrgraph/src/io/rr_graph_reader.h | 1 - vpr/src/route/rr_graph.cpp | 10 +++++----- 6 files changed, 34 insertions(+), 21 deletions(-) diff --git a/libs/librrgraph/src/base/rr_graph_builder.h b/libs/librrgraph/src/base/rr_graph_builder.h index 2a6a07dd439..2782a349474 100644 --- a/libs/librrgraph/src/base/rr_graph_builder.h +++ b/libs/librrgraph/src/base/rr_graph_builder.h @@ -125,6 +125,10 @@ class RRGraphBuilder { return switch_offset_info_id; } + inline void set_edge_offset_id(RREdgeId edge_id, RRSwitchOffsetInfoId offset_id) { + node_storage_.set_edge_offset_id(edge_id, offset_id); + } + inline vtr::vector& rr_switch_offset_inf() { return rr_switch_offset_inf_; } diff --git a/libs/librrgraph/src/base/rr_graph_storage.cpp b/libs/librrgraph/src/base/rr_graph_storage.cpp index 5ddf63cc8f1..7cd4ebc0080 100644 --- a/libs/librrgraph/src/base/rr_graph_storage.cpp +++ b/libs/librrgraph/src/base/rr_graph_storage.cpp @@ -20,7 +20,7 @@ void t_rr_graph_storage::emplace_back_edge(RRNodeId src, RRNodeId dest, short ed edge_src_node_.emplace_back(src); edge_dest_node_.emplace_back(dest); edge_switch_.emplace_back(edge_switch); - edge_switch_offset_inf_.emplace_back(); + edge_switch_offset_inf_.emplace_back(RRSwitchOffsetInfoId::INVALID()); edge_remapped_.emplace_back(remapped); } @@ -45,10 +45,11 @@ void t_rr_graph_storage::alloc_and_load_edges(const t_rr_edge_info_set* rr_edges edge_src_node_.reserve(new_capacity); edge_dest_node_.reserve(new_capacity); edge_switch_.reserve(new_capacity); + edge_switch_offset_inf_.reserve(new_capacity); edge_remapped_.reserve(new_capacity); } - for (const auto& new_edge : *rr_edges_to_create) { + for (const t_rr_edge_info& new_edge : *rr_edges_to_create) { emplace_back_edge( new_edge.from_node, new_edge.to_node, @@ -66,7 +67,7 @@ void t_rr_graph_storage::alloc_and_load_edges(const t_rr_edge_info_set* rr_edges * edge_swapper is a reference for the src/dest/switch tuple, and can convert * to and from t_rr_edge_info, the value_type for edge_sort_iterator. * - * edge_compare_src_node_and_configurable_first is a comparision operator + * edge_compare_src_node_and_configurable_first is a comparison operator * that first partitions the edge data by source rr node, and then by * configurable switches first. Sorting by this comparision operator means that * the edge data is directly usable for each node by simply slicing the arrays. @@ -89,6 +90,7 @@ struct edge_swapper { storage_->edge_src_node_[edge] = storage_->edge_src_node_[other_edge]; storage_->edge_dest_node_[edge] = storage_->edge_dest_node_[other_edge]; storage_->edge_switch_[edge] = storage_->edge_switch_[other_edge]; + storage_->edge_switch_offset_inf_[edge] = storage_->edge_switch_offset_inf_[other_edge]; storage_->edge_remapped_[edge] = storage_->edge_remapped_[other_edge]; return *this; } @@ -99,6 +101,7 @@ struct edge_swapper { storage_->edge_src_node_[RREdgeId(idx_)] = RRNodeId(edge.from_node); storage_->edge_dest_node_[RREdgeId(idx_)] = RRNodeId(edge.to_node); storage_->edge_switch_[RREdgeId(idx_)] = edge.switch_type; + storage_->edge_switch_offset_inf_[RREdgeId(idx_)] = RRSwitchOffsetInfoId::INVALID(); storage_->edge_remapped_[RREdgeId(idx_)] = edge.remapped; return *this; } @@ -357,6 +360,7 @@ void t_rr_graph_storage::assign_first_edges() { size_t num_edges = edge_src_node_.size(); VTR_ASSERT(edge_dest_node_.size() == num_edges); VTR_ASSERT(edge_switch_.size() == num_edges); + VTR_ASSERT(edge_switch_offset_inf_.size() == num_edges); VTR_ASSERT(edge_remapped_.size() == num_edges); while (true) { VTR_ASSERT(first_id < num_edges); @@ -551,6 +555,14 @@ void t_rr_graph_storage::partition_edges(const vtr::vector& rr_switches) const { VTR_ASSERT(!node_first_edge_.empty() && remapped_edges_); diff --git a/libs/librrgraph/src/base/rr_graph_storage.h b/libs/librrgraph/src/base/rr_graph_storage.h index b8bd046a14c..fea8d803db9 100644 --- a/libs/librrgraph/src/base/rr_graph_storage.h +++ b/libs/librrgraph/src/base/rr_graph_storage.h @@ -647,16 +647,16 @@ class t_rr_graph_storage { // initialize edges. All edges must be added prior to calling any // methods that read edge data. // - // Note: Either arch_switch_inf indicies or rr_switch_inf should be + // Note: Either arch_switch_inf indices or rr_switch_inf should be // used with emplace_back_edge and alloc_and_load_edges. Do not mix - // indicies, otherwise things will be break. + // indices, otherwise things will be break. // // The rr_switch_inf switches are remapped versions of the // arch_switch_inf switch indices that are used when we have // different delays and hence different indices based on the fanout // of a switch. Because fanout of the switch can only be computed // after the graph is built, the graph is initially built using - // arch_switch_inf indicies, and then remapped once fanout is + // arch_switch_inf indices, and then remapped once fanout is // determined. // // 2. The following methods read from the edge data, and lock out the @@ -667,7 +667,7 @@ class t_rr_graph_storage { // - remap_rr_node_switch_indices // - mark_edges_as_rr_switch_ids // - // 3. If edge_switch values are arch_switch_inf indicies, + // 3. If edge_switch values are arch_switch_inf indices, // remap_rr_node_switch_indices must be called prior to calling // partition_edges. // @@ -717,9 +717,8 @@ class t_rr_graph_storage { * * init_fan_in does not need to be invoked before this method. */ - size_t count_rr_switches( - const std::vector& arch_switch_inf, - t_arch_switch_fanin& arch_switch_fanins); + size_t count_rr_switches(const std::vector& arch_switch_inf, + t_arch_switch_fanin& arch_switch_fanins); /** @brief Maps arch_switch_inf indicies to rr_switch_inf indicies. * @@ -741,6 +740,8 @@ class t_rr_graph_storage { */ void partition_edges(const vtr::vector& rr_switches); + void set_edge_offset_id(RREdgeId edge_id, RRSwitchOffsetInfoId offset_id); + /** @brief Validate that edge data is partitioned correctly.*/ bool validate_node(RRNodeId node_id, const vtr::vector& rr_switches) const; bool validate(const vtr::vector& rr_switches) const; diff --git a/libs/librrgraph/src/io/rr_graph_reader.cpp b/libs/librrgraph/src/io/rr_graph_reader.cpp index f540742a7ac..f0fbcbbc7d6 100644 --- a/libs/librrgraph/src/io/rr_graph_reader.cpp +++ b/libs/librrgraph/src/io/rr_graph_reader.cpp @@ -117,7 +117,6 @@ void load_rr_file(RRGraphBuilder* rr_graph_builder, } void load_rr_edge_attribute_offset_file(RRGraphBuilder& rr_graph_builder, - RRGraphView& rr_graph, std::string_view rr_edge_attribute_offset_filename) { std::ifstream file(rr_edge_attribute_offset_filename.data()); @@ -156,10 +155,8 @@ void load_rr_edge_attribute_offset_file(RRGraphBuilder& rr_graph_builder, } else { // rr_switch_offset_inf is already added to the RRGraphBuilder object rr_switch_offset_id = it->second; } - // TODO: update edge information to point to this info + + rr_graph_builder.set_edge_offset_id((RREdgeId)edge_id, rr_switch_offset_id); } } - - -} diff --git a/libs/librrgraph/src/io/rr_graph_reader.h b/libs/librrgraph/src/io/rr_graph_reader.h index fa2e97fa04e..266fb67875e 100644 --- a/libs/librrgraph/src/io/rr_graph_reader.h +++ b/libs/librrgraph/src/io/rr_graph_reader.h @@ -36,7 +36,6 @@ void load_rr_file(RRGraphBuilder* rr_graph_builder, bool is_flat); void load_rr_edge_attribute_offset_file(RRGraphBuilder& rr_graph_builder, - RRGraphView& rr_graph, std::string_view rr_edge_attribute_offset_filename); #endif /* RR_GRAPH_READER_H */ diff --git a/vpr/src/route/rr_graph.cpp b/vpr/src/route/rr_graph.cpp index f9a5ae5838b..df239c55c2d 100644 --- a/vpr/src/route/rr_graph.cpp +++ b/vpr/src/route/rr_graph.cpp @@ -99,7 +99,7 @@ bool channel_widths_unchanged(const t_chan_width& current, const t_chan_width& p static vtr::NdMatrix, 5> alloc_and_load_pin_to_track_map(const e_pin_type pin_type, const vtr::Matrix& Fc, const t_physical_tile_type_ptr tile_type, - const std::set type_layer, + const std::set& type_layer, const std::vector& perturb_switch_pattern, const e_directionality directionality, const std::vector& seg_inf, @@ -2157,7 +2157,7 @@ static std::function alloc_and_load_rr_graph(RRGraphBuilder /* If Fc gets clipped, this will be flagged to true */ *Fc_clipped = false; - /* This function is called to build the general routing graph resoruces. Thus, + /* This function is called to build the general routing graph resources. Thus, the edges are not remapped yet.*/ bool switches_remapped = false; @@ -3418,12 +3418,12 @@ void alloc_and_load_edges(RRGraphBuilder& rr_graph_builder, const t_rr_edge_info static vtr::NdMatrix, 5> alloc_and_load_pin_to_track_map(const e_pin_type pin_type, const vtr::Matrix& Fc, const t_physical_tile_type_ptr tile_type, - const std::set type_layer, + const std::set& type_layer, const std::vector& perturb_switch_pattern, const e_directionality directionality, const std::vector& seg_inf, const int* sets_per_seg_type) { - /* allocate 'result' matrix and initialize entries to OPEN. also allocate and intialize matrix which will be + /* allocate 'result' matrix and initialize entries to OPEN. also allocate and initialize matrix which will be * used to index into the correct entries when loading up 'result' */ auto& grid = g_vpr_ctx.device().grid; auto result = vtr::NdMatrix, 5>({ @@ -3541,7 +3541,7 @@ static vtr::NdMatrix alloc_and_load_pin_to_seg_type(const e_pin_type pin 0); //List of *physical* pins of the correct type on each side of the current - //block type. For a specific width/height/side the valid enteries in the + //block type. For a specific width/height/side the valid entries in the //last dimension are [0 .. num_dir[width][height][side]-1] // //Max possible space alloced for simplicity From e0f34837804a0ba4401dc1cffca3fbd812f8f13c Mon Sep 17 00:00:00 2001 From: soheilshahrouz Date: Thu, 30 Jan 2025 14:55:08 -0500 Subject: [PATCH 10/23] store actual unique delays instead of offsets --- libs/libarchfpga/src/physical_types.h | 4 +-- libs/librrgraph/src/base/rr_graph_fwd.h | 2 +- libs/librrgraph/src/base/rr_graph_utils.cpp | 2 +- libs/librrgraph/src/base/rr_graph_view.h | 9 +------ libs/librrgraph/src/io/rr_graph_reader.cpp | 19 +++++++++---- libs/librrgraph/src/io/rr_graph_reader.h | 1 + .../utils/alloc_and_load_rr_indexed_data.cpp | 27 ++++++++++++++----- 7 files changed, 40 insertions(+), 24 deletions(-) diff --git a/libs/libarchfpga/src/physical_types.h b/libs/libarchfpga/src/physical_types.h index 24e41f24349..c7ac66041f5 100644 --- a/libs/libarchfpga/src/physical_types.h +++ b/libs/libarchfpga/src/physical_types.h @@ -1879,9 +1879,7 @@ struct t_rr_switch_offset_inf { // float Cinternal = 0.; float Tdel = 0.; - bool operator<(const t_rr_switch_offset_inf& other) const { - return std::tie(Tdel) < std::tie(other.Tdel); - } + auto operator<=>(const t_rr_switch_offset_inf&) const = default; }; /** diff --git a/libs/librrgraph/src/base/rr_graph_fwd.h b/libs/librrgraph/src/base/rr_graph_fwd.h index fbbb4629e62..b9b905990d5 100644 --- a/libs/librrgraph/src/base/rr_graph_fwd.h +++ b/libs/librrgraph/src/base/rr_graph_fwd.h @@ -27,7 +27,7 @@ typedef vtr::StrongId RRNodeId; typedef vtr::StrongId RREdgeId; typedef vtr::StrongId RRIndexedDataId; typedef vtr::StrongId RRSwitchId; -typedef vtr::StrongId RRSwitchOffsetInfoId; +typedef vtr::StrongId RRSwitchOffsetInfoId; typedef vtr::StrongId RRSegmentId; typedef vtr::StrongId NodeRCIndex; diff --git a/libs/librrgraph/src/base/rr_graph_utils.cpp b/libs/librrgraph/src/base/rr_graph_utils.cpp index 1769d1cae5f..649aa3616e6 100644 --- a/libs/librrgraph/src/base/rr_graph_utils.cpp +++ b/libs/librrgraph/src/base/rr_graph_utils.cpp @@ -137,7 +137,7 @@ vtr::vector> get_fan_in_list(const RRGraphView& 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 + //Walk the graph and increment fanin on all downstream nodes rr_graph.rr_nodes().for_each_edge( [&](RREdgeId edge, RRNodeId src, RRNodeId sink) -> void { (void) src; diff --git a/libs/librrgraph/src/base/rr_graph_view.h b/libs/librrgraph/src/base/rr_graph_view.h index c078304f56e..19f3424d176 100644 --- a/libs/librrgraph/src/base/rr_graph_view.h +++ b/libs/librrgraph/src/base/rr_graph_view.h @@ -421,15 +421,8 @@ class RRGraphView { inline float edge_delay(RRNodeId id, t_edge_size iedge) const { RREdgeId edge_id = node_storage_.edge_id(id, iedge); - auto switch_idx = node_storage_.edge_switch(edge_id); - const t_rr_switch_inf& rr_switch_info = rr_switch_inf((RRSwitchId)switch_idx); - float nominal_delay = rr_switch_info.Tdel; - RRSwitchOffsetInfoId switch_offset_inf_id = node_storage_.edge_switch_offset_inf(edge_id); - - float delay_offset = rr_switch_offset_inf_[switch_offset_inf_id].Tdel; - //TODO: find delay offset - return nominal_delay + delay_offset; + return rr_switch_offset_inf_[switch_offset_inf_id].Tdel;; } /** @brief Return the source node for the specified edge. diff --git a/libs/librrgraph/src/io/rr_graph_reader.cpp b/libs/librrgraph/src/io/rr_graph_reader.cpp index f0fbcbbc7d6..c6c8539b4af 100644 --- a/libs/librrgraph/src/io/rr_graph_reader.cpp +++ b/libs/librrgraph/src/io/rr_graph_reader.cpp @@ -117,6 +117,7 @@ void load_rr_file(RRGraphBuilder* rr_graph_builder, } void load_rr_edge_attribute_offset_file(RRGraphBuilder& rr_graph_builder, + RRGraphView& rr_graph, std::string_view rr_edge_attribute_offset_filename) { std::ifstream file(rr_edge_attribute_offset_filename.data()); @@ -137,9 +138,9 @@ void load_rr_edge_attribute_offset_file(RRGraphBuilder& rr_graph_builder, std::istringstream iss(line); int edge_id; - t_rr_switch_offset_inf rr_switch_offset_inf; + t_rr_switch_offset_inf rr_switch_detailed_inf; - if (!(iss >> edge_id >> rr_switch_offset_inf.Tdel)) { + if (!(iss >> edge_id >> rr_switch_detailed_inf.Tdel)) { throw std::runtime_error("Invalid line format: " + line); } @@ -147,12 +148,20 @@ void load_rr_edge_attribute_offset_file(RRGraphBuilder& rr_graph_builder, throw std::runtime_error("Negative integer found: " + std::to_string(edge_id)); } - auto it = unique_edge_offsets.find(rr_switch_offset_inf); + auto switch_idx = rr_graph.rr_nodes().edge_switch((RREdgeId)edge_id); + const t_rr_switch_inf& switch_inf = rr_graph.rr_switch_inf((RRSwitchId)switch_idx); + + rr_switch_detailed_inf.Tdel += switch_inf.Tdel; + + // check if the detailed info has already been added + auto it = unique_edge_offsets.find(rr_switch_detailed_inf); RRSwitchOffsetInfoId rr_switch_offset_id; if (it == unique_edge_offsets.end()) { - rr_switch_offset_id = rr_graph_builder.add_rr_switch_offset_info(rr_switch_offset_inf); - } else { // rr_switch_offset_inf is already added to the RRGraphBuilder object + // if the detailed info is seen for the first time, add it to RR graph + rr_switch_offset_id = rr_graph_builder.add_rr_switch_offset_info(rr_switch_detailed_inf); + } else { + // the detailed info has already been added to the RR graph rr_switch_offset_id = it->second; } diff --git a/libs/librrgraph/src/io/rr_graph_reader.h b/libs/librrgraph/src/io/rr_graph_reader.h index 266fb67875e..fa2e97fa04e 100644 --- a/libs/librrgraph/src/io/rr_graph_reader.h +++ b/libs/librrgraph/src/io/rr_graph_reader.h @@ -36,6 +36,7 @@ void load_rr_file(RRGraphBuilder* rr_graph_builder, bool is_flat); void load_rr_edge_attribute_offset_file(RRGraphBuilder& rr_graph_builder, + RRGraphView& rr_graph, std::string_view rr_edge_attribute_offset_filename); #endif /* RR_GRAPH_READER_H */ diff --git a/libs/librrgraph/src/utils/alloc_and_load_rr_indexed_data.cpp b/libs/librrgraph/src/utils/alloc_and_load_rr_indexed_data.cpp index 1cfdba42f92..bb88449ebcb 100644 --- a/libs/librrgraph/src/utils/alloc_and_load_rr_indexed_data.cpp +++ b/libs/librrgraph/src/utils/alloc_and_load_rr_indexed_data.cpp @@ -29,7 +29,15 @@ static float get_delay_normalization_fac(const vtr::vector& rr_indexed_data); -static void calculate_average_switch(const RRGraphView& rr_graph, int inode, double& avg_switch_R, double& avg_switch_T, double& avg_switch_Cinternal, int& num_switches, int& num_shorts, short& buffered, vtr::vector>& fan_in_list); +static void calculate_average_switch(const RRGraphView& rr_graph, + RRNodeId inode, + const vtr::vector>& fan_in_list, + double& avg_switch_R, + double& avg_switch_T, + double& avg_switch_Cinternal, + int& num_switches, + int& num_shorts, + short& buffered); static void fixup_rr_indexed_data_T_values(vtr::vector& rr_indexed_data, size_t num_segment); @@ -543,7 +551,7 @@ static void load_rr_indexed_data_T_values(const RRGraphView& rr_graph, int num_switches = 0; int num_shorts = 0; short buffered = UNDEFINED; - calculate_average_switch(rr_graph, (size_t)rr_id, avg_switch_R, avg_switch_T, avg_switch_Cinternal, num_switches, num_shorts, buffered, fan_in_list); + calculate_average_switch(rr_graph, rr_id, fan_in_list, avg_switch_R, avg_switch_T, avg_switch_Cinternal, num_switches, num_shorts, buffered); if (num_switches == 0) { if (num_shorts == 0) { @@ -636,8 +644,15 @@ static void load_rr_indexed_data_T_values(const RRGraphView& rr_graph, * It is not safe to assume that each node of the same wire type has the same switches with the same * delays, therefore we take their average to take into account the possible differences */ -static void calculate_average_switch(const RRGraphView& rr_graph, int inode, double& avg_switch_R, double& avg_switch_T, double& avg_switch_Cinternal, int& num_switches, int& num_shorts, short& buffered, vtr::vector>& fan_in_list) { - auto node = RRNodeId(inode); +static void calculate_average_switch(const RRGraphView& rr_graph, + RRNodeId inode, + const vtr::vector>& fan_in_list, + double& avg_switch_R, + double& avg_switch_T, + double& avg_switch_Cinternal, + int& num_switches, + int& num_shorts, + short& buffered) { avg_switch_R = 0; avg_switch_T = 0; @@ -645,9 +660,9 @@ static void calculate_average_switch(const RRGraphView& rr_graph, int inode, dou num_switches = 0; num_shorts = 0; buffered = UNDEFINED; - for (const auto& edge : fan_in_list[node]) { + for (const RREdgeId edge : fan_in_list[inode]) { /* 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) { + if (rr_graph.node_type(inode) == CHANX || rr_graph.node_type(inode) == CHANY) { int switch_index = rr_graph.rr_nodes().edge_switch(edge); if (rr_graph.rr_switch_inf(RRSwitchId(switch_index)).type() == SwitchType::SHORT) { From c6d6a40ab68bf2d8cfedfd0bae37ca648834d4fb Mon Sep 17 00:00:00 2001 From: soheilshahrouz Date: Sat, 1 Feb 2025 17:45:39 -0500 Subject: [PATCH 11/23] update edge_switch_offset_inf_ in the edge is already mapped --- libs/librrgraph/src/base/rr_graph_builder.cpp | 2 +- libs/librrgraph/src/base/rr_graph_storage.cpp | 6 +++--- vpr/src/route/rr_graph.cpp | 3 --- 3 files changed, 4 insertions(+), 7 deletions(-) diff --git a/libs/librrgraph/src/base/rr_graph_builder.cpp b/libs/librrgraph/src/base/rr_graph_builder.cpp index 565c99e3f75..a02f8b0a46b 100644 --- a/libs/librrgraph/src/base/rr_graph_builder.cpp +++ b/libs/librrgraph/src/base/rr_graph_builder.cpp @@ -93,7 +93,7 @@ void RRGraphBuilder::reorder_nodes(e_rr_node_reorder_algorithm reorder_rr_graph_ n = RRNodeId(cur_idx++); } - // This method works well. The intution is that highly connected nodes are enumerated first (together), + // This method works well. The intuition is that highly connected nodes are enumerated first (together), // and since there will be a lot of nodes with the same degree, they are then ordered based on some // distance from the starting node. if (reorder_rr_graph_nodes_algorithm == DEGREE_BFS) { diff --git a/libs/librrgraph/src/base/rr_graph_storage.cpp b/libs/librrgraph/src/base/rr_graph_storage.cpp index 7cd4ebc0080..3bc0355a338 100644 --- a/libs/librrgraph/src/base/rr_graph_storage.cpp +++ b/libs/librrgraph/src/base/rr_graph_storage.cpp @@ -20,7 +20,7 @@ void t_rr_graph_storage::emplace_back_edge(RRNodeId src, RRNodeId dest, short ed edge_src_node_.emplace_back(src); edge_dest_node_.emplace_back(dest); edge_switch_.emplace_back(edge_switch); - edge_switch_offset_inf_.emplace_back(RRSwitchOffsetInfoId::INVALID()); + edge_switch_offset_inf_.emplace_back(remapped ? (RRSwitchOffsetInfoId)edge_switch : RRSwitchOffsetInfoId::INVALID()); edge_remapped_.emplace_back(remapped); } @@ -101,7 +101,7 @@ struct edge_swapper { storage_->edge_src_node_[RREdgeId(idx_)] = RRNodeId(edge.from_node); storage_->edge_dest_node_[RREdgeId(idx_)] = RRNodeId(edge.to_node); storage_->edge_switch_[RREdgeId(idx_)] = edge.switch_type; - storage_->edge_switch_offset_inf_[RREdgeId(idx_)] = RRSwitchOffsetInfoId::INVALID(); + storage_->edge_switch_offset_inf_[RREdgeId(idx_)] = edge.remapped ? (RRSwitchOffsetInfoId)edge.switch_type : RRSwitchOffsetInfoId::INVALID(); storage_->edge_remapped_[RREdgeId(idx_)] = edge.remapped; return *this; } @@ -167,7 +167,7 @@ class edge_sort_iterator { // it needs to "act" like a pointer. One thing that it should do is that a // const variable of this type should be de-referenceable. Therefore, this // method should be const method; however, this requires modifying the class - // and may yield worst performance. For now the std::stable_sort allows this + // and may yield worse performance. For now the std::stable_sort allows this // but in the future it may not. If this breaks, this is why. // See issue #2517 and PR #2522 edge_swapper& operator*() { diff --git a/vpr/src/route/rr_graph.cpp b/vpr/src/route/rr_graph.cpp index df239c55c2d..9948ff6c721 100644 --- a/vpr/src/route/rr_graph.cpp +++ b/vpr/src/route/rr_graph.cpp @@ -1,7 +1,5 @@ #include -#include #include -#include #include #include #include @@ -21,7 +19,6 @@ #include "rr_graph_utils.h" #include "rr_graph.h" #include "rr_graph_area.h" -#include "rr_graph_utils.h" #include "rr_graph2.h" #include "rr_graph_sbox.h" #include "rr_graph_timing_params.h" From 417bf61ea874193fb784de421b8dea65c05775ea Mon Sep 17 00:00:00 2001 From: soheilshahrouz Date: Sun, 2 Feb 2025 16:17:49 -0500 Subject: [PATCH 12/23] create a t_rr_switch_offset_inf for each t_rr_switch_inf added to RR graph --- libs/libarchfpga/src/physical_types.h | 4 ++++ libs/librrgraph/src/base/rr_graph_builder.cpp | 1 + libs/librrgraph/src/base/rr_graph_builder.h | 7 ++++++- libs/librrgraph/src/base/rr_graph_storage.cpp | 6 ++++-- libs/librrgraph/src/base/rr_graph_view.h | 2 +- libs/librrgraph/src/io/rr_graph_reader.cpp | 3 ++- 6 files changed, 18 insertions(+), 5 deletions(-) diff --git a/libs/libarchfpga/src/physical_types.h b/libs/libarchfpga/src/physical_types.h index c7ac66041f5..53138c35c95 100644 --- a/libs/libarchfpga/src/physical_types.h +++ b/libs/libarchfpga/src/physical_types.h @@ -1879,6 +1879,10 @@ struct t_rr_switch_offset_inf { // float Cinternal = 0.; float Tdel = 0.; + t_rr_switch_offset_inf() = default; + t_rr_switch_offset_inf(const t_rr_switch_inf& switch_inf) + : Tdel(switch_inf.Tdel) {} + auto operator<=>(const t_rr_switch_offset_inf&) const = default; }; diff --git a/libs/librrgraph/src/base/rr_graph_builder.cpp b/libs/librrgraph/src/base/rr_graph_builder.cpp index a02f8b0a46b..3562e6db397 100644 --- a/libs/librrgraph/src/base/rr_graph_builder.cpp +++ b/libs/librrgraph/src/base/rr_graph_builder.cpp @@ -79,6 +79,7 @@ void RRGraphBuilder::clear() { rr_edge_metadata_.clear(); rr_segments_.clear(); rr_switch_inf_.clear(); + rr_switch_offset_inf_.clear(); } void RRGraphBuilder::reorder_nodes(e_rr_node_reorder_algorithm reorder_rr_graph_nodes_algorithm, diff --git a/libs/librrgraph/src/base/rr_graph_builder.h b/libs/librrgraph/src/base/rr_graph_builder.h index 2782a349474..c3d1afdb646 100644 --- a/libs/librrgraph/src/base/rr_graph_builder.h +++ b/libs/librrgraph/src/base/rr_graph_builder.h @@ -102,9 +102,13 @@ class RRGraphBuilder { inline RRSwitchId add_rr_switch(const t_rr_switch_inf& switch_info) { //Allocate an ID RRSwitchId switch_id = RRSwitchId(rr_switch_inf_.size()); - rr_switch_inf_.push_back(switch_info); + t_rr_switch_offset_inf switch_offset_info(switch_info); + rr_switch_offset_inf_.push_back(switch_offset_info); + + VTR_ASSERT_DEBUG(rr_switch_inf_.size() == rr_switch_offset_inf_.size()); + return switch_id; } /** @@ -119,6 +123,7 @@ class RRGraphBuilder { } inline RRSwitchOffsetInfoId add_rr_switch_offset_info(const t_rr_switch_offset_inf& switch_offset_info) { + VTR_ASSERT_DEBUG(rr_switch_inf_.size() <= rr_switch_offset_inf_.size()); // Allocate an ID RRSwitchOffsetInfoId switch_offset_info_id = RRSwitchOffsetInfoId(rr_switch_offset_inf_.size()); rr_switch_offset_inf_.push_back(switch_offset_info); diff --git a/libs/librrgraph/src/base/rr_graph_storage.cpp b/libs/librrgraph/src/base/rr_graph_storage.cpp index 3bc0355a338..ccaf438c2dd 100644 --- a/libs/librrgraph/src/base/rr_graph_storage.cpp +++ b/libs/librrgraph/src/base/rr_graph_storage.cpp @@ -417,7 +417,7 @@ void t_rr_graph_storage::init_fan_in() { node_fan_in_.resize(node_storage_.size(), 0); node_fan_in_.shrink_to_fit(); //Walk the graph and increment fanin on all downstream nodes - for(const auto& edge_id : edge_dest_node_.keys()) { + for(const RREdgeId edge_id : edge_dest_node_.keys()) { node_fan_in_[edge_dest_node_[edge_id]] += 1; } } @@ -504,6 +504,7 @@ void t_rr_graph_storage::remap_rr_node_switch_indices(const t_arch_switch_fanin& for (size_t i = 0; i < edge_src_node_.size(); ++i) { RREdgeId edge(i); if(edge_remapped_[edge]) { + VTR_ASSERT(edge_switch_offset_inf_[edge].is_valid()); continue; } @@ -521,6 +522,7 @@ void t_rr_graph_storage::remap_rr_node_switch_indices(const t_arch_switch_fanin& int rr_switch_index = itr->second; edge_switch_[edge] = rr_switch_index; + edge_switch_offset_inf_[edge] = (RRSwitchOffsetInfoId)rr_switch_index; edge_remapped_[edge] = true; } remapped_edges_ = true; @@ -558,7 +560,7 @@ void t_rr_graph_storage::partition_edges(const vtr::vectorsecond; From df1318b7bc2f13095dc995dfe168a49b2142803f Mon Sep 17 00:00:00 2001 From: soheilshahrouz Date: Sun, 2 Feb 2025 16:20:00 -0500 Subject: [PATCH 13/23] init rr_switch_offset_inf_ when RR graph is read from a file --- libs/librrgraph/src/io/rr_graph_reader.cpp | 1 + libs/librrgraph/src/io/rr_graph_uxsdcxx_serializer.h | 10 ++++++++++ 2 files changed, 11 insertions(+) diff --git a/libs/librrgraph/src/io/rr_graph_reader.cpp b/libs/librrgraph/src/io/rr_graph_reader.cpp index 2a8c5f32477..6e95d0e7e9e 100644 --- a/libs/librrgraph/src/io/rr_graph_reader.cpp +++ b/libs/librrgraph/src/io/rr_graph_reader.cpp @@ -83,6 +83,7 @@ void load_rr_file(RRGraphBuilder* rr_graph_builder, rr_graph_builder, rr_graph, &rr_graph_builder->rr_switch(), + &rr_graph_builder->rr_switch_offset_inf(), rr_indexed_data, rr_rc_data, arch_switch_inf, diff --git a/libs/librrgraph/src/io/rr_graph_uxsdcxx_serializer.h b/libs/librrgraph/src/io/rr_graph_uxsdcxx_serializer.h index e9e83988d0b..62f90dd736f 100644 --- a/libs/librrgraph/src/io/rr_graph_uxsdcxx_serializer.h +++ b/libs/librrgraph/src/io/rr_graph_uxsdcxx_serializer.h @@ -285,6 +285,7 @@ class RrGraphSerializer final : public uxsd::RrGraphBase { RRGraphBuilder* rr_graph_builder, RRGraphView* rr_graph, vtr::vector* rr_switch_inf, + vtr::vector* rr_switch_offset_inf, vtr::vector* rr_indexed_data, std::vector* rr_rc_data, const std::vector& arch_switch_inf, @@ -302,6 +303,7 @@ class RrGraphSerializer final : public uxsd::RrGraphBase { , rr_graph_builder_(rr_graph_builder) , rr_graph_(rr_graph) , rr_switch_inf_(rr_switch_inf) + , rr_switch_offset_inf_(rr_switch_offset_inf) , rr_indexed_data_(rr_indexed_data) , read_rr_graph_filename_(read_rr_graph_filename) , rr_rc_data_(rr_rc_data) @@ -624,6 +626,13 @@ class RrGraphSerializer final : public uxsd::RrGraphBase { // If make_room_in_vector was used for allocation, this ensures that // the final storage has no overhead. rr_switch_inf_->shrink_to_fit(); + + rr_switch_offset_inf_->reserve(rr_switch_inf_->size()); + std::ranges::transform(*rr_switch_inf_, + std::back_inserter(*rr_switch_offset_inf_), + [](const t_rr_switch_inf& rr_sw) -> t_rr_switch_offset_inf { + return t_rr_switch_offset_inf{rr_sw}; + }); } /** Generated for complex type "meta": @@ -2160,6 +2169,7 @@ class RrGraphSerializer final : public uxsd::RrGraphBase { RRGraphBuilder* rr_graph_builder_; RRGraphView* rr_graph_; vtr::vector* rr_switch_inf_; + vtr::vector* rr_switch_offset_inf_; vtr::vector* rr_indexed_data_; t_rr_node_indices* rr_node_indices_; std::string* read_rr_graph_filename_; From dda0e333b892eb0de9965aeeb6edf51aeeb334a3 Mon Sep 17 00:00:00 2001 From: soheilshahrouz Date: Sun, 2 Feb 2025 16:38:09 -0500 Subject: [PATCH 14/23] add --read_rr_edge_delay_offset_file command line option --- libs/librrgraph/src/io/rr_graph_reader.cpp | 2 +- libs/librrgraph/src/io/rr_graph_reader.h | 2 +- vpr/src/base/SetupVPR.cpp | 1 + vpr/src/base/read_options.cpp | 9 ++++++++- vpr/src/base/read_options.h | 1 + vpr/src/base/vpr_types.h | 2 +- vpr/src/route/rr_graph.cpp | 6 ++++++ 7 files changed, 19 insertions(+), 4 deletions(-) diff --git a/libs/librrgraph/src/io/rr_graph_reader.cpp b/libs/librrgraph/src/io/rr_graph_reader.cpp index 6e95d0e7e9e..3c2d2a6ebd0 100644 --- a/libs/librrgraph/src/io/rr_graph_reader.cpp +++ b/libs/librrgraph/src/io/rr_graph_reader.cpp @@ -118,7 +118,7 @@ void load_rr_file(RRGraphBuilder* rr_graph_builder, } void load_rr_edge_attribute_offset_file(RRGraphBuilder& rr_graph_builder, - RRGraphView& rr_graph, + const RRGraphView& rr_graph, std::string_view rr_edge_attribute_offset_filename) { std::ifstream file(rr_edge_attribute_offset_filename.data()); diff --git a/libs/librrgraph/src/io/rr_graph_reader.h b/libs/librrgraph/src/io/rr_graph_reader.h index fa2e97fa04e..e4cc1cb098d 100644 --- a/libs/librrgraph/src/io/rr_graph_reader.h +++ b/libs/librrgraph/src/io/rr_graph_reader.h @@ -36,7 +36,7 @@ void load_rr_file(RRGraphBuilder* rr_graph_builder, bool is_flat); void load_rr_edge_attribute_offset_file(RRGraphBuilder& rr_graph_builder, - RRGraphView& rr_graph, + const RRGraphView& rr_graph, std::string_view rr_edge_attribute_offset_filename); #endif /* RR_GRAPH_READER_H */ diff --git a/vpr/src/base/SetupVPR.cpp b/vpr/src/base/SetupVPR.cpp index 9c0fb69ba98..eec4b2b2033 100644 --- a/vpr/src/base/SetupVPR.cpp +++ b/vpr/src/base/SetupVPR.cpp @@ -232,6 +232,7 @@ void SetupVPR(const t_options* options, SetupPackerOpts(*options, packerOpts); routingArch->write_rr_graph_filename = options->write_rr_graph_file; routingArch->read_rr_graph_filename = options->read_rr_graph_file; + routingArch->read_rr_edge_delay_offset_filename = options->read_rr_edge_delay_offset_file; for (auto has_global_routing : arch->layer_global_routing) { device_ctx.inter_cluster_prog_routing_resources.emplace_back(has_global_routing); diff --git a/vpr/src/base/read_options.cpp b/vpr/src/base/read_options.cpp index 9e2c7718595..3f7445aa0c8 100644 --- a/vpr/src/base/read_options.cpp +++ b/vpr/src/base/read_options.cpp @@ -1623,6 +1623,13 @@ argparse::ArgumentParser create_arg_parser(const std::string& prog_name, t_optio .metavar("RR_GRAPH_FILE") .show_in(argparse::ShowIn::HELP_ONLY); + file_grp.add_argument(args.read_rr_edge_delay_offset_file, "--read_rr_edge_delay_offset_file") + .help( + "to be written") + .metavar("RR_GRAPH_EDGE_DELAY_OFFSET_FILE") + .show_in(argparse::ShowIn::HELP_ONLY); + + file_grp.add_argument(args.write_rr_graph_file, "--write_rr_graph") .help("Writes the routing resource graph to the specified file") .metavar("RR_GRAPH_FILE") @@ -3148,7 +3155,7 @@ void set_conditional_defaults(t_options& args) { bool verify_args(const t_options& args) { /* - * Check for conflicting paramaters or dependencies where one parameter set requires another parameter to be included + * Check for conflicting parameters or dependencies where one parameter set requires another parameter to be included */ if (args.read_rr_graph_file.provenance() == Provenance::SPECIFIED && args.RouteChanWidth.provenance() != Provenance::SPECIFIED) { diff --git a/vpr/src/base/read_options.h b/vpr/src/base/read_options.h index 55dc3d50c00..6566a2fcc55 100644 --- a/vpr/src/base/read_options.h +++ b/vpr/src/base/read_options.h @@ -28,6 +28,7 @@ struct t_options { argparse::ArgValue constraints_file; argparse::ArgValue write_rr_graph_file; argparse::ArgValue read_rr_graph_file; + argparse::ArgValue read_rr_edge_delay_offset_file; argparse::ArgValue write_initial_place_file; argparse::ArgValue read_initial_place_file; argparse::ArgValue read_vpr_constraints_file; diff --git a/vpr/src/base/vpr_types.h b/vpr/src/base/vpr_types.h index 5ffeb0e2f63..dded883acdb 100644 --- a/vpr/src/base/vpr_types.h +++ b/vpr/src/base/vpr_types.h @@ -1416,7 +1416,7 @@ struct t_det_routing_arch { float R_minW_pmos; std::string read_rr_graph_filename; - std::string read_rr_edge_attribute_offset_filename; + std::string read_rr_edge_delay_offset_filename; std::string write_rr_graph_filename; }; diff --git a/vpr/src/route/rr_graph.cpp b/vpr/src/route/rr_graph.cpp index 9948ff6c721..8a099e3a97f 100644 --- a/vpr/src/route/rr_graph.cpp +++ b/vpr/src/route/rr_graph.cpp @@ -830,6 +830,12 @@ void create_rr_graph(const t_graph_type graph_type, } } + if (!det_routing_arch->read_rr_edge_delay_offset_filename.empty()) { + load_rr_edge_attribute_offset_file(mutable_device_ctx.rr_graph_builder, + device_ctx.rr_graph, + det_routing_arch->read_rr_edge_delay_offset_filename); + } + if (is_flat) { int delayless_switch = get_delayless_switch_id(det_routing_arch, load_rr_graph); VTR_ASSERT(delayless_switch != OPEN); From df6062cca7c44fd13b568c86b00060cd3292cbde Mon Sep 17 00:00:00 2001 From: soheilshahrouz Date: Sun, 2 Feb 2025 19:22:35 -0500 Subject: [PATCH 15/23] update rr_switch_offset_inf when rr_switch is updated based on fanin data --- libs/librrgraph/src/base/rr_graph_builder.h | 2 +- libs/librrgraph/src/base/rr_graph_storage.cpp | 2 + libs/librrgraph/src/base/rr_graph_view.h | 12 +++- .../src/io/rr_graph_uxsdcxx_serializer.h | 2 +- libs/librrgraph/src/io/rr_graph_writer.cpp | 1 + vpr/src/route/router_lookahead_map.cpp | 3 +- vpr/src/route/rr_graph.cpp | 62 ++++++++++++++----- 7 files changed, 62 insertions(+), 22 deletions(-) diff --git a/libs/librrgraph/src/base/rr_graph_builder.h b/libs/librrgraph/src/base/rr_graph_builder.h index c3d1afdb646..0ef13c9ad37 100644 --- a/libs/librrgraph/src/base/rr_graph_builder.h +++ b/libs/librrgraph/src/base/rr_graph_builder.h @@ -336,7 +336,7 @@ class RRGraphBuilder { this->rr_switch_inf_.reserve(num_switches); } inline void reserve_switch_offse_info(size_t num_offsets) { - this->rr_switch_offset_inf_.resize(num_offsets); + this->rr_switch_offset_inf_.reserve(num_offsets); } /** @brief This function resize node storage to accomidate size RR nodes. */ inline void resize_nodes(size_t size) { diff --git a/libs/librrgraph/src/base/rr_graph_storage.cpp b/libs/librrgraph/src/base/rr_graph_storage.cpp index ccaf438c2dd..a1bf6aafb35 100644 --- a/libs/librrgraph/src/base/rr_graph_storage.cpp +++ b/libs/librrgraph/src/base/rr_graph_storage.cpp @@ -873,6 +873,7 @@ void t_rr_graph_storage::reorder(const vtr::vector& order, auto old_edge_src_node = edge_src_node_; auto old_edge_dest_node = edge_dest_node_; auto old_edge_switch = edge_switch_; + auto old_edge_switch_offset_inf_ = edge_switch_offset_inf_; auto old_edge_remapped = edge_remapped_; RREdgeId cur_edge(0); @@ -886,6 +887,7 @@ void t_rr_graph_storage::reorder(const vtr::vector& order, edge_src_node_[cur_edge] = order[old_edge_src_node[e]]; // == n? edge_dest_node_[cur_edge] = order[old_edge_dest_node[e]]; edge_switch_[cur_edge] = old_edge_switch[e]; + edge_switch_offset_inf_[cur_edge] = old_edge_switch_offset_inf_[e]; edge_remapped_[cur_edge] = old_edge_remapped[e]; cur_edge = RREdgeId(size_t(cur_edge) + 1); } diff --git a/libs/librrgraph/src/base/rr_graph_view.h b/libs/librrgraph/src/base/rr_graph_view.h index 126e2370c54..6ac5f959b91 100644 --- a/libs/librrgraph/src/base/rr_graph_view.h +++ b/libs/librrgraph/src/base/rr_graph_view.h @@ -419,12 +419,20 @@ class RRGraphView { return node_storage_.edge_switch(id, iedge); } - inline float edge_delay(RRNodeId id, t_edge_size iedge) const { - RREdgeId edge_id = node_storage_.edge_id(id, iedge); + inline short edge_switch(RREdgeId edge_id) const { + return node_storage_.edge_switch(edge_id); + } + + inline float edge_delay(RREdgeId edge_id) const { RRSwitchOffsetInfoId switch_offset_inf_id = node_storage_.edge_switch_offset_inf(edge_id); return rr_switch_offset_inf_[switch_offset_inf_id].Tdel; } + inline float edge_delay(RRNodeId id, t_edge_size iedge) const { + RREdgeId edge_id = node_storage_.edge_id(id, iedge); + return edge_delay(edge_id); + } + /** @brief Return the source node for the specified edge. */ inline RRNodeId edge_src_node(const RREdgeId edge_id) const { diff --git a/libs/librrgraph/src/io/rr_graph_uxsdcxx_serializer.h b/libs/librrgraph/src/io/rr_graph_uxsdcxx_serializer.h index 62f90dd736f..d8ce5737503 100644 --- a/libs/librrgraph/src/io/rr_graph_uxsdcxx_serializer.h +++ b/libs/librrgraph/src/io/rr_graph_uxsdcxx_serializer.h @@ -630,7 +630,7 @@ class RrGraphSerializer final : public uxsd::RrGraphBase { rr_switch_offset_inf_->reserve(rr_switch_inf_->size()); std::ranges::transform(*rr_switch_inf_, std::back_inserter(*rr_switch_offset_inf_), - [](const t_rr_switch_inf& rr_sw) -> t_rr_switch_offset_inf { + [](const t_rr_switch_inf& rr_sw) noexcept -> t_rr_switch_offset_inf { return t_rr_switch_offset_inf{rr_sw}; }); } diff --git a/libs/librrgraph/src/io/rr_graph_writer.cpp b/libs/librrgraph/src/io/rr_graph_writer.cpp index d254ae9edb7..48581f4b68b 100644 --- a/libs/librrgraph/src/io/rr_graph_writer.cpp +++ b/libs/librrgraph/src/io/rr_graph_writer.cpp @@ -57,6 +57,7 @@ void write_rr_graph(RRGraphBuilder* rr_graph_builder, rr_graph_builder, rr_graph_view, &rr_graph_builder->rr_switch(), + &rr_graph_builder->rr_switch_offset_inf(), rr_indexed_data, rr_rc_data, arch_switch_inf, diff --git a/vpr/src/route/router_lookahead_map.cpp b/vpr/src/route/router_lookahead_map.cpp index a3d468b901c..8c2f1f737cc 100644 --- a/vpr/src/route/router_lookahead_map.cpp +++ b/vpr/src/route/router_lookahead_map.cpp @@ -734,7 +734,8 @@ static void compute_tile_lookahead(std::unordered_map #include #include +#include #include "vtr_assert.h" #include "vtr_util.h" @@ -890,6 +891,29 @@ void create_rr_graph(const t_graph_type graph_type, echo_file_name, is_flat); } + { + std::ofstream file1("switch_delay.txt"); + std::ofstream file2("exact_delay.txt"); + + if (!file1.is_open() || !file2.is_open()) { + std::cerr << "Error opening files!" << std::endl; + return; + } + + for (const RRNodeId driver_node : device_ctx.rr_graph.nodes()) { + for (const RREdgeId edge_id : device_ctx.rr_graph.edge_range(driver_node)) { + int i_switch = device_ctx.rr_graph.edge_switch(edge_id); + float edge_switch_delay = device_ctx.rr_graph.rr_switch_inf(RRSwitchId(i_switch)).Tdel; + float edge_exact_delay = device_ctx.rr_graph.edge_delay(edge_id); + + file1 << size_t(edge_id) << " " << edge_switch_delay << "\n"; + file2 << size_t(edge_id) << " " << edge_exact_delay << "\n"; + } + } + + file1.close(); + file2.close(); + } } static void add_intra_cluster_edges_rr_graph(RRGraphBuilder& rr_graph_builder, @@ -1860,29 +1884,33 @@ void load_rr_switch_from_arch_switch(RRGraphBuilder& rr_graph_builder, int fanin, const float R_minW_nmos, const float R_minW_pmos) { - /* figure out, by looking at the arch switch's Tdel map, what the delay of the new - * rr switch should be */ - double rr_switch_Tdel = arch_sw_inf.at(arch_switch_idx).Tdel(fanin); + const t_arch_switch_inf& arch_switch = arch_sw_inf.at(arch_switch_idx); + t_rr_switch_inf& rr_switch_to_be_updated = rr_graph_builder.rr_switch()[RRSwitchId(rr_switch_idx)]; + t_rr_switch_offset_inf& rr_switch_offset_to_be_updated = rr_graph_builder.rr_switch_offset_inf()[RRSwitchOffsetInfoId (rr_switch_idx)]; /* copy over the arch switch to rr_switch_inf[rr_switch_idx], but with the changed Tdel value */ - rr_graph_builder.rr_switch()[RRSwitchId(rr_switch_idx)].set_type(arch_sw_inf.at(arch_switch_idx).type()); - rr_graph_builder.rr_switch()[RRSwitchId(rr_switch_idx)].R = arch_sw_inf.at(arch_switch_idx).R; - rr_graph_builder.rr_switch()[RRSwitchId(rr_switch_idx)].Cin = arch_sw_inf.at(arch_switch_idx).Cin; - rr_graph_builder.rr_switch()[RRSwitchId(rr_switch_idx)].Cinternal = arch_sw_inf.at(arch_switch_idx).Cinternal; - rr_graph_builder.rr_switch()[RRSwitchId(rr_switch_idx)].Cout = arch_sw_inf.at(arch_switch_idx).Cout; - rr_graph_builder.rr_switch()[RRSwitchId(rr_switch_idx)].Tdel = rr_switch_Tdel; - rr_graph_builder.rr_switch()[RRSwitchId(rr_switch_idx)].mux_trans_size = arch_sw_inf.at(arch_switch_idx).mux_trans_size; - if (arch_sw_inf.at(arch_switch_idx).buf_size_type == BufferSize::AUTO) { + rr_switch_to_be_updated.set_type(arch_switch.type()); + rr_switch_to_be_updated.R = arch_switch.R; + rr_switch_to_be_updated.Cin = arch_switch.Cin; + rr_switch_to_be_updated.Cinternal = arch_switch.Cinternal; + rr_switch_to_be_updated.Cout = arch_switch.Cout; + /* figure out, by looking at the arch switch's Tdel map, what the delay of the new + * rr switch should be */ + rr_switch_to_be_updated.Tdel = arch_switch.Tdel(fanin); + rr_switch_to_be_updated.mux_trans_size = arch_switch.mux_trans_size; + if (arch_switch.buf_size_type == BufferSize::AUTO) { //Size based on resistance - rr_graph_builder.rr_switch()[RRSwitchId(rr_switch_idx)].buf_size = trans_per_buf(arch_sw_inf.at(arch_switch_idx).R, R_minW_nmos, R_minW_pmos); + rr_switch_to_be_updated.buf_size = trans_per_buf(arch_switch.R, R_minW_nmos, R_minW_pmos); } else { - VTR_ASSERT(arch_sw_inf.at(arch_switch_idx).buf_size_type == BufferSize::ABSOLUTE); + VTR_ASSERT(arch_switch.buf_size_type == BufferSize::ABSOLUTE); //Use the specified size - rr_graph_builder.rr_switch()[RRSwitchId(rr_switch_idx)].buf_size = arch_sw_inf.at(arch_switch_idx).buf_size; + rr_switch_to_be_updated.buf_size = arch_switch.buf_size; } - rr_graph_builder.rr_switch()[RRSwitchId(rr_switch_idx)].name = arch_sw_inf.at(arch_switch_idx).name; - rr_graph_builder.rr_switch()[RRSwitchId(rr_switch_idx)].power_buffer_type = arch_sw_inf.at(arch_switch_idx).power_buffer_type; - rr_graph_builder.rr_switch()[RRSwitchId(rr_switch_idx)].power_buffer_size = arch_sw_inf.at(arch_switch_idx).power_buffer_size; + rr_switch_to_be_updated.name = arch_switch.name; + rr_switch_to_be_updated.power_buffer_type = arch_switch.power_buffer_type; + rr_switch_to_be_updated.power_buffer_size = arch_switch.power_buffer_size; + + rr_switch_offset_to_be_updated.Tdel = rr_switch_to_be_updated.Tdel; } /* switch indices of each rr_node original point into the global device_ctx.arch_switch_inf array. From dd1df5c5457e30725c43a601462dc055dbd730b0 Mon Sep 17 00:00:00 2001 From: soheilshahrouz Date: Mon, 3 Feb 2025 13:42:10 -0500 Subject: [PATCH 16/23] call edge_delay() instead of accessing switch delay --- .../utils/alloc_and_load_rr_indexed_data.cpp | 16 ++++++++-------- .../src/utils/alloc_and_load_rr_indexed_data.h | 4 ++-- vpr/src/route/connection_router.cpp | 5 ++++- vpr/src/route/route_tree.cpp | 13 +++++++------ vpr/src/route/router_lookahead_map_utils.cpp | 17 ++++++++++++----- vpr/src/route/rr_graph.cpp | 14 +++++--------- vpr/src/route/rr_graph2.cpp | 4 ++-- vpr/src/util/vpr_utils.cpp | 8 ++++++-- vpr/src/util/vpr_utils.h | 2 +- 9 files changed, 47 insertions(+), 36 deletions(-) diff --git a/libs/librrgraph/src/utils/alloc_and_load_rr_indexed_data.cpp b/libs/librrgraph/src/utils/alloc_and_load_rr_indexed_data.cpp index bb88449ebcb..20beddc6ec3 100644 --- a/libs/librrgraph/src/utils/alloc_and_load_rr_indexed_data.cpp +++ b/libs/librrgraph/src/utils/alloc_and_load_rr_indexed_data.cpp @@ -70,8 +70,6 @@ void alloc_and_load_rr_indexed_data(const RRGraphView& rr_graph, enum e_base_cost_type base_cost_type, const bool echo_enabled, const char* echo_file_name) { - int length, i, index; - (void)segment_inf; int total_num_segment = segment_inf_x.size() + segment_inf_y.size(); /*CHAX & CHANY segment lsit sizes may differ. but if we're using uniform channels, they @@ -85,7 +83,7 @@ void alloc_and_load_rr_indexed_data(const RRGraphView& rr_graph, * * other than base_cost are invalid. Mark invalid fields as OPEN for safety. */ constexpr float nan = std::numeric_limits::quiet_NaN(); - for (i = SOURCE_COST_INDEX; i <= IPIN_COST_INDEX; i++) { + for (int i = SOURCE_COST_INDEX; i <= IPIN_COST_INDEX; i++) { rr_indexed_data[RRIndexedDataId(i)].ortho_cost_index = OPEN; rr_indexed_data[RRIndexedDataId(i)].seg_index = OPEN; rr_indexed_data[RRIndexedDataId(i)].inv_length = nan; @@ -116,10 +114,11 @@ void alloc_and_load_rr_indexed_data(const RRGraphView& rr_graph, /* X-directed segments*/ for (size_t iseg = 0; iseg < segment_inf_x.size(); ++iseg) { - index = iseg + CHANX_COST_INDEX_START; + int index = iseg + CHANX_COST_INDEX_START; rr_indexed_data[RRIndexedDataId(index)].ortho_cost_index = ortho_costs[iseg]; + int length; if (segment_inf_x[iseg].longline) length = grid.width(); else @@ -134,9 +133,10 @@ void alloc_and_load_rr_indexed_data(const RRGraphView& rr_graph, /* Y-directed segments*/ for (size_t iseg = segment_inf_x.size(); iseg < ortho_costs.size(); ++iseg) { - index = iseg + CHANX_COST_INDEX_START; + int index = iseg + CHANX_COST_INDEX_START; rr_indexed_data[RRIndexedDataId(index)].ortho_cost_index = ortho_costs[iseg]; + int length; if (segment_inf_x[iseg - segment_inf_x.size()].longline) length = grid.width(); else @@ -171,8 +171,8 @@ void alloc_and_load_rr_indexed_data(const RRGraphView& rr_graph, * a copy passed to the function to store the index w.r.t the parallel axis segment list.*/ std::vector find_ortho_cost_index(const RRGraphView& rr_graph, - const std::vector segment_inf_x, - const std::vector segment_inf_y, + const std::vector& segment_inf_x, + const std::vector& segment_inf_y, e_parallel_axis parallel_axis) { auto segment_inf_parallel = parallel_axis == X_AXIS ? segment_inf_x : segment_inf_y; auto segment_inf_perp = parallel_axis == X_AXIS ? segment_inf_y : segment_inf_x; @@ -671,7 +671,7 @@ static void calculate_average_switch(const RRGraphView& rr_graph, } avg_switch_R += rr_graph.rr_switch_inf(RRSwitchId(switch_index)).R; - avg_switch_T += rr_graph.rr_switch_inf(RRSwitchId(switch_index)).Tdel; + avg_switch_T += rr_graph.edge_delay(edge); avg_switch_Cinternal += rr_graph.rr_switch_inf(RRSwitchId(switch_index)).Cinternal; if (buffered == UNDEFINED) { diff --git a/libs/librrgraph/src/utils/alloc_and_load_rr_indexed_data.h b/libs/librrgraph/src/utils/alloc_and_load_rr_indexed_data.h index 1a96141163a..aa3c4a16262 100644 --- a/libs/librrgraph/src/utils/alloc_and_load_rr_indexed_data.h +++ b/libs/librrgraph/src/utils/alloc_and_load_rr_indexed_data.h @@ -18,8 +18,8 @@ void alloc_and_load_rr_indexed_data(const RRGraphView& rr_graph, const char* echo_file_name); std::vector find_ortho_cost_index(const RRGraphView& rr_graph, - const std::vector segment_inf_x, - const std::vector segment_inf_y, + const std::vector& segment_inf_x, + const std::vector& segment_inf_y, e_parallel_axis parallel_axis); #endif \ No newline at end of file diff --git a/vpr/src/route/connection_router.cpp b/vpr/src/route/connection_router.cpp index 7216820726a..db563031b45 100644 --- a/vpr/src/route/connection_router.cpp +++ b/vpr/src/route/connection_router.cpp @@ -702,7 +702,10 @@ void ConnectionRouter::evaluate_timing_driven_node_costs(RTExploredNode* t bool switch_buffered = rr_switch_inf_[iswitch].buffered(); bool reached_configurably = rr_switch_inf_[iswitch].configurable(); float switch_R = rr_switch_inf_[iswitch].R; - float switch_Tdel = rr_switch_inf_[iswitch].Tdel; + // Instead of looking up the delay from the RR switch type info, + // we call edge_delay() method that returns the exact delay calculated + // by adding edge-specific delays to the nominal delay of switch type + float switch_Tdel = rr_graph_->edge_delay(to->prev_edge); float switch_Cinternal = rr_switch_inf_[iswitch].Cinternal; //To node info diff --git a/vpr/src/route/route_tree.cpp b/vpr/src/route/route_tree.cpp index 1ac8d8c13ff..4f0d6a7f524 100644 --- a/vpr/src/route/route_tree.cpp +++ b/vpr/src/route/route_tree.cpp @@ -184,7 +184,7 @@ void RouteTree::reload_timing(vtr::optional from_node) { } void RouteTree::reload_timing_unlocked(vtr::optional from_node) { - auto& device_ctx = g_vpr_ctx.device(); + const auto& device_ctx = g_vpr_ctx.device(); const auto& rr_graph = device_ctx.rr_graph; if (!from_node) @@ -208,6 +208,7 @@ void RouteTree::reload_timing_unlocked(vtr::optional from_node) /* TODO Just a note (no action needed for this PR): In future, we need to consider APIs that returns * the Tdel for a routing trace in RRGraphView.*/ Tdel_start += rr_graph.rr_switch_inf(iswitch).R * unbuffered_subtree_rt_root.C_downstream; + // TODO: probably call edge_delay() to retrieve the per-edge delay instead of per switch type delay Tdel_start += rr_graph.rr_switch_inf(iswitch).Tdel; } @@ -325,23 +326,23 @@ RouteTree::update_unbuffered_ancestors_C_downstream(RouteTreeNode& from_node) { * must be correct before this routine is called. Tarrival is the time at * at which the signal arrives at this node's *input*. */ void RouteTree::load_route_tree_Tdel(RouteTreeNode& from_node, float Tarrival) { - auto& device_ctx = g_vpr_ctx.device(); + const auto& device_ctx = g_vpr_ctx.device(); const auto& rr_graph = device_ctx.rr_graph; RRNodeId inode = from_node.inode; - float Tdel, Tchild; /* Assuming the downstream connections are, on average, connected halfway * along a wire segment's length. See discussion in net_delay.cpp if you want * to change this. */ - Tdel = Tarrival + 0.5 * from_node.C_downstream * rr_graph.node_R(inode); - from_node.Tdel = Tdel; + from_node.Tdel = Tarrival + 0.5 * from_node.C_downstream * rr_graph.node_R(inode); /* Now expand the children of this node to load their Tdel values */ for (RouteTreeNode& child : from_node._child_nodes()) { RRSwitchId iswitch = child.parent_switch; - Tchild = Tdel + rr_graph.rr_switch_inf(iswitch).R * child.C_downstream; + float Tchild = from_node.Tdel + rr_graph.rr_switch_inf(iswitch).R * child.C_downstream; + // TODO: we should probably look up the per-edge delay instead of switch type delay + // For this, we need to add a new member variable to RouteTreeNode to record it parent edge Tchild += rr_graph.rr_switch_inf(iswitch).Tdel; /* Intrinsic switch delay. */ load_route_tree_Tdel(child, Tchild); } diff --git a/vpr/src/route/router_lookahead_map_utils.cpp b/vpr/src/route/router_lookahead_map_utils.cpp index 5a55ed8c979..8bd55058d51 100644 --- a/vpr/src/route/router_lookahead_map_utils.cpp +++ b/vpr/src/route/router_lookahead_map_utils.cpp @@ -166,15 +166,16 @@ PQ_Entry::PQ_Entry(RRNodeId set_rr_node, int /*switch_ind*/, float parent_delay, this->cost = this->delay; } -PQ_Entry_Delay::PQ_Entry_Delay( - RRNodeId set_rr_node, - int switch_ind, - const PQ_Entry_Delay* parent) { +PQ_Entry_Delay::PQ_Entry_Delay(RRNodeId set_rr_node, + int switch_ind, + const PQ_Entry_Delay* parent) { this->rr_node = set_rr_node; if (parent != nullptr) { - auto& device_ctx = g_vpr_ctx.device(); + const auto& device_ctx = g_vpr_ctx.device(); const auto& rr_graph = device_ctx.rr_graph; + // We use nominal switch delay instead of per-edge delay that can be retrieved + // by calling edge_delay() method float Tsw = rr_graph.rr_switch_inf(RRSwitchId(switch_ind)).Tdel; float Rsw = rr_graph.rr_switch_inf(RRSwitchId(switch_ind)).R; float Cnode = rr_graph.node_C(set_rr_node); @@ -1019,6 +1020,8 @@ static void dijkstra_flood_to_wires(int itile, for (RREdgeId edge : rr_graph.edge_range(curr.node)) { int iswitch = rr_graph.rr_nodes().edge_switch(edge); + // We use nominal switch delay instead of per-edge delay that can be retrieved + // by calling edge_delay() method float incr_delay = rr_graph.rr_switch_inf(RRSwitchId(iswitch)).Tdel; RRNodeId next_node = rr_graph.rr_nodes().edge_sink_node(edge); @@ -1122,6 +1125,8 @@ static void dijkstra_flood_to_ipins(RRNodeId node, util::t_chan_ipins_delays& ch for (RREdgeId edge : rr_graph.edge_range(curr.node)) { int iswitch = rr_graph.rr_nodes().edge_switch(edge); + // We use nominal switch delay instead of per-edge delay that can be retrieved + // by calling edge_delay() method float new_delay = rr_graph.rr_switch_inf(RRSwitchId(iswitch)).Tdel; RRNodeId next_node = rr_graph.rr_nodes().edge_sink_node(edge); @@ -1262,6 +1267,8 @@ static void run_intra_tile_dijkstra(const RRGraphView& rr_graph, auto cost_index = rr_graph.node_cost_index(next_node); int iswitch = rr_graph.rr_nodes().edge_switch(edge); + // We use nominal switch delay instead of per-edge delay that can be retrieved + // by calling edge_delay() method float incr_delay = rr_graph.rr_switch_inf(RRSwitchId(iswitch)).Tdel; float incr_cong = device_ctx.rr_indexed_data[cost_index].base_cost; diff --git a/vpr/src/route/rr_graph.cpp b/vpr/src/route/rr_graph.cpp index 8b51fafb800..fb29cc15ae7 100644 --- a/vpr/src/route/rr_graph.cpp +++ b/vpr/src/route/rr_graph.cpp @@ -678,7 +678,7 @@ static void add_pin_chain(const std::vector& pin_chain, bool is_new_chain); /*** - * @brief Return a pair. The firt element indicates whether the switch is added or it was already added. The second element is the switch index. + * @brief Return a pair. The first element indicates whether the switch is added or it was already added. The second element is the switch index. * @param rr_graph * @param arch_sw_inf * @param R_minW_nmos Needs to be passed to use create_rr_switch_from_arch_switch @@ -1838,11 +1838,11 @@ static void load_rr_switch_inf(RRGraphBuilder& rr_graph_builder, } } } + /* This function creates a routing switch for the usage of routing resource graph, based on a routing switch defined in architecture file. * * Since users can specify a routing switch whose buffer size is automatically tuned for routing architecture, the function here sets a definite buffer size, as required by placers and routers. */ - t_rr_switch_inf create_rr_switch_from_arch_switch(const t_arch_switch_inf& arch_sw_inf, const float R_minW_nmos, const float R_minW_pmos) { @@ -5103,11 +5103,11 @@ static std::pair find_create_intra_cluster_sw(RRGraphBuilder& rr_grap float R_minW_pmos, bool is_rr_sw, float delay) { - const auto& rr_graph_switches = rr_graph.rr_switch(); + const vtr::vector& rr_graph_switches = rr_graph.rr_switch(); if (is_rr_sw) { for (int rr_switch_id = 0; rr_switch_id < (int)rr_graph_switches.size(); rr_switch_id++) { - const auto& rr_sw = rr_graph_switches[RRSwitchId(rr_switch_id)]; + const t_rr_switch_inf& rr_sw = rr_graph_switches[RRSwitchId(rr_switch_id)]; if (rr_sw.intra_tile) { if (rr_sw.Tdel == delay) { return std::make_pair(false, rr_switch_id); @@ -5126,11 +5126,7 @@ static std::pair find_create_intra_cluster_sw(RRGraphBuilder& rr_grap auto find_res = std::find_if(arch_sw_inf.begin(), arch_sw_inf.end(), [delay](const std::pair& sw_inf_pair) { const t_arch_switch_inf& sw_inf = std::get<1>(sw_inf_pair); - if (sw_inf.intra_tile && sw_inf.Tdel() == delay) { - return true; - } else { - return false; - } + return sw_inf.intra_tile && sw_inf.Tdel() == delay; }); // There isn't any other intra-tile edge with the same delay - Create a new one! diff --git a/vpr/src/route/rr_graph2.cpp b/vpr/src/route/rr_graph2.cpp index fc271a8b795..4403dbe09b5 100644 --- a/vpr/src/route/rr_graph2.cpp +++ b/vpr/src/route/rr_graph2.cpp @@ -60,7 +60,7 @@ static void add_classes_spatial_lookup(RRGraphBuilder& rr_graph_builder, int* index); static int get_bidir_track_to_chan_seg(RRGraphBuilder& rr_graph_builder, - const std::vector conn_tracks, + const std::vector& conn_tracks, const int layer, const int to_chan, const int to_seg, @@ -2168,7 +2168,7 @@ void alloc_and_load_tile_rr_node_indices(RRGraphBuilder& rr_graph_builder, } static int get_bidir_track_to_chan_seg(RRGraphBuilder& rr_graph_builder, - const std::vector conn_tracks, + const std::vector& conn_tracks, const int layer, const int to_chan, const int to_seg, diff --git a/vpr/src/util/vpr_utils.cpp b/vpr/src/util/vpr_utils.cpp index c59ad7af89c..665a4d54682 100644 --- a/vpr/src/util/vpr_utils.cpp +++ b/vpr/src/util/vpr_utils.cpp @@ -2019,10 +2019,14 @@ float get_min_cross_layer_delay() { const auto& rr_graph = g_vpr_ctx.device().rr_graph; float min_delay = std::numeric_limits::max(); - for (const auto& driver_node : rr_graph.nodes()) { + for (const RRNodeId driver_node : rr_graph.nodes()) { for (size_t edge_id = 0; edge_id < rr_graph.num_edges(driver_node); edge_id++) { - const auto& sink_node = rr_graph.edge_sink_node(driver_node, edge_id); + const RRNodeId sink_node = rr_graph.edge_sink_node(driver_node, edge_id); if (rr_graph.node_layer(driver_node) != rr_graph.node_layer(sink_node)) { + // Instead of calling edge_delay() method, we retrieve the delay from the switch type + // that the edge represents. Since the minimum delay returned by this function is used + // to construct the router lookahead, it is better nominal switch delays instead of exact + // ones that are calculated by adding edge-specific offsets. int i_switch = rr_graph.edge_switch(driver_node, edge_id); float edge_delay = rr_graph.rr_switch_inf(RRSwitchId(i_switch)).Tdel; min_delay = std::min(min_delay, edge_delay); diff --git a/vpr/src/util/vpr_utils.h b/vpr/src/util/vpr_utils.h index abaafadbfe7..8a40f0dcae8 100644 --- a/vpr/src/util/vpr_utils.h +++ b/vpr/src/util/vpr_utils.h @@ -329,7 +329,7 @@ void apply_route_constraints(const UserRouteConstraints& constraint); /** * @brief Iterate over all inter-layer switch types and return the minimum delay of it. * useful four router lookahead to to have some estimate of the cost of crossing a layer - * @return + * @return The minimum delay of goring through an inter-layer switch. */ float get_min_cross_layer_delay(); From 017ababaf6004fe1eaae44175914ea6c144c2e08 Mon Sep 17 00:00:00 2001 From: soheilshahrouz Date: Mon, 3 Feb 2025 14:58:08 -0500 Subject: [PATCH 17/23] clear edge_switch_offset_inf_ in RRGraphStorage --- libs/librrgraph/src/base/rr_graph_storage.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libs/librrgraph/src/base/rr_graph_storage.h b/libs/librrgraph/src/base/rr_graph_storage.h index fea8d803db9..eee6f8e3845 100644 --- a/libs/librrgraph/src/base/rr_graph_storage.h +++ b/libs/librrgraph/src/base/rr_graph_storage.h @@ -554,6 +554,7 @@ class t_rr_graph_storage { edge_src_node_.clear(); edge_dest_node_.clear(); edge_switch_.clear(); + edge_switch_offset_inf_.clear(); edge_remapped_.clear(); edges_read_ = false; partitioned_ = false; @@ -588,6 +589,7 @@ class t_rr_graph_storage { edge_src_node_.shrink_to_fit(); edge_dest_node_.shrink_to_fit(); edge_switch_.shrink_to_fit(); + edge_switch_offset_inf_.shrink_to_fit(); edge_remapped_.shrink_to_fit(); } From 31f617ad372f569b4ea39900653ed913f90413f5 Mon Sep 17 00:00:00 2001 From: soheilshahrouz Date: Mon, 3 Feb 2025 15:22:25 -0500 Subject: [PATCH 18/23] replace raw pointers with std::vector for seg_details_x/y --- vpr/src/route/rr_graph.cpp | 79 +++++++++++---------------- vpr/src/route/rr_graph2.cpp | 106 ++++++++++++++++-------------------- vpr/src/route/rr_graph2.h | 33 ++++++----- 3 files changed, 95 insertions(+), 123 deletions(-) diff --git a/vpr/src/route/rr_graph.cpp b/vpr/src/route/rr_graph.cpp index fb29cc15ae7..36fe82d84c8 100644 --- a/vpr/src/route/rr_graph.cpp +++ b/vpr/src/route/rr_graph.cpp @@ -598,8 +598,7 @@ static void rr_graph_externals(const std::vector& segment_inf, static t_clb_to_clb_directs* alloc_and_load_clb_to_clb_directs(const std::vector& directs, const int delayless_switch); -static t_seg_details* alloc_and_load_global_route_seg_details(const int global_route_switch, - int* num_seg_details = nullptr); +static std::vector alloc_and_load_global_route_seg_details(int global_route_switch); static std::vector> alloc_and_load_actual_fc(const std::vector& types, const int max_pins, @@ -1119,11 +1118,9 @@ static void build_rr_graph(const t_graph_type graph_type, device_ctx.rr_graph_builder.add_rr_segment(segment_inf[iseg]); } - int num_seg_details_x = 0; - int num_seg_details_y = 0; - t_seg_details* seg_details_x = nullptr; - t_seg_details* seg_details_y = nullptr; + std::vector seg_details_x; + std::vector seg_details_y; t_unified_to_parallel_seg_index segment_index_map; std::vector segment_inf_x = get_parallel_segs(segment_inf, segment_index_map, X_AXIS); @@ -1131,8 +1128,8 @@ static void build_rr_graph(const t_graph_type graph_type, if (is_global_graph) { /* Sets up a single unit length segment type for global routing. */ - seg_details_x = alloc_and_load_global_route_seg_details(global_route_switch, &num_seg_details_x); - seg_details_y = alloc_and_load_global_route_seg_details(global_route_switch, &num_seg_details_y); + seg_details_x = alloc_and_load_global_route_seg_details(global_route_switch); + seg_details_y = alloc_and_load_global_route_seg_details(global_route_switch); } else { /* Setup segments including distributing tracks and staggering. @@ -1147,13 +1144,11 @@ static void build_rr_graph(const t_graph_type graph_type, /*Get x & y segments separately*/ seg_details_x = alloc_and_load_seg_details(&max_chan_width_x, max_dim, segment_inf_x, - use_full_seg_groups, directionality, - &num_seg_details_x); + use_full_seg_groups, directionality); seg_details_y = alloc_and_load_seg_details(&max_chan_width_y, max_dim, segment_inf_y, - use_full_seg_groups, directionality, - &num_seg_details_y); + use_full_seg_groups, directionality); if (nodes_per_chan.x_max != max_chan_width_x || nodes_per_chan.y_max != max_chan_width_y) { nodes_per_chan.x_max = max_chan_width_x; @@ -1182,8 +1177,7 @@ static void build_rr_graph(const t_graph_type graph_type, t_chan_details chan_details_x; t_chan_details chan_details_y; - alloc_and_load_chan_details(grid, &nodes_per_chan, - num_seg_details_x, num_seg_details_y, + alloc_and_load_chan_details(grid, nodes_per_chan, seg_details_x, seg_details_y, chan_details_x, chan_details_y); @@ -1559,12 +1553,6 @@ static void build_rr_graph(const t_graph_type graph_type, graph_type, is_flat); - /* Free all temp structs */ - delete[] seg_details_x; - delete[] seg_details_y; - - seg_details_x = nullptr; - seg_details_y = nullptr; if (!chan_details_x.empty() || !chan_details_y.empty()) { free_chan_details(chan_details_x, chan_details_y); } @@ -1992,33 +1980,30 @@ static std::vector> alloc_and_load_perturb_ipins(const int L_n return result; } -static t_seg_details* alloc_and_load_global_route_seg_details(const int global_route_switch, - int* num_seg_details) { - t_seg_details* seg_details = new t_seg_details[1]; - - seg_details->index = 0; - seg_details->abs_index = 0; - seg_details->length = 1; - seg_details->arch_wire_switch = global_route_switch; - seg_details->arch_opin_switch = global_route_switch; - seg_details->longline = false; - seg_details->direction = Direction::BIDIR; - seg_details->Cmetal = 0.0; - seg_details->Rmetal = 0.0; - seg_details->start = 1; - seg_details->cb = std::make_unique(1); - seg_details->cb[0] = true; - seg_details->sb = std::make_unique(2); - seg_details->sb[0] = true; - seg_details->sb[1] = true; - seg_details->group_size = 1; - seg_details->group_start = 0; - seg_details->seg_start = -1; - seg_details->seg_end = -1; - - if (num_seg_details) { - *num_seg_details = 1; - } +static std::vector alloc_and_load_global_route_seg_details(int global_route_switch) { + std::vector seg_details(1); + + seg_details[0].index = 0; + seg_details[0].abs_index = 0; + seg_details[0].length = 1; + seg_details[0].arch_wire_switch = global_route_switch; + seg_details[0].arch_opin_switch = global_route_switch; + seg_details[0].longline = false; + seg_details[0].direction = Direction::BIDIR; + seg_details[0].Cmetal = 0.0; + seg_details[0].Rmetal = 0.0; + seg_details[0].start = 1; + seg_details[0].cb = std::make_unique(1); + seg_details[0].cb[0] = true; + seg_details[0].sb = std::make_unique(2); + seg_details[0].sb[0] = true; + seg_details[0].sb[1] = true; + seg_details[0].group_size = 1; + seg_details[0].group_start = 0; + seg_details[0].seg_start = -1; + seg_details[0].seg_end = -1; + + VTR_ASSERT_DEBUG(seg_details.size() == 1); return seg_details; } diff --git a/vpr/src/route/rr_graph2.cpp b/vpr/src/route/rr_graph2.cpp index 4403dbe09b5..48db5b3d639 100644 --- a/vpr/src/route/rr_graph2.cpp +++ b/vpr/src/route/rr_graph2.cpp @@ -386,12 +386,11 @@ std::unique_ptr get_ordered_seg_track_counts(const std::vector& segment_inf, - const bool use_full_seg_groups, - const enum e_directionality directionality, - int* num_seg_details) { +std::vector alloc_and_load_seg_details(int* max_chan_width, + int max_len, + const std::vector& segment_inf, + bool use_full_seg_groups, + enum e_directionality directionality) { /* Allocates and loads the seg_details data structure. Max_len gives the * * maximum length of a segment (dimension of array). The code below tries * * to: * @@ -401,14 +400,9 @@ t_seg_details* alloc_and_load_seg_details(int* max_chan_width, * (3) stagger the connection and switch boxes on different long lines, * * as they will not be staggered by different segment start points. */ - int cur_track, ntracks, itrack, length, j, index; - int fac, num_sets, tmp; - int arch_wire_switch, arch_opin_switch, arch_wire_switch_dec, arch_opin_switch_dec; - int arch_opin_between_dice_switch; - int group_start, first_track; - std::unique_ptr sets_per_seg_type; - t_seg_details* seg_details = nullptr; - bool longline; + int cur_track; + int fac; + std::vector seg_details; /* Unidir tracks are assigned in pairs, and bidir tracks individually */ if (directionality == BI_DIRECTIONAL) { @@ -423,46 +417,46 @@ t_seg_details* alloc_and_load_seg_details(int* max_chan_width, } /* Map segment type fractions and groupings to counts of tracks */ - sets_per_seg_type = get_seg_track_counts((*max_chan_width / fac), - segment_inf, use_full_seg_groups); + std::unique_ptr sets_per_seg_type = get_seg_track_counts((*max_chan_width / fac), + segment_inf, use_full_seg_groups); /* Count the number tracks actually assigned. */ - tmp = 0; + int tmp = 0; for (size_t i = 0; i < segment_inf.size(); ++i) { tmp += sets_per_seg_type[i] * fac; } VTR_ASSERT(use_full_seg_groups || (tmp == *max_chan_width)); *max_chan_width = tmp; - seg_details = new t_seg_details[*max_chan_width]; + seg_details.resize(*max_chan_width); /* Setup the seg_details data */ cur_track = 0; for (size_t i = 0; i < segment_inf.size(); ++i) { - first_track = cur_track; + int first_track = cur_track; - num_sets = sets_per_seg_type[i]; - ntracks = fac * num_sets; + int num_sets = sets_per_seg_type[i]; + int ntracks = fac * num_sets; if (ntracks < 1) { continue; } /* Avoid divide by 0 if ntracks */ - longline = segment_inf[i].longline; - length = segment_inf[i].length; + bool longline = segment_inf[i].longline; + int length = segment_inf[i].length; if (longline) { length = max_len; } - arch_wire_switch = segment_inf[i].arch_wire_switch; - arch_opin_switch = segment_inf[i].arch_opin_switch; - arch_wire_switch_dec = segment_inf[i].arch_wire_switch_dec; - arch_opin_switch_dec = segment_inf[i].arch_opin_switch_dec; - arch_opin_between_dice_switch = segment_inf[i].arch_opin_between_dice_switch; + int arch_wire_switch = segment_inf[i].arch_wire_switch; + int arch_opin_switch = segment_inf[i].arch_opin_switch; + int arch_wire_switch_dec = segment_inf[i].arch_wire_switch_dec; + int arch_opin_switch_dec = segment_inf[i].arch_opin_switch_dec; + int arch_opin_between_dice_switch = segment_inf[i].arch_opin_between_dice_switch; VTR_ASSERT((arch_wire_switch == arch_opin_switch && arch_wire_switch_dec == arch_opin_switch_dec) || (directionality != UNI_DIRECTIONAL)); /* Set up the tracks of same type */ - group_start = 0; - for (itrack = 0; itrack < ntracks; itrack++) { + int group_start = 0; + for (int itrack = 0; itrack < ntracks; itrack++) { /* set the name of the segment type this track belongs to */ seg_details[cur_track].type_name = segment_inf[i].name; @@ -498,21 +492,21 @@ t_seg_details* alloc_and_load_seg_details(int* max_chan_width, * since this is a property of a detailed route. */ seg_details[cur_track].cb = std::make_unique(length); seg_details[cur_track].sb = std::make_unique(length + 1); - for (j = 0; j < length; ++j) { + for (int j = 0; j < length; ++j) { if (seg_details[cur_track].longline) { seg_details[cur_track].cb[j] = true; } else { /* Use the segment's pattern. */ - index = j % segment_inf[i].cb.size(); + int index = j % segment_inf[i].cb.size(); seg_details[cur_track].cb[j] = segment_inf[i].cb[index]; } } - for (j = 0; j < (length + 1); ++j) { + for (int j = 0; j < (length + 1); ++j) { if (seg_details[cur_track].longline) { seg_details[cur_track].sb[j] = true; } else { /* Use the segment's pattern. */ - index = j % segment_inf[i].sb.size(); + int index = j % segment_inf[i].sb.size(); seg_details[cur_track].sb[j] = segment_inf[i].sb[index]; } } @@ -549,9 +543,7 @@ t_seg_details* alloc_and_load_seg_details(int* max_chan_width, } } /* End for each segment type. */ - if (num_seg_details) { - *num_seg_details = cur_track; - } + VTR_ASSERT_DEBUG(seg_details.size() == cur_track); return seg_details; } @@ -560,17 +552,13 @@ t_seg_details* alloc_and_load_seg_details(int* max_chan_width, * (ie. channel segments) for each horizontal and vertical channel. */ void alloc_and_load_chan_details(const DeviceGrid& grid, - const t_chan_width* nodes_per_chan, - const int num_seg_details_x, - const int num_seg_details_y, - const t_seg_details* seg_details_x, - const t_seg_details* seg_details_y, + const t_chan_width& nodes_per_chan, + const std::vector& seg_details_x, + const std::vector& seg_details_y, t_chan_details& chan_details_x, t_chan_details& chan_details_y) { - chan_details_x = init_chan_details(grid, nodes_per_chan, - num_seg_details_x, seg_details_x, X_AXIS); - chan_details_y = init_chan_details(grid, nodes_per_chan, - num_seg_details_y, seg_details_y, Y_AXIS); + chan_details_x = init_chan_details(grid, nodes_per_chan, seg_details_x, X_AXIS); + chan_details_y = init_chan_details(grid, nodes_per_chan, seg_details_y, Y_AXIS); /* Adjust segment start/end based on obstructed channels, if any */ adjust_chan_details(grid, nodes_per_chan, @@ -578,14 +566,14 @@ void alloc_and_load_chan_details(const DeviceGrid& grid, } t_chan_details init_chan_details(const DeviceGrid& grid, - const t_chan_width* nodes_per_chan, - const int num_seg_details, - const t_seg_details* seg_details, - const enum e_parallel_axis seg_parallel_axis) { + const t_chan_width& nodes_per_chan, + const std::vector& seg_details, + enum e_parallel_axis seg_parallel_axis) { + const int num_seg_details = (int)seg_details.size(); if (seg_parallel_axis == X_AXIS) { - VTR_ASSERT(num_seg_details <= nodes_per_chan->x_max); + VTR_ASSERT(num_seg_details <= nodes_per_chan.x_max); } else if (seg_parallel_axis == Y_AXIS) { - VTR_ASSERT(num_seg_details <= nodes_per_chan->y_max); + VTR_ASSERT(num_seg_details <= nodes_per_chan.y_max); } t_chan_details chan_details({grid.width(), grid.height(), size_t(num_seg_details)}); @@ -611,11 +599,11 @@ t_chan_details init_chan_details(const DeviceGrid& grid, p_seg_details[i].set_seg_end(seg_end); if (seg_parallel_axis == X_AXIS) { - if (i >= nodes_per_chan->x_list[y]) { + if (i >= nodes_per_chan.x_list[y]) { p_seg_details[i].set_length(0); } } else if (seg_parallel_axis == Y_AXIS) { - if (i >= nodes_per_chan->y_list[x]) { + if (i >= nodes_per_chan.y_list[x]) { p_seg_details[i].set_length(0); } } @@ -626,7 +614,7 @@ t_chan_details init_chan_details(const DeviceGrid& grid, } void adjust_chan_details(const DeviceGrid& grid, - const t_chan_width* nodes_per_chan, + const t_chan_width& nodes_per_chan, t_chan_details& chan_details_x, t_chan_details& chan_details_y) { for (size_t y = 0; y <= grid.height() - 2; ++y) { //-2 for no perim channels @@ -657,18 +645,18 @@ void adjust_chan_details(const DeviceGrid& grid, void adjust_seg_details(const int x, const int y, const DeviceGrid& grid, - const t_chan_width* nodes_per_chan, + const t_chan_width& nodes_per_chan, t_chan_details& chan_details, const enum e_parallel_axis seg_parallel_axis) { int seg_index = (seg_parallel_axis == X_AXIS ? x : y); int max_chan_width = 0; if (seg_parallel_axis == X_AXIS) { - max_chan_width = nodes_per_chan->x_max; + max_chan_width = nodes_per_chan.x_max; } else if (seg_parallel_axis == Y_AXIS) { - max_chan_width = nodes_per_chan->y_max; + max_chan_width = nodes_per_chan.y_max; } else { VTR_ASSERT(seg_parallel_axis == BOTH_AXIS); - max_chan_width = nodes_per_chan->max; + max_chan_width = nodes_per_chan.max; } for (int track = 0; track < max_chan_width; ++track) { diff --git a/vpr/src/route/rr_graph2.h b/vpr/src/route/rr_graph2.h index 348e5633708..bdd2577d354 100644 --- a/vpr/src/route/rr_graph2.h +++ b/vpr/src/route/rr_graph2.h @@ -96,34 +96,33 @@ int find_average_rr_node_index(int device_width, int ptc, const t_rr_node_indices& L_rr_node_indices); -t_seg_details* alloc_and_load_seg_details(int* max_chan_width, - const int max_len, - const std::vector& segment_inf, - const bool use_full_seg_groups, - const enum e_directionality directionality, - int* num_seg_details = nullptr); +std::vector alloc_and_load_seg_details(int* max_chan_width, + int max_len, + const std::vector& segment_inf, + bool use_full_seg_groups, + enum e_directionality directionality); void alloc_and_load_chan_details(const DeviceGrid& grid, - const t_chan_width* nodes_per_chan, - const int num_seg_details_x, - const int num_seg_details_y, - const t_seg_details* seg_details_x, - const t_seg_details* seg_details_y, + const t_chan_width& nodes_per_chan, + const std::vector& seg_details_x, + const std::vector& seg_details_y, t_chan_details& chan_details_x, t_chan_details& chan_details_y); + t_chan_details init_chan_details(const DeviceGrid& grid, - const t_chan_width* nodes_per_chan, - const int num_seg_details, - const t_seg_details* seg_details, - const enum e_parallel_axis seg_details_type); + const t_chan_width& nodes_per_chan, + const std::vector& seg_details, + enum e_parallel_axis seg_details_type); + void adjust_chan_details(const DeviceGrid& grid, - const t_chan_width* nodes_per_chan, + const t_chan_width& nodes_per_chan, t_chan_details& chan_details_x, t_chan_details& chan_details_y); + void adjust_seg_details(const int x, const int y, const DeviceGrid& grid, - const t_chan_width* nodes_per_chan, + const t_chan_width& nodes_per_chan, t_chan_details& chan_details, const enum e_parallel_axis seg_details_type); From 91aed469fa813b08ac7e41e8a1cdf0b7a7cbc034 Mon Sep 17 00:00:00 2001 From: soheilshahrouz Date: Mon, 3 Feb 2025 15:50:04 -0500 Subject: [PATCH 19/23] replace t_clb_to_clb_directs* with std::vector& --- vpr/src/route/rr_graph.cpp | 59 +++++++++++++------------------------- 1 file changed, 20 insertions(+), 39 deletions(-) diff --git a/vpr/src/route/rr_graph.cpp b/vpr/src/route/rr_graph.cpp index 36fe82d84c8..1b97751b4b4 100644 --- a/vpr/src/route/rr_graph.cpp +++ b/vpr/src/route/rr_graph.cpp @@ -155,7 +155,7 @@ static void build_bidir_rr_opins(RRGraphBuilder& rr_graph_builder, const t_chan_details& chan_details_y, const DeviceGrid& grid, const std::vector& directs, - const t_clb_to_clb_directs* clb_to_clb_directs, + const std::vector& clb_to_clb_directs, const int num_seg_types); static void build_unidir_rr_opins(RRGraphBuilder& rr_graph_builder, @@ -175,7 +175,7 @@ static void build_unidir_rr_opins(RRGraphBuilder& rr_graph_builder, bool* Fc_clipped, const t_unified_to_parallel_seg_index& seg_index_map, const std::vector& directs, - const t_clb_to_clb_directs* clb_to_clb_directs, + const std::vector& clb_to_clb_directs, const int num_seg_types, int& edge_count); @@ -189,7 +189,7 @@ static int get_opin_direct_connections(RRGraphBuilder& rr_graph_builder, RRNodeId from_rr_node, t_rr_edge_info_set& rr_edges_to_create, const std::vector& directs, - const t_clb_to_clb_directs* clb_to_clb_directs); + const std::vector& clb_to_clb_directs); static std::function alloc_and_load_rr_graph(RRGraphBuilder& rr_graph_builder, t_rr_graph_storage& L_rr_node, @@ -218,7 +218,7 @@ static std::function alloc_and_load_rr_graph(RRGraphBuilder const enum e_directionality directionality, bool* Fc_clipped, const std::vector& directs, - const t_clb_to_clb_directs* clb_to_clb_directs, + const std::vector& clb_to_clb_directs, bool is_global_graph, const enum e_clock_modeling clock_modeling, bool is_flat, @@ -596,7 +596,8 @@ static void rr_graph_externals(const std::vector& segment_inf, int wire_to_rr_ipin_switch, enum e_base_cost_type base_cost_type); -static t_clb_to_clb_directs* alloc_and_load_clb_to_clb_directs(const std::vector& directs, const int delayless_switch); +static std::vector alloc_and_load_clb_to_clb_directs(const std::vector& directs, + int delayless_switch); static std::vector alloc_and_load_global_route_seg_details(int global_route_switch); @@ -1106,10 +1107,7 @@ static void build_rr_graph(const t_graph_type graph_type, auto& device_ctx = g_vpr_ctx.mutable_device(); const auto& rr_graph = device_ctx.rr_graph; - t_clb_to_clb_directs* clb_to_clb_directs = nullptr; - if (!directs.empty()) { - clb_to_clb_directs = alloc_and_load_clb_to_clb_directs(directs, delayless_switch); - } + std::vector clb_to_clb_directs = alloc_and_load_clb_to_clb_directs(directs, delayless_switch); /* START SEG_DETAILS */ size_t num_segments = segment_inf.size(); @@ -1564,11 +1562,6 @@ static void build_rr_graph(const t_graph_type graph_type, track_to_pin_lookup_x.clear(); track_to_pin_lookup_y.clear(); - - if (clb_to_clb_directs != nullptr) { - delete[] clb_to_clb_directs; - } - // We are done with building the RR Graph. Thus, we can clear the storages only used // to build the RR Graph device_ctx.rr_graph_builder.clear_temp_storage(); @@ -2150,11 +2143,12 @@ static std::function alloc_and_load_rr_graph(RRGraphBuilder const enum e_directionality directionality, bool* Fc_clipped, const std::vector& directs, - const t_clb_to_clb_directs* clb_to_clb_directs, + const std::vector& clb_to_clb_directs, bool is_global_graph, const enum e_clock_modeling clock_modeling, bool /*is_flat*/, const int route_verbosity) { + VTR_ASSERT(directs.size() == clb_to_clb_directs.size()); //We take special care when creating RR graph edges (there are typically many more //edges than nodes in an RR graph). // @@ -2734,7 +2728,7 @@ static void build_bidir_rr_opins(RRGraphBuilder& rr_graph_builder, const t_chan_details& chan_details_y, const DeviceGrid& grid, const std::vector& directs, - const t_clb_to_clb_directs* clb_to_clb_directs, + const std::vector& clb_to_clb_directs, const int num_seg_types) { //Don't connect pins which are not adjacent to channels around the perimeter if ((i == 0 && side != RIGHT) @@ -4234,7 +4228,7 @@ static void build_unidir_rr_opins(RRGraphBuilder& rr_graph_builder, bool* Fc_clipped, const t_unified_to_parallel_seg_index& seg_index_map, const std::vector& directs, - const t_clb_to_clb_directs* clb_to_clb_directs, + const std::vector& clb_to_clb_directs, const int num_seg_types, int& rr_edge_count) { /* @@ -4343,15 +4337,12 @@ static void build_unidir_rr_opins(RRGraphBuilder& rr_graph_builder, * This data structure supplements the the info in the "directs" data structure * TODO: The function that does this parsing in placement is poorly done because it lacks generality on heterogeniety, should replace with this one */ -static t_clb_to_clb_directs* alloc_and_load_clb_to_clb_directs(const std::vector& directs, int delayless_switch) { - t_clb_to_clb_directs* clb_to_clb_directs; - t_physical_tile_type_ptr physical_tile = nullptr; - t_physical_tile_port tile_port; - - auto& device_ctx = g_vpr_ctx.device(); +static std::vector alloc_and_load_clb_to_clb_directs(const std::vector& directs, + int delayless_switch) { + const auto& device_ctx = g_vpr_ctx.device(); - const int num_directs = directs.size(); - clb_to_clb_directs = new t_clb_to_clb_directs[num_directs]; + const int num_directs = (int)directs.size(); + std::vector clb_to_clb_directs(num_directs); for (int i = 0; i < num_directs; i++) { //clb_to_clb_directs[i].from_clb_type; @@ -4367,12 +4358,7 @@ static t_clb_to_clb_directs* alloc_and_load_clb_to_clb_directs(const std::vector auto [start_pin_index, end_pin_index, tile_name, port_name] = parse_direct_pin_name(directs[i].from_pin, directs[i].line); // Figure out which type, port, and pin is used - for (const t_physical_tile_type& type : device_ctx.physical_tile_types) { - if (tile_name == type.name) { - physical_tile = &type; - break; - } - } + t_physical_tile_type_ptr physical_tile = find_tile_type_by_name(tile_name, device_ctx.physical_tile_types); if (physical_tile == nullptr) { VPR_THROW(VPR_ERROR_ARCH, "Unable to find block %s.\n", tile_name.c_str()); @@ -4380,7 +4366,7 @@ static t_clb_to_clb_directs* alloc_and_load_clb_to_clb_directs(const std::vector clb_to_clb_directs[i].from_clb_type = physical_tile; - tile_port = find_tile_port_by_name(physical_tile, port_name); + t_physical_tile_port tile_port = find_tile_port_by_name(physical_tile, port_name); if (start_pin_index == OPEN) { VTR_ASSERT(start_pin_index == end_pin_index); @@ -4456,7 +4442,7 @@ static int get_opin_direct_connections(RRGraphBuilder& rr_graph_builder, RRNodeId from_rr_node, t_rr_edge_info_set& rr_edges_to_create, const std::vector& directs, - const t_clb_to_clb_directs* clb_to_clb_directs) { + const std::vector& clb_to_clb_directs) { auto& device_ctx = g_vpr_ctx.device(); t_physical_tile_type_ptr curr_type = device_ctx.grid.get_physical_type({x, y, layer}); @@ -4585,7 +4571,6 @@ static std::vector alloc_and_load_perturb_opins(const t_physical_tile_type const std::vector& segment_inf) { int i, Fc_max, iclass, num_wire_types; int num, max_primes, factor, num_factors; - int* prime_factors; float step_size = 0; float n = 0; float threshold = 0.07; @@ -4629,10 +4614,7 @@ static std::vector alloc_and_load_perturb_opins(const t_physical_tile_type max_primes = (int)floor(log((float)num_wire_types) / log(2.0)); max_primes = std::max(max_primes, 1); //Minimum of 1 to ensure we allocate space for at least one prime_factor - prime_factors = new int[max_primes]; - for (i = 0; i < max_primes; i++) { - prime_factors[i] = 0; - } + std::vectorprime_factors(max_primes, 0); /* Find the prime factors of num_wire_types */ num = num_wire_types; @@ -4671,7 +4653,6 @@ static std::vector alloc_and_load_perturb_opins(const t_physical_tile_type perturb_opins[0] = false; } } - delete[] prime_factors; return perturb_opins; } From 190f8b09a800b0b3dabccfaa8471cd0043517f60 Mon Sep 17 00:00:00 2001 From: soheilshahrouz Date: Mon, 3 Feb 2025 17:07:59 -0500 Subject: [PATCH 20/23] resize rr_switch_offset_inf_ and rr_switch_inf_ together --- libs/librrgraph/src/base/rr_graph_builder.h | 3 --- vpr/src/route/rr_graph.cpp | 4 +--- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/libs/librrgraph/src/base/rr_graph_builder.h b/libs/librrgraph/src/base/rr_graph_builder.h index 0ef13c9ad37..31d42a9dee5 100644 --- a/libs/librrgraph/src/base/rr_graph_builder.h +++ b/libs/librrgraph/src/base/rr_graph_builder.h @@ -351,9 +351,6 @@ class RRGraphBuilder { /** @brief This function resize rr_switch to accomidate size RR Switch. */ inline void resize_switches(size_t size) { rr_switch_inf_.resize(size); - } - - inline void resize_switch_offset_info(size_t size) { rr_switch_offset_inf_.resize(size); } diff --git a/vpr/src/route/rr_graph.cpp b/vpr/src/route/rr_graph.cpp index 1b97751b4b4..69ef1ecd64b 100644 --- a/vpr/src/route/rr_graph.cpp +++ b/vpr/src/route/rr_graph.cpp @@ -1775,9 +1775,7 @@ static void alloc_rr_switch_inf(RRGraphBuilder& rr_graph_builder, for (const auto& map_it : arch_sw_map) { all_sw_inf[map_it.first] = map_it.second; } - size_t num_rr_switches = rr_graph_builder.count_rr_switches( - all_sw_inf, - arch_switch_fanins); + size_t num_rr_switches = rr_graph_builder.count_rr_switches(all_sw_inf, arch_switch_fanins); rr_graph_builder.resize_switches(num_rr_switches); } From 00739ed4f1cb9d0559d77efd0a4eda72715c8ffc Mon Sep 17 00:00:00 2001 From: soheilshahrouz Date: Wed, 5 Feb 2025 11:14:45 -0500 Subject: [PATCH 21/23] rename t_rr_switch_offset_inf to t_rr_switch_override_inf --- libs/libarchfpga/src/physical_types.h | 8 ++++---- libs/librrgraph/src/base/rr_graph_builder.h | 8 ++++---- libs/librrgraph/src/base/rr_graph_view.cpp | 2 +- libs/librrgraph/src/base/rr_graph_view.h | 4 ++-- libs/librrgraph/src/io/rr_graph_reader.cpp | 4 ++-- libs/librrgraph/src/io/rr_graph_uxsdcxx_serializer.h | 8 ++++---- vpr/src/route/rr_graph.cpp | 2 +- vpr/src/route/rr_graph2.cpp | 3 +-- 8 files changed, 19 insertions(+), 20 deletions(-) diff --git a/libs/libarchfpga/src/physical_types.h b/libs/libarchfpga/src/physical_types.h index 53138c35c95..aeb562ceec8 100644 --- a/libs/libarchfpga/src/physical_types.h +++ b/libs/libarchfpga/src/physical_types.h @@ -1872,18 +1872,18 @@ struct t_rr_switch_inf { SwitchType type_ = SwitchType::INVALID; }; -struct t_rr_switch_offset_inf { +struct t_rr_switch_override_inf { // float R = 0.f; // float Cin = 0.; // float Cout = 0.; // float Cinternal = 0.; float Tdel = 0.; - t_rr_switch_offset_inf() = default; - t_rr_switch_offset_inf(const t_rr_switch_inf& switch_inf) + t_rr_switch_override_inf() = default; + t_rr_switch_override_inf(const t_rr_switch_inf& switch_inf) : Tdel(switch_inf.Tdel) {} - auto operator<=>(const t_rr_switch_offset_inf&) const = default; + auto operator<=>(const t_rr_switch_override_inf&) const = default; }; /** diff --git a/libs/librrgraph/src/base/rr_graph_builder.h b/libs/librrgraph/src/base/rr_graph_builder.h index 31d42a9dee5..dcb61e6922a 100644 --- a/libs/librrgraph/src/base/rr_graph_builder.h +++ b/libs/librrgraph/src/base/rr_graph_builder.h @@ -104,7 +104,7 @@ class RRGraphBuilder { RRSwitchId switch_id = RRSwitchId(rr_switch_inf_.size()); rr_switch_inf_.push_back(switch_info); - t_rr_switch_offset_inf switch_offset_info(switch_info); + t_rr_switch_override_inf switch_offset_info(switch_info); rr_switch_offset_inf_.push_back(switch_offset_info); VTR_ASSERT_DEBUG(rr_switch_inf_.size() == rr_switch_offset_inf_.size()); @@ -122,7 +122,7 @@ class RRGraphBuilder { return rr_switch_inf_; } - inline RRSwitchOffsetInfoId add_rr_switch_offset_info(const t_rr_switch_offset_inf& switch_offset_info) { + inline RRSwitchOffsetInfoId add_rr_switch_offset_info(const t_rr_switch_override_inf& switch_offset_info) { VTR_ASSERT_DEBUG(rr_switch_inf_.size() <= rr_switch_offset_inf_.size()); // Allocate an ID RRSwitchOffsetInfoId switch_offset_info_id = RRSwitchOffsetInfoId(rr_switch_offset_inf_.size()); @@ -134,7 +134,7 @@ class RRGraphBuilder { node_storage_.set_edge_offset_id(edge_id, offset_id); } - inline vtr::vector& rr_switch_offset_inf() { + inline vtr::vector& rr_switch_offset_inf() { return rr_switch_offset_inf_; } @@ -420,7 +420,7 @@ class RRGraphBuilder { /* Detailed information about the switches, which are used in the RRGraph */ vtr::vector rr_switch_inf_; - vtr::vector rr_switch_offset_inf_; + vtr::vector rr_switch_offset_inf_; /** @warning The Metadata should stay as an independent data structure from the rest of the internal data, * e.g., node_lookup! */ diff --git a/libs/librrgraph/src/base/rr_graph_view.cpp b/libs/librrgraph/src/base/rr_graph_view.cpp index 9d07fb51d0c..fd52db453c0 100644 --- a/libs/librrgraph/src/base/rr_graph_view.cpp +++ b/libs/librrgraph/src/base/rr_graph_view.cpp @@ -10,7 +10,7 @@ RRGraphView::RRGraphView(const t_rr_graph_storage& node_storage, const std::vector& rr_rc_data, const vtr::vector& rr_segments, const vtr::vector& rr_switch_inf, - const vtr::vector& rr_switch_offset_inf) + const vtr::vector& rr_switch_offset_inf) : node_storage_(node_storage) , node_lookup_(node_lookup) , rr_node_metadata_(rr_node_metadata) diff --git a/libs/librrgraph/src/base/rr_graph_view.h b/libs/librrgraph/src/base/rr_graph_view.h index 6ac5f959b91..ba2cd1af578 100644 --- a/libs/librrgraph/src/base/rr_graph_view.h +++ b/libs/librrgraph/src/base/rr_graph_view.h @@ -74,7 +74,7 @@ class RRGraphView { const std::vector& rr_rc_data, const vtr::vector& rr_segments, const vtr::vector& rr_switch_inf, - const vtr::vector& rr_switch_offset_inf); + const vtr::vector& rr_switch_offset_inf); /* Disable copy constructors and copy assignment operator * This is to avoid accidental copy because it could be an expensive operation considering that the @@ -668,7 +668,7 @@ class RRGraphView { /// switch info for rr edges const vtr::vector& rr_switch_inf_; /// switch offset info for edges - const vtr::vector& rr_switch_offset_inf_; + const vtr::vector& rr_switch_offset_inf_; }; #endif diff --git a/libs/librrgraph/src/io/rr_graph_reader.cpp b/libs/librrgraph/src/io/rr_graph_reader.cpp index 3c2d2a6ebd0..10c6ad2756c 100644 --- a/libs/librrgraph/src/io/rr_graph_reader.cpp +++ b/libs/librrgraph/src/io/rr_graph_reader.cpp @@ -126,7 +126,7 @@ void load_rr_edge_attribute_offset_file(RRGraphBuilder& rr_graph_builder, VTR_LOG_ERROR("Failed to open RR edge offset file: %s ", rr_edge_attribute_offset_filename.data()); } - std::map unique_edge_offsets; + std::map unique_edge_offsets; std::string line; bool first_line = true; while (std::getline(file, line)) { @@ -139,7 +139,7 @@ void load_rr_edge_attribute_offset_file(RRGraphBuilder& rr_graph_builder, std::istringstream iss(line); int edge_id; - t_rr_switch_offset_inf rr_switch_detailed_inf; + t_rr_switch_override_inf rr_switch_detailed_inf; if (!(iss >> edge_id >> rr_switch_detailed_inf.Tdel)) { throw std::runtime_error("Invalid line format: " + line); diff --git a/libs/librrgraph/src/io/rr_graph_uxsdcxx_serializer.h b/libs/librrgraph/src/io/rr_graph_uxsdcxx_serializer.h index d8ce5737503..d8622ba1af2 100644 --- a/libs/librrgraph/src/io/rr_graph_uxsdcxx_serializer.h +++ b/libs/librrgraph/src/io/rr_graph_uxsdcxx_serializer.h @@ -285,7 +285,7 @@ class RrGraphSerializer final : public uxsd::RrGraphBase { RRGraphBuilder* rr_graph_builder, RRGraphView* rr_graph, vtr::vector* rr_switch_inf, - vtr::vector* rr_switch_offset_inf, + vtr::vector* rr_switch_offset_inf, vtr::vector* rr_indexed_data, std::vector* rr_rc_data, const std::vector& arch_switch_inf, @@ -630,8 +630,8 @@ class RrGraphSerializer final : public uxsd::RrGraphBase { rr_switch_offset_inf_->reserve(rr_switch_inf_->size()); std::ranges::transform(*rr_switch_inf_, std::back_inserter(*rr_switch_offset_inf_), - [](const t_rr_switch_inf& rr_sw) noexcept -> t_rr_switch_offset_inf { - return t_rr_switch_offset_inf{rr_sw}; + [](const t_rr_switch_inf& rr_sw) noexcept -> t_rr_switch_override_inf { + return t_rr_switch_override_inf{rr_sw}; }); } @@ -2169,7 +2169,7 @@ class RrGraphSerializer final : public uxsd::RrGraphBase { RRGraphBuilder* rr_graph_builder_; RRGraphView* rr_graph_; vtr::vector* rr_switch_inf_; - vtr::vector* rr_switch_offset_inf_; + vtr::vector* rr_switch_offset_inf_; vtr::vector* rr_indexed_data_; t_rr_node_indices* rr_node_indices_; std::string* read_rr_graph_filename_; diff --git a/vpr/src/route/rr_graph.cpp b/vpr/src/route/rr_graph.cpp index 69ef1ecd64b..7c701935808 100644 --- a/vpr/src/route/rr_graph.cpp +++ b/vpr/src/route/rr_graph.cpp @@ -1865,7 +1865,7 @@ void load_rr_switch_from_arch_switch(RRGraphBuilder& rr_graph_builder, const float R_minW_pmos) { const t_arch_switch_inf& arch_switch = arch_sw_inf.at(arch_switch_idx); t_rr_switch_inf& rr_switch_to_be_updated = rr_graph_builder.rr_switch()[RRSwitchId(rr_switch_idx)]; - t_rr_switch_offset_inf& rr_switch_offset_to_be_updated = rr_graph_builder.rr_switch_offset_inf()[RRSwitchOffsetInfoId (rr_switch_idx)]; + t_rr_switch_override_inf& rr_switch_offset_to_be_updated = rr_graph_builder.rr_switch_offset_inf()[RRSwitchOffsetInfoId (rr_switch_idx)]; /* copy over the arch switch to rr_switch_inf[rr_switch_idx], but with the changed Tdel value */ rr_switch_to_be_updated.set_type(arch_switch.type()); diff --git a/vpr/src/route/rr_graph2.cpp b/vpr/src/route/rr_graph2.cpp index 48db5b3d639..bb876a72c09 100644 --- a/vpr/src/route/rr_graph2.cpp +++ b/vpr/src/route/rr_graph2.cpp @@ -400,7 +400,6 @@ std::vector alloc_and_load_seg_details(int* max_chan_width, * (3) stagger the connection and switch boxes on different long lines, * * as they will not be staggered by different segment start points. */ - int cur_track; int fac; std::vector seg_details; @@ -431,7 +430,7 @@ std::vector alloc_and_load_seg_details(int* max_chan_width, seg_details.resize(*max_chan_width); /* Setup the seg_details data */ - cur_track = 0; + size_t cur_track = 0; for (size_t i = 0; i < segment_inf.size(); ++i) { int first_track = cur_track; From 3cc543f7423de52167227a3c66e0956ef476681d Mon Sep 17 00:00:00 2001 From: soheilshahrouz Date: Wed, 5 Feb 2025 11:57:09 -0500 Subject: [PATCH 22/23] add edge attribute methods --- libs/libarchfpga/src/physical_types.h | 14 +++--- libs/librrgraph/src/base/rr_graph_builder.cpp | 2 +- libs/librrgraph/src/base/rr_graph_builder.h | 22 +++++----- libs/librrgraph/src/base/rr_graph_view.h | 44 ++++++++++++++++++- libs/librrgraph/src/io/rr_graph_reader.cpp | 2 +- 5 files changed, 64 insertions(+), 20 deletions(-) diff --git a/libs/libarchfpga/src/physical_types.h b/libs/libarchfpga/src/physical_types.h index aeb562ceec8..40d116ba88a 100644 --- a/libs/libarchfpga/src/physical_types.h +++ b/libs/libarchfpga/src/physical_types.h @@ -1873,15 +1873,19 @@ struct t_rr_switch_inf { }; struct t_rr_switch_override_inf { -// float R = 0.f; -// float Cin = 0.; -// float Cout = 0.; -// float Cinternal = 0.; + float R = 0.f; + float Cin = 0.; + float Cout = 0.; + float Cinternal = 0.; float Tdel = 0.; t_rr_switch_override_inf() = default; t_rr_switch_override_inf(const t_rr_switch_inf& switch_inf) - : Tdel(switch_inf.Tdel) {} + : R(switch_inf.R) + , Cin(switch_inf.Cin) + , Cout(switch_inf.Cout) + , Cinternal(switch_inf.Cinternal) + , Tdel(switch_inf.Tdel) {} auto operator<=>(const t_rr_switch_override_inf&) const = default; }; diff --git a/libs/librrgraph/src/base/rr_graph_builder.cpp b/libs/librrgraph/src/base/rr_graph_builder.cpp index 3562e6db397..55488cac7de 100644 --- a/libs/librrgraph/src/base/rr_graph_builder.cpp +++ b/libs/librrgraph/src/base/rr_graph_builder.cpp @@ -79,7 +79,7 @@ void RRGraphBuilder::clear() { rr_edge_metadata_.clear(); rr_segments_.clear(); rr_switch_inf_.clear(); - rr_switch_offset_inf_.clear(); + rr_switch_override_inf_.clear(); } void RRGraphBuilder::reorder_nodes(e_rr_node_reorder_algorithm reorder_rr_graph_nodes_algorithm, diff --git a/libs/librrgraph/src/base/rr_graph_builder.h b/libs/librrgraph/src/base/rr_graph_builder.h index dcb61e6922a..7363274957f 100644 --- a/libs/librrgraph/src/base/rr_graph_builder.h +++ b/libs/librrgraph/src/base/rr_graph_builder.h @@ -104,10 +104,10 @@ class RRGraphBuilder { RRSwitchId switch_id = RRSwitchId(rr_switch_inf_.size()); rr_switch_inf_.push_back(switch_info); - t_rr_switch_override_inf switch_offset_info(switch_info); - rr_switch_offset_inf_.push_back(switch_offset_info); + t_rr_switch_override_inf switch_override_info(switch_info); + rr_switch_override_inf_.push_back(switch_override_info); - VTR_ASSERT_DEBUG(rr_switch_inf_.size() == rr_switch_offset_inf_.size()); + VTR_ASSERT_DEBUG(rr_switch_inf_.size() == rr_switch_override_inf_.size()); return switch_id; } @@ -122,11 +122,11 @@ class RRGraphBuilder { return rr_switch_inf_; } - inline RRSwitchOffsetInfoId add_rr_switch_offset_info(const t_rr_switch_override_inf& switch_offset_info) { - VTR_ASSERT_DEBUG(rr_switch_inf_.size() <= rr_switch_offset_inf_.size()); + inline RRSwitchOffsetInfoId add_rr_switch_override_info(const t_rr_switch_override_inf& switch_override_info) { + VTR_ASSERT_DEBUG(rr_switch_inf_.size() <= rr_switch_override_inf_.size()); // Allocate an ID - RRSwitchOffsetInfoId switch_offset_info_id = RRSwitchOffsetInfoId(rr_switch_offset_inf_.size()); - rr_switch_offset_inf_.push_back(switch_offset_info); + RRSwitchOffsetInfoId switch_offset_info_id = RRSwitchOffsetInfoId(rr_switch_override_inf_.size()); + rr_switch_override_inf_.push_back(switch_override_info); return switch_offset_info_id; } @@ -135,7 +135,7 @@ class RRGraphBuilder { } inline vtr::vector& rr_switch_offset_inf() { - return rr_switch_offset_inf_; + return rr_switch_override_inf_; } /** @brief Set the type of a node with a given valid id */ @@ -336,7 +336,7 @@ class RRGraphBuilder { this->rr_switch_inf_.reserve(num_switches); } inline void reserve_switch_offse_info(size_t num_offsets) { - this->rr_switch_offset_inf_.reserve(num_offsets); + this->rr_switch_override_inf_.reserve(num_offsets); } /** @brief This function resize node storage to accomidate size RR nodes. */ inline void resize_nodes(size_t size) { @@ -351,7 +351,7 @@ class RRGraphBuilder { /** @brief This function resize rr_switch to accomidate size RR Switch. */ inline void resize_switches(size_t size) { rr_switch_inf_.resize(size); - rr_switch_offset_inf_.resize(size); + rr_switch_override_inf_.resize(size); } /** @brief Validate that edge data is partitioned correctly @@ -420,7 +420,7 @@ class RRGraphBuilder { /* Detailed information about the switches, which are used in the RRGraph */ vtr::vector rr_switch_inf_; - vtr::vector rr_switch_offset_inf_; + vtr::vector rr_switch_override_inf_; /** @warning The Metadata should stay as an independent data structure from the rest of the internal data, * e.g., node_lookup! */ diff --git a/libs/librrgraph/src/base/rr_graph_view.h b/libs/librrgraph/src/base/rr_graph_view.h index ba2cd1af578..7087cbfcbec 100644 --- a/libs/librrgraph/src/base/rr_graph_view.h +++ b/libs/librrgraph/src/base/rr_graph_view.h @@ -424,8 +424,8 @@ class RRGraphView { } inline float edge_delay(RREdgeId edge_id) const { - RRSwitchOffsetInfoId switch_offset_inf_id = node_storage_.edge_switch_offset_inf(edge_id); - return rr_switch_offset_inf_[switch_offset_inf_id].Tdel; + RRSwitchOffsetInfoId switch_override_inf_id = node_storage_.edge_switch_offset_inf(edge_id); + return rr_switch_offset_inf_[switch_override_inf_id].Tdel; } inline float edge_delay(RRNodeId id, t_edge_size iedge) const { @@ -433,6 +433,46 @@ class RRGraphView { return edge_delay(edge_id); } + inline float edge_R(RREdgeId edge_id) const { + RRSwitchOffsetInfoId switch_override_inf_id = node_storage_.edge_switch_offset_inf(edge_id); + return rr_switch_offset_inf_[switch_override_inf_id].R; + } + + inline float edge_R(RRNodeId id, t_edge_size iedge) const { + RREdgeId edge_id = node_storage_.edge_id(id, iedge); + return edge_R(edge_id); + } + + inline float edge_Cin(RREdgeId edge_id) const { + RRSwitchOffsetInfoId switch_override_inf_id = node_storage_.edge_switch_offset_inf(edge_id); + return rr_switch_offset_inf_[switch_override_inf_id].Cin; + } + + inline float edge_Cin(RRNodeId id, t_edge_size iedge) const { + RREdgeId edge_id = node_storage_.edge_id(id, iedge); + return edge_Cin(edge_id); + } + + inline float edge_Cout(RREdgeId edge_id) const { + RRSwitchOffsetInfoId switch_override_inf_id = node_storage_.edge_switch_offset_inf(edge_id); + return rr_switch_offset_inf_[switch_override_inf_id].Cout; + } + + inline float edge_Cout(RRNodeId id, t_edge_size iedge) const { + RREdgeId edge_id = node_storage_.edge_id(id, iedge); + return edge_Cout(edge_id); + } + + inline float edge_Cint(RREdgeId edge_id) const { + RRSwitchOffsetInfoId switch_override_inf_id = node_storage_.edge_switch_offset_inf(edge_id); + return rr_switch_offset_inf_[switch_override_inf_id].Cinternal; + } + + inline float edge_Cint(RRNodeId id, t_edge_size iedge) const { + RREdgeId edge_id = node_storage_.edge_id(id, iedge); + return edge_Cint(edge_id); + } + /** @brief Return the source node for the specified edge. */ inline RRNodeId edge_src_node(const RREdgeId edge_id) const { diff --git a/libs/librrgraph/src/io/rr_graph_reader.cpp b/libs/librrgraph/src/io/rr_graph_reader.cpp index 10c6ad2756c..7c41f599e82 100644 --- a/libs/librrgraph/src/io/rr_graph_reader.cpp +++ b/libs/librrgraph/src/io/rr_graph_reader.cpp @@ -160,7 +160,7 @@ void load_rr_edge_attribute_offset_file(RRGraphBuilder& rr_graph_builder, RRSwitchOffsetInfoId rr_switch_offset_id; if (it == unique_edge_offsets.end()) { // if the detailed info is seen for the first time, add it to RR graph and record it in `unique_edge_offsets` - rr_switch_offset_id = rr_graph_builder.add_rr_switch_offset_info(rr_switch_detailed_inf); + rr_switch_offset_id = rr_graph_builder.add_rr_switch_override_info(rr_switch_detailed_inf); unique_edge_offsets.insert({rr_switch_detailed_inf, rr_switch_offset_id}); } else { // the detailed info has already been added to the RR graph From 5bc080e4db4c7660fd79b1c3ca1687626e8f61f1 Mon Sep 17 00:00:00 2001 From: soheilshahrouz Date: Wed, 5 Feb 2025 17:12:20 -0500 Subject: [PATCH 23/23] replace accesses to member vars of t_rr_switch with RRGraphView API calls --- libs/libarchfpga/src/physical_types.h | 11 +++ libs/librrgraph/src/base/rr_graph_storage.cpp | 15 +++ libs/librrgraph/src/base/rr_graph_storage.h | 3 + libs/librrgraph/src/base/rr_graph_view.h | 12 +++ .../utils/alloc_and_load_rr_indexed_data.cpp | 4 +- vpr/src/base/old_traceback.cpp | 25 ++--- vpr/src/base/old_traceback.h | 8 +- vpr/src/base/read_route.cpp | 19 ++-- vpr/src/route/check_route.cpp | 16 +-- vpr/src/route/connection_router.cpp | 9 +- vpr/src/route/route_tree.cpp | 98 +++++++++---------- vpr/src/route/route_tree.h | 6 +- .../route/router_lookahead_extended_map.cpp | 6 +- vpr/src/route/router_lookahead_map_utils.cpp | 47 ++++----- vpr/src/route/router_lookahead_map_utils.h | 6 +- vpr/src/route/rr_graph.cpp | 4 +- vpr/src/route/rr_graph_area.cpp | 7 +- vpr/src/route/rr_graph_timing_params.cpp | 38 ++----- vpr/src/util/vpr_utils.cpp | 7 +- 19 files changed, 170 insertions(+), 171 deletions(-) diff --git a/libs/libarchfpga/src/physical_types.h b/libs/libarchfpga/src/physical_types.h index 40d116ba88a..6fd2f669a20 100644 --- a/libs/libarchfpga/src/physical_types.h +++ b/libs/libarchfpga/src/physical_types.h @@ -1887,6 +1887,17 @@ struct t_rr_switch_override_inf { , Cinternal(switch_inf.Cinternal) , Tdel(switch_inf.Tdel) {} + t_rr_switch_override_inf& operator=(const t_rr_switch_override_inf& other) { + if (this != &other) { // Self-assignment check + R = other.R; + Cin = other.Cin; + Cout = other.Cout; + Cinternal = other.Cinternal; + Tdel = other.Tdel; + } + return *this; + } + auto operator<=>(const t_rr_switch_override_inf&) const = default; }; diff --git a/libs/librrgraph/src/base/rr_graph_storage.cpp b/libs/librrgraph/src/base/rr_graph_storage.cpp index a1bf6aafb35..c7182d9a67d 100644 --- a/libs/librrgraph/src/base/rr_graph_storage.cpp +++ b/libs/librrgraph/src/base/rr_graph_storage.cpp @@ -589,6 +589,21 @@ bool t_rr_graph_storage::edge_is_configurable(RRNodeId id, t_edge_size iedge, co return rr_switches[RRSwitchId(iswitch)].configurable(); } +bool t_rr_graph_storage::edge_is_configurable(RREdgeId id, const vtr::vector& rr_switches) const { + auto iswitch = edge_switch(id); + return rr_switches[RRSwitchId(iswitch)].configurable(); +} + +bool t_rr_graph_storage::edge_is_buffered(RRNodeId id, t_edge_size iedge, const vtr::vector& rr_switches) const { + auto iswitch = edge_switch(id, iedge); + return rr_switches[RRSwitchId(iswitch)].buffered(); +} + +bool t_rr_graph_storage::edge_is_buffered(RREdgeId id, const vtr::vector& rr_switches) const { + auto iswitch = edge_switch(id); + return rr_switches[RRSwitchId(iswitch)].buffered(); +} + bool t_rr_graph_storage::validate_node(RRNodeId node_id, const vtr::vector& rr_switches) const { t_edge_size iedge = 0; for (auto edge : edges(node_id)) { diff --git a/libs/librrgraph/src/base/rr_graph_storage.h b/libs/librrgraph/src/base/rr_graph_storage.h index eee6f8e3845..1b8c5aa35ff 100644 --- a/libs/librrgraph/src/base/rr_graph_storage.h +++ b/libs/librrgraph/src/base/rr_graph_storage.h @@ -357,6 +357,9 @@ class t_rr_graph_storage { return size_t(last_edge(id)) - size_t(first_edge(id)); } bool edge_is_configurable(RRNodeId id, t_edge_size iedge, const vtr::vector& rr_switches) const; + bool edge_is_configurable(RREdgeId id, const vtr::vector& rr_switches) const; + bool edge_is_buffered(RRNodeId id, t_edge_size iedge, const vtr::vector& rr_switches) const; + bool edge_is_buffered(RREdgeId id, const vtr::vector& rr_switches) const; t_edge_size num_configurable_edges(RRNodeId node, const vtr::vector& rr_switches) const; t_edge_size num_non_configurable_edges(RRNodeId node, const vtr::vector& rr_switches) const; diff --git a/libs/librrgraph/src/base/rr_graph_view.h b/libs/librrgraph/src/base/rr_graph_view.h index 7087cbfcbec..0b082c74608 100644 --- a/libs/librrgraph/src/base/rr_graph_view.h +++ b/libs/librrgraph/src/base/rr_graph_view.h @@ -499,6 +499,18 @@ class RRGraphView { return node_storage_.edge_is_configurable(id, iedge, rr_switch_inf_); } + inline bool edge_is_configurable(RREdgeId id) const { + return node_storage_.edge_is_configurable(id, rr_switch_inf_); + } + + inline bool edge_is_buffered(RRNodeId id, t_edge_size iedge) const { + return node_storage_.edge_is_buffered(id, iedge, rr_switch_inf_); + } + + inline bool edge_is_buffered(RREdgeId id) const { + return node_storage_.edge_is_buffered(id, rr_switch_inf_); + } + /** @brief Return the number of configurable edges. */ inline t_edge_size num_configurable_edges(RRNodeId node) const { diff --git a/libs/librrgraph/src/utils/alloc_and_load_rr_indexed_data.cpp b/libs/librrgraph/src/utils/alloc_and_load_rr_indexed_data.cpp index 20beddc6ec3..0c0e82e2a92 100644 --- a/libs/librrgraph/src/utils/alloc_and_load_rr_indexed_data.cpp +++ b/libs/librrgraph/src/utils/alloc_and_load_rr_indexed_data.cpp @@ -670,9 +670,9 @@ static void calculate_average_switch(const RRGraphView& rr_graph, continue; } - avg_switch_R += rr_graph.rr_switch_inf(RRSwitchId(switch_index)).R; + avg_switch_R += rr_graph.edge_R(edge); avg_switch_T += rr_graph.edge_delay(edge); - avg_switch_Cinternal += rr_graph.rr_switch_inf(RRSwitchId(switch_index)).Cinternal; + avg_switch_Cinternal += rr_graph.edge_Cint(edge); if (buffered == UNDEFINED) { if (rr_graph.rr_switch_inf(RRSwitchId(switch_index)).buffered()) { diff --git a/vpr/src/base/old_traceback.cpp b/vpr/src/base/old_traceback.cpp index a1bb21be232..901ab1145cb 100644 --- a/vpr/src/base/old_traceback.cpp +++ b/vpr/src/base/old_traceback.cpp @@ -18,19 +18,19 @@ vtr::optional TracebackCompat::traceback_to_route_tree(t_trace* head) RouteTree tree(RRNodeId(head->index)); if (head->next) - traceback_to_route_tree_x(head->next, tree, tree._root, RRSwitchId(head->iswitch)); + traceback_to_route_tree_x(head->next, tree, tree._root, head->edge_id); tree.reload_timing(); return tree; } /* Add the path indicated by the trace to parent */ -void TracebackCompat::traceback_to_route_tree_x(t_trace* trace, RouteTree& tree, RouteTreeNode* parent, RRSwitchId parent_switch) { +void TracebackCompat::traceback_to_route_tree_x(t_trace* trace, RouteTree& tree, RouteTreeNode* parent, RREdgeId parent_edge) { auto& device_ctx = g_vpr_ctx.device(); const auto& rr_graph = device_ctx.rr_graph; RRNodeId inode = RRNodeId(trace->index); - RouteTreeNode* new_node = new RouteTreeNode(inode, parent_switch, parent); + RouteTreeNode* new_node = new RouteTreeNode(inode, parent_edge, parent); tree.add_node(parent, new_node); new_node->net_pin_index = trace->net_pin_index; new_node->R_upstream = std::numeric_limits::quiet_NaN(); @@ -48,10 +48,10 @@ void TracebackCompat::traceback_to_route_tree_x(t_trace* trace, RouteTree& tree, RRNodeId next_rr_node = RRNodeId(trace->next->index); RouteTreeNode* branch = tree._rr_node_to_rt_node.at(next_rr_node); VTR_ASSERT(trace->next->next); - traceback_to_route_tree_x(trace->next->next, tree, branch, RRSwitchId(trace->next->iswitch)); + traceback_to_route_tree_x(trace->next->next, tree, branch, trace->next->edge_id); } } else { - traceback_to_route_tree_x(trace->next, tree, new_node, RRSwitchId(trace->iswitch)); + traceback_to_route_tree_x(trace->next, tree, new_node, trace->edge_id); } } @@ -62,7 +62,7 @@ std::pair traceback_from_route_tree_recurr(t_trace* head, t_ t_trace* curr = alloc_trace_data(); curr->index = size_t(node.inode); curr->net_pin_index = node.net_pin_index; - curr->iswitch = size_t(child.parent_switch); + curr->edge_id = child.parent_edge; curr->next = nullptr; if (tail) { @@ -83,7 +83,7 @@ std::pair traceback_from_route_tree_recurr(t_trace* head, t_ t_trace* curr = alloc_trace_data(); curr->index = size_t(node.inode); curr->net_pin_index = node.net_pin_index; - curr->iswitch = OPEN; + curr->edge_id = RREdgeId::INVALID(); curr->next = nullptr; if (tail) { @@ -122,11 +122,11 @@ void print_traceback(const t_trace* trace) { RRNodeId inode(trace->index); VTR_LOG("%d (%s)", inode, rr_node_typename[rr_graph.node_type(inode)]); - if (trace->iswitch == OPEN) { + if (!trace->edge_id.is_valid()) { VTR_LOG(" !"); //End of branch } - if (prev && prev->iswitch != OPEN && !rr_graph.rr_switch_inf(RRSwitchId(prev->iswitch)).configurable()) { + if (prev && prev->edge_id.is_valid() && !rr_graph.edge_is_configurable(prev->edge_id)) { VTR_LOG("*"); //Reached non-configurably } @@ -156,7 +156,7 @@ bool validate_traceback_recurr(t_trace* trace, std::set& seen_rr_nodes) { t_trace* next = trace->next; if (next) { - if (trace->iswitch == OPEN) { //End of a branch + if (!trace->edge_id.is_valid()) { //End of a branch //Verify that the next element (branch point) has been already seen in the traceback so far if (!seen_rr_nodes.count(next->index)) { @@ -179,12 +179,13 @@ bool validate_traceback_recurr(t_trace* trace, std::set& seen_rr_nodes) { found = true; //Verify that the switch matches - int rr_iswitch = rr_graph.edge_switch(RRNodeId(trace->index), iedge); + // TODO: fix this + /*int rr_iswitch = rr_graph.edge_switch(RRNodeId(trace->index), iedge); if (trace->iswitch != rr_iswitch) { VPR_FATAL_ERROR(VPR_ERROR_ROUTE, "Traceback mismatched switch type: traceback %d rr_graph %d (RR nodes %d -> %d)\n", trace->iswitch, rr_iswitch, trace->index, to_node); - } + }*/ break; } } diff --git a/vpr/src/base/old_traceback.h b/vpr/src/base/old_traceback.h index 6c9a9ed2581..cd136e669c9 100644 --- a/vpr/src/base/old_traceback.h +++ b/vpr/src/base/old_traceback.h @@ -19,8 +19,8 @@ * (i.e. special SINKs like the source of a clock tree * which do not correspond to an actual netlist connection), * the value for this member should be set to OPEN (-1). - * @param iswitch Index of the switch type used to go from this rr_node to - * the next one in the routing. OPEN if there is no next node + * @param edge_id Index of the edge used to go from this rr_node to + * the next one in the routing. INVALID() if there is no next node * (i.e. this node is the last one (a SINK) in a branch of the * net's routing). * @param next Pointer to the next traceback element in this route. @@ -30,7 +30,7 @@ struct t_trace { int index; int net_pin_index = -1; //int net_pin_index = OPEN; - short iswitch; + RREdgeId edge_id; }; /* This class is a friend of RouteTree so it can build one and we don't have to clutter route tree code */ @@ -40,7 +40,7 @@ class TracebackCompat { static vtr::optional traceback_to_route_tree(t_trace* head); private: - static void traceback_to_route_tree_x(t_trace* trace, RouteTree& tree, RouteTreeNode* parent, RRSwitchId parent_switch); + static void traceback_to_route_tree_x(t_trace* trace, RouteTree& tree, RouteTreeNode* parent, RREdgeId parent_edge); }; t_trace* alloc_trace_data(); diff --git a/vpr/src/base/read_route.cpp b/vpr/src/base/read_route.cpp index 6ac9d099c4b..76df075ce71 100644 --- a/vpr/src/base/read_route.cpp +++ b/vpr/src/base/read_route.cpp @@ -226,12 +226,13 @@ static void process_nodes(const Netlist<>& net_list, std::ifstream& fp, ClusterN /*remember the position of the last line in order to go back*/ std::streampos oldpos = fp.tellg(); - int inode, layer_num, x, y, layer_num2, x2, y2, ptc, switch_id, net_pin_index, offset; + int inode, layer_num, x, y, layer_num2, x2, y2, ptc, net_pin_index, offset; std::string prev_type; int node_count = 0; std::string input; std::vector tokens; RRNodeId prev_node(-1); + RREdgeId edge_id; /*Walk through every line that begins with Node:*/ while (std::getline(fp, input)) { @@ -326,7 +327,7 @@ static void process_nodes(const Netlist<>& net_list, std::ifstream& fp, ClusterN } /*Process switches and pb pin info if it is ipin or opin type*/ - if (tokens[6 + offset] != "Switch:") { + if (tokens[6 + offset] != "Edge:") { /*This is an opin or ipin, process its pin nums*/ auto type = device_ctx.grid.get_physical_type({x, y, layer_num}); if (!is_io_type(type) && (tokens[2] == "IPIN" || tokens[2] == "OPIN")) { @@ -363,9 +364,9 @@ static void process_nodes(const Netlist<>& net_list, std::ifstream& fp, ClusterN vpr_throw(VPR_ERROR_ROUTE, filename, lineno, "%d node does not have correct pins", inode); } - switch_id = atoi(tokens[8 + offset].c_str()); + edge_id = (RREdgeId)atoi(tokens[8 + offset].c_str()); } else { - switch_id = atoi(tokens[7 + offset].c_str()); + edge_id = (RREdgeId)atoi(tokens[7 + offset].c_str()); } /* Process net pin index for sinks * @@ -388,7 +389,7 @@ static void process_nodes(const Netlist<>& net_list, std::ifstream& fp, ClusterN head_ptr = alloc_trace_data(); head_ptr->index = inode; head_ptr->net_pin_index = net_pin_index; - head_ptr->iswitch = switch_id; + head_ptr->edge_id = edge_id; head_ptr->next = nullptr; tptr = head_ptr; node_count++; @@ -397,7 +398,7 @@ static void process_nodes(const Netlist<>& net_list, std::ifstream& fp, ClusterN tptr = tptr->next; tptr->index = inode; tptr->net_pin_index = net_pin_index; - tptr->iswitch = switch_id; + tptr->edge_id = edge_id; tptr->next = nullptr; node_count++; } @@ -551,9 +552,7 @@ static bool check_rr_graph_connectivity(RRNodeId prev_node, RRNodeId node) { return true; } - // If there are any non-configurable branches 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 (!rr_graph.edge_is_configurable(edge)) return true; } // If it's part of a non configurable node list, return true @@ -658,7 +657,7 @@ void print_route(const Netlist<>& net_list, /* Uncomment line below if you're debugging and want to see the switch types * * used in the routing. */ - fprintf(fp, "Switch: %d", int(tptr->iswitch)); + fprintf(fp, "Edge: %d", int(tptr->edge_id)); //Save net pin index for sinks if (rr_type == SINK) { diff --git a/vpr/src/route/check_route.cpp b/vpr/src/route/check_route.cpp index a8bc1f98126..7212d7eef19 100644 --- a/vpr/src/route/check_route.cpp +++ b/vpr/src/route/check_route.cpp @@ -258,12 +258,14 @@ static void check_switch(const RouteTreeNode& rt_node, size_t num_switch) { if (!rt_node.parent()) return; - if (size_t(rt_node.parent_switch) >= num_switch) { - VPR_FATAL_ERROR(VPR_ERROR_ROUTE, - "in check_switch: rr_node %d left via switch type %d.\n" - "\tSwitch type is out of range.\n", - size_t(rt_node.inode), size_t(rt_node.parent_switch)); - } + // TODO: fix this later + (void)num_switch; +// if (size_t(rt_node.parent_switch) >= num_switch) { +// VPR_FATAL_ERROR(VPR_ERROR_ROUTE, +// "in check_switch: rr_node %d left via switch type %d.\n" +// "\tSwitch type is out of range.\n", +// size_t(rt_node.inode), size_t(rt_node.parent_switch)); +// } } static bool check_adjacent(RRNodeId from_node, RRNodeId to_node, bool is_flat) { @@ -894,7 +896,7 @@ bool StubFinder::RecurseTree(const RouteTreeNode& rt_node) { bool is_stub = true; for (auto& child_node : rt_node.child_nodes()) { - bool driver_switch_configurable = rr_graph.rr_switch_inf(child_node.parent_switch).configurable(); + bool driver_switch_configurable = rr_graph.edge_is_configurable(child_node.parent_edge); bool child_is_stub = RecurseTree(child_node); if (!child_is_stub) { // Because the child was not a stub, this node is not a stub. diff --git a/vpr/src/route/connection_router.cpp b/vpr/src/route/connection_router.cpp index db563031b45..387f7abc9d0 100644 --- a/vpr/src/route/connection_router.cpp +++ b/vpr/src/route/connection_router.cpp @@ -698,15 +698,14 @@ void ConnectionRouter::evaluate_timing_driven_node_costs(RTExploredNode* t */ //Info for the switch connecting from_node to_node (i.e., to->index) - int iswitch = rr_nodes_.edge_switch(to->prev_edge); - bool switch_buffered = rr_switch_inf_[iswitch].buffered(); - bool reached_configurably = rr_switch_inf_[iswitch].configurable(); - float switch_R = rr_switch_inf_[iswitch].R; + bool switch_buffered = rr_graph_->edge_is_buffered(to->prev_edge); + bool reached_configurably = rr_graph_->edge_is_configurable(to->prev_edge); + float switch_R = rr_graph_->edge_R(to->prev_edge); // Instead of looking up the delay from the RR switch type info, // we call edge_delay() method that returns the exact delay calculated // by adding edge-specific delays to the nominal delay of switch type float switch_Tdel = rr_graph_->edge_delay(to->prev_edge); - float switch_Cinternal = rr_switch_inf_[iswitch].Cinternal; + float switch_Cinternal = rr_graph_->edge_Cint(to->prev_edge); //To node info auto rc_index = rr_graph_->node_rc_index(to->index); diff --git a/vpr/src/route/route_tree.cpp b/vpr/src/route/route_tree.cpp index 4f0d6a7f524..bf1b1db44b9 100644 --- a/vpr/src/route/route_tree.cpp +++ b/vpr/src/route/route_tree.cpp @@ -9,9 +9,9 @@ /* Construct a new RouteTreeNode. * Doesn't add the node to parent's child_nodes! (see add_child) */ -RouteTreeNode::RouteTreeNode(RRNodeId _inode, RRSwitchId _parent_switch, RouteTreeNode* parent) +RouteTreeNode::RouteTreeNode(RRNodeId _inode, RREdgeId _parent_edge, RouteTreeNode* parent) : inode(_inode) - , parent_switch(_parent_switch) + , parent_edge(_parent_edge) , _parent(parent) { auto& device_ctx = g_vpr_ctx.device(); const auto& rr_graph = device_ctx.rr_graph; @@ -52,8 +52,8 @@ void RouteTreeNode::print_x(int depth) const { Tdel); if (_parent) { - VTR_LOG("parent: %d \t parent_switch: %d", _parent->inode, parent_switch); - bool parent_edge_configurable = rr_graph.rr_switch_inf(parent_switch).configurable(); + VTR_LOG("parent: %d \t parent_edge: %d", _parent->inode, parent_edge); + bool parent_edge_configurable = rr_graph.edge_is_configurable(parent_edge); if (!parent_edge_configurable) { VTR_LOG("*"); } @@ -73,7 +73,7 @@ void RouteTreeNode::print_x(int depth) const { /* Construct a top-level route tree. */ RouteTree::RouteTree(RRNodeId _inode) { - _root = new RouteTreeNode(_inode, RRSwitchId::INVALID(), nullptr); + _root = new RouteTreeNode(_inode, RREdgeId::INVALID(), nullptr); _net_id = ParentNetId::INVALID(); _rr_node_to_rt_node[_inode] = _root; } @@ -82,7 +82,7 @@ RouteTree::RouteTree(ParentNetId _inet) { auto& route_ctx = g_vpr_ctx.routing(); RRNodeId inode = RRNodeId(route_ctx.net_rr_terminals[_inet][0]); - _root = new RouteTreeNode(inode, RRSwitchId::INVALID(), nullptr); + _root = new RouteTreeNode(inode, RREdgeId::INVALID(), nullptr); _net_id = _inet; _rr_node_to_rt_node[inode] = _root; @@ -94,7 +94,7 @@ RouteTree::RouteTree(ParentNetId _inet) { /** Make a copy of rhs and return it. * Traverse it as a tree so we can keep parent & child ptrs valid. */ RouteTreeNode* RouteTree::copy_tree(const RouteTreeNode* rhs) { - RouteTreeNode* root = new RouteTreeNode(rhs->inode, RRSwitchId::INVALID(), nullptr); + RouteTreeNode* root = new RouteTreeNode(rhs->inode, RREdgeId::INVALID(), nullptr); _rr_node_to_rt_node[root->inode] = root; copy_tree_x(root, *rhs); return root; @@ -204,12 +204,10 @@ void RouteTree::reload_timing_unlocked(vtr::optional from_node) if (unbuffered_subtree_rt_root._parent) { RouteTreeNode& subtree_parent_rt_node = *unbuffered_subtree_rt_root._parent; Tdel_start = subtree_parent_rt_node.Tdel; - RRSwitchId iswitch = unbuffered_subtree_rt_root.parent_switch; - /* TODO Just a note (no action needed for this PR): In future, we need to consider APIs that returns - * the Tdel for a routing trace in RRGraphView.*/ - Tdel_start += rr_graph.rr_switch_inf(iswitch).R * unbuffered_subtree_rt_root.C_downstream; - // TODO: probably call edge_delay() to retrieve the per-edge delay instead of per switch type delay - Tdel_start += rr_graph.rr_switch_inf(iswitch).Tdel; + RREdgeId edge_id = unbuffered_subtree_rt_root.parent_edge; + + Tdel_start += rr_graph.edge_R(edge_id) * unbuffered_subtree_rt_root.C_downstream; + Tdel_start += rr_graph.edge_delay(edge_id); } load_route_tree_Tdel(unbuffered_subtree_rt_root, Tdel_start); @@ -218,7 +216,7 @@ void RouteTree::reload_timing_unlocked(vtr::optional from_node) /** Sets the R_upstream values of all the nodes in the new path to the * correct value by traversing down to SINK from from_node. */ void RouteTree::load_new_subtree_R_upstream(RouteTreeNode& rt_node) { - auto& device_ctx = g_vpr_ctx.device(); + const auto& device_ctx = g_vpr_ctx.device(); const auto& rr_graph = device_ctx.rr_graph; RouteTreeNode* parent_rt_node = rt_node._parent; @@ -227,13 +225,13 @@ void RouteTree::load_new_subtree_R_upstream(RouteTreeNode& rt_node) { //Calculate upstream resistance float R_upstream = 0.; if (parent_rt_node) { - RRSwitchId iswitch = rt_node.parent_switch; - bool switch_buffered = rr_graph.rr_switch_inf(iswitch).buffered(); + RREdgeId edge_id = rt_node.parent_edge; + bool switch_buffered = rr_graph.edge_is_buffered(edge_id); if (!switch_buffered) { R_upstream += parent_rt_node->R_upstream; //Parent upstream R } - R_upstream += rr_graph.rr_switch_inf(iswitch).R; //Parent switch R + R_upstream += rr_graph.edge_R(edge_id); //Parent switch R } R_upstream += rr_graph.node_R(inode); //Current node R @@ -248,7 +246,7 @@ void RouteTree::load_new_subtree_R_upstream(RouteTreeNode& rt_node) { /** Sets the R_upstream values of all the nodes in the new path to the * correct value by traversing down to SINK from from_node. */ float RouteTree::load_new_subtree_C_downstream(RouteTreeNode& from_node) { - auto& device_ctx = g_vpr_ctx.device(); + const auto& device_ctx = g_vpr_ctx.device(); const auto& rr_graph = device_ctx.rr_graph; float C_downstream = 0.; @@ -257,9 +255,9 @@ float RouteTree::load_new_subtree_C_downstream(RouteTreeNode& from_node) { /* When switches such as multiplexers and tristate buffers are enabled, their fanout * produces an "internal capacitance". We account for this internal capacitance of the * switch by adding it to the total capacitance of the node. */ - C_downstream += rr_graph.rr_switch_inf(child.parent_switch).Cinternal; + C_downstream += rr_graph.edge_Cint(child.parent_edge); float C_downstream_child = load_new_subtree_C_downstream(child); - if (!rr_graph.rr_switch_inf(child.parent_switch).buffered()) { + if (!rr_graph.edge_is_buffered(child.parent_edge)) { C_downstream += C_downstream_child; } } @@ -277,17 +275,17 @@ RouteTree::update_unbuffered_ancestors_C_downstream(RouteTreeNode& from_node) { if (!from_node.parent()) return from_node; - auto& device_ctx = g_vpr_ctx.device(); + const auto& device_ctx = g_vpr_ctx.device(); const auto& rr_graph = device_ctx.rr_graph; - RRSwitchId iswitch = from_node.parent_switch; + RREdgeId parent_edge = from_node.parent_edge; /* Now that a connection has been made between rt_node and its parent we must also consider * the potential effect of internal capacitance. We will first assume that parent is connected * by an unbuffered switch, so the ancestors downstream capacitance must be equal to the sum * of the child's downstream capacitance with the internal capacitance of the switch.*/ - float C_downstream_addition = from_node.C_downstream + rr_graph.rr_switch_inf(iswitch).Cinternal; + float C_downstream_addition = from_node.C_downstream + rr_graph.edge_Cint(parent_edge); /* Having set the value of C_downstream_addition, we must check whether the parent switch * is a buffered or unbuffered switch with the if statement below. If the parent switch is @@ -302,19 +300,19 @@ RouteTree::update_unbuffered_ancestors_C_downstream(RouteTreeNode& from_node) { RouteTreeNode* last_node = std::addressof(from_node); RouteTreeNode* parent_rt_node = from_node._parent; - if (rr_graph.rr_switch_inf(iswitch).buffered() == true) { - C_downstream_addition = rr_graph.rr_switch_inf(iswitch).Cinternal; + if (rr_graph.edge_is_buffered(parent_edge)) { + C_downstream_addition = rr_graph.edge_Cint(parent_edge); last_node = parent_rt_node; last_node->C_downstream += C_downstream_addition; parent_rt_node = last_node->_parent; - iswitch = last_node->parent_switch; + parent_edge = last_node->parent_edge; } - while (parent_rt_node && rr_graph.rr_switch_inf(iswitch).buffered() == false) { + while (parent_rt_node && rr_graph.edge_is_buffered(parent_edge)) { last_node = parent_rt_node; last_node->C_downstream += C_downstream_addition; parent_rt_node = last_node->_parent; - iswitch = last_node->parent_switch; + parent_edge = last_node->parent_edge; } VTR_ASSERT(last_node); @@ -338,12 +336,10 @@ void RouteTree::load_route_tree_Tdel(RouteTreeNode& from_node, float Tarrival) { /* Now expand the children of this node to load their Tdel values */ for (RouteTreeNode& child : from_node._child_nodes()) { - RRSwitchId iswitch = child.parent_switch; + RREdgeId parent_edge = child.parent_edge; - float Tchild = from_node.Tdel + rr_graph.rr_switch_inf(iswitch).R * child.C_downstream; - // TODO: we should probably look up the per-edge delay instead of switch type delay - // For this, we need to add a new member variable to RouteTreeNode to record it parent edge - Tchild += rr_graph.rr_switch_inf(iswitch).Tdel; /* Intrinsic switch delay. */ + float Tchild = from_node.Tdel + rr_graph.edge_R(parent_edge) * child.C_downstream; + Tchild += rr_graph.edge_delay(parent_edge); /* Intrinsic switch delay. */ load_route_tree_Tdel(child, Tchild); } } @@ -377,16 +373,16 @@ bool RouteTree::is_valid_x(const RouteTreeNode& rt_node) const { constexpr float RES_ABS_TOL = vtr::DEFAULT_ABS_TOL; RRNodeId inode = rt_node.inode; - RRSwitchId iswitch = rt_node.parent_switch; + RREdgeId parent_edge = rt_node.parent_edge; if (rt_node.parent()) { - if (rr_graph.rr_switch_inf(iswitch).buffered()) { - float R_upstream_check = rr_graph.node_R(inode) + rr_graph.rr_switch_inf(iswitch).R; + if (rr_graph.edge_is_buffered(parent_edge)) { + float R_upstream_check = rr_graph.node_R(inode) + rr_graph.edge_R(parent_edge); if (!vtr::isclose(rt_node.R_upstream, R_upstream_check, RES_REL_TOL, RES_ABS_TOL)) { VTR_LOG("%d mismatch R upstream %e supposed %e\n", inode, rt_node.R_upstream, R_upstream_check); return false; } } else { - float R_upstream_check = rr_graph.node_R(inode) + rt_node.parent().value().R_upstream + rr_graph.rr_switch_inf(iswitch).R; + float R_upstream_check = rr_graph.node_R(inode) + rt_node.parent().value().R_upstream + rr_graph.edge_R(parent_edge); if (!vtr::isclose(rt_node.R_upstream, R_upstream_check, RES_REL_TOL, RES_ABS_TOL)) { VTR_LOG("%d mismatch R upstream %e supposed %e\n", inode, rt_node.R_upstream, R_upstream_check); return false; @@ -423,9 +419,9 @@ bool RouteTree::is_valid_x(const RouteTreeNode& rt_node) const { child.inode, rt_node.inode); return false; } - C_downstream_children += rr_graph.rr_switch_inf(child.parent_switch).Cinternal; + C_downstream_children += rr_graph.edge_Cint(child.parent_edge); - if (!rr_graph.rr_switch_inf(child.parent_switch).buffered()) { + if (!rr_graph.edge_is_buffered(child.parent_edge)) { C_downstream_children += child.C_downstream; } if (!is_valid_x(child)) { @@ -525,7 +521,7 @@ RouteTree::add_subtree_from_heap(RTExploredNode* hptr, int target_net_pin_index, /* Walk rr_node_route_inf up until we reach an existing RouteTreeNode */ std::vector new_branch_inodes; - std::vector new_branch_iswitches; + std::vector new_branch_iedges; std::unordered_set all_visited; std::unordered_set main_branch_visited; @@ -537,18 +533,16 @@ RouteTree::add_subtree_from_heap(RTExploredNode* hptr, int target_net_pin_index, * and new_branch_iswitches: [N-1->sink, N-2->N-1, ... 2->1, 1->found_node] of length N */ RREdgeId edge = hptr->prev_edge; RRNodeId new_inode = rr_graph.edge_src_node(edge); - RRSwitchId new_iswitch = RRSwitchId(rr_graph.rr_nodes().edge_switch(edge)); /* build a path, looking up rr nodes and switches from rr_node_route_inf */ new_branch_inodes.push_back(sink_inode); while (!_rr_node_to_rt_node.count(new_inode)) { new_branch_inodes.push_back(new_inode); - new_branch_iswitches.push_back(new_iswitch); + new_branch_iedges.push_back(edge); edge = route_ctx.rr_node_route_inf[new_inode].prev_edge; new_inode = rr_graph.edge_src_node(edge); - new_iswitch = RRSwitchId(rr_graph.rr_nodes().edge_switch(edge)); } - new_branch_iswitches.push_back(new_iswitch); + new_branch_iedges.push_back(edge); /* Build the new tree branch starting from the existing node we found */ RouteTreeNode* last_node = _rr_node_to_rt_node[new_inode]; @@ -560,7 +554,7 @@ RouteTree::add_subtree_from_heap(RTExploredNode* hptr, int target_net_pin_index, * --- * Walk through new_branch_iswitches and corresponding new_branch_inodes. */ for (int i = new_branch_inodes.size() - 1; i >= 0; i--) { - RouteTreeNode* new_node = new RouteTreeNode(new_branch_inodes[i], new_branch_iswitches[i], last_node); + RouteTreeNode* new_node = new RouteTreeNode(new_branch_inodes[i], new_branch_iedges[i], last_node); e_rr_type node_type = rr_graph.node_type(new_branch_inodes[i]); // If is_flat is enabled, IPINs should be added, since they are used for intra-cluster routing @@ -621,9 +615,9 @@ void RouteTree::add_non_configurable_nodes(RouteTreeNode* rt_node, if (_rr_node_to_rt_node.count(to_rr_node)) // TODO: not 100% sure about this continue; - RRSwitchId edge_switch(rr_graph.edge_switch(rr_node, iedge)); + RREdgeId edge_id = rr_graph.rr_nodes().edge_id(rr_node, iedge); - RouteTreeNode* new_node = new RouteTreeNode(to_rr_node, edge_switch, rt_node); + RouteTreeNode* new_node = new RouteTreeNode(to_rr_node, edge_id, rt_node); add_node(rt_node, new_node); new_node->net_pin_index = OPEN; @@ -702,7 +696,7 @@ RouteTree::prune_x(RouteTreeNode& rt_node, CBRR& connections_inf, bool force_pru } else { // Pruned // After removing a child node, check if non_config_node_set_usage // needs an update. - if (non_config_node_set_usage != nullptr && node_set != -1 && rr_graph.rr_switch_inf(child.parent_switch).configurable()) { + if (non_config_node_set_usage != nullptr && node_set != -1 && rr_graph.edge_is_configurable(child.parent_edge)) { (*non_config_node_set_usage)[node_set] -= 1; VTR_ASSERT((*non_config_node_set_usage)[node_set] >= 0); } @@ -751,7 +745,7 @@ RouteTree::prune_x(RouteTreeNode& rt_node, CBRR& connections_inf, bool force_pru bool reached_non_configurably = false; if (rt_node.parent()) { - reached_non_configurably = !rr_graph.rr_switch_inf(rt_node.parent_switch).configurable(); + reached_non_configurably = !rr_graph.edge_is_configurable(rt_node.parent_edge); if (reached_non_configurably) { // Check if this non-configurable node set is in use. @@ -780,7 +774,7 @@ RouteTree::prune_x(RouteTreeNode& rt_node, CBRR& connections_inf, bool force_pru // // Then prune this node. // - if (non_config_node_set_usage != nullptr && node_set != -1 && rr_graph.rr_switch_inf(rt_node.parent_switch).configurable() && (*non_config_node_set_usage)[node_set] == 0) { + if (non_config_node_set_usage != nullptr && node_set != -1 && rr_graph.edge_is_configurable(rt_node.parent_edge) && (*non_config_node_set_usage)[node_set] == 0) { // This node should be pruned, re-prune edges once more. // // If the following is true: @@ -873,14 +867,14 @@ std::vector RouteTree::get_non_config_node_set_usage(void) const { continue; if (device_ctx.rr_graph.node_type(rt_node.inode) == SINK) { - if (device_ctx.rr_graph.rr_switch_inf(rt_node.parent_switch).configurable()) { + if (device_ctx.rr_graph.edge_is_configurable(rt_node.parent_edge)) { usage[it->second] += 1; } continue; } for (auto& child : rt_node.child_nodes()) { - if (device_ctx.rr_graph.rr_switch_inf(child.parent_switch).configurable()) { + if (device_ctx.rr_graph.edge_is_configurable(child.parent_edge)) { usage[it->second] += 1; } } diff --git a/vpr/src/route/route_tree.h b/vpr/src/route/route_tree.h index 37e89db16ae..760300d895f 100644 --- a/vpr/src/route/route_tree.h +++ b/vpr/src/route/route_tree.h @@ -111,12 +111,12 @@ class RouteTreeNode { /** This struct makes little sense outside the context of a RouteTree. * This constructor is only public for compatibility purposes. */ - RouteTreeNode(RRNodeId inode, RRSwitchId parent_switch, RouteTreeNode* parent); + RouteTreeNode(RRNodeId inode, RREdgeId parent_edge, RouteTreeNode* parent); /** ID of the rr_node that corresponds to this node. */ RRNodeId inode; - /** Switch type driving this node (by its parent). */ - RRSwitchId parent_switch; + /** Edge driving this node (by its parent). */ + RREdgeId parent_edge; /** Should this node be put on the heap as part of the partial * routing to act as a source for subsequent connections? */ bool re_expand; diff --git a/vpr/src/route/router_lookahead_extended_map.cpp b/vpr/src/route/router_lookahead_extended_map.cpp index d72f5471130..6e05a9e7dd7 100644 --- a/vpr/src/route/router_lookahead_extended_map.cpp +++ b/vpr/src/route/router_lookahead_extended_map.cpp @@ -302,7 +302,7 @@ bool ExtendedMapLookahead::add_paths(RRNodeId start_node, current.adjust_Tsw(-site_pin_delay); // add each node along the path subtracting the incremental costs from the current costs - Entry start_to_here(start_node, UNDEFINED, nullptr); + Entry start_to_here(start_node, RREdgeId::INVALID(), nullptr); auto parent = start_node; for (auto it = path.rbegin(); it != path.rend(); it++) { RRNodeId this_node(*it); @@ -325,7 +325,7 @@ bool ExtendedMapLookahead::add_paths(RRNodeId start_node, delta}; if (size_t(this_node) != size_t(start_node)) { - start_to_here = Entry(this_node, rr_graph.edge_switch(RRNodeId(parent), paths[*it].edge), &start_to_here); + start_to_here = Entry(this_node, rr_graph.rr_nodes().edge_id(RRNodeId(parent), paths[*it].edge), &start_to_here); parent = this_node; } @@ -388,7 +388,7 @@ std::pair ExtendedMapLookahead::run_dijkstra(RRNodeId start_node, std::priority_queue, std::greater> pq; /* first entry has no upstream delay or congestion */ - Entry first_entry(start_node, UNDEFINED, nullptr); + Entry first_entry(start_node, RREdgeId::INVALID(), nullptr); float max_cost = first_entry.cost(); pq.push(first_entry); diff --git a/vpr/src/route/router_lookahead_map_utils.cpp b/vpr/src/route/router_lookahead_map_utils.cpp index 8bd55058d51..b6b5f64a1f5 100644 --- a/vpr/src/route/router_lookahead_map_utils.cpp +++ b/vpr/src/route/router_lookahead_map_utils.cpp @@ -130,7 +130,7 @@ static constexpr int DIRECT_CONNECT_SPECIAL_SEG_TYPE = -1; namespace util { -PQ_Entry::PQ_Entry(RRNodeId set_rr_node, int /*switch_ind*/, float parent_delay, float parent_R_upstream, float parent_congestion_upstream, bool starting_node) { +PQ_Entry::PQ_Entry(RRNodeId set_rr_node, RREdgeId /*edge_id*/, float parent_delay, float parent_R_upstream, float parent_congestion_upstream, bool starting_node) { this->rr_node = set_rr_node; auto& device_ctx = g_vpr_ctx.device(); @@ -167,7 +167,7 @@ PQ_Entry::PQ_Entry(RRNodeId set_rr_node, int /*switch_ind*/, float parent_delay, } PQ_Entry_Delay::PQ_Entry_Delay(RRNodeId set_rr_node, - int switch_ind, + RREdgeId edge_id, const PQ_Entry_Delay* parent) { this->rr_node = set_rr_node; @@ -176,13 +176,13 @@ PQ_Entry_Delay::PQ_Entry_Delay(RRNodeId set_rr_node, const auto& rr_graph = device_ctx.rr_graph; // We use nominal switch delay instead of per-edge delay that can be retrieved // by calling edge_delay() method - float Tsw = rr_graph.rr_switch_inf(RRSwitchId(switch_ind)).Tdel; - float Rsw = rr_graph.rr_switch_inf(RRSwitchId(switch_ind)).R; + float Tsw = rr_graph.edge_delay(edge_id); + float Rsw = rr_graph.edge_R(edge_id); float Cnode = rr_graph.node_C(set_rr_node); float Rnode = rr_graph.node_R(set_rr_node); float T_linear = 0.f; - if (rr_graph.rr_switch_inf(RRSwitchId(switch_ind)).buffered()) { + if (rr_graph.edge_is_buffered(edge_id)) { T_linear = Tsw + Rsw * Cnode + 0.5 * Rnode * Cnode; } else { /* Pass transistor */ T_linear = Tsw + 0.5 * Rsw * Cnode; @@ -195,16 +195,15 @@ PQ_Entry_Delay::PQ_Entry_Delay(RRNodeId set_rr_node, } } -PQ_Entry_Base_Cost::PQ_Entry_Base_Cost( - RRNodeId set_rr_node, - int switch_ind, - const PQ_Entry_Base_Cost* parent) { +PQ_Entry_Base_Cost::PQ_Entry_Base_Cost(RRNodeId set_rr_node, + RREdgeId edge_id, + const PQ_Entry_Base_Cost* parent) { this->rr_node = set_rr_node; if (parent != nullptr) { auto& device_ctx = g_vpr_ctx.device(); const auto& rr_graph = device_ctx.rr_graph; - if (rr_graph.rr_switch_inf(RRSwitchId(switch_ind)).configurable()) { + if (rr_graph.edge_is_configurable(edge_id)) { this->base_cost = parent->base_cost + get_single_rr_cong_base_cost(set_rr_node); } else { this->base_cost = parent->base_cost; @@ -326,14 +325,14 @@ void expand_dijkstra_neighbours(const RRGraphView& rr_graph, for (int iedge = 0; iedge < rr_graph.num_edges(parent); iedge++) { int child_node_ind = size_t(rr_graph.edge_sink_node(RRNodeId(parent), iedge)); - int switch_ind = rr_graph.edge_switch(parent, iedge); + RREdgeId edge_id = rr_graph.rr_nodes().edge_id(parent, iedge); /* skip this child if it has already been expanded from */ if ((*node_expanded)[child_node_ind]) { continue; } - Entry child_entry(RRNodeId(child_node_ind), switch_ind, &parent_entry); + Entry child_entry(RRNodeId(child_node_ind), edge_id, &parent_entry); VTR_ASSERT(child_entry.cost() >= 0); /* Create (if it doesn't exist) or update (if the new cost is lower) @@ -1019,11 +1018,7 @@ static void dijkstra_flood_to_wires(int itile, 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.rr_nodes().edge_switch(edge); - // We use nominal switch delay instead of per-edge delay that can be retrieved - // by calling edge_delay() method - float incr_delay = rr_graph.rr_switch_inf(RRSwitchId(iswitch)).Tdel; - + float incr_delay = rr_graph.edge_delay(edge); RRNodeId next_node = rr_graph.rr_nodes().edge_sink_node(edge); // For the time being, we decide to not let the lookahead explore the node inside the clusters @@ -1124,11 +1119,7 @@ static void dijkstra_flood_to_ipins(RRNodeId node, util::t_chan_ipins_delays& ch 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.rr_nodes().edge_switch(edge); - // We use nominal switch delay instead of per-edge delay that can be retrieved - // by calling edge_delay() method - float new_delay = rr_graph.rr_switch_inf(RRSwitchId(iswitch)).Tdel; - + float new_delay = rr_graph.edge_delay(edge); RRNodeId next_node = rr_graph.rr_nodes().edge_sink_node(edge); if (rr_graph.node_layer(next_node) != root_layer) { @@ -1265,11 +1256,7 @@ static void run_intra_tile_dijkstra(const RRGraphView& rr_graph, for (RREdgeId edge : rr_graph.edge_range(curr.node)) { RRNodeId next_node = rr_graph.rr_nodes().edge_sink_node(edge); auto cost_index = rr_graph.node_cost_index(next_node); - int iswitch = rr_graph.rr_nodes().edge_switch(edge); - - // We use nominal switch delay instead of per-edge delay that can be retrieved - // by calling edge_delay() method - float incr_delay = rr_graph.rr_switch_inf(RRSwitchId(iswitch)).Tdel; + float incr_delay = rr_graph.edge_delay(edge); float incr_cong = device_ctx.rr_indexed_data[cost_index].base_cost; t_pq_entry next; @@ -1320,7 +1307,7 @@ static void run_dijkstra(RRNodeId start_node, } /* first entry has no upstream delay or congestion */ - pq.emplace(start_node, UNDEFINED, 0, 0, 0, true); + pq.emplace(start_node, RREdgeId::INVALID(), 0, 0, 0, true); /* now do routing */ while (!pq.empty()) { @@ -1390,7 +1377,7 @@ static void expand_dijkstra_neighbours(util::PQ_Entry parent_entry, if (!is_inter_cluster_node(rr_graph, child_node)) { continue; } - int switch_ind = size_t(rr_graph.edge_switch(parent, edge)); + RREdgeId edge_id = rr_graph.rr_nodes().edge_id(parent, edge); if (rr_graph.node_type(child_node) == SINK) return; @@ -1399,7 +1386,7 @@ static void expand_dijkstra_neighbours(util::PQ_Entry parent_entry, continue; } - util::PQ_Entry child_entry(child_node, switch_ind, parent_entry.delay, + util::PQ_Entry child_entry(child_node, edge_id, parent_entry.delay, parent_entry.R_upstream, parent_entry.congestion_upstream, false); //VTR_ASSERT(child_entry.cost >= 0); //Asertion fails in practise. TODO: debug diff --git a/vpr/src/route/router_lookahead_map_utils.h b/vpr/src/route/router_lookahead_map_utils.h index 217bd0d2206..ebe9509b286 100644 --- a/vpr/src/route/router_lookahead_map_utils.h +++ b/vpr/src/route/router_lookahead_map_utils.h @@ -47,7 +47,7 @@ class PQ_Entry { float R_upstream; float congestion_upstream; - PQ_Entry(RRNodeId set_rr_node, int /*switch_ind*/, float parent_delay, float parent_R_upstream, float parent_congestion_upstream, bool starting_node); + PQ_Entry(RRNodeId set_rr_node, RREdgeId /*edge_id*/, float parent_delay, float parent_R_upstream, float parent_congestion_upstream, bool starting_node); bool operator<(const PQ_Entry& obj) const { /* inserted into max priority queue so want queue entries with a lower cost to be greater */ @@ -217,7 +217,7 @@ class PQ_Entry_Delay { RRNodeId rr_node; //index in device_ctx.rr_nodes that this entry represents float delay_cost; //the cost of the path to get to this node - PQ_Entry_Delay(RRNodeId set_rr_node, int /*switch_ind*/, const PQ_Entry_Delay* parent); + PQ_Entry_Delay(RRNodeId set_rr_node, RREdgeId edge_id, const PQ_Entry_Delay* parent); float cost() const { return delay_cost; @@ -238,7 +238,7 @@ class PQ_Entry_Base_Cost { RRNodeId rr_node; //index in device_ctx.rr_nodes that this entry represents float base_cost; - PQ_Entry_Base_Cost(RRNodeId set_rr_node, int /*switch_ind*/, const PQ_Entry_Base_Cost* parent); + PQ_Entry_Base_Cost(RRNodeId set_rr_node, RREdgeId edge_id, const PQ_Entry_Base_Cost* parent); float cost() const { return base_cost; diff --git a/vpr/src/route/rr_graph.cpp b/vpr/src/route/rr_graph.cpp index 7c701935808..dc10822939a 100644 --- a/vpr/src/route/rr_graph.cpp +++ b/vpr/src/route/rr_graph.cpp @@ -1829,7 +1829,7 @@ t_rr_switch_inf create_rr_switch_from_arch_switch(const t_arch_switch_inf& arch_ /* figure out, by looking at the arch switch's Tdel map, what the delay of the new * rr switch should be */ - double rr_switch_Tdel = arch_sw_inf.Tdel(0); + float rr_switch_Tdel = arch_sw_inf.Tdel(0); /* copy over the arch switch to rr_switch_inf[rr_switch_idx], but with the changed Tdel value */ rr_switch_inf.set_type(arch_sw_inf.type()); @@ -1889,7 +1889,7 @@ void load_rr_switch_from_arch_switch(RRGraphBuilder& rr_graph_builder, rr_switch_to_be_updated.power_buffer_type = arch_switch.power_buffer_type; rr_switch_to_be_updated.power_buffer_size = arch_switch.power_buffer_size; - rr_switch_offset_to_be_updated.Tdel = rr_switch_to_be_updated.Tdel; + rr_switch_offset_to_be_updated = rr_switch_to_be_updated; } /* switch indices of each rr_node original point into the global device_ctx.arch_switch_inf array. diff --git a/vpr/src/route/rr_graph_area.cpp b/vpr/src/route/rr_graph_area.cpp index 3ac736eebd8..8982ea11051 100644 --- a/vpr/src/route/rr_graph_area.cpp +++ b/vpr/src/route/rr_graph_area.cpp @@ -579,18 +579,17 @@ alloc_and_load_sharable_switch_trans(int num_switch, * of a tri-state buffer) are both unsharable. Only the buffer part of a * * buffer switch is sharable. */ - float *sharable_switch_trans, Rbuf; - int i; + float *sharable_switch_trans; auto& device_ctx = g_vpr_ctx.device(); const auto& rr_graph = device_ctx.rr_graph; sharable_switch_trans = new float[num_switch]; - for (i = 0; i < num_switch; i++) { + for (int i = 0; i < num_switch; i++) { if (!rr_graph.rr_switch_inf(RRSwitchId(i)).buffered()) { sharable_switch_trans[i] = 0.; } else { /* Buffer. Set Rbuf = Rpass = 1/2 Rtotal. */ - Rbuf = rr_graph.rr_switch_inf(RRSwitchId(i)).R / 2.; + float Rbuf = rr_graph.rr_switch_inf(RRSwitchId(i)).R / 2.; sharable_switch_trans[i] = trans_per_buf(Rbuf, R_minW_nmos, R_minW_pmos); } diff --git a/vpr/src/route/rr_graph_timing_params.cpp b/vpr/src/route/rr_graph_timing_params.cpp index ae316cef2c7..fc699883ea5 100644 --- a/vpr/src/route/rr_graph_timing_params.cpp +++ b/vpr/src/route/rr_graph_timing_params.cpp @@ -26,28 +26,17 @@ void add_rr_graph_C_from_switches(float C_ipin_cblock) { * 3) The input capacitance of the input connection block (or buffers * * separating tracks from the input connection block, if enabled by * * INCLUDE_TRACK_BUFFERS) */ - - int switch_index, maxlen; size_t to_node; int icblock, isblock, iseg_low, iseg_high; - float Cin, Cout; t_rr_type from_rr_type, to_rr_type; - bool* cblock_counted; /* [0..maxlen-1] -- 0th element unused. */ - float* buffer_Cin; /* [0..maxlen-1] */ - bool buffered; - float* Couts_to_add; /* UDSD */ auto& device_ctx = g_vpr_ctx.device(); const auto& rr_graph = device_ctx.rr_graph; auto& mutable_device_ctx = g_vpr_ctx.mutable_device(); - maxlen = std::max(device_ctx.grid.width(), device_ctx.grid.height()); - cblock_counted = new bool[maxlen]; - buffer_Cin = new float[maxlen]; - for (int i = 0; i < maxlen; i++) { - cblock_counted[i] = 0; - buffer_Cin[i] = 0; - } + int maxlen = std::max(device_ctx.grid.width(), device_ctx.grid.height()); + std::vector cblock_counted(maxlen, false); // 0th element unused + std::vector buffer_Cin(maxlen, 0.f); std::vector rr_node_C(rr_graph.num_nodes(), 0.); //Stores the final C @@ -64,10 +53,9 @@ void add_rr_graph_C_from_switches(float C_ipin_cblock) { to_rr_type = rr_graph.node_type(RRNodeId(to_node)); if (to_rr_type == CHANX || to_rr_type == CHANY) { - switch_index = rr_graph.edge_switch(rr_id, iedge); - Cin = rr_graph.rr_switch_inf(RRSwitchId(switch_index)).Cin; - Cout = rr_graph.rr_switch_inf(RRSwitchId(switch_index)).Cout; - buffered = rr_graph.rr_switch_inf(RRSwitchId(switch_index)).buffered(); + float Cin = rr_graph.edge_Cin(rr_id, iedge); + float Cout = rr_graph.edge_Cout(rr_id, iedge); + bool buffered = rr_graph.edge_is_buffered(rr_id, iedge); /* If both the switch from inode to to_node and the switch from * * to_node back to inode use bidirectional switches (i.e. pass * @@ -155,7 +143,6 @@ void add_rr_graph_C_from_switches(float C_ipin_cblock) { /* End node is CHANX or CHANY */ else if (from_rr_type == OPIN) { for (t_edge_size iedge = 0; iedge < rr_graph.num_edges(rr_id); iedge++) { - switch_index = rr_graph.edge_switch(rr_id, iedge); to_node = size_t(rr_graph.edge_sink_node(rr_id, iedge)); to_rr_type = rr_graph.node_type(RRNodeId(to_node)); @@ -163,7 +150,7 @@ void add_rr_graph_C_from_switches(float C_ipin_cblock) { continue; if (rr_graph.node_direction(RRNodeId(to_node)) == Direction::BIDIR) { - Cout = rr_graph.rr_switch_inf(RRSwitchId(switch_index)).Cout; + float Cout = rr_graph.edge_Cout(rr_id, iedge); to_node = size_t(rr_graph.edge_sink_node(rr_id, iedge)); /* Will be CHANX or CHANY */ rr_node_C[to_node] += Cout; } @@ -176,18 +163,16 @@ 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 = new float[rr_graph.num_nodes()]; - for (size_t i = 0; i < rr_graph.num_nodes(); i++) - Couts_to_add[i] = 0; + std::vectorCouts_to_add(rr_graph.num_nodes(), 0.f); 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)); to_rr_type = rr_graph.node_type(RRNodeId(to_node)); if (to_rr_type == CHANX || to_rr_type == CHANY) { if (rr_graph.node_direction(RRNodeId(to_node)) != Direction::BIDIR) { /* Cout was not added in these cases */ - Couts_to_add[to_node] = std::max(Couts_to_add[to_node], rr_graph.rr_switch_inf(RRSwitchId(switch_index)).Cout); + Couts_to_add[to_node] = std::max(Couts_to_add[to_node], rr_graph.edge_Cout(inode, iedge)); } } } @@ -201,7 +186,4 @@ void add_rr_graph_C_from_switches(float C_ipin_cblock) { mutable_device_ctx.rr_graph_builder.set_node_rc_index(rr_id, NodeRCIndex(find_create_rr_rc_data(rr_graph.node_R(rr_id), rr_node_C[(size_t)rr_id], mutable_device_ctx.rr_rc_data))); } - delete[] Couts_to_add; - delete[] cblock_counted; - delete[] buffer_Cin; } diff --git a/vpr/src/util/vpr_utils.cpp b/vpr/src/util/vpr_utils.cpp index 665a4d54682..79dd56bf203 100644 --- a/vpr/src/util/vpr_utils.cpp +++ b/vpr/src/util/vpr_utils.cpp @@ -2023,12 +2023,7 @@ float get_min_cross_layer_delay() { for (size_t edge_id = 0; edge_id < rr_graph.num_edges(driver_node); edge_id++) { const RRNodeId sink_node = rr_graph.edge_sink_node(driver_node, edge_id); if (rr_graph.node_layer(driver_node) != rr_graph.node_layer(sink_node)) { - // Instead of calling edge_delay() method, we retrieve the delay from the switch type - // that the edge represents. Since the minimum delay returned by this function is used - // to construct the router lookahead, it is better nominal switch delays instead of exact - // ones that are calculated by adding edge-specific offsets. - int i_switch = rr_graph.edge_switch(driver_node, edge_id); - float edge_delay = rr_graph.rr_switch_inf(RRSwitchId(i_switch)).Tdel; + float edge_delay = rr_graph.edge_delay(driver_node, edge_id); min_delay = std::min(min_delay, edge_delay); } }