55#include " vtr_assert.h"
66#include " vtr_error.h"
77#include " librrgraph_types.h"
8+ #include " vtr_sort.h"
89#include " vtr_util.h"
910
1011#include < algorithm>
@@ -194,23 +195,32 @@ void t_rr_graph_storage::init_fan_in() {
194195 }
195196}
196197
197- namespace {
198- // / Functor for sorting edges according to destination node's ID.
199- class edge_compare_dest_node {
200- public:
201- edge_compare_dest_node (const t_rr_graph_storage& rr_graph_storage) : rr_graph_storage_(rr_graph_storage) {}
198+ void t_rr_graph_storage::apply_edge_permutation (const std::vector<RREdgeId>& edge_indices) {
199+ // Generic lambda that allocates a 'vec'-sized new vector with all elements set to default value,
200+ // then builds the new vector to have rearranged elements from 'vec' and finally move the new vector
201+ // to replace vec. Essentially does a permutation on vec based on edge_indices.
202+ auto array_rearrange = [&edge_indices](auto & vec, auto default_value) {
203+ // Since vec could have any type, we need to figure out its type to allocate new_vec.
204+ // The scary std::remove_reference stuff does exactly that. This does nothing other than building a new 'vec' sized vector.
205+ typename std::remove_reference<decltype (vec)>::type new_vec (vec.size (), default_value);
202206
203- bool operator ()(RREdgeId lhs, RREdgeId rhs) const {
204- RRNodeId lhs_dest_node = rr_graph_storage_.edge_sink_node (lhs);
205- RRNodeId rhs_dest_node = rr_graph_storage_.edge_sink_node (rhs);
207+ size_t new_index = 0 ;
208+ for (RREdgeId edge_index : edge_indices) {
209+ RREdgeId new_edge_index = RREdgeId (new_index);
210+ new_vec[new_edge_index] = vec[edge_index];
206211
207- return lhs_dest_node < rhs_dest_node;
208- }
212+ new_index++;
213+ }
214+ VTR_ASSERT (new_index == vec.size ());
215+
216+ vec = std::move (new_vec);
217+ };
209218
210- private:
211- const t_rr_graph_storage& rr_graph_storage_;
212- };
213- } // namespace
219+ array_rearrange (edge_src_node_, RRNodeId::INVALID ());
220+ array_rearrange (edge_dest_node_, RRNodeId::INVALID ());
221+ array_rearrange (edge_switch_, LIBRRGRAPH_UNDEFINED_VAL );
222+ array_rearrange (edge_remapped_, false );
223+ }
214224
215225size_t t_rr_graph_storage::count_rr_switches (const std::vector<t_arch_switch_inf>& arch_switch_inf,
216226 t_arch_switch_fanin& arch_switch_fanins) {
@@ -222,7 +232,7 @@ size_t t_rr_graph_storage::count_rr_switches(const std::vector<t_arch_switch_inf
222232
223233 // Sort by destination node to collect per node/per switch fan in values
224234 // This sort is safe to do because partition_edges() has not been invoked yet.
225- sort_edges ( edge_compare_dest_node (* this ));
235+ sort_edges_by_keys ( vtr::sort_key (node_storage_. size (), [&](RREdgeId e) { return edge_dest_node_[e]; } ));
226236
227237 // Collect the fan-in per switch type for each node in the graph
228238 // Record the unique switch type/fanin combinations
@@ -318,35 +328,6 @@ void t_rr_graph_storage::mark_edges_as_rr_switch_ids() {
318328 remapped_edges_ = true ;
319329}
320330
321- namespace {
322- // / Functor for sorting edges according to source node, with configurable edges coming first
323- class edge_compare_src_node_and_configurable_first {
324- public:
325- edge_compare_src_node_and_configurable_first (const vtr::vector<RRSwitchId, t_rr_switch_inf>& rr_switch_inf, const t_rr_graph_storage& rr_graph_storage)
326- : rr_switch_inf_(rr_switch_inf),
327- rr_graph_storage_ (rr_graph_storage) {}
328-
329- bool operator ()(RREdgeId lhs, RREdgeId rhs) const {
330-
331- RRNodeId lhs_dest_node = rr_graph_storage_.edge_sink_node (lhs);
332- RRNodeId lhs_src_node = rr_graph_storage_.edge_source_node (lhs);
333- RRSwitchId lhs_switch_type = RRSwitchId (rr_graph_storage_.edge_switch (lhs));
334- bool lhs_is_configurable = rr_switch_inf_[lhs_switch_type].configurable ();
335-
336- RRNodeId rhs_dest_node = rr_graph_storage_.edge_sink_node (rhs);
337- RRNodeId rhs_src_node = rr_graph_storage_.edge_source_node (rhs);
338- RRSwitchId rhs_switch_type = RRSwitchId (rr_graph_storage_.edge_switch (rhs));
339- bool rhs_is_configurable = rr_switch_inf_[rhs_switch_type].configurable ();
340-
341- return std::make_tuple (lhs_src_node, !lhs_is_configurable, lhs_dest_node, lhs_switch_type) < std::make_tuple (rhs_src_node, !rhs_is_configurable, rhs_dest_node, rhs_switch_type);
342- }
343-
344- private:
345- const vtr::vector<RRSwitchId, t_rr_switch_inf>& rr_switch_inf_;
346- const t_rr_graph_storage& rr_graph_storage_;
347- };
348- } // namespace
349-
350331void t_rr_graph_storage::partition_edges (const vtr::vector<RRSwitchId, t_rr_switch_inf>& rr_switches) {
351332 if (partitioned_) {
352333 return ;
@@ -359,7 +340,11 @@ void t_rr_graph_storage::partition_edges(const vtr::vector<RRSwitchId, t_rr_swit
359340 // by assign_first_edges()
360341 // - Edges within a source node have the configurable edges before the
361342 // non-configurable edges.
362- sort_edges (edge_compare_src_node_and_configurable_first (rr_switches, *this ));
343+ // Keys are listed from the most significant to the least significant.
344+ sort_edges_by_keys (vtr::sort_key (node_storage_.size (), [&](RREdgeId e) { return edge_src_node_[e]; }),
345+ vtr::sort_key (2 , [&](RREdgeId e) { return !rr_switches[RRSwitchId (edge_switch_[e])].configurable (); }),
346+ vtr::sort_key (node_storage_.size (), [&](RREdgeId e) { return edge_dest_node_[e]; }),
347+ vtr::sort_key (rr_switches.size (), [&](RREdgeId e) { return edge_switch_[e]; }));
363348
364349 partitioned_ = true ;
365350
0 commit comments