Skip to content

Commit a3e451f

Browse files
Sort edges one by one
1 parent 3169003 commit a3e451f

File tree

1 file changed

+32
-24
lines changed

1 file changed

+32
-24
lines changed

libs/librrgraph/src/base/rr_graph_storage.h

Lines changed: 32 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)