Skip to content

Commit f049eee

Browse files
committed
🤦
1 parent 2845c07 commit f049eee

File tree

4 files changed

+99
-160
lines changed

4 files changed

+99
-160
lines changed

vpr/src/route/route_timing.cpp

Lines changed: 5 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -956,7 +956,7 @@ bool try_timing_driven_route_net(ConnectionRouter& router,
956956
const t_router_opts& router_opts,
957957
CBRR& connections_inf,
958958
RouterStats& router_stats,
959-
std::vector<float> pin_criticality,
959+
std::vector<float>& pin_criticality,
960960
std::vector<vtr::optional<RouteTreeNode&>>& rt_node_of_sink,
961961
NetPinsMatrix<float>& net_delay,
962962
const ClusteredPinAtomPinsLookup& netlist_pin_lookup,
@@ -1034,18 +1034,6 @@ int get_max_pins_per_net(const Netlist<>& net_list) {
10341034
return (max_pins_per_net);
10351035
}
10361036

1037-
struct Criticality_comp {
1038-
const std::vector<float> criticality;
1039-
1040-
Criticality_comp(const std::vector<float> calculated_criticalities)
1041-
: criticality{calculated_criticalities} {
1042-
}
1043-
1044-
bool operator()(int a, int b) const {
1045-
return criticality[a] > criticality[b];
1046-
}
1047-
};
1048-
10491037
template<typename ConnectionRouter>
10501038
bool timing_driven_route_net(ConnectionRouter& router,
10511039
const Netlist<>& net_list,
@@ -1055,7 +1043,7 @@ bool timing_driven_route_net(ConnectionRouter& router,
10551043
const t_router_opts& router_opts,
10561044
CBRR& connections_inf,
10571045
RouterStats& router_stats,
1058-
std::vector<float> pin_criticality,
1046+
std::vector<float>& pin_criticality,
10591047
std::vector<vtr::optional<RouteTreeNode&>>& rt_node_of_sink,
10601048
float* net_delay,
10611049
const ClusteredPinAtomPinsLookup& netlist_pin_lookup,
@@ -1126,7 +1114,9 @@ bool timing_driven_route_net(ConnectionRouter& router,
11261114
}
11271115

11281116
// compare the criticality of different sink nodes
1129-
sort(begin(remaining_targets), end(remaining_targets), Criticality_comp{pin_criticality});
1117+
sort(begin(remaining_targets), end(remaining_targets), [&](int a, int b) {
1118+
return pin_criticality[a] > pin_criticality[b];
1119+
});
11301120

11311121
/* Update base costs according to fanout and criticality rules */
11321122
update_rr_base_costs(num_sinks);
@@ -1232,13 +1222,6 @@ bool timing_driven_route_net(ConnectionRouter& router,
12321222
}
12331223
}
12341224

1235-
// if (!net_list.net_is_ignored(net_id)) {
1236-
// for (unsigned ipin = 1; ipin < net_list.net_pins(net_id).size(); ++ipin) {
1237-
// if (net_delay[ipin] == 0) { // should be SOURCE->OPIN->IPIN->SINK
1238-
// VTR_ASSERT(rr_graph.node_type(RRNodeId(rt_node_of_sink[ipin]->parent_node->parent_node->inode)) == OPIN);
1239-
// }
1240-
// }
1241-
// }
12421225
VTR_ASSERT_MSG(g_vpr_ctx.routing().rr_node_route_inf[size_t(tree.root().inode)].occ() <= rr_graph.node_capacity(tree.root().inode), "SOURCE should never be congested");
12431226

12441227
VTR_LOGV_DEBUG(f_router_debug, "Routed Net %zu (%zu sinks)\n", size_t(net_id), num_sinks);
@@ -1630,11 +1613,7 @@ static void update_net_delays_from_route_tree(float* net_delay,
16301613
ParentNetId inet,
16311614
TimingInfo* timing_info,
16321615
NetPinTimingInvalidator* pin_timing_invalidator) {
1633-
auto& device_ctx = g_vpr_ctx.device();
1634-
const auto& rr_graph = device_ctx.rr_graph;
1635-
16361616
for (unsigned int isink = 1; isink < net_list.net_pins(inet).size(); isink++) {
1637-
VTR_ASSERT(rr_graph.node_type(rt_node_of_sink[isink].value().inode) == SINK);
16381617
float new_delay = rt_node_of_sink[isink]->Tdel;
16391618

16401619
if (pin_timing_invalidator && new_delay != net_delay[isink]) {

vpr/src/route/route_timing.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ bool try_timing_driven_route_net(ConnectionRouter& router,
4040
const t_router_opts& router_opts,
4141
CBRR& connections_inf,
4242
RouterStats& router_stats,
43-
std::vector<float> pin_criticality,
43+
std::vector<float>& pin_criticality,
4444
std::vector<vtr::optional<RouteTreeNode&>>& rt_node_of_sink,
4545
ClbNetPinsMatrix<float>& net_delay,
4646
const ClusteredPinAtomPinsLookup& netlist_pin_lookup,
@@ -62,7 +62,7 @@ bool timing_driven_route_net(ConnectionRouter& router,
6262
const t_router_opts& router_opts,
6363
CBRR& connections_inf,
6464
RouterStats& router_stats,
65-
std::vector<float> pin_criticality,
65+
std::vector<float>& pin_criticality,
6666
std::vector<vtr::optional<RouteTreeNode&>>& rt_node_of_sink,
6767
float* net_delay,
6868
const ClusteredPinAtomPinsLookup& netlist_pin_lookup,

vpr/src/route/route_tree.cpp

Lines changed: 0 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -98,16 +98,6 @@ void RouteTreeNode::remove_child_if(const std::function<bool(RouteTreeNode&)>& p
9898
_child_nodes.remove_if(p);
9999
}
100100

101-
/* Get a list of child nodes. Useful for traversal.
102-
* Adding or removing child nodes manually can result in bugs. */
103-
const std::list<RouteTreeNode>& RouteTreeNode::child_nodes(void) const {
104-
/* If we don't cast this, gcc will complain because we are returning
105-
* a non-const reference from a const function. That doesn't make sense in my
106-
* opinion: this getter doesn't modify anything by itself, so it should
107-
* still be const */
108-
return _child_nodes;
109-
}
110-
111101
/* Update parent references after a copy or move */
112102
void RouteTreeNode::update_parent_links(void) {
113103
for (auto& child : _child_nodes) {
@@ -206,18 +196,6 @@ RouteTree& RouteTree::operator=(RouteTree&& rhs) {
206196
return *this;
207197
}
208198

209-
RouteTree::iterator RouteTree::Iterable::begin(void) const {
210-
return iterator(_root);
211-
}
212-
213-
RouteTree::iterator RouteTree::Iterable::end(void) const {
214-
return iterator();
215-
}
216-
217-
RouteTree::Iterable RouteTree::all_nodes(void) const {
218-
return Iterable(_root);
219-
}
220-
221199
/* Walk the tree and re-populate rr_node_to_rt_node */
222200
void RouteTree::update_references(RouteTreeNode& rt_node) {
223201
_rr_node_to_rt_node[rt_node.inode] = rt_node;
@@ -925,56 +903,3 @@ std::vector<int> RouteTree::get_non_config_node_set_usage(void) const {
925903

926904
return usage;
927905
}
928-
929-
/* Iterator implementation for a RouteTreeNode.
930-
* This replaces the traceback traversal, which goes over the tree
931-
* in a depth-first, pre-order fashion. */
932-
RTRecIterator::RTRecIterator(vtr::optional<const RouteTreeNode&> node) {
933-
if (!node) return;
934-
_root = node;
935-
_stack.push(node);
936-
}
937-
938-
/* UB if stack is empty. (iterator == end()) */
939-
RTRecIterator::reference RTRecIterator::operator*() const {
940-
return _stack.top().value();
941-
}
942-
943-
/* Move to the next node. */
944-
RTRecIterator& RTRecIterator::operator++() {
945-
if (_stack.empty()) // we are at end(), do nothing
946-
return *this;
947-
const RouteTreeNode& node = _stack.top().value();
948-
_stack.pop();
949-
if (node.child_nodes().empty()) // no child nodes to expand, do nothing
950-
return *this;
951-
// push child nodes in reverse order
952-
for (auto it = node.child_nodes().rbegin(); it != node.child_nodes().rend(); ++it) {
953-
_stack.push(*it);
954-
}
955-
return *this;
956-
}
957-
958-
/* Make a copy of this iterator and move to the next node. (expect performance hit) */
959-
RTRecIterator RTRecIterator::operator++(int) {
960-
RTRecIterator tmp = *this;
961-
++(*this);
962-
return tmp;
963-
}
964-
965-
/* Compare the original root and the current stack top. */
966-
bool RTRecIterator::operator==(const RTRecIterator& rhs) {
967-
if (_stack.empty() && rhs._stack.empty()) // both are end()
968-
return true;
969-
if (_stack.empty() || rhs._stack.empty()) // only one of the stacks are empty
970-
return false;
971-
if (_root != rhs._root) // both stacks full, but different root nodes
972-
return false;
973-
// true if same root nodes and same stack tops
974-
// (a bug if the tree changed in between but that's going to break things anyway)
975-
return *(*this) == *(rhs);
976-
}
977-
978-
bool RTRecIterator::operator!=(const RTRecIterator& rhs) {
979-
return !(*this == rhs);
980-
}

vpr/src/route/route_tree.h

Lines changed: 92 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,16 @@
11
#pragma once
22

33
#include <functional>
4-
#include <iostream>
54
#include <iterator>
65
#include <list>
76
#include <stack>
87
#include <unordered_map>
9-
#include <unordered_set>
108

119
#include "connection_based_routing_fwd.h"
1210
#include "route_tree_fwd.h"
13-
#include "rr_graph_fwd.h"
1411
#include "spatial_route_tree_lookup.h"
1512
#include "vtr_optional.h"
1613

17-
class RTRecIterator;
18-
1914
/**
2015
* @brief A single route tree node
2116
*
@@ -69,9 +64,15 @@ class RouteTreeNode {
6964

7065
/** Emplace child to the front of _child_nodes.
7166
* For best performance, call with constructor args
72-
* (will construct the node in the parent's list directly and save a copy) */
67+
* (will construct the node in the parent's list directly and save a copy)
68+
* Implemented in this file to enable template deduction */
7369
template<class... Args>
74-
RouteTreeNode& emplace_child(Args&&... args);
70+
inline RouteTreeNode& emplace_child(Args&&... args) {
71+
_child_nodes.emplace_front(std::forward<Args>(args)...);
72+
RouteTreeNode& new_node = _child_nodes.front();
73+
new_node.parent = *this; // Zeroed out after copy constructor
74+
return new_node;
75+
}
7576

7677
/** Remove child node by value. O(N) operation. */
7778
void remove_child(const RouteTreeNode&);
@@ -84,7 +85,9 @@ class RouteTreeNode {
8485
void remove_child_if(const std::function<bool(RouteTreeNode&)>&);
8586

8687
/** Get a list of child nodes. Useful for traversal. */
87-
const std::list<RouteTreeNode>& child_nodes(void) const;
88+
inline const std::list<RouteTreeNode>& child_nodes(void) const {
89+
return _child_nodes;
90+
}
8891

8992
/** Print information about this subtree to stdout. */
9093
void print(void) const;
@@ -106,6 +109,78 @@ class RouteTreeNode {
106109
std::list<RouteTreeNode> _child_nodes;
107110
};
108111

112+
/** Recursive iterator implementation for a RouteTreeNode.
113+
* This replaces the traceback traversal, which goes over the tree
114+
* in a depth-first, pre-order fashion.
115+
* This implementation uses a stack to do this,
116+
* which is not optimal for copying, so expect bad performance if using
117+
* <algorithm> fns on it.
118+
* Ideas about how to do it with less state are welcome.
119+
* (Using raw ptrs instead of optional here since this code can be a hotspot) */
120+
class RTRecIterator {
121+
public:
122+
using iterator_category = std::forward_iterator_tag;
123+
using difference_type = std::ptrdiff_t;
124+
using value_type = RouteTreeNode;
125+
using pointer = RouteTreeNode*;
126+
using reference = const RouteTreeNode&;
127+
128+
inline RTRecIterator() = default;
129+
inline RTRecIterator(const RouteTreeNode* node) {
130+
if (!node) return;
131+
_root = node;
132+
_stack.push(node);
133+
}
134+
135+
/** Access element. UB if stack is empty. (iterator == end()) */
136+
inline reference operator*() const {
137+
return *_stack.top();
138+
}
139+
/** ++it: Move to the next node. */
140+
inline RTRecIterator& operator++() {
141+
if (_stack.empty()) // we are at end(), do nothing
142+
return *this;
143+
const RouteTreeNode* node = _stack.top();
144+
_stack.pop();
145+
if (node->child_nodes().empty()) // no child nodes to expand, do nothing
146+
return *this;
147+
// push child nodes in reverse order
148+
for (auto it = node->child_nodes().rbegin(); it != node->child_nodes().rend(); ++it) {
149+
_stack.push(std::addressof(*it));
150+
}
151+
return *this;
152+
}
153+
/** it++: Make a copy of this iterator and move to the next node. (expect performance hit) */
154+
inline RTRecIterator operator++(int) {
155+
RTRecIterator tmp = *this;
156+
++(*this);
157+
return tmp;
158+
}
159+
/** Compare the original root and the current stack top. */
160+
inline bool operator==(const RTRecIterator& rhs) {
161+
if (_root != rhs._root) // root nodes aren't equal (most common case when rhs == end())
162+
return false;
163+
if (_stack.empty() && rhs._stack.empty()) // both are end()
164+
return true;
165+
if (_stack.empty() || rhs._stack.empty()) // only one of the stacks are empty
166+
return false;
167+
// true if same root nodes and same stack tops
168+
// (a bug if the tree changed in between but that's going to break things anyway)
169+
return *(*this) == *(rhs);
170+
}
171+
inline bool operator!=(const RTRecIterator& rhs) {
172+
return !(*this == rhs);
173+
}
174+
175+
private:
176+
/** Stack of nodes to visit.
177+
* std::stack can't be too slow here: it's std::deque under the hood which allocates
178+
* a 512B chunk right away and doesn't realloc */
179+
std::stack<const RouteTreeNode*> _stack;
180+
/* The root node of the iterator. Useful for comparisons. */
181+
const RouteTreeNode* _root = nullptr;
182+
};
183+
109184
/** Top level route tree used in timing analysis and keeping partial routing state.
110185
* Contains the root node and a lookup from RRNodeIds to RouteTreeNode&s in the tree. */
111186
class RouteTree {
@@ -174,17 +249,21 @@ class RouteTree {
174249
using iterator = RTRecIterator;
175250
class Iterable {
176251
public:
177-
Iterable(const RouteTreeNode& root)
252+
inline Iterable(const RouteTreeNode* root)
178253
: _root(root) {}
179-
const RouteTreeNode& _root;
180-
iterator begin() const;
181-
iterator end() const;
254+
const RouteTreeNode* _root;
255+
inline iterator begin() const {
256+
return iterator(_root);
257+
}
258+
inline iterator end() const {
259+
return iterator();
260+
}
182261
};
183262

184263
/** Get an iterable for all nodes under this RouteTree (walks the tree).
185264
* Take care to iterate by reference.
186265
* Copying a RouteTreeNode is a recursive action and it zeroes out the parent reference. */
187-
Iterable all_nodes(void) const;
266+
inline Iterable all_nodes(void) const { return Iterable(std::addressof(_root)); }
188267

189268
/** Get a reference to the root RouteTreeNode. */
190269
inline const RouteTreeNode& root(void) const { return _root; }
@@ -230,47 +309,3 @@ class RouteTree {
230309
* index "inode". */
231310
std::unordered_map<RRNodeId, vtr::optional<RouteTreeNode&>> _rr_node_to_rt_node;
232311
};
233-
234-
/* Recursive iterator implementation for a RouteTreeNode.
235-
* This replaces the traceback traversal, which goes over the tree
236-
* in a depth-first, pre-order fashion.
237-
* This implementation uses a stack to do this,
238-
* which is not optimal for copying, so expect bad performance if using
239-
* <algorithm> fns on it.
240-
* Ideas about how to do it with less state are welcome. */
241-
class RTRecIterator {
242-
public:
243-
using iterator_category = std::forward_iterator_tag;
244-
using difference_type = std::ptrdiff_t;
245-
using value_type = RouteTreeNode;
246-
using pointer = RouteTreeNode*;
247-
using reference = const RouteTreeNode&;
248-
249-
RTRecIterator() = default;
250-
RTRecIterator(vtr::optional<const RouteTreeNode&> node);
251-
252-
/* Required operators for a forward iterator. */
253-
reference operator*() const;
254-
RTRecIterator& operator++();
255-
RTRecIterator operator++(int);
256-
bool operator==(const RTRecIterator& rhs);
257-
bool operator!=(const RTRecIterator& rhs);
258-
259-
private:
260-
/* Stack of nodes to visit. */
261-
std::stack<vtr::optional<const RouteTreeNode&>> _stack;
262-
/* The root node of the iterator. Useful for comparisons. */
263-
vtr::optional<const RouteTreeNode&> _root;
264-
};
265-
266-
/* Emplace child to the front of _child_nodes.
267-
* For best performance, call with constructor args
268-
* (will construct the node in the parent's list directly and save a copy)
269-
* Implemented in this file to enable template deduction */
270-
template<class... Args>
271-
RouteTreeNode& RouteTreeNode::emplace_child(Args&&... args) {
272-
_child_nodes.emplace_front(std::forward<Args>(args)...);
273-
RouteTreeNode& new_node = _child_nodes.front();
274-
new_node.parent = *this; // Zeroed out after copy constructor
275-
return new_node;
276-
}

0 commit comments

Comments
 (0)