Skip to content

Commit 6f8fdab

Browse files
authored
Merge branch 'master' into make_mode_conflict_non_fatal
2 parents 6d3594f + a137fbe commit 6f8fdab

File tree

16 files changed

+113
-208
lines changed

16 files changed

+113
-208
lines changed

doc/src/vpr/command_line_usage.rst

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1120,6 +1120,14 @@ VPR uses a negotiated congestion algorithm (based on Pathfinder) to perform rout
11201120

11211121
.. seealso:: :ref:`timing_driven_router_options`
11221122

1123+
.. option:: --flat_routing {on | off}
1124+
1125+
If this option is enabled, the *run-flat* router is used instead of the *two-stage* router.
1126+
This means that during the routing stage, all nets, both intra- and inter-cluster, are routed directly from one primitive pin to another primitive pin.
1127+
This increases routing time but can improve routing quality by re-arranging LUT inputs and exposing additional optimization opportunities in architectures with local intra-cluster routing that is not a full crossbar.
1128+
1129+
**Default:** ``OFF`
1130+
11231131
.. option:: --max_router_iterations <int>
11241132
11251133
The number of iterations of a Pathfinder-based router that will be executed before a circuit is declared unrouteable (if it hasn’t routed successfully yet) at a given channel width.

libs/librrgraph/src/utils/alloc_and_load_rr_indexed_data.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -351,7 +351,18 @@ static void load_rr_indexed_data_base_costs(const RRGraphView& rr_graph,
351351
rr_indexed_data[RRIndexedDataId(SOURCE_COST_INDEX)].base_cost = delay_normalization_fac;
352352
rr_indexed_data[RRIndexedDataId(SINK_COST_INDEX)].base_cost = 0.;
353353
rr_indexed_data[RRIndexedDataId(OPIN_COST_INDEX)].base_cost = delay_normalization_fac;
354+
// If the SPEC_CPU flag is set, we need to make sure that all floating point numbers are perfectly representable in
355+
// binary format. Thus, we changed the IPIN_COST_INDEX base cost from 0.95 to 0.875.
356+
// This number is perfectly representable in a binary mantissa (without round-off) so we can get the same routing result on different platforms.
357+
// Since the router cost calculations and heap use floating point numbers, normally we get slightly different round off with different compiler settings,
358+
// leading to different heap sorts and hence different routings.
359+
// To make result validation for SPEC easier, we choose all router parameters to result in calculations that fit perfectly in a 24-bit binary mantissa.
360+
// .875 = 1/2 + 1/4 + 1/8 can be perfectly represented in a binary mantissa with only the first 3 bits set.
361+
#ifdef SPEC_CPU
362+
rr_indexed_data[RRIndexedDataId(IPIN_COST_INDEX)].base_cost = 0.875 * delay_normalization_fac;
363+
#else
354364
rr_indexed_data[RRIndexedDataId(IPIN_COST_INDEX)].base_cost = 0.95 * delay_normalization_fac;
365+
#endif
355366

356367
auto rr_segment_counts = count_rr_segment_types(rr_graph, rr_indexed_data);
357368
size_t total_segments = std::accumulate(rr_segment_counts.begin(), rr_segment_counts.end(), 0u);

libs/libvtrutil/src/vtr_strong_id_range.h

Lines changed: 32 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -88,61 +88,59 @@ class StrongIdIterator {
8888
return StrongId(size_t(id_) + offset);
8989
}
9090

91-
///@brief + operator
92-
template<typename IdType>
93-
friend StrongIdIterator<IdType> operator+(
94-
const StrongIdIterator<IdType>& lhs,
95-
ssize_t n) {
96-
StrongIdIterator ret = lhs;
97-
ret += n;
98-
return ret;
99-
}
100-
101-
///@brief - operator
102-
template<typename IdType>
103-
friend StrongIdIterator<IdType> operator-(
104-
const StrongIdIterator<IdType>& lhs,
105-
ssize_t n) {
106-
StrongIdIterator ret = lhs;
107-
ret -= n;
108-
return ret;
109-
}
110-
11191
///@brief ~ operator
11292
template<typename IdType>
113-
friend ssize_t operator-(
114-
const StrongIdIterator<IdType>& lhs,
115-
const StrongIdIterator<IdType>& rhs) {
116-
VTR_ASSERT_SAFE(bool(lhs.id_));
117-
VTR_ASSERT_SAFE(bool(rhs.id_));
118-
119-
ssize_t ret = size_t(lhs.id_);
120-
ret -= size_t(rhs.id_);
93+
ssize_t operator-(const StrongIdIterator<IdType>& other) const {
94+
VTR_ASSERT_SAFE(bool(id_));
95+
VTR_ASSERT_SAFE(bool(other.id_));
96+
97+
ssize_t ret = size_t(id_);
98+
ret -= size_t(other.id_);
12199
return ret;
122100
}
123101

124102
///@brief == operator
125103
template<typename IdType>
126-
friend bool operator==(const StrongIdIterator<IdType>& lhs, const StrongIdIterator<IdType>& rhs) {
127-
return lhs.id_ == rhs.id_;
104+
bool operator==(const StrongIdIterator<IdType>& other) const {
105+
return id_ == other.id_;
128106
}
129107

130108
///@brief != operator
131109
template<typename IdType>
132-
friend bool operator!=(const StrongIdIterator<IdType>& lhs, const StrongIdIterator<IdType>& rhs) {
133-
return lhs.id_ != rhs.id_;
110+
bool operator!=(const StrongIdIterator<IdType>& other) const {
111+
return id_ != other.id_;
134112
}
135113

136114
///@brief < operator
137115
template<typename IdType>
138-
friend bool operator<(const StrongIdIterator<IdType>& lhs, const StrongIdIterator<IdType>& rhs) {
139-
return lhs.id_ < rhs.id_;
116+
bool operator<(const StrongIdIterator<IdType>& other) const {
117+
return id_ < other.id_;
140118
}
141119

142120
private:
143121
StrongId id_;
144122
};
145123

124+
///@brief + operator
125+
template<typename IdType>
126+
inline StrongIdIterator<IdType> operator+(
127+
const StrongIdIterator<IdType>& lhs,
128+
ssize_t n) {
129+
StrongIdIterator ret = lhs;
130+
ret += n;
131+
return ret;
132+
}
133+
134+
///@brief - operator
135+
template<typename IdType>
136+
inline StrongIdIterator<IdType> operator-(
137+
const StrongIdIterator<IdType>& lhs,
138+
ssize_t n) {
139+
StrongIdIterator ret = lhs;
140+
ret -= n;
141+
return ret;
142+
}
143+
146144
/**
147145
* @brief StrongIdRange class
148146
*

vpr/src/base/read_options.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ t_options read_options(int argc, const char** argv) {
3131

3232
struct ParseOnOff {
3333
ConvertedValue<bool> from_str(std::string str) {
34+
std::transform(str.begin(), str.end(), str.begin(), ::tolower);
3435
ConvertedValue<bool> conv_value;
3536
if (str == "on")
3637
conv_value.set_value(true);
@@ -42,7 +43,6 @@ struct ParseOnOff {
4243
conv_value.set_error(msg.str());
4344
}
4445
return conv_value;
45-
;
4646
}
4747

4848
ConvertedValue<std::string> to_str(bool val) {
@@ -2441,9 +2441,9 @@ argparse::ArgumentParser create_arg_parser(std::string prog_name, t_options& arg
24412441
.default_value("1")
24422442
.show_in(argparse::ShowIn::HELP_ONLY);
24432443

2444-
route_grp.add_argument(args.flat_routing, "--flat_routing")
2444+
route_grp.add_argument<bool, ParseOnOff>(args.flat_routing, "--flat_routing")
24452445
.help("Enable VPR's flat routing (routing the nets from the source primitive to the destination primitive)")
2446-
.default_value("false")
2446+
.default_value("off")
24472447
.show_in(argparse::ShowIn::HELP_ONLY);
24482448

24492449
route_grp.add_argument(args.has_choking_spot, "--has_choking_spot")

vpr/src/route/connection_router.cpp

Lines changed: 46 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,17 @@ static bool relevant_node_to_target(const RRGraphView* rr_graph,
2525
RRNodeId node_to_add,
2626
RRNodeId target_node);
2727

28-
static void update_router_stats(const DeviceContext& device_ctx,
29-
const RRGraphView* rr_graph,
30-
RouterStats* router_stats,
28+
#ifdef VTR_ENABLE_DEBUG_LOGGING
29+
static void update_router_stats(RouterStats* router_stats,
30+
bool is_push,
3131
RRNodeId rr_node_id,
32-
bool is_push);
32+
const RRGraphView* rr_graph);
33+
#else
34+
static void update_router_stats(RouterStats* router_stats,
35+
bool is_push,
36+
RRNodeId /*rr_node_id*/,
37+
const RRGraphView* /*rr_graph*/);
38+
#endif
3339

3440
/** return tuple <found_path, retry_with_full_bb, cheapest> */
3541
template<typename Heap>
@@ -73,7 +79,7 @@ std::tuple<bool, t_heap*> ConnectionRouter<Heap>::timing_driven_route_connection
7379
//Re-add route nodes from the existing route tree to the heap.
7480
//They need to be repushed onto the heap since each node's cost is target specific.
7581

76-
add_route_tree_to_heap(rt_root, sink_node, cost_params, false);
82+
add_route_tree_to_heap(rt_root, sink_node, cost_params);
7783
heap_.build_heap(); // via sifting down everything
7884

7985
RRNodeId source_node = rt_root.inode;
@@ -137,7 +143,6 @@ std::tuple<bool, bool, t_heap> ConnectionRouter<Heap>::timing_driven_route_conne
137143

138144
// re-explore route tree from root to add any new nodes (buildheap afterwards)
139145
// route tree needs to be repushed onto the heap since each node's cost is target specific
140-
router_stats_->add_high_fanout_rt++;
141146
t_bb high_fanout_bb = add_high_fanout_route_tree_to_heap(rt_root, sink_node, cost_params, spatial_rt_lookup, net_bounding_box);
142147
heap_.build_heap();
143148

@@ -215,11 +220,10 @@ t_heap* ConnectionRouter<Heap>::timing_driven_route_connection_from_heap(RRNodeI
215220
while (!heap_.is_empty_heap()) {
216221
// cheapest t_heap in current route tree to be expanded on
217222
cheapest = heap_.get_heap_head();
218-
update_router_stats(device_ctx,
219-
rr_graph_,
220-
router_stats_,
223+
update_router_stats(router_stats_,
224+
false,
221225
cheapest->index,
222-
false);
226+
rr_graph_);
223227

224228
RRNodeId inode = cheapest->index;
225229
VTR_LOGV_DEBUG(router_debug_, " Popping node %d (cost: %g)\n",
@@ -274,7 +278,7 @@ vtr::vector<RRNodeId, t_heap> ConnectionRouter<Heap>::timing_driven_find_all_sho
274278

275279
// Add the route tree to the heap with no specific target node
276280
RRNodeId target_node = RRNodeId::INVALID();
277-
add_route_tree_to_heap(rt_root, target_node, cost_params, false);
281+
add_route_tree_to_heap(rt_root, target_node, cost_params);
278282
heap_.build_heap(); // via sifting down everything
279283

280284
auto res = timing_driven_find_all_shortest_paths_from_heap(cost_params, bounding_box);
@@ -305,11 +309,10 @@ vtr::vector<RRNodeId, t_heap> ConnectionRouter<Heap>::timing_driven_find_all_sho
305309
while (!heap_.is_empty_heap()) {
306310
// cheapest t_heap in current route tree to be expanded on
307311
t_heap* cheapest = heap_.get_heap_head();
308-
update_router_stats(g_vpr_ctx.device(),
309-
rr_graph_,
310-
router_stats_,
312+
update_router_stats(router_stats_,
313+
false,
311314
cheapest->index,
312-
false);
315+
rr_graph_);
313316

314317
RRNodeId inode = cheapest->index;
315318
VTR_LOGV_DEBUG(router_debug_, " Popping node %d (cost: %g)\n",
@@ -614,11 +617,10 @@ void ConnectionRouter<Heap>::timing_driven_add_to_heap(const t_conn_cost_params
614617
}
615618

616619
heap_.add_to_heap(next_ptr);
617-
update_router_stats(device_ctx,
618-
rr_graph_,
619-
router_stats_,
620+
update_router_stats(router_stats_,
621+
true,
620622
to_node,
621-
true);
623+
rr_graph_);
622624

623625
} else {
624626
VTR_LOGV_DEBUG(router_debug_, " Didn't expand to %d (%s)\n", to_node, describe_rr_node(device_ctx.rr_graph, device_ctx.grid, device_ctx.rr_indexed_data, to_node, is_flat_).c_str());
@@ -852,18 +854,11 @@ template<typename Heap>
852854
void ConnectionRouter<Heap>::add_route_tree_to_heap(
853855
const RouteTreeNode& rt_node,
854856
RRNodeId target_node,
855-
const t_conn_cost_params cost_params,
856-
bool from_high_fanout) {
857+
const t_conn_cost_params cost_params) {
857858
/* Puts the entire partial routing below and including rt_node onto the heap *
858859
* (except for those parts marked as not to be expanded) by calling itself *
859860
* recursively. */
860861

861-
if (from_high_fanout) {
862-
router_stats_->add_all_rt_from_high_fanout++;
863-
} else {
864-
router_stats_->add_all_rt++;
865-
}
866-
867862
/* Pre-order depth-first traversal */
868863
// IPINs and SINKS are not re_expanded
869864
if (rt_node.re_expand) {
@@ -872,8 +867,7 @@ void ConnectionRouter<Heap>::add_route_tree_to_heap(
872867
}
873868
add_route_tree_node_to_heap(rt_node,
874869
target_node,
875-
cost_params,
876-
false);
870+
cost_params);
877871
}
878872

879873
for (const RouteTreeNode& child_node : rt_node.child_nodes()) {
@@ -883,14 +877,12 @@ void ConnectionRouter<Heap>::add_route_tree_to_heap(
883877
target_node)) {
884878
add_route_tree_to_heap(child_node,
885879
target_node,
886-
cost_params,
887-
from_high_fanout);
880+
cost_params);
888881
}
889882
} else {
890883
add_route_tree_to_heap(child_node,
891884
target_node,
892-
cost_params,
893-
from_high_fanout);
885+
cost_params);
894886
}
895887
}
896888
}
@@ -903,8 +895,7 @@ template<typename Heap>
903895
void ConnectionRouter<Heap>::add_route_tree_node_to_heap(
904896
const RouteTreeNode& rt_node,
905897
RRNodeId target_node,
906-
const t_conn_cost_params cost_params,
907-
bool is_high_fanout) {
898+
const t_conn_cost_params cost_params) {
908899
const auto& device_ctx = g_vpr_ctx.device();
909900
const RRNodeId inode = rt_node.inode;
910901
float backward_path_cost = cost_params.criticality * rt_node.Tdel;
@@ -939,18 +930,14 @@ void ConnectionRouter<Heap>::add_route_tree_node_to_heap(
939930
backward_path_cost, R_upstream, rt_node.Tdel, &rcv_path_manager);
940931
}
941932

942-
update_router_stats(device_ctx,
943-
rr_graph_,
944-
router_stats_,
933+
update_router_stats(router_stats_,
934+
true,
945935
inode,
946-
true);
936+
rr_graph_);
947937

938+
#ifdef VTR_ENABLE_DEBUG_LOGGING
948939
router_stats_->rt_node_pushes[rr_graph_->node_type(inode)]++;
949-
if (is_high_fanout) {
950-
router_stats_->rt_node_high_fanout_pushes[rr_graph_->node_type(inode)]++;
951-
} else {
952-
router_stats_->rt_node_entire_tree_pushes[rr_graph_->node_type(inode)]++;
953-
}
940+
#endif
954941
}
955942

956943
/* Expand bb by inode's extents and clip against net_bb */
@@ -1034,7 +1021,7 @@ t_bb ConnectionRouter<Heap>::add_high_fanout_route_tree_to_heap(
10341021
continue;
10351022
}
10361023
// Put the node onto the heap
1037-
add_route_tree_node_to_heap(rt_node, target_node, cost_params, true);
1024+
add_route_tree_node_to_heap(rt_node, target_node, cost_params);
10381025

10391026
// Expand HF BB to include the node (clip by original BB)
10401027
expand_highfanout_bounding_box(highfanout_bb, net_bounding_box, rr_node_to_add, rr_graph_);
@@ -1065,7 +1052,7 @@ t_bb ConnectionRouter<Heap>::add_high_fanout_route_tree_to_heap(
10651052
}
10661053

10671054
if (nodes_added == 0) { //If the target bin, and it's surrounding bins were empty, just add the full route tree
1068-
add_route_tree_to_heap(rt_root, target_node, cost_params, true);
1055+
add_route_tree_to_heap(rt_root, target_node, cost_params);
10691056
return net_bounding_box;
10701057
} else {
10711058
//We found nearby routing, replace original bounding box to be localized around that routing
@@ -1113,17 +1100,25 @@ static inline bool relevant_node_to_target(const RRGraphView* rr_graph,
11131100
return false;
11141101
}
11151102

1116-
static inline void update_router_stats(const DeviceContext& device_ctx,
1117-
const RRGraphView* rr_graph,
1118-
RouterStats* router_stats,
1103+
#ifdef VTR_ENABLE_DEBUG_LOGGING
1104+
static inline void update_router_stats(RouterStats* router_stats,
1105+
bool is_push,
11191106
RRNodeId rr_node_id,
1120-
bool is_push) {
1107+
const RRGraphView* rr_graph) {
1108+
#else
1109+
static inline void update_router_stats(RouterStats* router_stats,
1110+
bool is_push,
1111+
RRNodeId /*rr_node_id*/,
1112+
const RRGraphView* /*rr_graph*/) {
1113+
#endif
11211114
if (is_push) {
11221115
router_stats->heap_pushes++;
11231116
} else {
11241117
router_stats->heap_pops++;
11251118
}
11261119

1120+
#ifdef VTR_ENABLE_DEBUG_LOGGING
1121+
const auto& device_ctx = g_vpr_ctx.device();
11271122
auto node_type = rr_graph->node_type(rr_node_id);
11281123
VTR_ASSERT(node_type != NUM_RR_TYPES);
11291124
t_physical_tile_type_ptr physical_type = device_ctx.grid.get_physical_type({rr_graph->node_xlow(rr_node_id),
@@ -1150,6 +1145,7 @@ static inline void update_router_stats(const DeviceContext& device_ctx,
11501145
router_stats->intra_cluster_node_type_cnt_pops[node_type]++;
11511146
}
11521147
}
1148+
#endif
11531149
}
11541150

11551151
std::unique_ptr<ConnectionRouterInterface> make_connection_router(e_heap_type heap_type,

0 commit comments

Comments
 (0)