refactoring node expansion in LbRouter
This commit is contained in:
parent
11879d43b4
commit
c7ef14fc23
|
@ -1,6 +1,8 @@
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* Memember functions for data structure LbRouter
|
* Memember functions for data structure LbRouter
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
#include <queue>
|
||||||
|
|
||||||
#include "vtr_assert.h"
|
#include "vtr_assert.h"
|
||||||
#include "vtr_log.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;
|
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
|
* Private validators
|
||||||
*************************************************/
|
*************************************************/
|
||||||
|
|
|
@ -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 */
|
public : /* Public constructors */
|
||||||
LbRouter(const LbRRGraph& lb_rr_graph);
|
LbRouter(const LbRRGraph& lb_rr_graph);
|
||||||
|
|
||||||
|
@ -174,6 +202,20 @@ class LbRouter {
|
||||||
private : /* Private mutators */
|
private : /* Private mutators */
|
||||||
void reset_explored_node_tb();
|
void reset_explored_node_tb();
|
||||||
bool add_to_rt(t_trace* rt, const LbRRNodeId& node_index, const int& irt_net);
|
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 */
|
private : /* Private validators */
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -69,6 +69,11 @@ std::vector<LbRREdgeId> LbRRGraph::node_in_edges(const LbRRNodeId& node, t_mode*
|
||||||
return in_edges;
|
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> LbRRGraph::node_out_edges(const LbRRNodeId& node, t_mode* mode) const {
|
||||||
std::vector<LbRREdgeId> out_edges;
|
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 LbRRGraph::create_ext_source_node(const e_lb_rr_type& type) {
|
||||||
LbRRNodeId ext_source_node = create_node(type);
|
LbRRNodeId ext_source_node = create_node(type);
|
||||||
ext_source_node_ = ext_source_node;
|
ext_source_node_ = ext_source_node;
|
||||||
|
|
||||||
|
return ext_source_node;
|
||||||
}
|
}
|
||||||
|
|
||||||
LbRRNodeId LbRRGraph::create_ext_sink_node(const e_lb_rr_type& type) {
|
LbRRNodeId LbRRGraph::create_ext_sink_node(const e_lb_rr_type& type) {
|
||||||
LbRRNodeId ext_sink_node = create_node(type);
|
LbRRNodeId ext_sink_node = create_node(type);
|
||||||
ext_sink_node_ = ext_sink_node;
|
ext_sink_node_ = ext_sink_node;
|
||||||
|
|
||||||
|
return ext_sink_node;
|
||||||
}
|
}
|
||||||
|
|
||||||
void LbRRGraph::set_node_type(const LbRRNodeId& node, const e_lb_rr_type& type) {
|
void LbRRGraph::set_node_type(const LbRRNodeId& node, const e_lb_rr_type& type) {
|
||||||
|
|
|
@ -202,6 +202,7 @@ class LbRRGraph {
|
||||||
std::vector<LbRREdgeId> node_in_edges(const LbRRNodeId& node, t_mode* mode) const;
|
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 */
|
/* 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;
|
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 */
|
/* General method to look up a node with type and only pb_graph_pin information */
|
||||||
|
|
Loading…
Reference in New Issue