11#include < climits>
2- #include " arch_types.h"
32#include " rr_graph_storage.h"
43#include " physical_types.h"
4+ #include " rr_graph_fwd.h"
55#include " vtr_error.h"
66#include " librrgraph_types.h"
77
88#include < algorithm>
9+ #include < cstddef>
910
1011void t_rr_graph_storage::reserve_edges (size_t num_edges) {
1112 edge_src_node_.reserve (num_edges);
@@ -56,289 +57,6 @@ void t_rr_graph_storage::alloc_and_load_edges(const t_rr_edge_info_set* rr_edges
5657 }
5758}
5859
59- /* edge_swapper / edge_sort_iterator / edge_compare_src_node_and_configurable_first
60- * are used to sort the edge data arrays
61- * edge_src_node_ / edge_dest_node_ / edge_switch_.
62- *
63- * edge_sort_iterator is a random access iterator for the edge data arrays.
64- *
65- * edge_swapper is a reference for the src/dest/switch tuple, and can convert
66- * to and from t_rr_edge_info, the value_type for edge_sort_iterator.
67- *
68- * edge_compare_src_node_and_configurable_first is a comparision operator
69- * that first partitions the edge data by source rr node, and then by
70- * configurable switches first. Sorting by this comparision operator means that
71- * the edge data is directly usable for each node by simply slicing the arrays.
72- *
73- * */
74- struct edge_swapper {
75- edge_swapper (t_rr_graph_storage* storage, size_t idx)
76- : storage_(storage)
77- , idx_(idx) {}
78- t_rr_graph_storage* storage_;
79- size_t idx_;
80-
81- edge_swapper (const edge_swapper&) = delete ;
82- edge_swapper& operator =(const edge_swapper& other) {
83- VTR_ASSERT (idx_ < storage_->edge_src_node_ .size ());
84- VTR_ASSERT (other.idx_ < storage_->edge_src_node_ .size ());
85-
86- RREdgeId edge (idx_);
87- RREdgeId other_edge (other.idx_ );
88- storage_->edge_src_node_ [edge] = storage_->edge_src_node_ [other_edge];
89- storage_->edge_dest_node_ [edge] = storage_->edge_dest_node_ [other_edge];
90- storage_->edge_switch_ [edge] = storage_->edge_switch_ [other_edge];
91- storage_->edge_remapped_ [edge] = storage_->edge_remapped_ [other_edge];
92- return *this ;
93- }
94-
95- edge_swapper& operator =(const t_rr_edge_info& edge) {
96- VTR_ASSERT (idx_ < storage_->edge_src_node_ .size ());
97-
98- storage_->edge_src_node_ [RREdgeId (idx_)] = RRNodeId (edge.from_node );
99- storage_->edge_dest_node_ [RREdgeId (idx_)] = RRNodeId (edge.to_node );
100- storage_->edge_switch_ [RREdgeId (idx_)] = edge.switch_type ;
101- storage_->edge_remapped_ [RREdgeId (idx_)] = edge.remapped ;
102- return *this ;
103- }
104-
105- operator t_rr_edge_info () const {
106- VTR_ASSERT (idx_ < storage_->edge_src_node_ .size ());
107- t_rr_edge_info info (
108- storage_->edge_src_node_ [RREdgeId (idx_)],
109- storage_->edge_dest_node_ [RREdgeId (idx_)],
110- storage_->edge_switch_ [RREdgeId (idx_)],
111- storage_->edge_remapped_ [RREdgeId (idx_)]);
112-
113- return info;
114- }
115-
116- friend class edge_compare ;
117-
118- static void swap (edge_swapper& a, edge_swapper& b) {
119- VTR_ASSERT (a.idx_ < a.storage_ ->edge_src_node_ .size ());
120- VTR_ASSERT (b.idx_ < a.storage_ ->edge_src_node_ .size ());
121- RREdgeId a_edge (a.idx_ );
122- RREdgeId b_edge (b.idx_ );
123-
124- std::swap (a.storage_ ->edge_src_node_ [a_edge], a.storage_ ->edge_src_node_ [b_edge]);
125- std::swap (a.storage_ ->edge_dest_node_ [a_edge], a.storage_ ->edge_dest_node_ [b_edge]);
126- std::swap (a.storage_ ->edge_switch_ [a_edge], a.storage_ ->edge_switch_ [b_edge]);
127- std::vector<bool >::swap (a.storage_ ->edge_remapped_ [a_edge], a.storage_ ->edge_remapped_ [b_edge]);
128- }
129-
130- friend void swap (edge_swapper& a, edge_swapper& b) {
131- edge_swapper::swap (a, b);
132- }
133- };
134-
135- class edge_sort_iterator {
136- public:
137- edge_sort_iterator ()
138- : swapper_(nullptr , 0 ) {}
139- edge_sort_iterator (t_rr_graph_storage* storage, size_t idx)
140- : swapper_(storage, idx) {}
141-
142- edge_sort_iterator (const edge_sort_iterator& other)
143- : swapper_(
144- other.swapper_.storage_,
145- other.swapper_.idx_) {
146- }
147-
148- edge_sort_iterator& operator =(const edge_sort_iterator& other) {
149- swapper_.storage_ = other.swapper_ .storage_ ;
150- swapper_.idx_ = other.swapper_ .idx_ ;
151-
152- return *this ;
153- }
154-
155- using iterator_category = std::random_access_iterator_tag;
156- using value_type = t_rr_edge_info;
157- using reference = edge_swapper&;
158- using pointer = edge_swapper*;
159- using difference_type = ssize_t ;
160-
161- // In order for this class to be used as an iterator within the std library,
162- // it needs to "act" like a pointer. One thing that it should do is that a
163- // const variable of this type should be de-referenceable. Therefore, this
164- // method should be const method; however, this requires modifying the class
165- // and may yield worst performance. For now the std::stable_sort allows this
166- // but in the future it may not. If this breaks, this is why.
167- // See issue #2517 and PR #2522
168- edge_swapper& operator *() {
169- return this ->swapper_ ;
170- }
171-
172- edge_swapper* operator ->() {
173- return &this ->swapper_ ;
174- }
175-
176- edge_sort_iterator& operator +=(ssize_t n) {
177- swapper_.idx_ += n;
178- return *this ;
179- }
180-
181- edge_sort_iterator& operator -=(ssize_t n) {
182- swapper_.idx_ -= n;
183- return *this ;
184- }
185-
186- edge_sort_iterator& operator ++() {
187- ++swapper_.idx_ ;
188- return *this ;
189- }
190-
191- edge_sort_iterator& operator --() {
192- --swapper_.idx_ ;
193- return *this ;
194- }
195-
196- friend edge_sort_iterator operator +(const edge_sort_iterator& lhs, ssize_t n) {
197- edge_sort_iterator ret = lhs;
198- ret.swapper_ .idx_ += n;
199- return ret;
200- }
201-
202- friend edge_sort_iterator operator -(const edge_sort_iterator& lhs, ssize_t n) {
203- edge_sort_iterator ret = lhs;
204- ret.swapper_ .idx_ -= n;
205- return ret;
206- }
207-
208- friend ssize_t operator -(const edge_sort_iterator& lhs, const edge_sort_iterator& rhs) {
209- ssize_t diff = lhs.swapper_ .idx_ ;
210- diff -= rhs.swapper_ .idx_ ;
211- return diff;
212- }
213-
214- friend bool operator ==(const edge_sort_iterator& lhs, const edge_sort_iterator& rhs) {
215- return lhs.swapper_ .idx_ == rhs.swapper_ .idx_ ;
216- }
217-
218- friend bool operator !=(const edge_sort_iterator& lhs, const edge_sort_iterator& rhs) {
219- return lhs.swapper_ .idx_ != rhs.swapper_ .idx_ ;
220- }
221-
222- friend bool operator <(const edge_sort_iterator& lhs, const edge_sort_iterator& rhs) {
223- return lhs.swapper_ .idx_ < rhs.swapper_ .idx_ ;
224- }
225-
226- friend bool operator >(const edge_sort_iterator& lhs, const edge_sort_iterator& rhs) {
227- return lhs.swapper_ .idx_ > rhs.swapper_ .idx_ ;
228- }
229-
230- friend bool operator >=(const edge_sort_iterator& lhs, const edge_sort_iterator& rhs) {
231- return lhs.swapper_ .idx_ >= rhs.swapper_ .idx_ ;
232- }
233-
234- friend bool operator <=(const edge_sort_iterator& lhs, const edge_sort_iterator& rhs) {
235- return lhs.swapper_ .idx_ <= rhs.swapper_ .idx_ ;
236- }
237-
238- RREdgeId edge () const {
239- return RREdgeId (swapper_.idx_ );
240- }
241-
242- private:
243- edge_swapper swapper_;
244- };
245-
246- class edge_compare_src_node_and_configurable_first {
247- public:
248- edge_compare_src_node_and_configurable_first (const vtr::vector<RRSwitchId, t_rr_switch_inf>& rr_switch_inf)
249- : rr_switch_inf_(rr_switch_inf) {}
250-
251- bool operator ()(const t_rr_edge_info& lhs, const edge_swapper& rhs) {
252- auto lhs_src_node = RRNodeId (lhs.from_node );
253- auto lhs_dest_node = RRNodeId (lhs.to_node );
254- auto lhs_is_configurable = rr_switch_inf_[RRSwitchId (lhs.switch_type )].configurable ();
255-
256- auto rhs_edge = RREdgeId (rhs.idx_ );
257- auto rhs_src_node = rhs.storage_ ->edge_src_node_ [rhs_edge];
258- auto rhs_dest_node = rhs.storage_ ->edge_dest_node_ [rhs_edge];
259- auto rhs_is_configurable = rr_switch_inf_[RRSwitchId (rhs.storage_ ->edge_switch_ [rhs_edge])].configurable ();
260-
261- return std::make_tuple (lhs_src_node, !lhs_is_configurable, lhs_dest_node, lhs.switch_type ) < std::make_tuple (rhs_src_node, !rhs_is_configurable, rhs_dest_node, rhs.storage_ ->edge_switch_ [rhs_edge]);
262- }
263-
264- bool operator ()(const t_rr_edge_info& lhs, const t_rr_edge_info& rhs) {
265- auto lhs_src_node = lhs.from_node ;
266- auto lhs_dest_node = lhs.to_node ;
267- auto lhs_is_configurable = rr_switch_inf_[RRSwitchId (lhs.switch_type )].configurable ();
268-
269- auto rhs_src_node = rhs.from_node ;
270- auto rhs_dest_node = rhs.to_node ;
271- auto rhs_is_configurable = rr_switch_inf_[RRSwitchId (rhs.switch_type )].configurable ();
272-
273- return std::make_tuple (lhs_src_node, !lhs_is_configurable, lhs_dest_node, lhs.switch_type ) < std::make_tuple (rhs_src_node, !rhs_is_configurable, rhs_dest_node, rhs.switch_type );
274- }
275- bool operator ()(const edge_swapper& lhs, const t_rr_edge_info& rhs) {
276- auto lhs_edge = RREdgeId (lhs.idx_ );
277- auto lhs_src_node = lhs.storage_ ->edge_src_node_ [lhs_edge];
278- auto lhs_dest_node = lhs.storage_ ->edge_dest_node_ [lhs_edge];
279- auto lhs_is_configurable = rr_switch_inf_[RRSwitchId (lhs.storage_ ->edge_switch_ [lhs_edge])].configurable ();
280-
281- auto rhs_src_node = RRNodeId (rhs.from_node );
282- auto rhs_dest_node = RRNodeId (rhs.to_node );
283- auto rhs_is_configurable = rr_switch_inf_[RRSwitchId (rhs.switch_type )].configurable ();
284-
285- return std::make_tuple (lhs_src_node, !lhs_is_configurable, lhs_dest_node, lhs.storage_ ->edge_switch_ [lhs_edge]) < std::make_tuple (rhs_src_node, !rhs_is_configurable, rhs_dest_node, rhs.switch_type );
286- }
287- bool operator ()(const edge_swapper& lhs, const edge_swapper& rhs) {
288- auto lhs_edge = RREdgeId (lhs.idx_ );
289- auto lhs_src_node = lhs.storage_ ->edge_src_node_ [lhs_edge];
290- auto lhs_dest_node = lhs.storage_ ->edge_dest_node_ [lhs_edge];
291- auto lhs_is_configurable = rr_switch_inf_[RRSwitchId (lhs.storage_ ->edge_switch_ [lhs_edge])].configurable ();
292-
293- auto rhs_edge = RREdgeId (rhs.idx_ );
294- auto rhs_src_node = rhs.storage_ ->edge_src_node_ [rhs_edge];
295- auto rhs_dest_node = rhs.storage_ ->edge_dest_node_ [rhs_edge];
296- auto rhs_is_configurable = rr_switch_inf_[RRSwitchId (rhs.storage_ ->edge_switch_ [rhs_edge])].configurable ();
297-
298- return std::make_tuple (lhs_src_node, !lhs_is_configurable, lhs_dest_node, lhs.storage_ ->edge_switch_ [lhs_edge]) < std::make_tuple (rhs_src_node, !rhs_is_configurable, rhs_dest_node, rhs.storage_ ->edge_switch_ [rhs_edge]);
299- }
300-
301- private:
302- const vtr::vector<RRSwitchId, t_rr_switch_inf>& rr_switch_inf_;
303- };
304-
305- class edge_compare_dest_node {
306- public:
307- bool operator ()(const t_rr_edge_info& lhs, const edge_swapper& rhs) {
308- auto lhs_dest_node = RRNodeId (lhs.to_node );
309-
310- auto rhs_edge = RREdgeId (rhs.idx_ );
311- auto rhs_dest_node = rhs.storage_ ->edge_dest_node_ [rhs_edge];
312-
313- return lhs_dest_node < rhs_dest_node;
314- }
315-
316- bool operator ()(const t_rr_edge_info& lhs, const t_rr_edge_info& rhs) {
317- auto lhs_dest_node = lhs.to_node ;
318-
319- auto rhs_dest_node = rhs.to_node ;
320-
321- return lhs_dest_node < rhs_dest_node;
322- }
323- bool operator ()(const edge_swapper& lhs, const t_rr_edge_info& rhs) {
324- auto lhs_edge = RREdgeId (lhs.idx_ );
325- auto lhs_dest_node = lhs.storage_ ->edge_dest_node_ [lhs_edge];
326-
327- auto rhs_dest_node = RRNodeId (rhs.to_node );
328-
329- return lhs_dest_node < rhs_dest_node;
330- }
331- bool operator ()(const edge_swapper& lhs, const edge_swapper& rhs) {
332- auto lhs_edge = RREdgeId (lhs.idx_ );
333- auto lhs_dest_node = lhs.storage_ ->edge_dest_node_ [lhs_edge];
334-
335- auto rhs_edge = RREdgeId (rhs.idx_ );
336- auto rhs_dest_node = rhs.storage_ ->edge_dest_node_ [rhs_edge];
337-
338- return lhs_dest_node < rhs_dest_node;
339- }
340- };
341-
34260void t_rr_graph_storage::assign_first_edges () {
34361 VTR_ASSERT (node_first_edge_.empty ());
34462
@@ -419,6 +137,24 @@ void t_rr_graph_storage::init_fan_in() {
419137 }
420138}
421139
140+ namespace {
141+ // / Functor for sorting edges according to destination node's ID.
142+ class edge_compare_dest_node {
143+ public:
144+ edge_compare_dest_node (const t_rr_graph_storage& rr_graph_storage) : rr_graph_storage_(rr_graph_storage) {}
145+
146+ bool operator ()(RREdgeId lhs, RREdgeId rhs) const {
147+ RRNodeId lhs_dest_node = rr_graph_storage_.edge_sink_node (lhs);
148+ RRNodeId rhs_dest_node = rr_graph_storage_.edge_sink_node (rhs);
149+
150+ return lhs_dest_node < rhs_dest_node;
151+ }
152+
153+ private:
154+ const t_rr_graph_storage& rr_graph_storage_;
155+ };
156+ } // namespace
157+
422158size_t t_rr_graph_storage::count_rr_switches (const std::vector<t_arch_switch_inf>& arch_switch_inf,
423159 t_arch_switch_fanin& arch_switch_fanins) {
424160 VTR_ASSERT (!partitioned_);
@@ -429,10 +165,7 @@ size_t t_rr_graph_storage::count_rr_switches(const std::vector<t_arch_switch_inf
429165
430166 // Sort by destination node to collect per node/per switch fan in values
431167 // This sort is safe to do because partition_edges() has not been invoked yet.
432- std::stable_sort (
433- edge_sort_iterator (this , 0 ),
434- edge_sort_iterator (this , edge_dest_node_.size ()),
435- edge_compare_dest_node ());
168+ sort_edges (edge_compare_dest_node (*this ));
436169
437170 // Collect the fan-in per switch type for each node in the graph
438171 // Record the unique switch type/fanin combinations
@@ -527,6 +260,35 @@ void t_rr_graph_storage::mark_edges_as_rr_switch_ids() {
527260 remapped_edges_ = true ;
528261}
529262
263+ namespace {
264+ // / Functor for sorting edges according to source node, with configurable edges coming first
265+ class edge_compare_src_node_and_configurable_first {
266+ public:
267+ edge_compare_src_node_and_configurable_first (const vtr::vector<RRSwitchId, t_rr_switch_inf>& rr_switch_inf, const t_rr_graph_storage& rr_graph_storage)
268+ : rr_switch_inf_(rr_switch_inf),
269+ rr_graph_storage_ (rr_graph_storage) {}
270+
271+ bool operator ()(RREdgeId lhs, RREdgeId rhs) const {
272+
273+ RRNodeId lhs_dest_node = rr_graph_storage_.edge_sink_node (lhs);
274+ RRNodeId lhs_src_node = rr_graph_storage_.edge_source_node (lhs);
275+ RRSwitchId lhs_switch_type = RRSwitchId (rr_graph_storage_.edge_switch (lhs));
276+ bool lhs_is_configurable = rr_switch_inf_[lhs_switch_type].configurable ();
277+
278+ RRNodeId rhs_dest_node = rr_graph_storage_.edge_sink_node (rhs);
279+ RRNodeId rhs_src_node = rr_graph_storage_.edge_source_node (rhs);
280+ RRSwitchId rhs_switch_type = RRSwitchId (rr_graph_storage_.edge_switch (rhs));
281+ bool rhs_is_configurable = rr_switch_inf_[rhs_switch_type].configurable ();
282+
283+ return std::make_tuple (lhs_src_node, !lhs_is_configurable, lhs_dest_node, lhs_switch_type) < std::make_tuple (rhs_src_node, !rhs_is_configurable, rhs_dest_node, rhs_switch_type);
284+ }
285+
286+ private:
287+ const vtr::vector<RRSwitchId, t_rr_switch_inf>& rr_switch_inf_;
288+ const t_rr_graph_storage& rr_graph_storage_;
289+ };
290+ } // namespace
291+
530292void t_rr_graph_storage::partition_edges (const vtr::vector<RRSwitchId, t_rr_switch_inf>& rr_switches) {
531293 if (partitioned_) {
532294 return ;
@@ -539,9 +301,7 @@ void t_rr_graph_storage::partition_edges(const vtr::vector<RRSwitchId, t_rr_swit
539301 // by assign_first_edges()
540302 // - Edges within a source node have the configurable edges before the
541303 // non-configurable edges.
542- std::stable_sort (edge_sort_iterator (this , 0 ),
543- edge_sort_iterator (this , edge_src_node_.size ()),
544- edge_compare_src_node_and_configurable_first (rr_switches));
304+ sort_edges (edge_compare_src_node_and_configurable_first (rr_switches, *this ));
545305
546306 partitioned_ = true ;
547307
0 commit comments