Skip to content

Commit 0fea9d1

Browse files
authored
Merge pull request #1271 from HackerFoo/node_reordering_flag
Add flags to reorder RR graph nodes
2 parents c5c1c0b + 2012743 commit 0fea9d1

19 files changed

+313
-72
lines changed

vpr/src/base/SetupVPR.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -352,6 +352,9 @@ static void SetupRouterOpts(const t_options& Options, t_router_opts* RouterOpts)
352352
RouterOpts->fixed_channel_width = Options.RouteChanWidth;
353353
RouterOpts->min_channel_width_hint = Options.min_route_chan_width_hint;
354354
RouterOpts->read_rr_edge_metadata = Options.read_rr_edge_metadata;
355+
RouterOpts->reorder_rr_graph_nodes_algorithm = Options.reorder_rr_graph_nodes_algorithm;
356+
RouterOpts->reorder_rr_graph_nodes_threshold = Options.reorder_rr_graph_nodes_threshold;
357+
RouterOpts->reorder_rr_graph_nodes_seed = Options.reorder_rr_graph_nodes_seed;
355358

356359
//TODO document these?
357360
RouterOpts->trim_empty_channels = false; /* DEFAULT */

vpr/src/base/place_and_route.cpp

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -353,16 +353,17 @@ int binary_search_place_and_route(const t_placer_opts& placer_opts_ref,
353353
device_ctx.num_arch_switches,
354354
det_routing_arch,
355355
segment_inf,
356-
router_opts.base_cost_type,
357-
router_opts.trim_empty_channels,
358-
router_opts.trim_obs_channels,
359-
router_opts.clock_modeling,
356+
router_opts,
360357
arch->Directs, arch->num_directs,
361-
&warnings,
362-
router_opts.read_rr_edge_metadata,
363-
router_opts.do_check_rr_graph);
358+
&warnings);
364359

365360
init_draw_coords(final);
361+
362+
/* Allocate and load additional rr_graph information needed only by the router. */
363+
alloc_and_load_rr_node_route_structs();
364+
365+
init_route_structs(router_opts.bb_factor);
366+
366367
restore_routing(best_routing, route_ctx.clb_opins_used_locally, saved_clb_opins_used_locally);
367368

368369
if (Fc_clipped) {

vpr/src/base/read_options.cpp

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,41 @@ struct ParseRouterAlgorithm {
163163
}
164164
};
165165

166+
struct ParseNodeReorderAlgorithm {
167+
ConvertedValue<e_rr_node_reorder_algorithm> from_str(std::string str) {
168+
ConvertedValue<e_rr_node_reorder_algorithm> conv_value;
169+
if (str == "none")
170+
conv_value.set_value(DONT_REORDER);
171+
else if (str == "degree_bfs")
172+
conv_value.set_value(DEGREE_BFS);
173+
else if (str == "random_shuffle")
174+
conv_value.set_value(RANDOM_SHUFFLE);
175+
else {
176+
std::stringstream msg;
177+
msg << "Invalid conversion from '" << str << "' to e_rr_node_reorder_algorithm (expected one of: " << argparse::join(default_choices(), ", ") << ")";
178+
conv_value.set_error(msg.str());
179+
}
180+
return conv_value;
181+
}
182+
183+
ConvertedValue<std::string> to_str(e_rr_node_reorder_algorithm val) {
184+
ConvertedValue<std::string> conv_value;
185+
if (val == DONT_REORDER)
186+
conv_value.set_value("none");
187+
else if (val == DEGREE_BFS)
188+
conv_value.set_value("degree_bfs");
189+
else {
190+
VTR_ASSERT(val == RANDOM_SHUFFLE);
191+
conv_value.set_value("random_shuffle");
192+
}
193+
return conv_value;
194+
}
195+
196+
std::vector<std::string> default_choices() {
197+
return {"none", "degree_bfs", "random_shuffle"};
198+
}
199+
};
200+
166201
struct RouteBudgetsAlgorithm {
167202
ConvertedValue<e_routing_budgets_algorithm> from_str(std::string str) {
168203
ConvertedValue<e_routing_budgets_algorithm> conv_value;
@@ -1897,6 +1932,28 @@ argparse::ArgumentParser create_arg_parser(std::string prog_name, t_options& arg
18971932
.default_value("off")
18981933
.show_in(argparse::ShowIn::HELP_ONLY);
18991934

1935+
route_grp.add_argument<e_rr_node_reorder_algorithm, ParseNodeReorderAlgorithm>(args.reorder_rr_graph_nodes_algorithm, "--reorder_rr_graph_nodes_algorithm")
1936+
.help(
1937+
"Specifies the node reordering algorithm to use.\n"
1938+
" * none: don't reorder nodes\n"
1939+
" * degree_bfs: sort by degree and then by BFS\n"
1940+
" * random_shuffle: a random shuffle\n")
1941+
.default_value("none")
1942+
.choices({"none", "degree_bfs", "random_shuffle"})
1943+
.show_in(argparse::ShowIn::HELP_ONLY);
1944+
1945+
route_grp.add_argument(args.reorder_rr_graph_nodes_threshold, "--reorder_rr_graph_nodes_threshold")
1946+
.help(
1947+
"Reorder rr_graph nodes to optimize memory layout above this number of nodes.")
1948+
.default_value("0")
1949+
.show_in(argparse::ShowIn::HELP_ONLY);
1950+
1951+
route_grp.add_argument(args.reorder_rr_graph_nodes_seed, "--reorder_rr_graph_nodes_seed")
1952+
.help(
1953+
"Pseudo-random number generator seed used for the random_shuffle reordering algorithm")
1954+
.default_value("1")
1955+
.show_in(argparse::ShowIn::HELP_ONLY);
1956+
19001957
auto& route_timing_grp = parser.add_argument_group("timing-driven routing options");
19011958

19021959
route_timing_grp.add_argument(args.astar_fac, "--astar_fac")

vpr/src/base/read_options.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,9 @@ struct t_options {
150150
argparse::ArgValue<e_check_route_option> check_route;
151151
argparse::ArgValue<size_t> max_logged_overused_rr_nodes;
152152
argparse::ArgValue<bool> generate_rr_node_overuse_report;
153+
argparse::ArgValue<e_rr_node_reorder_algorithm> reorder_rr_graph_nodes_algorithm;
154+
argparse::ArgValue<int> reorder_rr_graph_nodes_threshold;
155+
argparse::ArgValue<int> reorder_rr_graph_nodes_seed;
153156

154157
/* Timing-driven router options only */
155158
argparse::ArgValue<float> astar_fac;

vpr/src/base/vpr_api.cpp

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -888,14 +888,9 @@ void vpr_create_rr_graph(t_vpr_setup& vpr_setup, const t_arch& arch, int chan_wi
888888
device_ctx.num_arch_switches,
889889
det_routing_arch,
890890
vpr_setup.Segments,
891-
router_opts.base_cost_type,
892-
router_opts.trim_empty_channels,
893-
router_opts.trim_obs_channels,
894-
router_opts.clock_modeling,
891+
router_opts,
895892
arch.Directs, arch.num_directs,
896-
&warnings,
897-
router_opts.read_rr_edge_metadata,
898-
router_opts.do_check_rr_graph);
893+
&warnings);
899894
//Initialize drawing, now that we have an RR graph
900895
init_draw_coords(chan_width_fac);
901896
}

vpr/src/base/vpr_types.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -994,6 +994,13 @@ enum e_router_algorithm {
994994
TIMING_DRIVEN,
995995
};
996996

997+
// Node reordering algorithms for rr_nodes
998+
enum e_rr_node_reorder_algorithm {
999+
DONT_REORDER,
1000+
DEGREE_BFS,
1001+
RANDOM_SHUFFLE,
1002+
};
1003+
9971004
enum e_base_cost_type {
9981005
DELAY_NORMALIZED,
9991006
DELAY_NORMALIZED_LENGTH,
@@ -1105,6 +1112,11 @@ struct t_router_opts {
11051112

11061113
size_t max_logged_overused_rr_nodes;
11071114
bool generate_rr_node_overuse_report;
1115+
1116+
// Options related to rr_node reordering, for testing and possible cache optimization
1117+
e_rr_node_reorder_algorithm reorder_rr_graph_nodes_algorithm = DONT_REORDER;
1118+
int reorder_rr_graph_nodes_threshold = 0;
1119+
int reorder_rr_graph_nodes_seed = 1;
11081120
};
11091121

11101122
struct t_analysis_opts {

vpr/src/route/edge_groups.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ bool EdgeGroups::add_non_config_edge(int from_node, int to_node) {
1313
// will form groups of nodes that are connected via non-configurable
1414
// edges.
1515
void EdgeGroups::create_sets() {
16-
rr_non_config_node_sets_map_.clear();
16+
rr_non_config_node_sets_.clear();
1717

1818
// https://en.wikipedia.org/wiki/Component_(graph_theory)#Algorithms
1919
std::vector<size_t> group_size;
@@ -34,20 +34,20 @@ void EdgeGroups::create_sets() {
3434
}
3535

3636
// Create compact set of sets.
37-
rr_non_config_node_sets_map_.resize(group_size.size());
37+
rr_non_config_node_sets_.resize(group_size.size());
3838
for (size_t i = 0; i < group_size.size(); i++) {
39-
rr_non_config_node_sets_map_[i].reserve(group_size[i]);
39+
rr_non_config_node_sets_[i].reserve(group_size[i]);
4040
}
4141
for (const auto& node : graph_) {
42-
rr_non_config_node_sets_map_[node.second.set].push_back(node.first);
42+
rr_non_config_node_sets_[node.second.set].push_back(node.first);
4343
}
4444
}
4545

4646
// Create t_non_configurable_rr_sets from set data.
4747
// NOTE: The stored graph is undirected, so this may generate reverse edges that don't exist.
4848
t_non_configurable_rr_sets EdgeGroups::output_sets() {
4949
t_non_configurable_rr_sets sets;
50-
for (const auto& nodes : rr_non_config_node_sets_map_) {
50+
for (const auto& nodes : rr_non_config_node_sets_) {
5151
std::set<t_node_edge> edge_set;
5252
std::set<int> node_set(nodes.begin(), nodes.end());
5353

@@ -67,7 +67,7 @@ t_non_configurable_rr_sets EdgeGroups::output_sets() {
6767
// Set device context structures for non-configurable node sets.
6868
void EdgeGroups::set_device_context(DeviceContext& device_ctx) {
6969
std::vector<std::vector<int>> rr_non_config_node_sets;
70-
for (const auto& item : rr_non_config_node_sets_map_) {
70+
for (const auto& item : rr_non_config_node_sets_) {
7171
rr_non_config_node_sets.emplace_back(std::move(item));
7272
}
7373

vpr/src/route/edge_groups.h

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,16 @@
99
#include "vpr_types.h"
1010
#include "vpr_context.h"
1111

12-
// Class for building a group of connected edges.
12+
// Class for identifying the components of a graph as sets of nodes.
13+
// Each node is reachable from any other node in the same set, and
14+
// unreachable from nodes in any other set.
15+
// Note that edges are undirected.
16+
//
17+
// This is used by the router to group nodes connected by
18+
// non-configurable edges, because a connection to one node
19+
// must connect them all.
20+
//
21+
// https://en.wikipedia.org/wiki/Component_(graph_theory)
1322
class EdgeGroups {
1423
public:
1524
EdgeGroups() {}
@@ -33,8 +42,8 @@ class EdgeGroups {
3342

3443
private:
3544
struct node_data {
36-
std::unordered_set<int> edges;
37-
int set = OPEN;
45+
std::unordered_set<int> edges; // Set of indices into graph_
46+
int set = OPEN; // Index into rr_non_config_node_sets_
3847
};
3948

4049
// Perform a DFS traversal marking everything reachable with the same set id
@@ -43,8 +52,9 @@ class EdgeGroups {
4352
// Set of non-configurable edges.
4453
std::unordered_map<int, node_data> graph_;
4554

46-
// Compact set of node sets. Map key is arbitrary.
47-
std::vector<std::vector<int>> rr_non_config_node_sets_map_;
55+
// Connected components, representing nodes connected by non-configurable edges.
56+
// Order is arbitrary.
57+
std::vector<std::vector<int>> rr_non_config_node_sets_;
4858
};
4959

5060
#endif

vpr/src/route/route_common.cpp

Lines changed: 4 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -227,14 +227,9 @@ void try_graph(int width_fac, const t_router_opts& router_opts, t_det_routing_ar
227227
device_ctx.num_arch_switches,
228228
det_routing_arch,
229229
segment_inf,
230-
router_opts.base_cost_type,
231-
router_opts.trim_empty_channels,
232-
router_opts.trim_obs_channels,
233-
router_opts.clock_modeling,
230+
router_opts,
234231
directs, num_directs,
235-
&warning_count,
236-
router_opts.read_rr_edge_metadata,
237-
router_opts.do_check_rr_graph);
232+
&warning_count);
238233
}
239234

240235
bool try_route(int width_fac,
@@ -279,14 +274,9 @@ bool try_route(int width_fac,
279274
device_ctx.num_arch_switches,
280275
det_routing_arch,
281276
segment_inf,
282-
router_opts.base_cost_type,
283-
router_opts.trim_empty_channels,
284-
router_opts.trim_obs_channels,
285-
router_opts.clock_modeling,
277+
router_opts,
286278
directs, num_directs,
287-
&warning_count,
288-
router_opts.read_rr_edge_metadata,
289-
router_opts.do_check_rr_graph);
279+
&warning_count);
290280

291281
//Initialize drawing, now that we have an RR graph
292282
init_draw_coords(width_fac);

vpr/src/route/router_delay_profiling.cpp

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -221,14 +221,9 @@ void alloc_routing_structs(t_chan_width chan_width,
221221
device_ctx.num_arch_switches,
222222
det_routing_arch,
223223
segment_inf,
224-
router_opts.base_cost_type,
225-
router_opts.trim_empty_channels,
226-
router_opts.trim_obs_channels,
227-
router_opts.clock_modeling,
224+
router_opts,
228225
directs, num_directs,
229-
&warnings,
230-
router_opts.read_rr_edge_metadata,
231-
router_opts.do_check_rr_graph);
226+
&warnings);
232227

233228
alloc_and_load_rr_node_route_structs();
234229

vpr/src/route/rr_graph.cpp

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -317,15 +317,10 @@ void create_rr_graph(const t_graph_type graph_type,
317317
const int num_arch_switches,
318318
t_det_routing_arch* det_routing_arch,
319319
const std::vector<t_segment_inf>& segment_inf,
320-
const enum e_base_cost_type base_cost_type,
321-
const bool trim_empty_channels,
322-
const bool trim_obs_channels,
323-
const enum e_clock_modeling clock_modeling,
320+
const t_router_opts& router_opts,
324321
const t_direct_inf* directs,
325322
const int num_directs,
326-
int* Warnings,
327-
bool read_rr_edge_metadata,
328-
bool do_check_rr_graph) {
323+
int* Warnings) {
329324
const auto& device_ctx = g_vpr_ctx.device();
330325

331326
if (!det_routing_arch->read_rr_graph_filename.empty()) {
@@ -335,11 +330,12 @@ void create_rr_graph(const t_graph_type graph_type,
335330
load_rr_file(graph_type,
336331
grid,
337332
segment_inf,
338-
base_cost_type,
333+
router_opts.base_cost_type,
339334
&det_routing_arch->wire_to_rr_ipin_switch,
340335
det_routing_arch->read_rr_graph_filename.c_str(),
341-
read_rr_edge_metadata,
342-
do_check_rr_graph);
336+
router_opts.read_rr_edge_metadata,
337+
router_opts.do_check_rr_graph);
338+
reorder_rr_graph_nodes(router_opts);
343339
}
344340
} else {
345341
if (channel_widths_unchanged(device_ctx.chan_width, nodes_per_chan) && !device_ctx.rr_nodes.empty()) {
@@ -364,13 +360,14 @@ void create_rr_graph(const t_graph_type graph_type,
364360
det_routing_arch->delayless_switch,
365361
det_routing_arch->R_minW_nmos,
366362
det_routing_arch->R_minW_pmos,
367-
base_cost_type,
368-
clock_modeling,
369-
trim_empty_channels,
370-
trim_obs_channels,
363+
router_opts.base_cost_type,
364+
router_opts.clock_modeling,
365+
router_opts.trim_empty_channels,
366+
router_opts.trim_obs_channels,
371367
directs, num_directs,
372368
&det_routing_arch->wire_to_rr_ipin_switch,
373369
Warnings);
370+
reorder_rr_graph_nodes(router_opts);
374371
}
375372

376373
process_non_config_sets();

vpr/src/route/rr_graph.h

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -33,15 +33,10 @@ void create_rr_graph(const t_graph_type graph_type,
3333
const int num_arch_switches,
3434
t_det_routing_arch* det_routing_arch,
3535
const std::vector<t_segment_inf>& segment_inf,
36-
const enum e_base_cost_type base_cost_type,
37-
const bool trim_empty_channels,
38-
const bool trim_obs_channels,
39-
const enum e_clock_modeling clock_modeling,
36+
const t_router_opts& router_opts,
4037
const t_direct_inf* directs,
4138
const int num_directs,
42-
int* Warnings,
43-
bool read_rr_edge_metadata,
44-
bool do_check_rr_graph);
39+
int* Warnings);
4540

4641
void free_rr_graph();
4742

0 commit comments

Comments
 (0)