4
4
#include < ctime>
5
5
#include < algorithm>
6
6
#include < vector>
7
+ #include < stack>
7
8
#include " vtr_assert.h"
8
9
9
10
#include " vtr_util.h"
@@ -2960,22 +2961,13 @@ static int pick_best_direct_connect_target_rr_node(const t_rr_graph_storage& rr_
2960
2961
// Class for building a group of connected edges.
2961
2962
class EdgeGroups {
2962
2963
public:
2963
- EdgeGroups ()
2964
- : node_count_(std::numeric_limits<size_t >::max()) {}
2964
+ EdgeGroups () {}
2965
2965
2966
- // set_node_count must be invoked before create_sets with the count of
2967
- // nodes. Assumption is that from_node/to_node arguments to
2968
- // add_non_config_edge are less than node_count.
2969
- void set_node_count (size_t node_count) {
2970
- node_count_ = node_count;
2971
- }
2972
-
2973
- // Adds non-configurable edge to be group.
2966
+ // Adds non-configurable (undirected) edge to be grouped.
2974
2967
//
2975
2968
// Returns true if this is a new edge.
2976
2969
bool add_non_config_edge (int from_node, int to_node) {
2977
- auto result = node_edges_.insert (std::make_pair (from_node, to_node));
2978
- return result.second ;
2970
+ return graph_[from_node].edges .insert (to_node).second && graph_[to_node].edges .insert (from_node).second ;
2979
2971
}
2980
2972
2981
2973
// After add_non_config_edge has been called for all edges, create_sets
@@ -2984,93 +2976,45 @@ class EdgeGroups {
2984
2976
void create_sets () {
2985
2977
rr_non_config_node_sets_map_.clear ();
2986
2978
2987
- size_t num_groups = 0 ;
2988
- std::vector<std::pair<int , int >> merges;
2989
-
2990
- VTR_ASSERT (node_count_ != std::numeric_limits<size_t >::max ());
2991
- std::vector<int > node_to_node_set (node_count_, OPEN);
2992
-
2993
- // First nievely make node groups. When an edge joins two groups,
2994
- // mark it for cleanup latter.
2995
- for (const auto & edge : node_edges_) {
2996
- VTR_ASSERT (edge.first >= 0 && static_cast <size_t >(edge.first ) < node_count_);
2997
- VTR_ASSERT (edge.second >= 0 && static_cast <size_t >(edge.second ) < node_count_);
2998
-
2999
- int & from_set = node_to_node_set[edge.first ];
3000
- int & to_set = node_to_node_set[edge.second ];
3001
-
3002
- if (from_set == OPEN && to_set == OPEN) {
3003
- from_set = num_groups++;
3004
- to_set = from_set;
3005
- } else if (from_set == OPEN && to_set != OPEN) {
3006
- from_set = to_set;
3007
- } else if (from_set != OPEN && to_set == OPEN) {
3008
- to_set = from_set;
3009
- } else {
3010
- VTR_ASSERT (from_set != OPEN);
3011
- VTR_ASSERT (to_set != OPEN);
3012
-
3013
- if (from_set != to_set) {
3014
- merges.push_back (std::make_pair (
3015
- std::min (from_set, to_set),
3016
- std::max (from_set, to_set)));
3017
- }
2979
+ // https://en.wikipedia.org/wiki/Component_(graph_theory)#Algorithms
2980
+ std::vector<size_t > group_size;
2981
+ for (auto & node : graph_) {
2982
+ if (node.second .set == OPEN) {
2983
+ node.second .set = group_size.size ();
2984
+ group_size.push_back (add_connected_group (node.second ));
3018
2985
}
3019
2986
}
3020
2987
3021
- // We are going to always collapse sets to lower ids, so sort
3022
- // the merge list to ensure that the merge first elements are always
3023
- // increasing.
3024
- std::sort (merges.begin (), merges.end (), [](const std::pair<int , int >& a, const std::pair<int , int >& b) {
3025
- return a.first < b.first ;
3026
- });
3027
-
3028
- // Update final_set_map with the final merge id for the second element.
3029
- // The first element will either be the final value, or already have
3030
- // an entry in the final_set_map (because sorting), so we can depend on
3031
- // find_target_set(first) returning a stable value.
3032
- std::unordered_map<int , int > final_set_map;
3033
- for (const auto & merge : merges) {
3034
- VTR_ASSERT (merge.first < merge.second );
3035
- VTR_ASSERT (merge.first != OPEN);
3036
- VTR_ASSERT (merge.second != OPEN);
3037
-
3038
- int target_set = find_target_set (final_set_map, merge.first );
3039
-
3040
- final_set_map.insert (std::make_pair (merge.second , target_set));
3041
- }
3042
-
3043
- // Finalize merges between node set ids.
3044
- for (auto & set : node_to_node_set) {
3045
- set = find_target_set (final_set_map, set);
3046
- }
3047
- final_set_map.clear ();
3048
-
3049
2988
// Sanity check the node sets.
3050
- for (const auto & edge : node_edges_) {
3051
- VTR_ASSERT (node_to_node_set[edge.first ] != OPEN);
3052
- VTR_ASSERT (node_to_node_set[edge.second ] != OPEN);
3053
- VTR_ASSERT (node_to_node_set[edge.first ] == node_to_node_set[edge.second ]);
2989
+ for (const auto & node : graph_) {
2990
+ VTR_ASSERT (node.second .set != OPEN);
2991
+ for (const auto & e : node.second .edges ) {
2992
+ int set = graph_[e].set ;
2993
+ VTR_ASSERT (set == node.second .set );
2994
+ }
3054
2995
}
3055
2996
3056
2997
// Create compact set of sets.
3057
- for (size_t inode = 0 ; inode < node_to_node_set.size (); ++inode) {
3058
- if (node_to_node_set[inode] != OPEN) {
3059
- rr_non_config_node_sets_map_[node_to_node_set[inode]].push_back (inode);
3060
- }
2998
+ rr_non_config_node_sets_map_.resize (group_size.size ());
2999
+ for (size_t i = 0 ; i < group_size.size (); i++) {
3000
+ rr_non_config_node_sets_map_[i].reserve (group_size[i]);
3001
+ }
3002
+ for (const auto & node : graph_) {
3003
+ rr_non_config_node_sets_map_[node.second .set ].push_back (node.first );
3061
3004
}
3062
3005
}
3063
3006
3064
3007
// Create t_non_configurable_rr_sets from set data.
3008
+ // NOTE: The stored graph is undirected, so this may generate reverse edges that don't exist.
3065
3009
t_non_configurable_rr_sets output_sets () {
3066
3010
t_non_configurable_rr_sets sets;
3067
- for (auto & item : rr_non_config_node_sets_map_) {
3011
+ for (const auto & nodes : rr_non_config_node_sets_map_) {
3068
3012
std::set<t_node_edge> edge_set;
3069
- std::set<int > node_set (item. second . begin (), item. second .end ());
3013
+ std::set<int > node_set (nodes. begin (), nodes .end ());
3070
3014
3071
- for (const auto & edge : node_edges_ ) {
3072
- if (node_set. find (edge. first ) != node_set. end () ) {
3073
- edge_set.emplace (t_node_edge (edge. first , edge. second ));
3015
+ for (const auto & src : node_set ) {
3016
+ for ( const auto & dest : graph_[src]. edges ) {
3017
+ edge_set.emplace (t_node_edge (src, dest ));
3074
3018
}
3075
3019
}
3076
3020
@@ -3084,8 +3028,8 @@ class EdgeGroups {
3084
3028
// Set device context structures for non-configurable node sets.
3085
3029
void set_device_context () {
3086
3030
std::vector<std::vector<int >> rr_non_config_node_sets;
3087
- for (auto & item : rr_non_config_node_sets_map_) {
3088
- rr_non_config_node_sets.emplace_back (std::move (item. second ));
3031
+ for (const auto & item : rr_non_config_node_sets_map_) {
3032
+ rr_non_config_node_sets.emplace_back (std::move (item));
3089
3033
}
3090
3034
3091
3035
std::unordered_map<int , int > rr_node_to_non_config_node_set;
@@ -3102,67 +3046,56 @@ class EdgeGroups {
3102
3046
}
3103
3047
3104
3048
private:
3105
- // Final target set for given set id.
3106
- static int find_target_set (
3107
- const std::unordered_map<int , int >& final_set_map,
3108
- int set) {
3109
- int target_set = set;
3110
- while (true ) {
3111
- auto iter = final_set_map.find (target_set);
3112
- if (iter != final_set_map.end ()) {
3113
- target_set = iter->second ;
3114
- } else {
3115
- break ;
3049
+ struct node_data {
3050
+ std::unordered_set<int > edges;
3051
+ int set = OPEN;
3052
+ };
3053
+
3054
+ // Perform a DFS traversal marking everything reachable with the same set id
3055
+ size_t add_connected_group (const node_data& node) {
3056
+ // stack contains nodes with edges to mark with node.set
3057
+ // The set for each node must be set before pushing it onto the stack
3058
+ std::stack<const node_data*> stack;
3059
+ stack.push (&node);
3060
+ size_t n = 1 ;
3061
+ while (!stack.empty ()) {
3062
+ auto top = stack.top ();
3063
+ stack.pop ();
3064
+ for (auto e : top->edges ) {
3065
+ auto & next = graph_[e];
3066
+ if (next.set != node.set ) {
3067
+ VTR_ASSERT (next.set == OPEN);
3068
+ n++;
3069
+ next.set = node.set ;
3070
+ stack.push (&next);
3071
+ }
3116
3072
}
3117
3073
}
3118
-
3119
- return target_set;
3074
+ return n;
3120
3075
}
3121
3076
3122
- // Number of nodes. All elements of node_edges_ should be less than this
3123
- // value.
3124
- size_t node_count_;
3125
-
3126
3077
// Set of non-configurable edges.
3127
- std::set<std::pair< int , int >> node_edges_ ;
3078
+ std::unordered_map< int , node_data> graph_ ;
3128
3079
3129
3080
// Compact set of node sets. Map key is arbitrary.
3130
- std::map< int , std::vector<int >> rr_non_config_node_sets_map_;
3081
+ std::vector< std::vector<int >> rr_non_config_node_sets_map_;
3131
3082
};
3132
3083
3133
- static void expand_non_configurable (int inode, EdgeGroups* groups);
3134
-
3135
3084
// Collects the sets of connected non-configurable edges in the RR graph
3136
3085
static void create_edge_groups (EdgeGroups* groups) {
3137
- // Walk through the RR graph and recursively expand non-configurable edges
3138
- // to collect the sets of non-configurably connected nodes
3139
3086
auto & device_ctx = g_vpr_ctx.device ();
3140
- groups-> set_node_count ( device_ctx.rr_nodes . size ()) ;
3087
+ auto & rr_nodes = device_ctx.rr_nodes ;
3141
3088
3142
- for (size_t inode = 0 ; inode < device_ctx.rr_nodes .size (); ++inode) {
3143
- expand_non_configurable (inode, groups);
3089
+ for (size_t iedge = 0 ; iedge < rr_nodes.edges_size (); ++iedge) {
3090
+ RREdgeId edge (iedge);
3091
+ if (!device_ctx.rr_switch_inf [rr_nodes.edge_switch (edge)].configurable ()) {
3092
+ groups->add_non_config_edge (size_t (rr_nodes.edge_source_node (edge)), size_t (rr_nodes.edge_sink_node (edge)));
3093
+ }
3144
3094
}
3145
3095
3146
3096
groups->create_sets ();
3147
3097
}
3148
3098
3149
- // Builds a set of non-configurably connected RR graph edges
3150
- static void expand_non_configurable (int inode, EdgeGroups* groups) {
3151
- auto & device_ctx = g_vpr_ctx.device ();
3152
-
3153
- for (t_edge_size iedge = 0 ; iedge < device_ctx.rr_nodes [inode].num_edges (); ++iedge) {
3154
- bool edge_non_configurable = !device_ctx.rr_nodes [inode].edge_is_configurable (iedge);
3155
-
3156
- if (edge_non_configurable) {
3157
- int to_node = device_ctx.rr_nodes [inode].edge_sink_node (iedge);
3158
-
3159
- if (groups->add_non_config_edge (inode, to_node)) {
3160
- expand_non_configurable (to_node, groups);
3161
- }
3162
- }
3163
- }
3164
- }
3165
-
3166
3099
t_non_configurable_rr_sets identify_non_configurable_rr_sets () {
3167
3100
EdgeGroups groups;
3168
3101
create_edge_groups (&groups);
0 commit comments