@@ -186,8 +186,8 @@ void t_rr_graph_storage::init_fan_in() {
186186 node_fan_in_.resize (node_storage_.size (), 0 );
187187 node_fan_in_.shrink_to_fit ();
188188 // Walk the graph and increment fanin on all downstream nodes
189- for (const auto & edge_id : edge_dest_node_.keys ()) {
190- node_fan_in_[edge_dest_node_[edge_id] ] += 1 ;
189+ for (const auto & [_, dest_node] : edge_dest_node_.pairs ()) {
190+ node_fan_in_[dest_node ] += 1 ;
191191 }
192192}
193193
@@ -629,16 +629,22 @@ void t_rr_graph_storage::set_node_direction(RRNodeId id, Direction new_direction
629629 node_storage_[id].dir_side_ .direction = new_direction;
630630}
631631
632- void t_rr_graph_storage::set_node_ptc_nums (RRNodeId node, const std::string& ptc_str ) {
632+ void t_rr_graph_storage::set_node_ptc_nums (RRNodeId node, const std::vector< int >& ptc_numbers ) {
633633 VTR_ASSERT (size_t (node) < node_storage_.size ());
634- std::vector<std::string> ptc_tokens = vtr::StringToken (ptc_str).split (" ," );
635- VTR_ASSERT (ptc_tokens.size () >= 1 );
636- set_node_ptc_num (node, std::stoi (ptc_tokens[0 ]));
637- if (ptc_tokens.size () > 1 ) {
634+ VTR_ASSERT (!ptc_numbers.empty ());
635+ // The default VTR RR graph generator assigns only one PTC number per node, which is
636+ // stored in the node_ptc_ field of rr_graph_storage. However, when the tileable RR
637+ // graph is used, CHANX/CHANY nodes can have multiple PTC numbers.
638+ //
639+ // To satisfy VPR's requirements, we store the PTC number for offset = 0 in the
640+ // node_ptc_ field, and store all PTC numbers assigned to the node in the
641+ // node_tileable_track_nums_ field.
642+ set_node_ptc_num (node, ptc_numbers[0 ]);
643+ if (ptc_numbers.size () > 1 ) {
638644 VTR_ASSERT (size_t (node) < node_tilable_track_nums_.size ());
639- node_tilable_track_nums_[node].resize (ptc_tokens .size ());
640- for (size_t iptc = 0 ; iptc < ptc_tokens .size (); iptc++) {
641- node_tilable_track_nums_[node][iptc] = std::stoi (ptc_tokens [iptc]) ;
645+ node_tilable_track_nums_[node].resize (ptc_numbers .size ());
646+ for (size_t iptc = 0 ; iptc < ptc_numbers .size (); iptc++) {
647+ node_tilable_track_nums_[node][iptc] = ptc_numbers [iptc];
642648 }
643649 }
644650}
@@ -650,33 +656,17 @@ void t_rr_graph_storage::add_node_tilable_track_num(RRNodeId node, size_t node_o
650656 " Track number valid only for CHANX/CHANY RR nodes" );
651657
652658 size_t node_length = std::abs (node_xhigh (node) - node_xlow (node))
653- + std::abs (node_yhigh (node) - node_ylow (node));
654- if (node_length + 1 != node_tilable_track_nums_[node].size ()) {
655- node_tilable_track_nums_[node].resize (node_length + 1 );
656- }
659+ + std::abs (node_yhigh (node) - node_ylow (node))
660+ + 1 ;
661+ VTR_ASSERT (node_offset < node_length);
657662
658- VTR_ASSERT (node_offset < node_tilable_track_nums_[node].size ());
663+ if (node_length != node_tilable_track_nums_[node].size ()) {
664+ node_tilable_track_nums_[node].resize (node_length);
665+ }
659666
660667 node_tilable_track_nums_[node][node_offset] = track_id;
661668}
662669
663- std::string t_rr_graph_storage::node_ptc_nums_to_string (RRNodeId node) const {
664- if (node_tilable_track_nums_.empty ()) {
665- return std::to_string (size_t (node_ptc_num (node)));
666- }
667- VTR_ASSERT (size_t (node) < node_tilable_track_nums_.size ());
668- if (node_tilable_track_nums_[node].empty ()) {
669- return std::to_string (size_t (node_ptc_num (node)));
670- }
671- std::string ret;
672- for (size_t iptc = 0 ; iptc < node_tilable_track_nums_[node].size (); iptc++) {
673- ret += std::to_string (size_t (node_tilable_track_nums_[node][iptc])) + " ," ;
674- }
675- // Remove the last comma
676- ret.pop_back ();
677- return ret;
678- }
679-
680670void t_rr_graph_storage::add_node_side (RRNodeId id, e_side new_side) {
681671 if (node_type (id) != e_rr_type::IPIN && node_type (id) != e_rr_type::OPIN) {
682672 VTR_LOG_ERROR (" Attempted to set RR node 'side' for non-pin type '%s'" , node_type_string (id));
@@ -703,26 +693,26 @@ void t_rr_graph_storage::set_virtual_clock_network_root_idx(RRNodeId virtual_clo
703693 }
704694}
705695
706- void t_rr_graph_storage::remove_nodes (const std::vector<RRNodeId>& nodes ) {
696+ void t_rr_graph_storage::remove_nodes (std::vector<RRNodeId> nodes_to_remove ) {
707697 VTR_ASSERT (!edges_read_);
698+ VTR_ASSERT (!partitioned_);
708699 // To remove the nodes, we first sort them in ascending order. This makes it easy
709700 // to calculate the offset by which other node IDs need to be adjusted.
710701 // For example, after sorting the nodes to be removed, if a node ID falls between
711702 // the first and second element, its ID should be reduced by 1.
712703 // If a node ID is larger than the last element, its ID should be reduced by
713704 // the total number of nodes being removed.
714- std::vector<RRNodeId> sorted_nodes = nodes;
715- std::sort (sorted_nodes.begin (), sorted_nodes.end ());
705+ std::sort (nodes_to_remove.begin (), nodes_to_remove.end ());
716706
717707 // Iterate over the nodes to be removed and adjust the IDs of nodes
718708 // that fall between them.
719- for (size_t i = 0 ; i < sorted_nodes .size (); ++i ) {
720- size_t start_rr_node_index = size_t (sorted_nodes[i ]) + 1 ;
721- size_t end_rr_node_index = (i == sorted_nodes .size () - 1 ) ? node_storage_.size () : size_t (sorted_nodes[i + 1 ]);
722- for (size_t j = start_rr_node_index; j < end_rr_node_index; ++j ) {
723- RRNodeId old_node = RRNodeId (j );
709+ for (size_t removal_idx = 0 ; removal_idx < nodes_to_remove .size (); ++removal_idx ) {
710+ size_t start_rr_node_index = size_t (nodes_to_remove[removal_idx ]) + 1 ;
711+ size_t end_rr_node_index = (removal_idx == nodes_to_remove .size () - 1 ) ? node_storage_.size () : size_t (nodes_to_remove[removal_idx + 1 ]);
712+ for (size_t node_idx = start_rr_node_index; node_idx < end_rr_node_index; ++node_idx ) {
713+ RRNodeId old_node = RRNodeId (node_idx );
724714 // New node index is equal to the old nodex index minus the number of nodes being removed before it.
725- RRNodeId new_node = RRNodeId (j-(i +1 ));
715+ RRNodeId new_node = RRNodeId (node_idx-(removal_idx +1 ));
726716 node_storage_[new_node] = node_storage_[old_node];
727717 node_ptc_[new_node] = node_ptc_[old_node];
728718 node_layer_[new_node] = node_layer_[old_node];
@@ -736,11 +726,15 @@ void t_rr_graph_storage::remove_nodes(const std::vector<RRNodeId>& nodes) {
736726 }
737727
738728 // Now that the data structures are adjusted, we can shrink the size of them
739- size_t num_nodes_to_remove = sorted_nodes .size ();
729+ size_t num_nodes_to_remove = nodes_to_remove .size ();
740730 VTR_ASSERT (num_nodes_to_remove <= node_storage_.size ());
741731 node_storage_.erase (node_storage_.end ()-num_nodes_to_remove, node_storage_.end ());
742732 node_ptc_.erase (node_ptc_.end ()-num_nodes_to_remove, node_ptc_.end ());
743733 node_layer_.erase (node_layer_.end ()-num_nodes_to_remove, node_layer_.end ());
734+ // After shifting the IDs of nodes that are not removed to the left, the last
735+ // `num_nodes_to_remove` node IDs become invalid (their names have already been
736+ // updated for other nodes). Therefore, the corresponding entries in `node_name_`
737+ // must be removed.
744738 for (size_t node_index = node_name_.size ()-num_nodes_to_remove; node_index < node_name_.size (); ++node_index) {
745739 RRNodeId node = RRNodeId (node_index);
746740 node_name_.erase (node);
@@ -752,19 +746,25 @@ void t_rr_graph_storage::remove_nodes(const std::vector<RRNodeId>& nodes) {
752746 }
753747
754748 std::vector<RREdgeId> removed_edges;
749+ // This function iterates over edge_src_node_ and edge_dest_node_ to remove
750+ // entries where either endpoint of an edge is in the nodes_to_remove list.
751+ // It also updates the node IDs of the remaining edges, since node IDs have
752+ // been shifted.
755753 auto adjust_edges = [&](vtr::vector<RREdgeId, RRNodeId>& edge_nodes) {
756754 for (size_t edge_index = 0 ; edge_index < edge_nodes.size (); ++edge_index) {
757755 RREdgeId edge_id = RREdgeId (edge_index);
758756 RRNodeId node = edge_nodes[edge_id];
759757
760758 // Find insertion point in the sorted vector
761- auto node_it = std::lower_bound (sorted_nodes .begin (), sorted_nodes .end (), node);
759+ auto node_it = std::lower_bound (nodes_to_remove .begin (), nodes_to_remove .end (), node);
762760
763- if (node_it != sorted_nodes .end () && *node_it == node) {
764- // Node exists in sorted_nodes , mark edge for removal
761+ if (node_it != nodes_to_remove .end () && *node_it == node) {
762+ // Node exists in nodes_to_remove , mark edge for removal
765763 removed_edges.push_back (edge_id);
766764 } else {
767- size_t node_offset = std::distance (sorted_nodes.begin (), node_it);
765+ // If the node is not in the nodes_to_remove list, update the node ID of the edge
766+ // by finding how many nodes are there in nodes_to_remove before the node.
767+ size_t node_offset = std::distance (nodes_to_remove.begin (), node_it);
768768 size_t new_node_index = size_t (node) - node_offset;
769769 edge_nodes[edge_id] = RRNodeId (new_node_index);
770770 }
0 commit comments