Skip to content

Commit 203c738

Browse files
committed
[Router] Added ConnectionRouter Abstraction and Reduced Code Duplication
Added a partial abstract class for ConnectionRouter, derived from the pure abstract ConnectionRouterInterface. The SerialConnectionRouter and ParallelConnectionRouter classes are now derived from the ConnectionRouter class, utilizing the common class members and helper functions to reduce code duplication.
1 parent 25bfd18 commit 203c738

7 files changed

+1090
-1730
lines changed

vpr/src/route/connection_router.h

Lines changed: 238 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,238 @@
1+
#ifndef _CONNECTION_ROUTER_H
2+
#define _CONNECTION_ROUTER_H
3+
4+
#include "connection_router_interface.h"
5+
#include "rr_graph_storage.h"
6+
#include "route_common.h"
7+
#include "router_lookahead.h"
8+
#include "route_tree.h"
9+
#include "rr_rc_data.h"
10+
#include "router_stats.h"
11+
#include "spatial_route_tree_lookup.h"
12+
13+
// This class encapsulates the timing driven connection router. This class
14+
// routes from some initial set of sources (via the input rt tree) to a
15+
// particular sink.
16+
//
17+
// When the ConnectionRouter is used, it mutates the provided
18+
// rr_node_route_inf. The routed path can be found by tracing from the sink
19+
// node (which is returned) through the rr_node_route_inf. See
20+
// update_traceback as an example of this tracing.
21+
template<typename HeapImplementation>
22+
class ConnectionRouter : public ConnectionRouterInterface {
23+
public:
24+
ConnectionRouter(
25+
const DeviceGrid& grid,
26+
const RouterLookahead& router_lookahead,
27+
const t_rr_graph_storage& rr_nodes,
28+
const RRGraphView* rr_graph,
29+
const std::vector<t_rr_rc_data>& rr_rc_data,
30+
const vtr::vector<RRSwitchId, t_rr_switch_inf>& rr_switch_inf,
31+
vtr::vector<RRNodeId, t_rr_node_route_inf>& rr_node_route_inf,
32+
bool is_flat)
33+
: grid_(grid)
34+
, router_lookahead_(router_lookahead)
35+
, rr_nodes_(rr_nodes.view())
36+
, rr_graph_(rr_graph)
37+
, rr_rc_data_(rr_rc_data.data(), rr_rc_data.size())
38+
, rr_switch_inf_(rr_switch_inf.data(), rr_switch_inf.size())
39+
, net_terminal_groups(g_vpr_ctx.routing().net_terminal_groups)
40+
, net_terminal_group_num(g_vpr_ctx.routing().net_terminal_group_num)
41+
, rr_node_route_inf_(rr_node_route_inf)
42+
, is_flat_(is_flat)
43+
, router_stats_(nullptr)
44+
, router_debug_(false)
45+
, path_search_cumulative_time(0) {
46+
heap_.init_heap(grid);
47+
only_opin_inter_layer = (grid.get_num_layers() > 1) && inter_layer_connections_limited_to_opin(*rr_graph);
48+
}
49+
50+
virtual ~ConnectionRouter() {}
51+
52+
// Clear's the modified list. Should be called after reset_path_costs
53+
// have been called.
54+
virtual void clear_modified_rr_node_info() = 0;
55+
56+
// Reset modified data in rr_node_route_inf based on modified_rr_node_inf.
57+
virtual void reset_path_costs() = 0;
58+
59+
/** Finds a path from the route tree rooted at rt_root to sink_node.
60+
* This is used when you want to allow previous routing of the same net to
61+
* serve as valid start locations for the current connection.
62+
*
63+
* Returns a tuple of:
64+
* bool: path exists? (hard failure, rr graph disconnected)
65+
* bool: should retry with full bounding box? (only used in parallel routing)
66+
* RTExploredNode: the explored sink node, from which the cheapest path can be found via back-tracing */
67+
std::tuple<bool, bool, RTExploredNode> timing_driven_route_connection_from_route_tree(
68+
const RouteTreeNode& rt_root,
69+
RRNodeId sink_node,
70+
const t_conn_cost_params& cost_params,
71+
const t_bb& bounding_box,
72+
RouterStats& router_stats,
73+
const ConnectionParameters& conn_params) final;
74+
75+
/** Finds a path from the route tree rooted at rt_root to sink_node for a
76+
* high fanout net.
77+
*
78+
* Unlike timing_driven_route_connection_from_route_tree(), only part of
79+
* the route tree which is spatially close to the sink is added to the heap.
80+
*
81+
* Returns a tuple of:
82+
* bool: path exists? (hard failure, rr graph disconnected)
83+
* bool: should retry with full bounding box? (only used in parallel routing)
84+
* RTExploredNode: the explored sink node, from which the cheapest path can be found via back-tracing */
85+
std::tuple<bool, bool, RTExploredNode> timing_driven_route_connection_from_route_tree_high_fanout(
86+
const RouteTreeNode& rt_root,
87+
RRNodeId sink_node,
88+
const t_conn_cost_params& cost_params,
89+
const t_bb& net_bounding_box,
90+
const SpatialRouteTreeLookup& spatial_rt_lookup,
91+
RouterStats& router_stats,
92+
const ConnectionParameters& conn_params) final;
93+
94+
// Finds a path from the route tree rooted at rt_root to all sinks
95+
// available.
96+
//
97+
// Each element of the returned vector is a reachable sink.
98+
//
99+
// If cost_params.astar_fac is set to 0, this effectively becomes
100+
// Dijkstra's algorithm with a modified exit condition (runs until heap is
101+
// empty). When using cost_params.astar_fac = 0, for efficiency the
102+
// RouterLookahead used should be the NoOpLookahead.
103+
//
104+
// Note: This routine is currently used only to generate information that
105+
// may be helpful in debugging an architecture.
106+
virtual vtr::vector<RRNodeId, RTExploredNode> timing_driven_find_all_shortest_paths_from_route_tree(
107+
const RouteTreeNode& rt_root,
108+
const t_conn_cost_params& cost_params,
109+
const t_bb& bounding_box,
110+
RouterStats& router_stats,
111+
const ConnectionParameters& conn_params) = 0;
112+
113+
void set_router_debug(bool router_debug) final {
114+
router_debug_ = router_debug;
115+
}
116+
117+
// Empty the route tree set used for RCV node detection
118+
// Will return if RCV is disabled
119+
// Called after each net is finished routing to flush the set
120+
void empty_rcv_route_tree_set() final;
121+
122+
// Enable or disable RCV in connection router
123+
// Enabling this will utilize extra path structures, as well as the RCV cost function
124+
//
125+
// Ensure route budgets have been calculated before enabling this
126+
virtual void set_rcv_enabled(bool enable) = 0;
127+
128+
protected:
129+
/** Common logic from timing_driven_route_connection_from_route_tree and
130+
* timing_driven_route_connection_from_route_tree_high_fanout for running
131+
* the connection router.
132+
* @param[in] rt_root RouteTreeNode describing the current routing state
133+
* @param[in] sink_node Sink node ID to route to
134+
* @param[in] cost_params
135+
* @param[in] bounding_box Keep search confined to this bounding box
136+
* @return bool Signal to retry this connection with a full-device bounding box */
137+
bool timing_driven_route_connection_common_setup(
138+
const RouteTreeNode& rt_root,
139+
RRNodeId sink_node,
140+
const t_conn_cost_params& cost_params,
141+
const t_bb& bounding_box);
142+
143+
// Finds a path to sink_node, starting from the elements currently in the
144+
// heap.
145+
//
146+
// If the path is not found, which means that the path_cost of sink_node in
147+
// RR node route info has never been updated, `rr_node_route_inf_[sink_node]
148+
// .path_cost` will be the initial value (i.e., float infinity). This case
149+
// can be detected by `std::isinf(rr_node_route_inf_[sink_node].path_cost)`.
150+
//
151+
// This is the core maze routing routine.
152+
//
153+
// Note: For understanding the connection router, start here.
154+
void timing_driven_route_connection_from_heap(
155+
RRNodeId sink_node,
156+
const t_conn_cost_params& cost_params,
157+
const t_bb& bounding_box);
158+
159+
// Find the shortest path from current heap to the sink node in the RR graph
160+
virtual void timing_driven_find_single_shortest_path_from_heap(RRNodeId sink_node,
161+
const t_conn_cost_params& cost_params,
162+
const t_bb& bounding_box,
163+
const t_bb& target_bb) = 0;
164+
165+
// Find paths from current heap to all nodes in the RR graph
166+
virtual vtr::vector<RRNodeId, RTExploredNode> timing_driven_find_all_shortest_paths_from_heap(
167+
const t_conn_cost_params& cost_params,
168+
const t_bb& bounding_box) = 0;
169+
170+
//Unconditionally adds rt_node to the heap
171+
//
172+
//Note that if you want to respect rt_node->re_expand that is the caller's
173+
//responsibility.
174+
virtual void add_route_tree_node_to_heap(
175+
const RouteTreeNode& rt_node,
176+
RRNodeId target_node,
177+
const t_conn_cost_params& cost_params,
178+
const t_bb& net_bb) = 0;
179+
180+
// Calculates the cost of reaching to_node
181+
void evaluate_timing_driven_node_costs(
182+
RTExploredNode* to,
183+
const t_conn_cost_params& cost_params,
184+
RRNodeId from_node,
185+
RRNodeId target_node);
186+
187+
// Evaluate node costs using the RCV algorith
188+
float compute_node_cost_using_rcv(const t_conn_cost_params cost_params,
189+
RRNodeId to_node,
190+
RRNodeId target_node,
191+
float backwards_delay,
192+
float backwards_cong,
193+
float R_upstream);
194+
195+
//Adds the route tree rooted at rt_node to the heap, preparing it to be
196+
//used as branch-points for further routing.
197+
void add_route_tree_to_heap(const RouteTreeNode& rt_node,
198+
RRNodeId target_node,
199+
const t_conn_cost_params& cost_params,
200+
const t_bb& net_bb);
201+
202+
t_bb add_high_fanout_route_tree_to_heap(
203+
const RouteTreeNode& rt_root,
204+
RRNodeId target_node,
205+
const t_conn_cost_params& cost_params,
206+
const SpatialRouteTreeLookup& spatial_route_tree_lookup,
207+
const t_bb& net_bounding_box);
208+
209+
const DeviceGrid& grid_;
210+
const RouterLookahead& router_lookahead_;
211+
const t_rr_graph_view rr_nodes_;
212+
const RRGraphView* rr_graph_;
213+
vtr::array_view<const t_rr_rc_data> rr_rc_data_;
214+
vtr::array_view<const t_rr_switch_inf> rr_switch_inf_;
215+
const vtr::vector<ParentNetId, std::vector<std::vector<int>>>& net_terminal_groups;
216+
const vtr::vector<ParentNetId, std::vector<int>>& net_terminal_group_num;
217+
vtr::vector<RRNodeId, t_rr_node_route_inf>& rr_node_route_inf_;
218+
bool is_flat_;
219+
std::vector<RRNodeId> modified_rr_node_inf_;
220+
RouterStats* router_stats_;
221+
const ConnectionParameters* conn_params_;
222+
HeapImplementation heap_;
223+
bool router_debug_;
224+
225+
bool only_opin_inter_layer;
226+
227+
// Cumulative time spent in the path search part of the connection router.
228+
std::chrono::microseconds path_search_cumulative_time;
229+
230+
// The path manager for RCV, keeps track of the route tree as a set, also
231+
// manages the allocation of `rcv_path_data`.
232+
PathManager rcv_path_manager;
233+
vtr::vector<RRNodeId, t_heap_path*> rcv_path_data;
234+
};
235+
236+
#include "connection_router.tpp"
237+
238+
#endif /* _CONNECTION_ROUTER_H */

0 commit comments

Comments
 (0)