@@ -801,8 +801,15 @@ class t_rr_graph_storage {
801801 void mark_edges_as_rr_switch_ids ();
802802
803803 /* * @brief
804- * Sorts edge data such that configurable edges appears before
805- * non-configurable edges.
804+ * Sorts all edges based on source node with configurable coming first, or equivalently
805+ * partitions the edges based on their source node and configurability. Afterwards, it
806+ * builds a list of indices to each RRNodeId's first edge. With this, it can then easily
807+ * say which edges belong to which node.
808+ *
809+ * @param rr_switches Information of switches, used to figure out if edge is configurable or not.
810+ *
811+ * @note Must be called after constructing the RR Graph. You can not use most of the edge accessor
812+ * methods before this method is called since the relevant data structures are not set up yet.
806813 */
807814 void partition_edges (const vtr::vector<RRSwitchId, t_rr_switch_inf>& rr_switches);
808815
@@ -829,31 +836,32 @@ class t_rr_graph_storage {
829836 std::vector<RREdgeId> edge_indices (edge_range.begin (), edge_range.end ());
830837
831838 std::ranges::stable_sort (edge_indices, comparison_function);
832-
833- vtr::vector<RREdgeId, RRNodeId> new_edge_src_node_ (num_edges, RRNodeId::INVALID ());
834- vtr::vector<RREdgeId, RRNodeId> new_edge_dest_node_ (num_edges, RRNodeId::INVALID ());
835- vtr::vector<RREdgeId, short > new_edge_switch_ (num_edges, LIBRRGRAPH_UNDEFINED_VAL);
836- vtr::vector<RREdgeId, bool > new_edge_remapped_ (num_edges, false );
837839
838- size_t new_index = 0 ;
839- for (RREdgeId edge_index : edge_indices) {
840-
841- RREdgeId new_edge_index = RREdgeId (new_index);
842-
843- new_edge_src_node_[new_edge_index] = edge_src_node_[edge_index];
844- new_edge_dest_node_[new_edge_index] = edge_dest_node_[edge_index];
845- new_edge_switch_[new_edge_index] = edge_switch_[edge_index];
846- new_edge_remapped_[new_edge_index] = edge_remapped_[edge_index];
847-
848- new_index++;
849- }
840+ // Generic lambda that allocates a 'vec'-sized new vector with all elements set to default value,
841+ // then builds the new vector to have rearranged elements from 'vec' and finaly move the new vector
842+ // to replace vec. Essentially does a permutation on vec based on edge_indices.
843+ auto array_rearrage = [&edge_indices] (auto & vec, auto default_value) {
844+
845+ // Since vec could have any type, we need to figure out it's type to allocate new_vec.
846+ // The scary std::remove_reference stuff does exactly that. This does nothing other than building a new 'vec' sized vector.
847+ typename std::remove_reference<decltype (vec)>::type new_vec (vec.size (), default_value);
848+
849+ size_t new_index = 0 ;
850+ for (RREdgeId edge_index : edge_indices) {
851+ RREdgeId new_edge_index = RREdgeId (new_index);
852+ new_vec[new_edge_index] = vec[edge_index];
853+
854+ new_index++;
855+ }
856+ VTR_ASSERT (new_index == vec.size ());
850857
851- VTR_ASSERT (new_index == num_edges);
858+ vec = std::move (new_vec);
859+ };
852860
853- edge_src_node_ = std::move (new_edge_src_node_ );
854- edge_dest_node_ = std::move (new_edge_dest_node_ );
855- edge_switch_ = std::move (new_edge_switch_ );
856- edge_remapped_ = std::move (new_edge_remapped_ );
861+ array_rearrage ( edge_src_node_, RRNodeId::INVALID () );
862+ array_rearrage ( edge_dest_node_, RRNodeId::INVALID () );
863+ array_rearrage ( edge_switch_, LIBRRGRAPH_UNDEFINED_VAL );
864+ array_rearrage ( edge_remapped_, false );
857865 }
858866
859867 /* *****************
0 commit comments