From c7ef14fc23517859a7b15cae30f518edb767bad7 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Tue, 18 Feb 2020 21:51:03 -0700 Subject: [PATCH] refactoring node expansion in LbRouter --- openfpga/src/repack/lb_router.cpp | 116 ++++++++++++++++++++++++++++ openfpga/src/repack/lb_router.h | 42 ++++++++++ openfpga/src/repack/lb_rr_graph.cpp | 9 +++ openfpga/src/repack/lb_rr_graph.h | 1 + 4 files changed, 168 insertions(+) diff --git a/openfpga/src/repack/lb_router.cpp b/openfpga/src/repack/lb_router.cpp index f362ce34a..63fc0105b 100644 --- a/openfpga/src/repack/lb_router.cpp +++ b/openfpga/src/repack/lb_router.cpp @@ -1,6 +1,8 @@ /****************************************************************************** * Memember functions for data structure LbRouter ******************************************************************************/ +#include + #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, 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, 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, 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 *************************************************/ diff --git a/openfpga/src/repack/lb_router.h b/openfpga/src/repack/lb_router.h index e5f1ba432..51778df91 100644 --- a/openfpga/src/repack/lb_router.h +++ b/openfpga/src/repack/lb_router.h @@ -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 reservable_pq : public std::priority_queue { + public: + typedef typename std::priority_queue::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, compare_expansion_node>& pq); + void expand_node(const LbRRGraph& lb_rr_graph, + const t_expansion_node& exp_node, + reservable_pq, 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, compare_expansion_node>& pq, + const int& net_fanout); private : /* Private validators */ /** diff --git a/openfpga/src/repack/lb_rr_graph.cpp b/openfpga/src/repack/lb_rr_graph.cpp index 581edd905..3645e60e6 100644 --- a/openfpga/src/repack/lb_rr_graph.cpp +++ b/openfpga/src/repack/lb_rr_graph.cpp @@ -69,6 +69,11 @@ std::vector LbRRGraph::node_in_edges(const LbRRNodeId& node, t_mode* return in_edges; } +std::vector LbRRGraph::node_out_edges(const LbRRNodeId& node) const { + VTR_ASSERT(true == valid_node_id(node)); + return node_out_edges_[node]; +} + std::vector LbRRGraph::node_out_edges(const LbRRNodeId& node, t_mode* mode) const { std::vector 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) { diff --git a/openfpga/src/repack/lb_rr_graph.h b/openfpga/src/repack/lb_rr_graph.h index a85bcd4c5..e75d866b3 100644 --- a/openfpga/src/repack/lb_rr_graph.h +++ b/openfpga/src/repack/lb_rr_graph.h @@ -202,6 +202,7 @@ class LbRRGraph { std::vector 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 node_out_edges(const LbRRNodeId& node) const; std::vector 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 */