refactoring node expansion in LbRouter

This commit is contained in:
tangxifan 2020-02-18 21:51:03 -07:00
parent 11879d43b4
commit c7ef14fc23
4 changed files with 168 additions and 0 deletions

View File

@ -1,6 +1,8 @@
/******************************************************************************
* Memember functions for data structure LbRouter
******************************************************************************/
#include <queue>
#include "vtr_assert.h"
#include "vtr_log.h"
@ -121,6 +123,120 @@ bool LbRouter::add_to_rt(t_trace* rt, const LbRRNodeId& node_index, const int& i
return false;
}
void LbRouter::expand_edges(const LbRRGraph& lb_rr_graph,
t_mode* mode,
const LbRRNodeId& cur_inode,
float cur_cost,
int net_fanout,
reservable_pq<t_expansion_node, std::vector<t_expansion_node>, compare_expansion_node>& pq) {
/* Validate if the rr_graph is the one we used to initialize the router */
VTR_ASSERT(true == matched_lb_rr_graph(lb_rr_graph));
t_expansion_node enode;
int usage;
float incr_cost;
for (const LbRREdgeId& iedge : lb_rr_graph.node_out_edges(cur_inode, mode)) {
/* Init new expansion node */
enode.prev_index = cur_inode;
enode.node_index = lb_rr_graph.edge_sink_node(iedge);
enode.cost = cur_cost;
/* Determine incremental cost of using expansion node */
usage = routing_status_[enode.node_index].occ + 1 - lb_rr_graph.node_capacity(enode.node_index);
incr_cost = lb_rr_graph.node_intrinsic_cost(enode.node_index);
incr_cost += lb_rr_graph.edge_intrinsic_cost(iedge);
incr_cost += params_.hist_fac * routing_status_[enode.node_index].historical_usage;
if (usage > 0) {
incr_cost *= (usage * pres_con_fac_);
}
/* Adjust cost so that higher fanout nets prefer higher fanout routing nodes while lower fanout nets prefer lower fanout routing nodes */
float fanout_factor = 1.0;
t_mode* next_mode = routing_status_[enode.node_index].mode;
/* Assume first mode if a mode hasn't been forced. */
if (nullptr == next_mode) {
next_mode = &(lb_rr_graph.node_pb_graph_pin(enode.node_index)->parent_node->pb_type->modes[0]);
}
if (lb_rr_graph.node_out_edges(enode.node_index, next_mode).size() > 1) {
fanout_factor = 0.85 + (0.25 / net_fanout);
} else {
fanout_factor = 1.15 - (0.25 / net_fanout);
}
incr_cost *= fanout_factor;
enode.cost = cur_cost + incr_cost;
/* Add to queue if cost is lower than lowest cost path to this enode */
if (explored_node_tb_[enode.node_index].enqueue_id == explore_id_index_) {
if (enode.cost < explored_node_tb_[enode.node_index].enqueue_cost) {
pq.push(enode);
}
} else {
explored_node_tb_[enode.node_index].enqueue_id = explore_id_index_;
explored_node_tb_[enode.node_index].enqueue_cost = enode.cost;
pq.push(enode);
}
}
}
void LbRouter::expand_node(const LbRRGraph& lb_rr_graph,
const t_expansion_node& exp_node,
reservable_pq<t_expansion_node, std::vector<t_expansion_node>, compare_expansion_node>& pq,
const int& net_fanout) {
/* Validate if the rr_graph is the one we used to initialize the router */
VTR_ASSERT(true == matched_lb_rr_graph(lb_rr_graph));
t_expansion_node enode;
LbRRNodeId cur_node = exp_node.node_index;
float cur_cost = exp_node.cost;
t_mode* mode = routing_status_[cur_node].mode;
if (nullptr == mode) {
mode = &(lb_rr_graph.node_pb_graph_pin(cur_node)->parent_node->pb_type->modes[0]);
}
expand_edges(lb_rr_graph, mode, cur_node, cur_cost, net_fanout, pq);
}
void LbRouter::expand_node_all_modes(const LbRRGraph& lb_rr_graph,
const t_expansion_node& exp_node,
reservable_pq<t_expansion_node, std::vector<t_expansion_node>, compare_expansion_node>& pq,
const int& net_fanout) {
/* Validate if the rr_graph is the one we used to initialize the router */
VTR_ASSERT(true == matched_lb_rr_graph(lb_rr_graph));
LbRRNodeId cur_inode = exp_node.node_index;
float cur_cost = exp_node.cost;
t_mode* cur_mode = routing_status_[cur_inode].mode;
auto* pin = lb_rr_graph.node_pb_graph_pin(cur_inode);
for (const LbRREdgeId& edge : lb_rr_graph.node_out_edges(cur_inode)) {
t_mode* mode = lb_rr_graph.edge_mode(edge);
/* If a mode has been forced, only add edges from that mode, otherwise add edges from all modes. */
if (cur_mode != nullptr && mode != cur_mode) {
continue;
}
/* Check whether a mode is illegal. If it is then the node will not be expanded */
bool is_illegal = false;
if (pin != nullptr) {
auto* pb_graph_node = pin->parent_node;
for (auto illegal_mode : pb_graph_node->illegal_modes) {
if (mode->index == illegal_mode) {
is_illegal = true;
break;
}
}
}
if (is_illegal == true) {
continue;
}
expand_edges(lb_rr_graph, mode, cur_inode, cur_cost, net_fanout, pq);
}
}
/**************************************************
* Private validators
*************************************************/

View File

@ -149,6 +149,34 @@ class LbRouter {
}
};
// TODO: check if this hacky class memory reserve thing is still necessary, if not, then delete
/* Packing uses a priority queue that requires a large number of elements.
* This backdoor
* allows me to use a priority queue where I can pre-allocate the # of elements
* in the underlying container
* for efficiency reasons. Note: Must use vector with this
*/
template<class T, class U, class V>
class reservable_pq : public std::priority_queue<T, U, V> {
public:
typedef typename std::priority_queue<T>::size_type size_type;
reservable_pq(size_type capacity = 0) {
reserve(capacity);
cur_cap = capacity;
}
void reserve(size_type capacity) {
this->c.reserve(capacity);
cur_cap = capacity;
}
void clear() {
this->c.clear();
this->c.reserve(cur_cap);
}
private:
size_type cur_cap;
};
public : /* Public constructors */
LbRouter(const LbRRGraph& lb_rr_graph);
@ -174,6 +202,20 @@ class LbRouter {
private : /* Private mutators */
void reset_explored_node_tb();
bool add_to_rt(t_trace* rt, const LbRRNodeId& node_index, const int& irt_net);
void expand_edges(const LbRRGraph& lb_rr_graph,
t_mode* mode,
const LbRRNodeId& cur_inode,
float cur_cost,
int net_fanout,
reservable_pq<t_expansion_node, std::vector<t_expansion_node>, compare_expansion_node>& pq);
void expand_node(const LbRRGraph& lb_rr_graph,
const t_expansion_node& exp_node,
reservable_pq<t_expansion_node, std::vector<t_expansion_node>, compare_expansion_node>& pq,
const int& net_fanout);
void expand_node_all_modes(const LbRRGraph& lb_rr_graph,
const t_expansion_node& exp_node,
reservable_pq<t_expansion_node, std::vector<t_expansion_node>, compare_expansion_node>& pq,
const int& net_fanout);
private : /* Private validators */
/**

View File

@ -69,6 +69,11 @@ std::vector<LbRREdgeId> LbRRGraph::node_in_edges(const LbRRNodeId& node, t_mode*
return in_edges;
}
std::vector<LbRREdgeId> LbRRGraph::node_out_edges(const LbRRNodeId& node) const {
VTR_ASSERT(true == valid_node_id(node));
return node_out_edges_[node];
}
std::vector<LbRREdgeId> LbRRGraph::node_out_edges(const LbRRNodeId& node, t_mode* mode) const {
std::vector<LbRREdgeId> out_edges;
@ -175,11 +180,15 @@ LbRRNodeId LbRRGraph::create_node(const e_lb_rr_type& type) {
LbRRNodeId LbRRGraph::create_ext_source_node(const e_lb_rr_type& type) {
LbRRNodeId ext_source_node = create_node(type);
ext_source_node_ = ext_source_node;
return ext_source_node;
}
LbRRNodeId LbRRGraph::create_ext_sink_node(const e_lb_rr_type& type) {
LbRRNodeId ext_sink_node = create_node(type);
ext_sink_node_ = ext_sink_node;
return ext_sink_node;
}
void LbRRGraph::set_node_type(const LbRRNodeId& node, const e_lb_rr_type& type) {

View File

@ -202,6 +202,7 @@ class LbRRGraph {
std::vector<LbRREdgeId> node_in_edges(const LbRRNodeId& node, t_mode* mode) const;
/* Get a list of edge ids, which are outgoing edges from a node */
std::vector<LbRREdgeId> node_out_edges(const LbRRNodeId& node) const;
std::vector<LbRREdgeId> node_out_edges(const LbRRNodeId& node, t_mode* mode) const;
/* General method to look up a node with type and only pb_graph_pin information */