Skip to content

Commit 0e5a4a8

Browse files
committed
cleanup and add baseline parallel router
1 parent c4156f2 commit 0e5a4a8

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

73 files changed

+2651
-1437
lines changed

.github/scripts/hostsetup.sh

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,8 @@ apt install -y \
6969
default-jdk \
7070
g++-9 \
7171
gcc-9 \
72-
wget
72+
wget \
73+
libtbb-dev
7374

7475
# installing the latest version of cmake
7576
apt install -y apt-transport-https ca-certificates gnupg

doc/src/vpr/command_line_usage.rst

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1127,7 +1127,7 @@ VPR uses a negotiated congestion algorithm (based on Pathfinder) to perform rout
11271127

11281128
* ``delay_normalized_length_frequency`` like ``delay_normalized``, but scaled by routing resource length and scaled inversely by routing resource frequency.
11291129

1130-
**Default:** ``delay_normalized_length`` for the timing-driven router and ``demand_only`` for the breadth-first router
1130+
**Default:** ``delay_normalized_length``
11311131

11321132
.. option:: --bend_cost <float>
11331133

@@ -1172,22 +1172,13 @@ VPR uses a negotiated congestion algorithm (based on Pathfinder) to perform rout
11721172

11731173
This option attempts to verify the minimum by routing at successively lower channel widths until two consecutive routing failures are observed.
11741174

1175-
.. option:: --router_algorithm {breadth_first | timing_driven}
1175+
.. option:: --router_algorithm {parallel | timing_driven}
11761176

11771177
Selects which router algorithm to use.
11781178

11791179
.. warning::
11801180

1181-
The ``breadth_first`` router **should NOT be used to compare the run-time/quality** of alternate routing algorithms.
1182-
1183-
It is inferrior to the ``timing_driven`` router from a circuit speed (2x - 10x slower) and run-time perspective (takes 10-100x longer on the large benchmarks).
1184-
The ``breadth_first`` router is deprecated and may be removed in a future release.
1185-
1186-
The ``breadth_first`` router :cite:`betz_arch_cad` focuses solely on routing a design successfully, while the ``timing_driven`` router :cite:`betz_arch_cad,murray_air` focuses both on achieving a successful route and achieving good circuit speed.
1187-
1188-
The breadth-first router is capable of routing a design using slightly fewer tracks than the timing-driving router (typically 5% if the timing-driven router uses its default parameters.
1189-
This can be reduced to about 2% if the router parameters are set so the timing-driven router pays more attention to routability and less to area).
1190-
The designs produced by the timing-driven router are much faster, however, (2x - 10x) and it uses less CPU time to route.
1181+
The ``parallel`` router is experimental. (TODO: more explanation)
11911182

11921183
**Default:** ``timing_driven``
11931184

libs/EXTERNAL/libargparse/argparse_test.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -399,10 +399,10 @@ int main(
399399
.show_in(argparse::ShowIn::HELP_ONLY);
400400
route_grp.add_argument(args.router_algorithm, "--router_algorithm")
401401
.help("Specifies the router algorithm to use.\n"
402-
" * breadth_first: focuses solely on routability\n"
402+
" * parallel: timing_driven with tricks to run on multiple cores (may be worse)\n"
403403
" * timing driven: focuses on routability and circuit speed\n")
404404
.default_value("timing_driven")
405-
.choices({"breadth_first", "timing_driven"})
405+
.choices({"parallel", "timing_driven"})
406406
.show_in(argparse::ShowIn::HELP_ONLY);
407407
route_grp.add_argument(args.min_incremental_reroute_fanout, "--min_incremental_reroute_fanout")
408408
.help("The net fanout thershold above which nets will be re-routed incrementally.")

libs/librrgraph/src/base/check_rr_graph.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -596,7 +596,7 @@ static void check_rr_edge(const RRGraphView& rr_graph,
596596
std::string msg = "Non-configurable BUFFER type switch must have only one driver. ";
597597
msg += vtr::string_fmt(" Actual fan-in was %d (expected 1).\n", to_fanin);
598598
msg += " Possible cause is complex block output pins connecting to:\n";
599-
msg += " " + describe_rr_node(rr_graph, grid, rr_indexed_data, to_node, is_flat);
599+
msg += " " + describe_rr_node(rr_graph, grid, rr_indexed_data, RRNodeId(to_node), is_flat);
600600
VPR_FATAL_ERROR(VPR_ERROR_ROUTE, msg.c_str());
601601
}
602602
break;

libs/librrgraph/src/utils/describe_rr_node.cpp

Lines changed: 17 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -4,50 +4,49 @@
44
#include "physical_types_util.h"
55
#include "vtr_util.h"
66

7-
/* TODO: This function should adapt RRNodeId */
87
std::string describe_rr_node(const RRGraphView& rr_graph,
98
const DeviceGrid& grid,
109
const vtr::vector<RRIndexedDataId, t_rr_indexed_data>& rr_indexed_data,
11-
int inode,
10+
RRNodeId inode,
1211
bool is_flat) {
1312

1413
std::string msg = vtr::string_fmt("RR node: %d", inode);
1514

16-
if (rr_graph.node_type(RRNodeId(inode)) == CHANX || rr_graph.node_type(RRNodeId(inode)) == CHANY) {
17-
auto cost_index = rr_graph.node_cost_index(RRNodeId(inode));
15+
if (rr_graph.node_type(inode) == CHANX || rr_graph.node_type(inode) == CHANY) {
16+
auto cost_index = rr_graph.node_cost_index(inode);
1817

1918
int seg_index = rr_indexed_data[cost_index].seg_index;
20-
std::string rr_node_direction_string = rr_graph.node_direction_string(RRNodeId(inode));
19+
std::string rr_node_direction_string = rr_graph.node_direction_string(inode);
2120

2221
if (seg_index < (int)rr_graph.num_rr_segments()) {
2322
msg += vtr::string_fmt(" track: %d longline: %d",
24-
rr_graph.node_track_num(RRNodeId(inode)),
23+
rr_graph.node_track_num(inode),
2524
rr_graph.rr_segments(RRSegmentId(seg_index)).longline);
2625
} else {
2726
msg += vtr::string_fmt(" track: %d seg_type: ILLEGAL_SEG_INDEX %d",
28-
rr_graph.node_track_num(RRNodeId(inode)),
27+
rr_graph.node_track_num(inode),
2928
seg_index);
3029
}
31-
} else if (rr_graph.node_type(RRNodeId(inode)) == IPIN || rr_graph.node_type(RRNodeId(inode)) == OPIN) {
32-
auto type = grid.get_physical_type(rr_graph.node_xlow(RRNodeId(inode)),
33-
rr_graph.node_ylow(RRNodeId(inode)));
30+
} else if (rr_graph.node_type(inode) == IPIN || rr_graph.node_type(inode) == OPIN) {
31+
auto type = grid.get_physical_type(rr_graph.node_xlow(inode),
32+
rr_graph.node_ylow(inode));
3433

35-
std::string pin_name = block_type_pin_index_to_name(type, rr_graph.node_pin_num(RRNodeId(inode)), is_flat);
34+
std::string pin_name = block_type_pin_index_to_name(type, rr_graph.node_pin_num(inode), is_flat);
3635

3736
msg += vtr::string_fmt(" pin: %d pin_name: %s",
38-
rr_graph.node_pin_num(RRNodeId(inode)),
37+
rr_graph.node_pin_num(inode),
3938
pin_name.c_str());
4039
} else {
41-
VTR_ASSERT(rr_graph.node_type(RRNodeId(inode)) == SOURCE || rr_graph.node_type(RRNodeId(inode)) == SINK);
40+
VTR_ASSERT(rr_graph.node_type(inode) == SOURCE || rr_graph.node_type(inode) == SINK);
4241

43-
msg += vtr::string_fmt(" class: %d", rr_graph.node_class_num(RRNodeId(inode)));
42+
msg += vtr::string_fmt(" class: %d", rr_graph.node_class_num(inode));
4443
}
4544

46-
msg += vtr::string_fmt(" capacity: %d", rr_graph.node_capacity(RRNodeId(inode)));
47-
msg += vtr::string_fmt(" fan-in: %d", rr_graph.node_fan_in(RRNodeId(inode)));
48-
msg += vtr::string_fmt(" fan-out: %d", rr_graph.num_edges(RRNodeId(inode)));
45+
msg += vtr::string_fmt(" capacity: %d", rr_graph.node_capacity(inode));
46+
msg += vtr::string_fmt(" fan-in: %d", rr_graph.node_fan_in(inode));
47+
msg += vtr::string_fmt(" fan-out: %d", rr_graph.num_edges(inode));
4948

50-
msg += " " + rr_graph.node_coordinate_to_string(RRNodeId(inode));
49+
msg += " " + rr_graph.node_coordinate_to_string(inode);
5150

5251
return msg;
5352
}

libs/librrgraph/src/utils/describe_rr_node.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
std::string describe_rr_node(const RRGraphView& rr_graph,
1010
const DeviceGrid& grid,
1111
const vtr::vector<RRIndexedDataId, t_rr_indexed_data>& rr_indexed_data,
12-
int inode,
12+
RRNodeId inode,
1313
bool is_flat);
1414

1515
#endif

libs/libvtrutil/src/vtr_strong_id.h

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* @file
55
* @brief This header provides the StrongId class.
66
*
7-
* It is template which can be used to create strong Id's
7+
* It is template which can be used to create strong Id's
88
* which avoid accidental type conversions (generating compiler errors when they occur).
99
*
1010
* Motivation
@@ -146,6 +146,7 @@
146146
#include <type_traits> //for std::is_integral
147147
#include <cstddef> //for std::size_t
148148
#include <functional> //for std::hash
149+
#include <ostream> //for std::ostream
149150

150151
namespace vtr {
151152

@@ -168,6 +169,9 @@ bool operator!=(const StrongId<tag, T, sentinel>& lhs, const StrongId<tag, T, se
168169
template<typename tag, typename T, T sentinel>
169170
bool operator<(const StrongId<tag, T, sentinel>& lhs, const StrongId<tag, T, sentinel>& rhs);
170171

172+
template<typename tag, typename T, T sentinel>
173+
std::ostream& operator<<(std::ostream& out, const StrongId<tag, T, sentinel>& rhs);
174+
171175
///@brief Class template definition with default template parameters
172176
template<typename tag, typename T = int, T sentinel = T(-1)>
173177
class StrongId {
@@ -197,7 +201,7 @@ class StrongId {
197201
friend std::hash<StrongId<tag, T, sentinel>>;
198202

199203
/**
200-
* @brief To enable comparisions between Ids
204+
* @brief To enable comparisons between Ids
201205
*
202206
* Note that since these are templated functions we provide an empty set of template parameters
203207
* after the function name (i.e. <>)
@@ -208,6 +212,11 @@ class StrongId {
208212
///@brief < operator
209213
friend bool operator< <>(const StrongId<tag, T, sentinel>& lhs, const StrongId<tag, T, sentinel>& rhs);
210214

215+
/**
216+
* @brief to be able to print them out
217+
*/
218+
friend std::ostream& operator<< <>(std::ostream& out, const StrongId<tag, T, sentinel>& rhs);
219+
211220
private:
212221
T id_;
213222
};
@@ -230,6 +239,12 @@ bool operator<(const StrongId<tag, T, sentinel>& lhs, const StrongId<tag, T, sen
230239
return lhs.id_ < rhs.id_;
231240
}
232241

242+
///@brief operator << Needed for print-debugging
243+
template<typename tag, typename T, T sentinel>
244+
std::ostream& operator<<(std::ostream& out, const StrongId<tag, T, sentinel>& rhs) {
245+
out << rhs.id_;
246+
return out;
247+
}
233248
} //namespace vtr
234249

235250
///@brief Specialize std::hash for StrongId's (needed for std::unordered_map-like containers)

utils/route_diag/src/main.cpp

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -60,8 +60,8 @@ constexpr int INTERRUPTED_EXIT_CODE = 3; //VPR was interrupted by the user (e.g.
6060

6161
static void do_one_route(const Netlist<>& net_list,
6262
const t_det_routing_arch& det_routing_arch,
63-
int source_node,
64-
int sink_node,
63+
RRNodeId source_node,
64+
RRNodeId sink_node,
6565
const t_router_opts& router_opts,
6666
const std::vector<t_segment_inf>& segment_inf,
6767
bool is_flat) {
@@ -117,15 +117,16 @@ static void do_one_route(const Netlist<>& net_list,
117117
-1,
118118
false,
119119
std::unordered_map<RRNodeId, int>());
120-
std::tie(found_path, cheapest) = router.timing_driven_route_connection_from_route_tree(tree.root(),
120+
std::tie(found_path, std::ignore, cheapest) = router.timing_driven_route_connection_from_route_tree(tree.root(),
121121
sink_node,
122122
cost_params,
123123
bounding_box,
124124
router_stats,
125-
conn_params);
125+
conn_params,
126+
true);
126127

127128
if (found_path) {
128-
VTR_ASSERT(cheapest.index == sink_node);
129+
VTR_ASSERT(RRNodeId(cheapest.index) == sink_node);
129130

130131
vtr::optional<const RouteTreeNode&> rt_node_of_sink;
131132
std::tie(std::ignore, rt_node_of_sink) = tree.update_from_heap(&cheapest, OPEN, nullptr, router_opts.flat_routing);
@@ -137,7 +138,7 @@ static void do_one_route(const Netlist<>& net_list,
137138
tree.print();
138139
VTR_LOG("\n");
139140

140-
VTR_ASSERT_MSG(route_ctx.rr_node_route_inf[size_t(tree.root().inode)].occ() <= rr_graph.node_capacity(tree.root().inode), "SOURCE should never be congested");
141+
VTR_ASSERT_MSG(route_ctx.rr_node_route_inf[tree.root().inode].occ() <= rr_graph.node_capacity(tree.root().inode), "SOURCE should never be congested");
141142
} else {
142143
VTR_LOG("Routing failed");
143144
}
@@ -148,7 +149,7 @@ static void do_one_route(const Netlist<>& net_list,
148149

149150
static void profile_source(const Netlist<>& net_list,
150151
const t_det_routing_arch& det_routing_arch,
151-
int source_rr_node,
152+
RRNodeId source_rr_node,
152153
const t_router_opts& router_opts,
153154
const std::vector<t_segment_inf>& segment_inf,
154155
bool is_flat) {
@@ -185,26 +186,26 @@ static void profile_source(const Netlist<>& net_list,
185186
for (int sink_ptc : best_sink_ptcs) {
186187
VTR_ASSERT(sink_ptc != OPEN);
187188

188-
int sink_rr_node = size_t(device_ctx.rr_graph.node_lookup().find_node(sink_x, sink_y, SINK, sink_ptc));
189+
RRNodeId sink_rr_node = device_ctx.rr_graph.node_lookup().find_node(sink_x, sink_y, SINK, sink_ptc);
189190

190191
if (directconnect_exists(source_rr_node, sink_rr_node)) {
191192
//Skip if we shouldn't measure direct connects and a direct connect exists
192193
continue;
193194
}
194195

195-
VTR_ASSERT(sink_rr_node != OPEN);
196+
VTR_ASSERT(sink_rr_node);
196197

197198
{
198199
vtr::ScopedStartFinishTimer delay_timer(vtr::string_fmt(
199200
"Routing Src: %d Sink: %d", source_rr_node,
200201
sink_rr_node));
201-
successfully_routed = profiler.calculate_delay(source_rr_node, sink_rr_node,
202+
successfully_routed = profiler.calculate_delay(RRNodeId(source_rr_node), RRNodeId(sink_rr_node),
202203
router_opts,
203204
&delays[sink_x][sink_y]);
204205
}
205206

206207
if (successfully_routed) {
207-
sink_nodes[sink_x][sink_y] = sink_rr_node;
208+
sink_nodes[sink_x][sink_y] = size_t(sink_rr_node);
208209
break;
209210
}
210211
}
@@ -331,15 +332,15 @@ int main(int argc, const char **argv) {
331332
if(route_options.profile_source) {
332333
profile_source(net_list,
333334
vpr_setup.RoutingArch,
334-
route_options.source_rr_node,
335+
RRNodeId(route_options.source_rr_node),
335336
vpr_setup.RouterOpts,
336337
vpr_setup.Segments,
337338
is_flat);
338339
} else {
339340
do_one_route(net_list,
340341
vpr_setup.RoutingArch,
341-
route_options.source_rr_node,
342-
route_options.sink_rr_node,
342+
RRNodeId(route_options.source_rr_node),
343+
RRNodeId(route_options.sink_rr_node),
343344
vpr_setup.RouterOpts,
344345
vpr_setup.Segments,
345346
is_flat);

vpr/src/base/ShowSetup.cpp

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -260,8 +260,8 @@ static void ShowRouterOpts(const t_router_opts& RouterOpts) {
260260
if (DETAILED == RouterOpts.route_type) {
261261
VTR_LOG("RouterOpts.router_algorithm: ");
262262
switch (RouterOpts.router_algorithm) {
263-
case BREADTH_FIRST:
264-
VTR_LOG("BREADTH_FIRST\n");
263+
case PARALLEL:
264+
VTR_LOG("PARALLEL\n");
265265
break;
266266
case TIMING_DRIVEN:
267267
VTR_LOG("TIMING_DRIVEN\n");
@@ -432,9 +432,6 @@ static void ShowRouterOpts(const t_router_opts& RouterOpts) {
432432

433433
VTR_LOG("RouterOpts.router_algorithm: ");
434434
switch (RouterOpts.router_algorithm) {
435-
case BREADTH_FIRST:
436-
VTR_LOG("BREADTH_FIRST\n");
437-
break;
438435
case TIMING_DRIVEN:
439436
VTR_LOG("TIMING_DRIVEN\n");
440437
break;

vpr/src/base/old_traceback.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -121,8 +121,8 @@ void print_traceback(const t_trace* trace) {
121121
auto& route_ctx = g_vpr_ctx.routing();
122122
const t_trace* prev = nullptr;
123123
while (trace) {
124-
int inode = trace->index;
125-
VTR_LOG("%d (%s)", inode, rr_node_typename[rr_graph.node_type(RRNodeId(inode))]);
124+
RRNodeId inode(trace->index);
125+
VTR_LOG("%d (%s)", inode, rr_node_typename[rr_graph.node_type(inode)]);
126126

127127
if (trace->iswitch == OPEN) {
128128
VTR_LOG(" !"); //End of branch
@@ -132,7 +132,7 @@ void print_traceback(const t_trace* trace) {
132132
VTR_LOG("*"); //Reached non-configurably
133133
}
134134

135-
if (route_ctx.rr_node_route_inf[inode].occ() > rr_graph.node_capacity(RRNodeId(inode))) {
135+
if (route_ctx.rr_node_route_inf[inode].occ() > rr_graph.node_capacity(inode)) {
136136
VTR_LOG(" x"); //Overused
137137
}
138138
VTR_LOG("\n");

0 commit comments

Comments
 (0)