diff --git a/libs/librrgraph/src/base/rr_graph_builder.cpp b/libs/librrgraph/src/base/rr_graph_builder.cpp index a09c4a727a..85b7d2bf96 100644 --- a/libs/librrgraph/src/base/rr_graph_builder.cpp +++ b/libs/librrgraph/src/base/rr_graph_builder.cpp @@ -31,10 +31,6 @@ vtr::vector>& RRGraphBuilder::node_in_edge_stora return node_in_edges_; } -vtr::vector>& RRGraphBuilder::node_ptc_storage() { - return node_tilable_track_nums_; -} - void RRGraphBuilder::add_node_to_all_locs(RRNodeId node) { e_rr_type node_type = node_storage_.node_type(node); short node_ptc_num = node_storage_.node_ptc_num(node); @@ -76,7 +72,6 @@ RRNodeId RRGraphBuilder::create_node(int layer, int x, int y, e_rr_type type, in node_side = side; } node_storage_.emplace_back(); - node_tilable_track_nums_.emplace_back(); RRNodeId new_node = RRNodeId(node_storage_.size() - 1); node_storage_.set_node_layer(new_node, layer, layer); node_storage_.set_node_type(new_node, type); @@ -102,7 +97,6 @@ void RRGraphBuilder::clear() { node_lookup_.clear(); node_storage_.clear(); node_in_edges_.clear(); - node_tilable_track_nums_.clear(); rr_node_metadata_.clear(); rr_edge_metadata_.clear(); rr_segments_.clear(); @@ -231,59 +225,17 @@ std::vector RRGraphBuilder::node_in_edges(RRNodeId node) const { return node_in_edges_[node]; } -void RRGraphBuilder::set_node_ptc_nums(RRNodeId node, const std::string& ptc_str) { - VTR_ASSERT(size_t(node) < node_storage_.size()); - std::vector ptc_tokens = vtr::StringToken(ptc_str).split(","); - VTR_ASSERT(ptc_tokens.size() >= 1); - set_node_ptc_num(node, std::stoi(ptc_tokens[0])); - if (ptc_tokens.size() > 1) { - VTR_ASSERT(size_t(node) < node_tilable_track_nums_.size()); - node_tilable_track_nums_[node].resize(ptc_tokens.size()); - for (size_t iptc = 0; iptc < ptc_tokens.size(); iptc++) { - node_tilable_track_nums_[node][iptc] = std::stoi(ptc_tokens[iptc]); - } - } -} - -std::string RRGraphBuilder::node_ptc_nums_to_string(RRNodeId node) const { - if (node_tilable_track_nums_.empty()) { - return std::to_string(size_t(node_storage_.node_ptc_num(node))); - } - VTR_ASSERT(size_t(node) < node_tilable_track_nums_.size()); - if (node_tilable_track_nums_[node].empty()) { - return std::to_string(size_t(node_storage_.node_ptc_num(node))); - } - std::string ret; - for (size_t iptc = 0; iptc < node_tilable_track_nums_[node].size(); iptc++) { - ret += std::to_string(size_t(node_tilable_track_nums_[node][iptc])) + ","; - } - // Remove the last comma - ret.pop_back(); - return ret; +void RRGraphBuilder::set_node_ptc_nums(RRNodeId node, const std::vector& ptc_numbers) { + node_storage_.set_node_ptc_nums(node, ptc_numbers); } bool RRGraphBuilder::node_contain_multiple_ptc(RRNodeId node) const { - if (node_tilable_track_nums_.empty()) { - return false; - } - return node_tilable_track_nums_[node].size() > 1; + return node_storage_.node_contain_multiple_ptc(node); } void RRGraphBuilder::add_node_track_num(RRNodeId node, vtr::Point node_offset, short track_id) { - VTR_ASSERT(size_t(node) < node_storage_.size()); - VTR_ASSERT(size_t(node) < node_tilable_track_nums_.size()); - VTR_ASSERT_MSG(node_storage_.node_type(node) == e_rr_type::CHANX || node_storage_.node_type(node) == e_rr_type::CHANY, "Track number valid only for CHANX/CHANY RR nodes"); - - size_t node_length = std::abs(node_storage_.node_xhigh(node) - node_storage_.node_xlow(node)) - + std::abs(node_storage_.node_yhigh(node) - node_storage_.node_ylow(node)); - if (node_length + 1 != node_tilable_track_nums_[node].size()) { - node_tilable_track_nums_[node].resize(node_length + 1); - } - - size_t offset = node_offset.x() - node_storage_.node_xlow(node) + node_offset.y() - node_storage_.node_ylow(node); - VTR_ASSERT(offset < node_tilable_track_nums_[node].size()); - - node_tilable_track_nums_[node][offset] = track_id; + size_t node_offset_value = node_offset.x() - node_storage_.node_xlow(node) + node_offset.y() - node_storage_.node_ylow(node); + node_storage_.add_node_tilable_track_num(node, node_offset_value, track_id); } void RRGraphBuilder::add_track_node_to_lookup(RRNodeId node) { @@ -309,8 +261,13 @@ void RRGraphBuilder::add_track_node_to_lookup(RRNodeId node) { // Routing channel nodes may have different ptc num // Find the track ids using the x/y offset if (e_rr_type::CHANX == node_type || e_rr_type::CHANY == node_type) { - ptc = (node_type == e_rr_type::CHANX) ? node_tilable_track_nums_[node][x - node_storage_.node_xlow(node)] : - node_tilable_track_nums_[node][y - node_storage_.node_ylow(node)]; + const std::vector& track_nums = node_storage_.node_tilable_track_nums(node); + if (node_type == e_rr_type::CHANX) { + ptc = track_nums[x - node_storage_.node_xlow(node)]; + } else { + VTR_ASSERT_DEBUG(node_type == e_rr_type::CHANY); + ptc = track_nums[y - node_storage_.node_ylow(node)]; + } node_lookup_.add_node(node, node_storage_.node_layer_low(node), x, y, node_type, ptc); } } diff --git a/libs/librrgraph/src/base/rr_graph_builder.h b/libs/librrgraph/src/base/rr_graph_builder.h index cfe8236ebb..ed1d3d015c 100644 --- a/libs/librrgraph/src/base/rr_graph_builder.h +++ b/libs/librrgraph/src/base/rr_graph_builder.h @@ -50,9 +50,6 @@ class RRGraphBuilder { /** @brief Return a writable object for the incoming edge storage */ vtr::vector>& node_in_edge_storage(); - - /** @brief Return a writable object of the node ptc storage (for tileable routing resource graph) */ - vtr::vector>& node_ptc_storage(); /** @brief Return the size for rr_node_metadata */ inline size_t rr_node_metadata_size() const { @@ -279,11 +276,8 @@ class RRGraphBuilder { node_storage_.set_node_mux_num(id, new_mux_num); } - /** @brief Add a list of ptc number in string (split by comma) to a given node. This function is used by rr graph reader only. */ - void set_node_ptc_nums(RRNodeId node, const std::string& ptc_str); - - /** @brief With a given node, output ptc numbers into a string (use comma as delima). This function is used by rr graph writer only. */ - std::string node_ptc_nums_to_string(RRNodeId node) const; + /** @brief Add a list of ptc numbers to a given node. This function is used by rr graph reader only. */ + void set_node_ptc_nums(RRNodeId node, const std::vector& ptc_numbers); /** @brief Identify if a node contains multiple ptc numbers. It is used for tileable RR Graph and mainly used by I/O reader only. */ bool node_contain_multiple_ptc(RRNodeId node) const; @@ -407,13 +401,6 @@ class RRGraphBuilder { return node_storage_.count_rr_switches(arch_switch_inf, arch_switch_fanins); } - /** @brief Unlock storage; required to modify an routing resource graph after edge is read */ - inline void unlock_storage() { - node_storage_.edges_read_ = false; - node_storage_.partitioned_ = false; - node_storage_.clear_node_first_edge(); - } - /** @brief Reserve the lists of nodes, edges, switches etc. to be memory efficient. * This function is mainly used to reserve memory space inside RRGraph, * when adding a large number of nodes/edge/switches/segments, @@ -432,10 +419,6 @@ class RRGraphBuilder { inline void resize_nodes(size_t size) { node_storage_.resize(size); } - /** @brief This function resize node ptc nums. Only used by RR graph I/O reader and writers. */ - inline void resize_node_ptc_nums(size_t size) { - node_tilable_track_nums_.resize(size); - } /** @brief This function resize rr_switch to accommodate size RR Switch. */ @@ -539,29 +522,6 @@ class RRGraphBuilder { */ vtr::vector> node_in_edges_; - /** - * @brief Extra ptc number for each routing resource node. - * @note This is required by tileable routing resource graphs. The first index is the node id, and - * the second index is is the relative distance from the starting point of the node. - * @details - * In a tileable routing architecture, routing tracks, e.g., CHANX and CHANY, follow a staggered organization. - * Hence, a routing track may appear in different routing channels, representing different ptc/track id. - * Here is an illustrative example of a X-direction routing track (CHANX) in INC direction, which is organized in staggered way. - * - * Coord(x,y) (1,0) (2,0) (3,0) (4,0) Another track (node) - * ptc=0 ------> ------> - * \ / - * ptc=1 ------> / - * \ / - * ptc=2 ------> / - * \ / - * ptc=3 -------> - * ^ ^ - * | | - * starting point ending point - */ - vtr::vector> node_tilable_track_nums_; - /** @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_storage.cpp b/libs/librrgraph/src/base/rr_graph_storage.cpp index 9c4871e39e..9c7fa25f79 100644 --- a/libs/librrgraph/src/base/rr_graph_storage.cpp +++ b/libs/librrgraph/src/base/rr_graph_storage.cpp @@ -63,6 +63,10 @@ void t_rr_graph_storage::alloc_and_load_edges(const t_rr_edge_info_set* rr_edges void t_rr_graph_storage::remove_edges(std::vector& rr_edges_to_remove) { VTR_ASSERT(!edges_read_); + if (rr_edges_to_remove.empty()) { + return; + } + size_t starting_edge_count = edge_dest_node_.size(); // Sort and make sure all edge indices are unique @@ -178,12 +182,12 @@ bool t_rr_graph_storage::verify_first_edges() const { void t_rr_graph_storage::init_fan_in() { //Reset all fan-ins to zero - edges_read_ = true; + node_fan_in_.clear(); 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()) { - node_fan_in_[edge_dest_node_[edge_id]] += 1; + for(const auto& [_, dest_node] : edge_dest_node_.pairs()) { + node_fan_in_[dest_node] += 1; } } @@ -625,6 +629,44 @@ void t_rr_graph_storage::set_node_direction(RRNodeId id, Direction new_direction node_storage_[id].dir_side_.direction = new_direction; } +void t_rr_graph_storage::set_node_ptc_nums(RRNodeId node, const std::vector& ptc_numbers) { + VTR_ASSERT(size_t(node) < node_storage_.size()); + VTR_ASSERT(!ptc_numbers.empty()); + // The default VTR RR graph generator assigns only one PTC number per node, which is + // stored in the node_ptc_ field of rr_graph_storage. However, when the tileable RR + // graph is used, CHANX/CHANY nodes can have multiple PTC numbers. + // + // To satisfy VPR's requirements, we store the PTC number for offset = 0 in the + // node_ptc_ field, and store all PTC numbers assigned to the node in the + // node_tileable_track_nums_ field. + set_node_ptc_num(node, ptc_numbers[0]); + if (ptc_numbers.size() > 1) { + VTR_ASSERT(size_t(node) < node_tilable_track_nums_.size()); + node_tilable_track_nums_[node].resize(ptc_numbers.size()); + for (size_t iptc = 0; iptc < ptc_numbers.size(); iptc++) { + node_tilable_track_nums_[node][iptc] = ptc_numbers[iptc]; + } + } +} + +void t_rr_graph_storage::add_node_tilable_track_num(RRNodeId node, size_t node_offset, short track_id) { + VTR_ASSERT(size_t(node) < node_storage_.size()); + VTR_ASSERT(size_t(node) < node_tilable_track_nums_.size()); + VTR_ASSERT_MSG(node_type(node) == e_rr_type::CHANX || node_type(node) == e_rr_type::CHANY, + "Track number valid only for CHANX/CHANY RR nodes"); + + size_t node_length = std::abs(node_xhigh(node) - node_xlow(node)) + + std::abs(node_yhigh(node) - node_ylow(node)) + + 1; + VTR_ASSERT(node_offset < node_length); + + if (node_length != node_tilable_track_nums_[node].size()) { + node_tilable_track_nums_[node].resize(node_length); + } + + node_tilable_track_nums_[node][node_offset] = track_id; +} + void t_rr_graph_storage::add_node_side(RRNodeId id, e_side new_side) { if (node_type(id) != e_rr_type::IPIN && node_type(id) != e_rr_type::OPIN) { VTR_LOG_ERROR("Attempted to set RR node 'side' for non-pin type '%s'", node_type_string(id)); @@ -651,6 +693,90 @@ void t_rr_graph_storage::set_virtual_clock_network_root_idx(RRNodeId virtual_clo } } +void t_rr_graph_storage::remove_nodes(std::vector nodes_to_remove) { + VTR_ASSERT(!edges_read_); + VTR_ASSERT(!partitioned_); + // To remove the nodes, we first sort them in ascending order. This makes it easy + // to calculate the offset by which other node IDs need to be adjusted. + // For example, after sorting the nodes to be removed, if a node ID falls between + // the first and second element, its ID should be reduced by 1. + // If a node ID is larger than the last element, its ID should be reduced by + // the total number of nodes being removed. + std::sort(nodes_to_remove.begin(), nodes_to_remove.end()); + + // Iterate over the nodes to be removed and adjust the IDs of nodes + // that fall between them. + for (size_t removal_idx = 0; removal_idx < nodes_to_remove.size(); ++removal_idx) { + size_t start_rr_node_index = size_t(nodes_to_remove[removal_idx]) + 1; + size_t end_rr_node_index = (removal_idx == nodes_to_remove.size() - 1) ? node_storage_.size() : size_t(nodes_to_remove[removal_idx + 1]); + for (size_t node_idx = start_rr_node_index; node_idx < end_rr_node_index; ++node_idx) { + RRNodeId old_node = RRNodeId(node_idx); + // New node index is equal to the old nodex index minus the number of nodes being removed before it. + RRNodeId new_node = RRNodeId(node_idx-(removal_idx+1)); + node_storage_[new_node] = node_storage_[old_node]; + node_ptc_[new_node] = node_ptc_[old_node]; + node_layer_[new_node] = node_layer_[old_node]; + node_name_[new_node] = node_name_[old_node]; + if (is_tileable_) { + node_bend_start_[new_node] = node_bend_start_[old_node]; + node_bend_end_[new_node] = node_bend_end_[old_node]; + node_tilable_track_nums_[new_node] = node_tilable_track_nums_[old_node]; + } + } + } + + // Now that the data structures are adjusted, we can shrink the size of them + size_t num_nodes_to_remove = nodes_to_remove.size(); + VTR_ASSERT(num_nodes_to_remove <= node_storage_.size()); + node_storage_.erase(node_storage_.end()-num_nodes_to_remove, node_storage_.end()); + node_ptc_.erase(node_ptc_.end()-num_nodes_to_remove, node_ptc_.end()); + node_layer_.erase(node_layer_.end()-num_nodes_to_remove, node_layer_.end()); + // After shifting the IDs of nodes that are not removed to the left, the last + // `num_nodes_to_remove` node IDs become invalid (their names have already been + // updated for other nodes). Therefore, the corresponding entries in `node_name_` + // must be removed. + for (size_t node_index = node_name_.size()-num_nodes_to_remove; node_index < node_name_.size(); ++node_index) { + RRNodeId node = RRNodeId(node_index); + node_name_.erase(node); + } + if (is_tileable_) { + node_bend_start_.erase(node_bend_start_.end()-num_nodes_to_remove, node_bend_start_.end()); + node_bend_end_.erase(node_bend_end_.end()-num_nodes_to_remove, node_bend_end_.end()); + node_tilable_track_nums_.erase(node_tilable_track_nums_.end()-num_nodes_to_remove, node_tilable_track_nums_.end()); + } + + std::vector removed_edges; + // This function iterates over edge_src_node_ and edge_dest_node_ to remove + // entries where either endpoint of an edge is in the nodes_to_remove list. + // It also updates the node IDs of the remaining edges, since node IDs have + // been shifted. + auto adjust_edges = [&](vtr::vector& edge_nodes) { + for (size_t edge_index = 0; edge_index < edge_nodes.size(); ++edge_index) { + RREdgeId edge_id = RREdgeId(edge_index); + RRNodeId node = edge_nodes[edge_id]; + + // Find insertion point in the sorted vector + auto node_it = std::lower_bound(nodes_to_remove.begin(), nodes_to_remove.end(), node); + + if (node_it != nodes_to_remove.end() && *node_it == node) { + // Node exists in nodes_to_remove, mark edge for removal + removed_edges.push_back(edge_id); + } else { + // If the node is not in the nodes_to_remove list, update the node ID of the edge + // by finding how many nodes are there in nodes_to_remove before the node. + size_t node_offset = std::distance(nodes_to_remove.begin(), node_it); + size_t new_node_index = size_t(node) - node_offset; + edge_nodes[edge_id] = RRNodeId(new_node_index); + } + } + }; + + adjust_edges(edge_src_node_); + adjust_edges(edge_dest_node_); + + remove_edges(removed_edges); +} + int t_rr_graph_view::node_ptc_num(RRNodeId id) const { return node_ptc_[id].ptc_.pin_num; } diff --git a/libs/librrgraph/src/base/rr_graph_storage.h b/libs/librrgraph/src/base/rr_graph_storage.h index 5f78430a65..9fe67e7f56 100644 --- a/libs/librrgraph/src/base/rr_graph_storage.h +++ b/libs/librrgraph/src/base/rr_graph_storage.h @@ -564,6 +564,9 @@ class t_rr_graph_storage { node_bend_end_.reserve(node_storage_.capacity()); node_bend_end_.resize(node_storage_.size()); + + node_tilable_track_nums_.reserve(node_storage_.capacity()); + node_tilable_track_nums_.resize(node_storage_.size()); } } @@ -577,6 +580,7 @@ class t_rr_graph_storage { if (is_tileable_) { node_bend_start_.reserve(size); node_bend_end_.reserve(size); + node_tilable_track_nums_.reserve(size); } } @@ -590,6 +594,7 @@ class t_rr_graph_storage { if (is_tileable_) { node_bend_start_.resize(size); node_bend_end_.resize(size); + node_tilable_track_nums_.resize(size); } } @@ -614,6 +619,7 @@ class t_rr_graph_storage { node_layer_.clear(); node_bend_start_.clear(); node_bend_end_.clear(); + node_tilable_track_nums_.clear(); node_name_.clear(); virtual_clock_network_root_idx_.clear(); edge_src_node_.clear(); @@ -623,7 +629,6 @@ class t_rr_graph_storage { edges_read_ = false; partitioned_ = false; remapped_edges_ = false; - is_tileable_ = false; } /** @brief @@ -652,7 +657,7 @@ class t_rr_graph_storage { node_layer_.shrink_to_fit(); node_bend_start_.shrink_to_fit(); node_bend_end_.shrink_to_fit(); - + node_tilable_track_nums_.shrink_to_fit(); edge_src_node_.shrink_to_fit(); edge_dest_node_.shrink_to_fit(); edge_switch_.shrink_to_fit(); @@ -669,6 +674,7 @@ class t_rr_graph_storage { if (is_tileable_) { node_bend_start_.emplace_back(); node_bend_end_.emplace_back(); + node_tilable_track_nums_.emplace_back(); } } @@ -699,6 +705,33 @@ class t_rr_graph_storage { void set_node_capacity(RRNodeId, short new_capacity); void set_node_direction(RRNodeId, Direction new_direction); + /** + * @brief Set the ptc numbers for a node. + * @param node The node id + * @param ptc_numbers The ptc numbers vector to be set for the node. + */ + void set_node_ptc_nums(RRNodeId node, const std::vector& ptc_numbers); + + /** + * @brief Add a track number to a node. + * @param node The node id + * @param node_offset The offset of the node from the beginning of the node. + * @param track_id The track number (ptc number) of the node at the given offset. + */ + void add_node_tilable_track_num(RRNodeId node, size_t node_offset, short track_id); + + bool node_contain_multiple_ptc(RRNodeId node) const { + if (node_tilable_track_nums_.empty()) { + return false; + } else { + return node_tilable_track_nums_[node].size() > 1; + } + } + + const std::vector& node_tilable_track_nums(RRNodeId node) const { + return node_tilable_track_nums_[node]; + } + /** @brief * Add a side to the node attributes * This is the function to use when you just add a new side WITHOUT resetting side attributes @@ -712,6 +745,20 @@ class t_rr_graph_storage { */ void set_virtual_clock_network_root_idx(RRNodeId virtual_clock_network_root_idx); + /** + * @brief Removes a given list of RRNodes from the RR Graph + * This method should be called before partition_edges has been called. + * If init_fan_in has been called, you need to call it again after removing the nodes. + * @note This a very expensive method, so should be called only when necessary. It is better + * to not add nodes in the first place, instead of relying on this method to remove nodes. + * + * @note This operation is O(|V| + |E|·log k), where k is the number of nodes to remove, + * and should not be called frequently. + * + * @param nodes_to_remove list of RRNodes to be removed + */ + void remove_nodes(std::vector nodes_to_remove); + /**************** * Edge methods * ****************/ @@ -962,6 +1009,29 @@ class t_rr_graph_storage { */ vtr::vector node_ptc_; + /** + * @brief Extra ptc number for each routing resource node. + * @note This is required by tileable routing resource graphs. The first index is the node id, and + * the second index is is the relative distance from the starting point of the node. + * @details + * In a tileable routing architecture, routing tracks, e.g., CHANX and CHANY, follow a staggered organization. + * Hence, a routing track may appear in different routing channels, representing different ptc/track id. + * Here is an illustrative example of a X-direction routing track (CHANX) in INC direction, which is organized in staggered way. + * + * Coord(x,y) (1,0) (2,0) (3,0) (4,0) Another track (node) + * ptc=0 ------> ------> + * \ / + * ptc=1 ------> / + * \ / + * ptc=2 ------> / + * \ / + * ptc=3 -------> + * ^ ^ + * | | + * starting point ending point + */ + vtr::vector> node_tilable_track_nums_; + /** @brief * This array stores the first edge of each RRNodeId. Not that the length * of this vector is always storage_.size() + 1, where the last value is diff --git a/libs/librrgraph/src/base/rr_graph_utils.cpp b/libs/librrgraph/src/base/rr_graph_utils.cpp index 67a7f8a759..5995aef197 100644 --- a/libs/librrgraph/src/base/rr_graph_utils.cpp +++ b/libs/librrgraph/src/base/rr_graph_utils.cpp @@ -390,4 +390,30 @@ bool chan_same_type_are_adjacent(const RRGraphView& rr_graph, RRNodeId node1, RR } return false; // unreachable -} \ No newline at end of file +} + +std::vector parse_ptc_numbers(const std::string& ptc_str) { + std::vector ptc_numbers; + std::vector ptc_tokens = vtr::StringToken(ptc_str).split(","); + for (const std::string& ptc_token : ptc_tokens) { + ptc_numbers.push_back(std::stoi(ptc_token)); + } + return ptc_numbers; +} + +std::string node_ptc_number_to_string(const RRGraphView& rr_graph, RRNodeId node) { + const t_rr_graph_storage& node_storage = rr_graph.rr_nodes(); + + if (!node_storage.node_contain_multiple_ptc(node)) { + return std::to_string(size_t(node_storage.node_ptc_num(node))); + } + + std::string ret; + const std::vector& track_nums = node_storage.node_tilable_track_nums(node); + for (size_t iptc = 0; iptc < track_nums.size(); iptc++) { + ret += std::to_string(track_nums[iptc]) + ","; + } + // Remove the last comma + ret.pop_back(); + return ret; +} diff --git a/libs/librrgraph/src/base/rr_graph_utils.h b/libs/librrgraph/src/base/rr_graph_utils.h index ebe48e3b37..cc708edafe 100644 --- a/libs/librrgraph/src/base/rr_graph_utils.h +++ b/libs/librrgraph/src/base/rr_graph_utils.h @@ -125,3 +125,17 @@ bool chanxy_chanz_adjacent(const RRGraphView& rr_graph, RRNodeId node1, RRNodeId bool chan_same_type_are_adjacent(const RRGraphView& rr_graph, RRNodeId node1, RRNodeId node2); +/** + * @brief Parse the ptc numbers string into a vector of integers. + * @param ptc_str The ptc numbers string in the format of "ptc1,ptc2,ptc3,...ptcn". + * @return A vector of integers representing the ptc numbers. + */ +std::vector parse_ptc_numbers(const std::string& ptc_str); + +/** + * @brief Convert the ptc numbers of a node to a string. + * @param rr_graph The routing resource graph + * @param node The node id + * @return A string representing the ptc numbers of the node in the format of "ptc1,ptc2,ptc3,...ptcn". + */ +std::string node_ptc_number_to_string(const RRGraphView& rr_graph, RRNodeId node); diff --git a/libs/librrgraph/src/base/rr_graph_view.cpp b/libs/librrgraph/src/base/rr_graph_view.cpp index 0b8b04b13e..4f5cbb7773 100644 --- a/libs/librrgraph/src/base/rr_graph_view.cpp +++ b/libs/librrgraph/src/base/rr_graph_view.cpp @@ -10,8 +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>& node_in_edges, - const vtr::vector>& node_tileable_track_nums) + const vtr::vector>& node_in_edges) : node_storage_(node_storage) , node_lookup_(node_lookup) , rr_node_metadata_(rr_node_metadata) @@ -20,9 +19,7 @@ RRGraphView::RRGraphView(const t_rr_graph_storage& node_storage, , rr_rc_data_(rr_rc_data) , rr_segments_(rr_segments) , rr_switch_inf_(rr_switch_inf) - , node_in_edges_(node_in_edges) - , node_tileable_track_nums_(node_tileable_track_nums) { -} + , node_in_edges_(node_in_edges) {} std::vector RRGraphView::node_in_edges(RRNodeId node) const { VTR_ASSERT(size_t(node) < node_storage_.size()); diff --git a/libs/librrgraph/src/base/rr_graph_view.h b/libs/librrgraph/src/base/rr_graph_view.h index 77c0b5b1ce..f9af258ffc 100644 --- a/libs/librrgraph/src/base/rr_graph_view.h +++ b/libs/librrgraph/src/base/rr_graph_view.h @@ -83,8 +83,7 @@ class RRGraphView { const std::vector& rr_rc_data, const vtr::vector& rr_segments, const vtr::vector& rr_switch_inf, - const vtr::vector>& node_in_edges, - const vtr::vector>& node_ptc_nums); + const vtr::vector>& node_in_edges); /* Disable copy constructors and copy assignment operator * This is to avoid accidental copy because it could be an expensive operation considering that the @@ -825,8 +824,4 @@ class RRGraphView { /// A list of incoming edges for each routing resource node. This can be built optionally, as required by applications. /// By default, it is empty. Call build_in_edges() to construct it. const vtr::vector>& node_in_edges_; - - /// A list of extra ptc numbers for each routing resource node. This is only used for tileable architecture. - /// See details in RRGraphBuilder class - const vtr::vector>& node_tileable_track_nums_; }; diff --git a/libs/librrgraph/src/io/rr_graph_reader.cpp b/libs/librrgraph/src/io/rr_graph_reader.cpp index ff0f8b9e4a..41d3d76211 100644 --- a/libs/librrgraph/src/io/rr_graph_reader.cpp +++ b/libs/librrgraph/src/io/rr_graph_reader.cpp @@ -83,6 +83,10 @@ void load_rr_file(RRGraphBuilder* rr_graph_builder, rr_graph_builder->add_rr_segment(segment_inf[(iseg)]); } + if (graph_type == e_graph_type::UNIDIR_TILEABLE) { + rr_graph_builder->set_tileable(true); + } + RrGraphSerializer reader( graph_type, base_cost_type, diff --git a/libs/librrgraph/src/io/rr_graph_uxsdcxx_serializer.h b/libs/librrgraph/src/io/rr_graph_uxsdcxx_serializer.h index 3f76fa47f2..69240efb78 100644 --- a/libs/librrgraph/src/io/rr_graph_uxsdcxx_serializer.h +++ b/libs/librrgraph/src/io/rr_graph_uxsdcxx_serializer.h @@ -713,11 +713,12 @@ class RrGraphSerializer final : public uxsd::RrGraphBase { inline void set_node_loc_ptc(const char* ptc, int& inode) final { t_rr_node node = (*rr_nodes_)[inode]; RRNodeId node_id = node.id(); - return rr_graph_builder_->set_node_ptc_nums(node_id, std::string(ptc)); + std::vector ptc_numbers = parse_ptc_numbers(ptc); + return rr_graph_builder_->set_node_ptc_nums(node_id, ptc_numbers); } inline const char* get_node_loc_ptc(const t_rr_node& node) final { - temp_string_ = rr_graph_builder_->node_ptc_nums_to_string(node.id()); + temp_string_ = node_ptc_number_to_string(*rr_graph_, node.id()); return temp_string_.c_str(); } inline int get_node_loc_layer_low(const t_rr_node& node) final { @@ -896,7 +897,6 @@ class RrGraphSerializer final : public uxsd::RrGraphBase { */ inline void preallocate_rr_nodes_node(void*& /*ctx*/, size_t size) final { rr_graph_builder_->reserve_nodes(size); - rr_graph_builder_->resize_node_ptc_nums(size); } inline int add_rr_nodes_node(void*& /*ctx*/, unsigned int capacity, unsigned int id, uxsd::enum_node_type type) final { // make_room_in_vector will not allocate if preallocate_rr_nodes_node @@ -1195,7 +1195,7 @@ class RrGraphSerializer final : public uxsd::RrGraphBase { most_frequent_switch.first = switch_id; most_frequent_switch.second = count_for_wire_to_ipin_switches[switch_id]; } - } else{ + } else { VTR_ASSERT(rr_graph.node_layer_low(RRNodeId(sink_node)) != rr_graph.node_layer_low(RRNodeId(source_node))); count_for_wire_to_ipin_switches_between_dice[switch_id]++; if(count_for_wire_to_ipin_switches_between_dice[switch_id] > most_frequent_switch_between_dice.second){ diff --git a/vpr/src/base/vpr_context.h b/vpr/src/base/vpr_context.h index dce08e1504..6749c7f42f 100644 --- a/vpr/src/base/vpr_context.h +++ b/vpr/src/base/vpr_context.h @@ -237,8 +237,7 @@ struct DeviceContext : public Context { rr_rc_data, rr_graph_builder.rr_segments(), rr_graph_builder.rr_switch(), - rr_graph_builder.node_in_edge_storage(), - rr_graph_builder.node_ptc_storage()}; + rr_graph_builder.node_in_edge_storage()}; ///@brief Track ids for each rr_node in the rr_graph. This is used by drawer for tileable routing resource graph std::map> rr_node_track_ids; diff --git a/vpr/src/route/router_lookahead/router_lookahead_map.cpp b/vpr/src/route/router_lookahead/router_lookahead_map.cpp index c7ea331f45..2cacbe1424 100644 --- a/vpr/src/route/router_lookahead/router_lookahead_map.cpp +++ b/vpr/src/route/router_lookahead/router_lookahead_map.cpp @@ -760,8 +760,7 @@ static void compute_tile_lookahead(std::unordered_map