Breadth first router adopt RRGraph object

This commit is contained in:
tangxifan 2020-02-01 14:45:59 -07:00
parent 3536cc8ed5
commit 266b4b6fbe
4 changed files with 47 additions and 49 deletions

View File

@ -287,7 +287,7 @@ struct RoutingContext : public Context {
vtr::vector<ClusterNetId, std::unordered_set<int>> trace_nodes; vtr::vector<ClusterNetId, std::unordered_set<int>> trace_nodes;
/* Xifan Tang: this should adopt RRNodeId as well */ /* Xifan Tang: this should adopt RRNodeId as well */
vtr::vector<ClusterNetId, std::vector<int>> net_rr_terminals; /* [0..num_nets-1][0..num_pins-1] */ vtr::vector<ClusterNetId, std::vector<RRNodeId>> net_rr_terminals; /* [0..num_nets-1][0..num_pins-1] */
vtr::vector<ClusterBlockId, std::vector<int>> rr_blk_source; /* [0..num_blocks-1][0..num_class-1] */ vtr::vector<ClusterBlockId, std::vector<int>> rr_blk_source; /* [0..num_blocks-1][0..num_class-1] */

View File

@ -17,13 +17,13 @@ static bool breadth_first_route_net(ClusterNetId net_id, float bend_cost);
static void breadth_first_expand_trace_segment(t_trace* start_ptr, static void breadth_first_expand_trace_segment(t_trace* start_ptr,
int remaining_connections_to_sink, int remaining_connections_to_sink,
std::vector<int>& modified_rr_node_inf); std::vector<RRNodeId>& modified_rr_node_inf);
static void breadth_first_expand_neighbours(int inode, float pcost, ClusterNetId net_id, float bend_cost); static void breadth_first_expand_neighbours(const RRNodeId& inode, float pcost, ClusterNetId net_id, float bend_cost);
static void breadth_first_add_to_heap(const float path_cost, const float bend_cost, const int from_node, const int to_node, const int iconn); static void breadth_first_add_to_heap(const float path_cost, const float bend_cost, const RRNodeId& from_node, const RRNodeId& to_node, const RREdgeId& iconn);
static float evaluate_node_cost(const float prev_path_cost, const float bend_cost, const int from_node, const int to_node); static float evaluate_node_cost(const float prev_path_cost, const float bend_cost, const RRNodeId& from_node, const RRNodeId& to_node);
static void breadth_first_add_source_to_heap(ClusterNetId net_id); static void breadth_first_add_source_to_heap(ClusterNetId net_id);
@ -156,7 +156,8 @@ static bool breadth_first_route_net(ClusterNetId net_id, float bend_cost) {
* lack of potential paths, rather than congestion), it returns false, as * * lack of potential paths, rather than congestion), it returns false, as *
* routing is impossible on this architecture. Otherwise it returns true. */ * routing is impossible on this architecture. Otherwise it returns true. */
int inode, remaining_connections_to_sink; int remaining_connections_to_sink;
RRNodeId inode;
float pcost, new_pcost; float pcost, new_pcost;
t_heap* current; t_heap* current;
t_trace* tptr; t_trace* tptr;
@ -178,7 +179,7 @@ static bool breadth_first_route_net(ClusterNetId net_id, float bend_cost) {
auto src_pin_id = cluster_ctx.clb_nlist.net_driver(net_id); auto src_pin_id = cluster_ctx.clb_nlist.net_driver(net_id);
std::vector<int> modified_rr_node_inf; //RR node indicies with modified rr_node_route_inf std::vector<RRNodeId> modified_rr_node_inf; //RR node indicies with modified rr_node_route_inf
for (auto pin_id : cluster_ctx.clb_nlist.net_sinks(net_id)) { /* Need n-1 wires to connect n pins */ for (auto pin_id : cluster_ctx.clb_nlist.net_sinks(net_id)) { /* Need n-1 wires to connect n pins */
@ -197,7 +198,7 @@ static bool breadth_first_route_net(ClusterNetId net_id, float bend_cost) {
inode = current->index; inode = current->index;
#ifdef ROUTER_DEBUG #ifdef ROUTER_DEBUG
VTR_LOG(" Popped node %d\n", inode); VTR_LOG(" Popped node %d\n", size_t(inode));
#endif #endif
while (route_ctx.rr_node_route_inf[inode].target_flag == 0) { while (route_ctx.rr_node_route_inf[inode].target_flag == 0) {
@ -269,7 +270,7 @@ static bool breadth_first_route_net(ClusterNetId net_id, float bend_cost) {
static void breadth_first_expand_trace_segment(t_trace* start_ptr, static void breadth_first_expand_trace_segment(t_trace* start_ptr,
int remaining_connections_to_sink, int remaining_connections_to_sink,
std::vector<int>& modified_rr_node_inf) { std::vector<RRNodeId>& modified_rr_node_inf) {
/* Adds all the rr_nodes in the traceback segment starting at tptr (and * /* Adds all the rr_nodes in the traceback segment starting at tptr (and *
* continuing to the end of the traceback) to the heap with a cost of zero. * * continuing to the end of the traceback) to the heap with a cost of zero. *
* This allows expansion to begin from the existing wiring. The * * This allows expansion to begin from the existing wiring. The *
@ -287,13 +288,13 @@ static void breadth_first_expand_trace_segment(t_trace* start_ptr,
* this means two connections to the same SINK. */ * this means two connections to the same SINK. */
t_trace *tptr, *next_ptr; t_trace *tptr, *next_ptr;
int inode, sink_node, last_ipin_node; RRNodeId inode, sink_node, last_ipin_node;
auto& device_ctx = g_vpr_ctx.device(); auto& device_ctx = g_vpr_ctx.device();
auto& route_ctx = g_vpr_ctx.mutable_routing(); auto& route_ctx = g_vpr_ctx.mutable_routing();
tptr = start_ptr; tptr = start_ptr;
if (tptr != nullptr && device_ctx.rr_nodes[tptr->index].type() == SINK) { if (tptr != nullptr && device_ctx.rr_graph.node_type(tptr->index) == SINK) {
/* During logical equivalence case, only use one opin */ /* During logical equivalence case, only use one opin */
tptr = tptr->next; tptr = tptr->next;
} }
@ -301,9 +302,9 @@ static void breadth_first_expand_trace_segment(t_trace* start_ptr,
if (remaining_connections_to_sink == 0) { /* Usual case. */ if (remaining_connections_to_sink == 0) { /* Usual case. */
while (tptr != nullptr) { while (tptr != nullptr) {
#ifdef ROUTER_DEBUG #ifdef ROUTER_DEBUG
VTR_LOG(" Adding previous routing node %d to heap\n", tptr->index); VTR_LOG(" Adding previous routing node %d to heap\n", size_t(tptr->index));
#endif #endif
node_to_heap(tptr->index, 0., NO_PREVIOUS, NO_PREVIOUS, OPEN, OPEN); node_to_heap(tptr->index, 0., RRNodeId::INVALID(), RREdgeId::INVALID(), OPEN, OPEN);
tptr = tptr->next; tptr = tptr->next;
} }
} else { /* This case never executes for most logic blocks. */ } else { /* This case never executes for most logic blocks. */
@ -318,7 +319,7 @@ static void breadth_first_expand_trace_segment(t_trace* start_ptr,
return; /* No route yet */ return; /* No route yet */
next_ptr = tptr->next; next_ptr = tptr->next;
last_ipin_node = OPEN; /* Stops compiler from complaining. */ last_ipin_node = RRNodeId::INVALID(); /* Stops compiler from complaining. */
/* Can't put last SINK on heap with NO_PREVIOUS, etc, since that won't let * /* Can't put last SINK on heap with NO_PREVIOUS, etc, since that won't let *
* us reach it again. Instead, leave the last traceback element (SINK) off * * us reach it again. Instead, leave the last traceback element (SINK) off *
@ -327,17 +328,17 @@ static void breadth_first_expand_trace_segment(t_trace* start_ptr,
while (next_ptr != nullptr) { while (next_ptr != nullptr) {
inode = tptr->index; inode = tptr->index;
#ifdef ROUTER_DEBUG #ifdef ROUTER_DEBUG
VTR_LOG(" Adding previous routing node %d to heap*\n", tptr->index); VTR_LOG(" Adding previous routing node %d to heap*\n", size_t(tptr->index));
#endif #endif
node_to_heap(inode, 0., NO_PREVIOUS, NO_PREVIOUS, OPEN, OPEN); node_to_heap(inode, 0., RRNodeId::INVALID(), RREdgeId::INVALID(), OPEN, OPEN);
if (device_ctx.rr_nodes[inode].type() == IPIN) if (device_ctx.rr_graph.node_type(inode) == IPIN)
last_ipin_node = inode; last_ipin_node = inode;
tptr = next_ptr; tptr = next_ptr;
next_ptr = tptr->next; next_ptr = tptr->next;
} }
VTR_ASSERT(last_ipin_node >= 0); VTR_ASSERT(true == device_ctx.rr_graph.valid_node_id(last_ipin_node));
/* This will stop the IPIN node used to get to this SINK from being * /* This will stop the IPIN node used to get to this SINK from being *
* reexpanded for the remainder of this net's routing. This will make us * * reexpanded for the remainder of this net's routing. This will make us *
@ -363,24 +364,21 @@ static void breadth_first_expand_trace_segment(t_trace* start_ptr,
} }
} }
static void breadth_first_expand_neighbours(int inode, float pcost, ClusterNetId net_id, float bend_cost) { static void breadth_first_expand_neighbours(const RRNodeId& inode, float pcost, ClusterNetId net_id, float bend_cost) {
/* Puts all the rr_nodes adjacent to inode on the heap. rr_nodes outside * /* Puts all the rr_nodes adjacent to inode on the heap. rr_nodes outside *
* the expanded bounding box specified in route_bb are not added to the * * the expanded bounding box specified in route_bb are not added to the *
* heap. pcost is the path_cost to get to inode. */ * heap. pcost is the path_cost to get to inode. */
int iconn, to_node, num_edges;
auto& device_ctx = g_vpr_ctx.device(); auto& device_ctx = g_vpr_ctx.device();
auto& route_ctx = g_vpr_ctx.routing(); auto& route_ctx = g_vpr_ctx.routing();
num_edges = device_ctx.rr_nodes[inode].num_edges(); for (const RREdgeId& iconn : device_ctx.rr_graph.node_out_edges(inode)) {
for (iconn = 0; iconn < num_edges; iconn++) { const RRNodeId& to_node = device_ctx.rr_graph.edge_sink_node(iconn);
to_node = device_ctx.rr_nodes[inode].edge_sink_node(iconn);
if (device_ctx.rr_nodes[to_node].xhigh() < route_ctx.route_bb[net_id].xmin if (device_ctx.rr_graph.node_xhigh(to_node) < route_ctx.route_bb[net_id].xmin
|| device_ctx.rr_nodes[to_node].xlow() > route_ctx.route_bb[net_id].xmax || device_ctx.rr_graph.node_xlow(to_node) > route_ctx.route_bb[net_id].xmax
|| device_ctx.rr_nodes[to_node].yhigh() < route_ctx.route_bb[net_id].ymin || device_ctx.rr_graph.node_yhigh(to_node) < route_ctx.route_bb[net_id].ymin
|| device_ctx.rr_nodes[to_node].ylow() > route_ctx.route_bb[net_id].ymax) || device_ctx.rr_graph.node_ylow(to_node) > route_ctx.route_bb[net_id].ymax)
continue; /* Node is outside (expanded) bounding box. */ continue; /* Node is outside (expanded) bounding box. */
breadth_first_add_to_heap(pcost, bend_cost, inode, to_node, iconn); breadth_first_add_to_heap(pcost, bend_cost, inode, to_node, iconn);
@ -388,9 +386,9 @@ static void breadth_first_expand_neighbours(int inode, float pcost, ClusterNetId
} }
//Add to_node to the heap, and also add any nodes which are connected by non-configurable edges //Add to_node to the heap, and also add any nodes which are connected by non-configurable edges
static void breadth_first_add_to_heap(const float path_cost, const float bend_cost, const int from_node, const int to_node, const int iconn) { static void breadth_first_add_to_heap(const float path_cost, const float bend_cost, const RRNodeId& from_node, const RRNodeId& to_node, const RREdgeId& iconn) {
#ifdef ROUTER_DEBUG #ifdef ROUTER_DEBUG
VTR_LOG(" Expanding node %d\n", to_node); VTR_LOG(" Expanding node %d\n", size_t(to_node));
#endif #endif
//Create a heap element to represent this node (and any non-configurably connected nodes) //Create a heap element to represent this node (and any non-configurably connected nodes)
@ -413,14 +411,14 @@ static void breadth_first_add_to_heap(const float path_cost, const float bend_co
add_to_heap(next); add_to_heap(next);
} }
static float evaluate_node_cost(const float prev_path_cost, const float bend_cost, const int from_node, const int to_node) { static float evaluate_node_cost(const float prev_path_cost, const float bend_cost, const RRNodeId& from_node, const RRNodeId& to_node) {
auto& device_ctx = g_vpr_ctx.device(); auto& device_ctx = g_vpr_ctx.device();
float tot_cost = prev_path_cost + get_rr_cong_cost(to_node); float tot_cost = prev_path_cost + get_rr_cong_cost(to_node);
if (bend_cost != 0.) { if (bend_cost != 0.) {
t_rr_type from_type = device_ctx.rr_nodes[from_node].type(); t_rr_type from_type = device_ctx.rr_graph.node_type(from_node);
t_rr_type to_type = device_ctx.rr_nodes[to_node].type(); t_rr_type to_type = device_ctx.rr_graph.node_type(to_node);
if ((from_type == CHANX && to_type == CHANY) if ((from_type == CHANX && to_type == CHANY)
|| (from_type == CHANY && to_type == CHANX)) || (from_type == CHANY && to_type == CHANX))
tot_cost += bend_cost; tot_cost += bend_cost;
@ -432,7 +430,7 @@ static float evaluate_node_cost(const float prev_path_cost, const float bend_cos
static void breadth_first_add_source_to_heap(ClusterNetId net_id) { static void breadth_first_add_source_to_heap(ClusterNetId net_id) {
/* Adds the SOURCE of this net to the heap. Used to start a net's routing. */ /* Adds the SOURCE of this net to the heap. Used to start a net's routing. */
int inode; RRNodeId inode;
float cost; float cost;
auto& route_ctx = g_vpr_ctx.routing(); auto& route_ctx = g_vpr_ctx.routing();
@ -444,5 +442,5 @@ static void breadth_first_add_source_to_heap(ClusterNetId net_id) {
VTR_LOG(" Adding Source node %d to heap\n", inode); VTR_LOG(" Adding Source node %d to heap\n", inode);
#endif #endif
node_to_heap(inode, cost, NO_PREVIOUS, NO_PREVIOUS, OPEN, OPEN); node_to_heap(inode, cost, RRNodeId::INVALID(), RREdgeId::INVALID(), OPEN, OPEN);
} }

View File

@ -104,7 +104,7 @@ static void adjust_one_rr_occ_and_apcost(int inode, int add_or_sub, float pres_f
bool validate_traceback_recurr(t_trace* trace, std::set<int>& seen_rr_nodes); bool validate_traceback_recurr(t_trace* trace, std::set<int>& seen_rr_nodes);
static bool validate_trace_nodes(t_trace* head, const std::unordered_set<int>& trace_nodes); static bool validate_trace_nodes(t_trace* head, const std::unordered_set<int>& trace_nodes);
static float get_single_rr_cong_cost(int inode); static float get_single_rr_cong_cost(const RRNodeId& inode);
/************************** Subroutine definitions ***************************/ /************************** Subroutine definitions ***************************/
@ -774,7 +774,7 @@ void mark_remaining_ends(const std::vector<int>& remaining_sinks) {
++route_ctx.rr_node_route_inf[sink_node].target_flag; ++route_ctx.rr_node_route_inf[sink_node].target_flag;
} }
void node_to_heap(int inode, float total_cost, int prev_node, int prev_edge, float backward_path_cost, float R_upstream) { void node_to_heap(const RRNodeId& inode, float total_cost, const RRNodeId& prev_node, const RREdgeId& prev_edge, float backward_path_cost, float R_upstream) {
/* Puts an rr_node on the heap, if the new cost given is lower than the * /* Puts an rr_node on the heap, if the new cost given is lower than the *
* current path_cost to this channel segment. The index of its predecessor * * current path_cost to this channel segment. The index of its predecessor *
* is stored to make traceback easy. The index of the edge used to get * * is stored to make traceback easy. The index of the edge used to get *
@ -790,8 +790,8 @@ void node_to_heap(int inode, float total_cost, int prev_node, int prev_edge, flo
t_heap* hptr = alloc_heap_data(); t_heap* hptr = alloc_heap_data();
hptr->index = inode; hptr->index = inode;
hptr->cost = total_cost; hptr->cost = total_cost;
VTR_ASSERT_SAFE(hptr->u.prev.node == NO_PREVIOUS); VTR_ASSERT_SAFE(hptr->u.prev.node == RRNodeId::INVALID());
VTR_ASSERT_SAFE(hptr->u.prev.edge == NO_PREVIOUS); VTR_ASSERT_SAFE(hptr->u.prev.edge == RREdgeId::INVALID());
hptr->u.prev.node = prev_node; hptr->u.prev.node = prev_node;
hptr->u.prev.edge = prev_edge; hptr->u.prev.edge = prev_edge;
hptr->backward_path_cost = backward_path_cost; hptr->backward_path_cost = backward_path_cost;
@ -1193,7 +1193,7 @@ t_bb load_net_route_bb(ClusterNetId net_id, int bb_factor) {
return bb; return bb;
} }
void add_to_mod_list(int inode, std::vector<int>& modified_rr_node_inf) { void add_to_mod_list(const RRNodeId& inode, std::vector<RRNodeId>& modified_rr_node_inf) {
auto& route_ctx = g_vpr_ctx.routing(); auto& route_ctx = g_vpr_ctx.routing();
if (std::isinf(route_ctx.rr_node_route_inf[inode].path_cost)) { if (std::isinf(route_ctx.rr_node_route_inf[inode].path_cost)) {
@ -1413,7 +1413,7 @@ void free_heap_data(t_heap* hptr) {
num_heap_allocated--; num_heap_allocated--;
} }
void invalidate_heap_entries(int sink_node, int ipin_node) { void invalidate_heap_entries(const RRNodeId& sink_node, const RRNodeId& ipin_node) {
/* Marks all the heap entries consisting of sink_node, where it was reached * /* Marks all the heap entries consisting of sink_node, where it was reached *
* via ipin_node, as invalid (OPEN). Used only by the breadth_first router * * via ipin_node, as invalid (OPEN). Used only by the breadth_first router *
* and even then only in rare circumstances. */ * and even then only in rare circumstances. */
@ -1421,7 +1421,7 @@ void invalidate_heap_entries(int sink_node, int ipin_node) {
for (int i = 1; i < heap_tail; i++) { for (int i = 1; i < heap_tail; i++) {
if (heap[i]->index == sink_node) { if (heap[i]->index == sink_node) {
if (heap[i]->u.prev.node == ipin_node) { if (heap[i]->u.prev.node == ipin_node) {
heap[i]->index = OPEN; /* Invalid. */ heap[i]->index = RRNodeId::INVALID(); /* Invalid. */
break; break;
} }
} }
@ -1816,7 +1816,7 @@ void print_invalid_routing_info() {
auto& route_ctx = g_vpr_ctx.routing(); auto& route_ctx = g_vpr_ctx.routing();
//Build a look-up of nets using each RR node //Build a look-up of nets using each RR node
std::multimap<int, ClusterNetId> rr_node_nets; std::multimap<RRNodeId, ClusterNetId> rr_node_nets;
for (auto net_id : cluster_ctx.clb_nlist.nets()) { for (auto net_id : cluster_ctx.clb_nlist.nets()) {
t_trace* tptr = route_ctx.trace[net_id].head; t_trace* tptr = route_ctx.trace[net_id].head;
@ -1827,9 +1827,9 @@ void print_invalid_routing_info() {
} }
} }
for (size_t inode = 0; inode < device_ctx.rr_graph.nodes().size(); inode++) { for (const RRNodeId& inode : device_ctx.rr_graph.nodes()) {
int occ = route_ctx.rr_node_route_inf[inode].occ(); int occ = route_ctx.rr_node_route_inf[inode].occ();
int cap = device_ctx.rr_nodes[inode].capacity(); int cap = device_ctx.rr_graph.node_capacity(inode);
if (occ > cap) { if (occ > cap) {
VTR_LOG(" %s is overused (occ=%d capacity=%d)\n", describe_rr_node(inode).c_str(), occ, cap); VTR_LOG(" %s is overused (occ=%d capacity=%d)\n", describe_rr_node(inode).c_str(), occ, cap);

View File

@ -66,7 +66,7 @@ void pathfinder_update_cost(float pres_fac, float acc_fac);
t_trace* update_traceback(t_heap* hptr, ClusterNetId net_id); t_trace* update_traceback(t_heap* hptr, ClusterNetId net_id);
void reset_path_costs(const std::vector<int>& visited_rr_nodes); void reset_path_costs(const std::vector<RRNodeId>& visited_rr_nodes);
float get_rr_cong_cost(const RRNodeId& inode); float get_rr_cong_cost(const RRNodeId& inode);
@ -75,7 +75,7 @@ void mark_remaining_ends(const std::vector<int>& remaining_sinks);
void add_to_heap(t_heap* hptr); void add_to_heap(t_heap* hptr);
t_heap* alloc_heap_data(); t_heap* alloc_heap_data();
void node_to_heap(int inode, float cost, int prev_node, int prev_edge, float backward_path_cost, float R_upstream); void node_to_heap(const RRNodeId& inode, float cost, const RRNodeId& prev_node, const RREdgeId& prev_edge, float backward_path_cost, float R_upstream);
bool is_empty_heap(); bool is_empty_heap();
@ -83,7 +83,7 @@ void free_traceback(ClusterNetId net_id);
void drop_traceback_tail(ClusterNetId net_id); void drop_traceback_tail(ClusterNetId net_id);
void free_traceback(t_trace* tptr); void free_traceback(t_trace* tptr);
void add_to_mod_list(int inode, std::vector<int>& modified_rr_node_inf); void add_to_mod_list(const RRNodeId& inode, std::vector<RRNodeId>& modified_rr_node_inf);
namespace heap_ { namespace heap_ {
void build_heap(); void build_heap();
@ -103,7 +103,7 @@ void empty_heap();
void free_heap_data(t_heap* hptr); void free_heap_data(t_heap* hptr);
void invalidate_heap_entries(int sink_node, int ipin_node); void invalidate_heap_entries(const RRNodeId& sink_node, const RRNodeId& ipin_node);
void init_route_structs(int bb_factor); void init_route_structs(int bb_factor);