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