@@ -67,8 +67,6 @@ struct t_pin_loc {
67
67
e_side side;
68
68
};
69
69
70
- typedef std::vector<std::map<int , int >> t_arch_switch_fanin;
71
-
72
70
/* ****************** Variables local to this module. ***********************/
73
71
74
72
/* ******************** Subroutines local to this module. *******************/
@@ -822,44 +820,11 @@ static void alloc_and_load_rr_switch_inf(const int num_arch_switches, const floa
822
820
static void alloc_rr_switch_inf (t_arch_switch_fanin& arch_switch_fanins) {
823
821
auto & device_ctx = g_vpr_ctx.mutable_device ();
824
822
825
- int num_rr_switches = 0 ;
826
- {
827
- // Collect the fan-in per switch type for each node in the graph
828
- //
829
- // Note that since we don't store backward edge info in the RR graph we need to walk
830
- // the whole graph to get the per-switch-type fanin info
831
- std::vector<vtr::flat_map<int , int >> inward_switch_inf (device_ctx.rr_nodes .size ()); // [to_node][arch_switch] -> fanin
832
- for (size_t inode = 0 ; inode < device_ctx.rr_nodes .size (); ++inode) {
833
- for (auto iedge : device_ctx.rr_nodes [inode].edges ()) {
834
- int iswitch = device_ctx.rr_nodes [inode].edge_switch (iedge);
835
- int to_node = device_ctx.rr_nodes [inode].edge_sink_node (iedge);
836
-
837
- if (inward_switch_inf[to_node].count (iswitch) == 0 ) {
838
- inward_switch_inf[to_node][iswitch] = 0 ;
839
- }
840
- inward_switch_inf[to_node][iswitch]++;
841
- }
842
- }
843
-
844
- // Record the unique switch type/fanin combinations
845
- for (size_t inode = 0 ; inode < device_ctx.rr_nodes .size (); ++inode) {
846
- for (auto & switch_fanin : inward_switch_inf[inode]) {
847
- int iswitch, fanin;
848
- std::tie (iswitch, fanin) = switch_fanin;
849
-
850
- if (device_ctx.arch_switch_inf [iswitch].fixed_Tdel ()) {
851
- // If delay is independent of fanin drop the unique fanin info
852
- fanin = UNDEFINED;
853
- }
854
-
855
- if (arch_switch_fanins[iswitch].count (fanin) == 0 ) { // New fanin for this switch
856
- arch_switch_fanins[iswitch][fanin] = num_rr_switches++; // Assign it a unique index
857
- }
858
- }
859
- }
860
- }
861
-
862
823
/* allocate space for the rr_switch_inf array */
824
+ size_t num_rr_switches = device_ctx.rr_nodes .count_rr_switches (
825
+ device_ctx.num_arch_switches ,
826
+ device_ctx.arch_switch_inf ,
827
+ arch_switch_fanins);
863
828
device_ctx.rr_switch_inf .resize (num_rr_switches);
864
829
}
865
830
@@ -930,27 +895,7 @@ void load_rr_switch_from_arch_switch(int arch_switch_idx,
930
895
static void remap_rr_node_switch_indices (const t_arch_switch_fanin& switch_fanin) {
931
896
auto & device_ctx = g_vpr_ctx.mutable_device ();
932
897
933
- for (size_t inode = 0 ; inode < device_ctx.rr_nodes .size (); inode++) {
934
- auto from_node = device_ctx.rr_nodes [inode];
935
- int num_edges = from_node.num_edges ();
936
- for (int iedge = 0 ; iedge < num_edges; iedge++) {
937
- const t_rr_node& to_node = device_ctx.rr_nodes [from_node.edge_sink_node (iedge)];
938
- /* get the switch which this edge uses and its fanin */
939
- int switch_index = from_node.edge_switch (iedge);
940
- int fanin = to_node.fan_in ();
941
-
942
- if (switch_fanin[switch_index].count (UNDEFINED) == 1 ) {
943
- fanin = UNDEFINED;
944
- }
945
-
946
- auto itr = switch_fanin[switch_index].find (fanin);
947
- VTR_ASSERT (itr != switch_fanin[switch_index].end ());
948
-
949
- int rr_switch_index = itr->second ;
950
-
951
- from_node.set_edge_switch (iedge, rr_switch_index);
952
- }
953
- }
898
+ device_ctx.rr_nodes .remap_rr_node_switch_indices (switch_fanin);
954
899
}
955
900
956
901
static void rr_graph_externals (const std::vector<t_segment_inf>& segment_inf,
@@ -1324,7 +1269,7 @@ static std::function<void(t_chan_width*)> alloc_and_load_rr_graph(t_rr_node_stor
1324
1269
};
1325
1270
}
1326
1271
1327
- init_fan_in ( L_rr_node, L_rr_node. size () );
1272
+ L_rr_node. init_fan_in ( );
1328
1273
1329
1274
return update_chan_width;
1330
1275
}
@@ -1481,9 +1426,6 @@ static void build_rr_sinks_sources(const int i,
1481
1426
* leads to. If route throughs are allowed, you may want to increase the *
1482
1427
* base cost of OPINs and/or SOURCES so they aren't used excessively. */
1483
1428
1484
- /* Initialize to unconnected */
1485
- L_rr_node[inode].set_num_edges (0 );
1486
-
1487
1429
L_rr_node[inode].set_cost_index (SINK_COST_INDEX);
1488
1430
L_rr_node[inode].set_type (SINK);
1489
1431
}
@@ -1555,24 +1497,6 @@ static void build_rr_sinks_sources(const int i,
1555
1497
// Create the actual edges
1556
1498
}
1557
1499
1558
- void init_fan_in (t_rr_node_storage& L_rr_node, const int num_rr_nodes) {
1559
- // Loads fan-ins for all nodes
1560
-
1561
- // Reset all fan-ins to zero
1562
- for (int i = 0 ; i < num_rr_nodes; i++) {
1563
- L_rr_node[i].set_fan_in (0 );
1564
- }
1565
-
1566
- // Walk the graph and increment fanin on all downstream nodes
1567
- for (int i = 0 ; i < num_rr_nodes; i++) {
1568
- for (t_edge_size iedge = 0 ; iedge < L_rr_node[i].num_edges (); iedge++) {
1569
- int to_node = L_rr_node[i].edge_sink_node (iedge);
1570
-
1571
- L_rr_node[to_node].set_fan_in (L_rr_node[to_node].fan_in () + 1 );
1572
- }
1573
- }
1574
- }
1575
-
1576
1500
/* Allocates/loads edges for nodes belonging to specified channel segment and initializes
1577
1501
* node properties such as cost, occupancy and capacity */
1578
1502
static void build_rr_chan (const int x_coord,
@@ -1756,54 +1680,7 @@ void uniquify_edges(t_rr_edge_info_set& rr_edges_to_create) {
1756
1680
1757
1681
void alloc_and_load_edges (t_rr_node_storage& L_rr_node,
1758
1682
const t_rr_edge_info_set& rr_edges_to_create) {
1759
- /* Sets up all the edge related information for rr_node */
1760
-
1761
- struct compare_from_node {
1762
- auto operator ()(const t_rr_edge_info& lhs, const int from_node) {
1763
- return lhs.from_node < from_node;
1764
- }
1765
- auto operator ()(const int from_node, const t_rr_edge_info& rhs) {
1766
- return from_node < rhs.from_node ;
1767
- }
1768
- };
1769
-
1770
- std::set<int > from_nodes;
1771
- for (auto & edge : rr_edges_to_create) {
1772
- from_nodes.insert (edge.from_node );
1773
- }
1774
-
1775
- VTR_ASSERT_SAFE (std::is_sorted (rr_edges_to_create.begin (), rr_edges_to_create.end ()));
1776
-
1777
- for (int inode : from_nodes) {
1778
- auto edge_range = std::equal_range (rr_edges_to_create.begin (), rr_edges_to_create.end (), inode, compare_from_node ());
1779
-
1780
- size_t edge_count = std::distance (edge_range.first , edge_range.second );
1781
-
1782
- if (L_rr_node[inode].num_edges () == 0 ) {
1783
- // Create initial edges
1784
- //
1785
- // Note that we do this in bulk instead of via add_edge() to reduce
1786
- // memory fragmentation
1787
-
1788
- L_rr_node[inode].set_num_edges (edge_count);
1789
-
1790
- int iedge = 0 ;
1791
- for (auto itr = edge_range.first ; itr != edge_range.second ; ++itr) {
1792
- VTR_ASSERT (itr->from_node == inode);
1793
-
1794
- L_rr_node[inode].set_edge_sink_node (iedge, itr->to_node );
1795
- L_rr_node[inode].set_edge_switch (iedge, itr->switch_type );
1796
- ++iedge;
1797
- }
1798
- } else {
1799
- // Add new edge incrementally
1800
- //
1801
- // This should occur relatively rarely (e.g. a backward bidir edge) so memory fragmentation shouldn't be a big problem
1802
- for (auto itr = edge_range.first ; itr != edge_range.second ; ++itr) {
1803
- L_rr_node[inode].add_edge (itr->to_node , itr->switch_type );
1804
- }
1805
- }
1806
- }
1683
+ L_rr_node.alloc_and_load_edges (&rr_edges_to_create);
1807
1684
}
1808
1685
1809
1686
/* allocate pin to track map for each segment type individually and then combine into a single
@@ -2545,7 +2422,7 @@ std::string describe_rr_node(int inode) {
2545
2422
2546
2423
std::string msg = vtr::string_fmt (" RR node: %d" , inode);
2547
2424
2548
- const auto & rr_node = device_ctx.rr_nodes [inode];
2425
+ auto rr_node = device_ctx.rr_nodes [inode];
2549
2426
2550
2427
msg += vtr::string_fmt (" type: %s" , rr_node.type_string ());
2551
2428
0 commit comments