PandA-2024.02
port_swapping.cpp
Go to the documentation of this file.
1 /*
2  *
3  * _/_/_/ _/_/ _/ _/ _/_/_/ _/_/
4  * _/ _/ _/ _/ _/_/ _/ _/ _/ _/ _/
5  * _/_/_/ _/_/_/_/ _/ _/_/ _/ _/ _/_/_/_/
6  * _/ _/ _/ _/ _/ _/ _/ _/ _/
7  * _/ _/ _/ _/ _/ _/_/_/ _/ _/
8  *
9  * ***********************************************
10  * PandA Project
11  * URL: http://panda.dei.polimi.it
12  * Politecnico di Milano - DEIB
13  * System Architectures Group
14  * ***********************************************
15  * Copyright (C) 2004-2024 Politecnico di Milano
16  *
17  * This file is part of the PandA framework.
18  *
19  * The PandA framework is free software; you can redistribute it and/or modify
20  * it under the terms of the GNU General Public License as published by
21  * the Free Software Foundation; either version 3 of the License, or
22  * (at your option) any later version.
23  *
24  * This program is distributed in the hope that it will be useful,
25  * but WITHOUT ANY WARRANTY; without even the implied warranty of
26  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27  * GNU General Public License for more details.
28  *
29  * You should have received a copy of the GNU General Public License
30  * along with this program. If not, see <http://www.gnu.org/licenses/>.
31  *
32  */
44 #include "port_swapping.hpp"
45 
46 #include "Parameter.hpp"
48 #include "behavioral_helper.hpp"
49 #include "dbgPrintHelper.hpp"
50 #include "fileIO.hpp"
51 #include "fu_binding.hpp"
52 #include "function_behavior.hpp"
53 #include "hls.hpp"
54 #include "hls_manager.hpp"
55 #include "liveness.hpp"
56 #include "reg_binding.hpp"
58 #include "string_manipulation.hpp"
59 #include "token_interface.hpp"
60 #include "tree_helper.hpp"
61 #include "utility.hpp"
62 
63 #include <boost/graph/random_spanning_tree.hpp>
64 #include <random>
65 
66 #define SET_A 0
67 #define SET_B 1
68 #define SET_AB 2
69 
70 port_swapping::port_swapping(const ParameterConstRef _Param, const HLS_managerRef _HLSMgr, unsigned int _funId,
71  const DesignFlowManagerConstRef _design_flow_manager)
72  : HLSFunctionStep(_Param, _HLSMgr, _funId, _design_flow_manager, HLSFlowStep_Type::PORT_SWAPPING)
73 {
74  debug_level = _Param->get_class_debug_level(GET_CLASS(*this));
75 }
76 
78 
81 {
83  switch(relationship_type)
84  {
86  {
87  if(HLSMgr->get_HLS(funId))
88  {
89  if(HLSMgr->GetFunctionBehavior(funId)->is_simple_pipeline())
90  {
93  }
94  else
95  {
96  ret.insert(std::make_tuple(HLSMgr->get_HLS(funId)->module_binding_algorithm,
99  }
100  }
101  if(HLSMgr->GetFunctionBehavior(funId)->is_simple_pipeline())
102  {
105  }
106  else
107  {
108  ret.insert(std::make_tuple(parameters->getOption<HLSFlowStep_Type>(OPT_register_allocation_algorithm),
110  }
111  break;
112  }
114  {
115  break;
116  }
118  {
119  break;
120  }
121  default:
122  THROW_UNREACHABLE("");
123  }
124  return ret;
125 }
126 
127 //
128 // This function calculates the levels of all the vertices in a spanning tree
129 //
130 void port_swapping::vertex_levels(const std::vector<PSE>& spt_edges, PSVertex root, size_t num_vertices_g,
131  std::vector<PSVSet>& vset)
132 {
133  PSVSet set;
134  set.v = root;
135  set.level = 0;
136  set.belongs = SET_A;
137  vset.push_back(set);
138 
139  bool flag = false;
140  while(vset.size() < num_vertices_g)
141  {
142  for(const auto& i : spt_edges)
143  {
144  for(const auto j : vset)
145  {
146  if(j.v == i.first)
147  {
148  set.level = j.level + 1;
149  set.v = i.second;
150  flag = true;
151  break;
152  }
153  }
154  for(const auto lvl : vset)
155  {
156  if(lvl.v == set.v)
157  {
158  flag = false;
159  }
160  }
161  if(flag)
162  {
163  if(set.level % 2 == 0)
164  {
165  set.belongs = SET_A;
166  }
167  else
168  {
169  set.belongs = SET_B;
170  }
171  vset.push_back(set);
172  }
173  flag = false;
174  }
175  }
176 }
177 
178 //
179 // This function calculates the distances between two vertices in a spanning tree
180 //
181 int port_swapping::vertex_distance(const std::vector<PSE>& spt_edges, PSVertex root, PSVertex dest,
182  std::vector<PSVSet>& vset)
183 {
184  PSVSet set;
185  set.v = root;
186  set.level = 0;
187  set.belongs = SET_A;
188  vset.push_back(set);
189  int distance = 0;
190  bool flag = false;
191  bool found = false;
192  while(!found)
193  {
194  for(const auto& i : spt_edges)
195  {
196  for(const auto& j : vset)
197  {
198  if(j.v == i.first)
199  {
200  set.level = j.level + 1;
201  set.v = i.second;
202  if(set.v == dest)
203  {
204  distance = set.level + 1;
205  found = true;
206  }
207  flag = true;
208  break;
209  }
210  else if(j.v == i.second)
211  {
212  set.level = j.level + 1;
213  set.v = i.first;
214  if(set.v == dest)
215  {
216  distance = set.level + 1;
217  found = true;
218  }
219  flag = true;
220  break;
221  }
222  }
223  for(const auto& lvl : vset)
224  {
225  if(lvl.v == set.v)
226  {
227  flag = false;
228  }
229  }
230  if(flag)
231  {
232  vset.push_back(set);
233  }
234  flag = false;
235  }
236  }
237  THROW_ASSERT(distance, "");
238  THROW_ASSERT(found, "");
239  return distance;
240 }
241 
242 port_swapping::PSVertex port_swapping::find_max_degree(const CustomOrderedSet<std::pair<PSVertex, unsigned int>>& dSet)
243 {
244  long unsigned int max = 0;
245  PSVertex v = 0;
246  for(const auto& e : dSet)
247  {
248  if(e.second > max)
249  {
250  max = e.second;
251  v = e.first;
252  }
253  }
254  return v;
255 }
256 
257 void port_swapping::update_degree(PSGraph g2, CustomOrderedSet<std::pair<PSVertex, unsigned int>>& dSet)
258 {
259  auto g2_vertices = boost::vertices(g2);
260  for(auto iterator = g2_vertices.first; iterator != g2_vertices.second; ++iterator)
261  {
262  dSet.insert(std::make_pair(*iterator, boost::out_degree(*iterator, g2)));
263  }
264 }
265 
267 {
268  for(const auto& ed : e)
269  {
270  if(v == ed.second)
271  {
272  return ed.first;
273  }
274  else if(v == ed.first)
275  {
276  return ed.second;
277  }
278  }
279  return v;
280 }
281 
282 void port_swapping::port_swapping_algorithm(PSGraph& g, std::vector<PSMultiStart>& vector_sets, size_t num_vertices_g,
283  PSVertex root)
284 {
285  //
286  // Generating the Spanning Tree starting from Graph g
287  //
288  std::random_device rd;
289  std::mt19937 generator(rd());
290  generator.seed(parameters->getOption<long unsigned int>(OPT_seed));
291  std::vector<PSVertex> p(num_vertices(g));
292 
293  std::vector<PSVertex> component(boost::num_vertices(g));
294  size_t num_components = boost::connected_components(g, &component[0]);
295  PSVertex connection_ver_1 = *vertices(g).first;
296  for(size_t count = 1; count < num_components; count++)
297  {
298  for(size_t i = 0; i < num_vertices_g; i++)
299  {
300  if(component[i] == count)
301  {
302  auto connection_ver_2 = PSVertex(i);
303  add_edge(connection_ver_1, connection_ver_2, g);
304  connection_ver_1 = connection_ver_2;
305  break;
306  }
307  }
308  }
309 
310  boost::random_spanning_tree(g, generator,
311  boost::root_vertex(root).predecessor_map(
312  boost::make_iterator_property_map(p.begin(), boost::get(boost::vertex_index, g))));
313 
314  //
315  // Generating a list of edges following the predecessor map created
316  // with the random_spanning_tree algorithm
317  //
318  auto vertices_g = boost::vertices(g);
319  std::vector<PSE> spt_edges;
320 
321  for(auto iterator = vertices_g.first; iterator != vertices_g.second; ++iterator)
322  {
323  PSVertex u = *iterator;
324  PSVertex v = p[*iterator];
325  if(v > num_vertices_g)
326  {
327  root = u;
328  continue;
329  }
330  spt_edges.push_back(PSE(v, u));
331  }
332 
333  auto edge = boost::edges(g);
334  std::vector<PSE> g_edges;
335  for(auto iterator = edge.first; iterator != edge.second; ++iterator)
336  {
337  g_edges.push_back(PSE(source(*iterator, g), target(*iterator, g)));
338  }
339 
340  //
341  // Calculating the levels of the various vertices in the
342  // spanning tree
343  // vset: vector of VSet
344  //
345  std::vector<PSVSet> vset;
346  vertex_levels(spt_edges, root, num_vertices_g, vset);
347 
348  std::vector<PSE> co_tree_edges;
349  for(auto e : g_edges)
350  {
351  if(find(spt_edges.begin(), spt_edges.end(), PSE(source(e, g), target(e, g))) != spt_edges.end() ||
352  find(spt_edges.begin(), spt_edges.end(), PSE(target(e, g), source(e, g))) != spt_edges.end())
353  {
354  continue;
355  }
356  else
357  {
358  co_tree_edges.push_back(PSE(source(e, g), target(e, g)));
359  }
360  }
361 
362  //
363  // Calculating which co_tree_edges are odd. Those who are odd are added to a vector of edges
364  //
365  std::vector<PSVSet> loop_size;
366  std::vector<PSE> odd_co_tree_edges;
367  for(auto e : co_tree_edges)
368  {
369  loop_size.clear();
370  if(vertex_distance(spt_edges, e.first, e.second, loop_size) % 2 != 0)
371  {
372  odd_co_tree_edges.push_back(e);
373  }
374  }
375 
376  PSGraph g2(num_vertices_g);
377  for(auto e : odd_co_tree_edges)
378  {
379  add_edge(e.first, e.second, g2);
380  }
381 
383  CustomOrderedSet<PSVertex> cover_set;
384  auto g2_vertices = boost::vertices(g2);
385  update_degree(g2, degree_set);
386 
387  // while(num_edges(g2) != 0)
388  for(auto iterator = g2_vertices.first; iterator != g2_vertices.second; ++iterator)
389  {
390  if(out_degree(*iterator, g2) == 1)
391  {
392  auto u1 = get_co_tree_vertex(*iterator, odd_co_tree_edges);
393  cover_set.insert(u1);
394  clear_vertex(u1, g2);
395  }
396  else if(out_degree(*iterator, g2) > 1)
397  {
398  auto u2 = find_max_degree(degree_set);
399  cover_set.insert(u2);
400  clear_vertex(u2, g2);
401  }
402  degree_set.clear();
403  update_degree(g2, degree_set);
404  }
405 
406  long unsigned int abCardinality = 0;
407  std::vector<PSVSet> temp_set;
408  PSVSet v;
409  for(auto vs : vset)
410  {
411  temp_set.push_back(vs);
412  }
413 
414  vset.clear();
415 
416  for(auto set : temp_set)
417  {
418  if(find(cover_set.begin(), cover_set.end(), set.v) != cover_set.end())
419  {
420  v.v = set.v;
421  v.belongs = SET_AB;
422  v.level = set.level;
423  vset.push_back(v);
424  abCardinality++;
425  }
426  else
427  {
428  vset.push_back(set);
429  }
430  }
431 
432  PSMultiStart run;
433  run.vset = vset;
434  run.cardinality = abCardinality;
435  run.spt_vector_edges = spt_edges;
436  run.co_tree_vector_edges = co_tree_edges;
437  run.odd_co_tree_vector_edges = odd_co_tree_edges;
438  vector_sets.push_back(run);
439 
440  return;
441 }
442 
443 std::vector<std::pair<port_swapping::PSVertex, unsigned int>> port_swapping::p_swap(PSGraph& g)
444 {
445  auto g_vertices = vertices(g);
446  std::vector<PSMultiStart> vector_sets;
447  for(auto iterator = g_vertices.first; iterator != g_vertices.second; ++iterator)
448  {
449  port_swapping_algorithm(g, vector_sets, boost::num_vertices(g), *iterator);
450  }
451  long unsigned int max = boost::num_vertices(g);
452  PSMultiStart best_candidate;
453  for(const auto& vset : vector_sets)
454  {
455  if(vset.cardinality < max)
456  {
457  max = vset.cardinality;
458  best_candidate = vset;
459  }
460  }
461 
462  std::vector<std::pair<PSVertex, unsigned int>> return_values;
463  for(auto vertex_set : best_candidate.vset)
464  {
465  return_values.push_back(std::make_pair(vertex_set.v, vertex_set.belongs));
466  }
467  return return_values;
468 }
469 
471 {
472  return operation == STOK(TOK_PLUS_EXPR) || operation == STOK(TOK_POINTER_PLUS_EXPR) ||
473  operation == STOK(TOK_MULT_EXPR) || operation == STOK(TOK_BIT_IOR_EXPR) ||
474  operation == STOK(TOK_BIT_XOR_EXPR) || operation == STOK(TOK_BIT_AND_EXPR) ||
475  operation == STOK(TOK_EQ_EXPR) || operation == STOK(TOK_NE_EXPR) || operation == STOK(TOK_WIDEN_SUM_EXPR) ||
476  operation == STOK(TOK_WIDEN_MULT_EXPR);
477 }
478 
479 unsigned int port_swapping::get_results(PSVertex operand, const std::vector<std::pair<PSVertex, unsigned int>>& results)
480 {
481  for(auto res : results)
482  {
483  if(res.first == operand)
484  {
485  return res.second;
486  }
487  }
488  return 0;
489 }
490 
492 {
493  const FunctionBehaviorConstRef FB = HLSMgr->CGetFunctionBehavior(funId);
495  const BehavioralHelperConstRef behavioral_helper = FB->CGetBehavioralHelper();
496  const tree_managerRef TreeM = HLSMgr->get_tree_manager();
497 
498  using Operands = struct
499  {
500  vertex op;
501  PSVertex first_op;
502  PSVertex second_op;
503  };
504 
505  std::map<std::pair<unsigned int, unsigned int>, std::vector<vertex>> fu_map;
506  std::map<std::tuple<unsigned int, unsigned int, unsigned int>, PSVertex> op_vertex_map;
507  std::tuple<unsigned int, unsigned int, unsigned int> key_value;
508  std::vector<PSVertex> vertices_in_op;
509  std::vector<Operands> operands;
510  std::vector<std::pair<PSVertex, unsigned int>> results;
511  bool changed = false;
512  size_t n_swaps = 0;
513  vertices_in_op.resize(2);
514 
515  PSVertex v_input;
516  PSGraph g;
517 
518  VertexIterator op, opend;
519  for(boost::tie(op, opend) = boost::vertices(*data); op != opend; op++)
520  {
521  std::string operation = data->CGetOpNodeInfo(*op)->GetOperation();
522  if(is_commutative_op(operation))
523  {
524  unsigned int fu = HLS->Rfu->get_assign(*op);
525  unsigned int idx = HLS->Rfu->get_index(*op);
526  auto fu_key = std::make_pair(fu, idx);
527  fu_map[fu_key].push_back(*op);
528  }
529  }
530 
531  for(const auto& fu : fu_map)
532  {
534  "-->Functional Unit ID: " + HLS->allocation_information->get_string_name(fu.first.first));
535  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "Functional Unit INDEX: " + STR(fu.first.second));
536  for(const auto& fu_operation : fu.second)
537  {
539  "---Operation: " + GET_NAME(data, fu_operation) + " (" +
540  data->CGetOpNodeInfo(fu_operation)->GetOperation() + ")");
541  std::vector<HLS_manager::io_binding_type> var_read =
542  HLSMgr->get_required_values(HLS->functionId, fu_operation);
543  THROW_ASSERT(var_read.size() == 2, STR(var_read.size()) + " Vertices in op has wrong size!");
544  for(unsigned int var_num = 0; var_num < var_read.size(); var_num++)
545  {
547  unsigned int tree_var = std::get<0>(var_read[var_num]);
548  if(tree_var == 0)
549  {
551  "---Constant: " + STR(std::get<1>(var_read[var_num])));
552  key_value = std::make_tuple(0, 0, std::get<1>(var_read[var_num]));
553  }
554  else
555  {
557  "-->Read: " + behavioral_helper->PrintVariable(tree_var));
558  const CustomOrderedSet<vertex>& running_states = HLS->Rliv->get_state_where_run(fu_operation);
559  for(const auto state : running_states)
560  {
561  if(tree_helper::is_parameter(TreeM, tree_var) || !HLS->Rliv->has_op_where_defined(tree_var))
562  {
564  key_value = std::make_tuple(1, 0, tree_var);
565  }
566  else
567  {
568  vertex def_op = HLS->Rliv->get_op_where_defined(tree_var);
569  const CustomOrderedSet<vertex>& def_op_ending_states = HLS->Rliv->get_state_where_end(def_op);
570  if((GET_TYPE(data, def_op) & TYPE_PHI) == 0)
571  {
572  if(def_op_ending_states.find(state) != def_op_ending_states.end())
573  {
574  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "---Chained operand");
575  if(HLS->Rfu->get_index(def_op) != INFINITE_UINT)
576  {
577  key_value = std::make_tuple(2, HLS->Rfu->get_assign(def_op), HLS->Rfu->get_index(def_op));
578  }
579  else
580  {
581  key_value = std::make_tuple(2, 0, tree_var);
582  }
583  }
584  else if(HLS->storage_value_information->is_a_storage_value(state, tree_var))
585  {
586  unsigned int storage_value =
588  unsigned int r_index = HLS->Rreg->get_register(storage_value);
589  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "---Register: " + STR(r_index));
590  key_value = std::make_tuple(3, 0, r_index);
591  }
592  else
593  {
594  THROW_UNREACHABLE("unexpected");
595  }
596  }
597  else
598  {
599  unsigned int storage_value =
601  unsigned int r_index = HLS->Rreg->get_register(storage_value);
602  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "---Register: " + STR(r_index));
603  key_value = std::make_tuple(3, 0, r_index);
604  }
605  }
606 
608  break;
609  }
611  }
612  if(op_vertex_map.find(key_value) == op_vertex_map.end())
613  {
614  v_input = boost::add_vertex(g);
615  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "Vertex: " + STR(v_input));
616  op_vertex_map[key_value] = v_input;
617  }
618  vertices_in_op[var_num] = op_vertex_map.at(key_value);
619  }
620 
621  if(vertices_in_op[0] != vertices_in_op[1])
622  {
623  Operands tmp_op;
624  add_edge(vertices_in_op[0], vertices_in_op[1], g);
625  tmp_op.op = fu_operation;
626  tmp_op.first_op = vertices_in_op[0];
627  tmp_op.second_op = vertices_in_op[1];
629  operands.push_back(tmp_op);
630  }
631  }
632 
633  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "PORT_SWAPPING STARTING");
635  {
636  std::ofstream file(GetPath("starting-graph_" + HLS->allocation_information->get_string_name(fu.first.first) +
637  "_" + STR(fu.first.second) + ".dot"));
638  boost::write_graphviz(file, g);
639  file.close();
640  }
641  results = p_swap(g);
642  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "PORT_SWAPPING ENDED");
643 
644 #ifndef NDEBUG
645  for(auto res : results)
646  {
648  "---Vertex: " + STR(res.first) + " Belongs To: " + STR(res.second));
649  }
650 #endif
652  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "---Printing Results");
653 
654  for(const auto& opt : operands)
655  {
656  unsigned int op1, op2;
657  op1 = get_results(opt.first_op, results);
658  op2 = get_results(opt.second_op, results);
659  if((op1 == op2) && (op1 == SET_B || op1 == SET_A))
660  {
661  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "--- Error in the algorithm");
662  }
663  else if((op1 == SET_A && op2 == SET_B) || (op1 == SET_AB && op2 == SET_B) || (op1 == SET_A && op2 == SET_AB) ||
664  (op1 == SET_AB && op2 == SET_AB))
665  {
667  HLS->Rfu->set_ports_are_swapped(opt.op, false);
668  }
669  else if((op1 == SET_AB && op2 == SET_A) || (op1 == SET_B && op2 == SET_AB))
670  {
672  "--> Swap ports in operation: " + GET_NAME(data, opt.op));
674  "--- Vertices swapped: " + STR(opt.first_op) + " and " + STR(opt.second_op));
676  HLS->Rfu->set_ports_are_swapped(opt.op, true);
677  changed = true;
678  ++n_swaps;
679  }
680  }
681 
682  operands.clear();
683  op_vertex_map.clear();
684  g.clear();
685  }
686 
687  if(n_swaps)
688  {
690  "-->Port swapping: number of operations swapped= " + STR(n_swaps));
692  }
693  if(changed)
694  {
696  }
697  else
698  {
700  }
701 }
Class specification to contain liveness information.
unsigned int get_register(unsigned int sv) const
return the register index where the storage value is stored
#define DEBUG_LEVEL_VERY_PEDANTIC
extremely verbose debugging print is performed.
const HLS_managerRef HLSMgr
information about all the HLS synthesis
Definition: hls_step.hpp:205
Data structure representing the entire HLS information.
#define INDENT_DBG_MEX(dbgLevel, curDbgLevel, mex)
We are producing a debug version of the program, so the message is printed;.
#define GET_TYPE(data, vertex_index)
Helper macro returning the type associated with a node.
PSVertex find_max_degree(const CustomOrderedSet< std::pair< PSVertex, unsigned int >> &dSet)
This function finds the maximum degree (out_edges) of a vertex.
File containing functions and utilities to support the printing of debug messagges.
#define STOK(token)
Macro used to convert a token symbol into the corresponding string.
int flag
Definition: SPARC-GCC.h:58
const CustomOrderedSet< vertex > & get_state_where_end(vertex op) const
return in which support vertex the operation is ending
Definition: liveness.cpp:235
Step successfully executed.
string target
Definition: lenet_tvm.py:16
~port_swapping() override
Destructor.
#define GET_CLASS(obj)
Macro returning the actual type of an object.
bool has_op_where_defined(unsigned int var) const
return true in case there exist an operation defining it
Definition: liveness.cpp:161
const int output_level
The output level.
#define SET_A
RelationshipType
The relationship type.
Source must be executed to satisfy target.
#define INDENT_OUT_MEX(outLevel, curOutLevel, mex)
unsigned int get_assign(const vertex &v) const
Returns the functional unit assigned to the vertex.
Definition: fu_binding.cpp:242
const unsigned int funId
identifier of the function to be processed (0 means that it is a global step)
#define GET_NAME(data, vertex_index)
Helper macro returning the name associated with a node.
static bool is_parameter(const tree_managerConstRef &TM, const unsigned int index)
return true in case the index corresponds to a parameter in ssa form or not
AllocationInformationRef allocation_information
Store the technology information.
Definition: hls.hpp:115
A simple interface to token object of the raw files.
virtual bool is_a_storage_value(vertex curr_vertex, unsigned int var_index)=0
return true in case a storage value exist for the pair vertex variable
#define TYPE_PHI
constant string identifying an operation node of type PHI
Definition: op_graph.hpp:135
#define STR(s)
Macro which performs a lexical_cast to a string.
Auxiliary methods for manipulating string.
struct { PSVertex v PSVSet
#define max
Definition: backprop.h:17
struct { std::vector< PSVSet > vset PSMultiStart
const OpNodeInfoConstRef CGetOpNodeInfo(const vertex node) const
Returns the info associated with a node.
Definition: op_graph.hpp:843
DesignFlowStep_Status InternalExec() override
Execute the step.
#define THROW_UNREACHABLE(str_expr)
helper function used to specify that some points should never be reached
Definition: exceptions.hpp:292
fu_bindingRef Rfu
Store the refcounted functional unit binding of the operations.
Definition: hls.hpp:121
port_swapping(const ParameterConstRef Param, const HLS_managerRef HLSMgr, unsigned int funId, const DesignFlowManagerConstRef design_flow_manager)
Constructor.
unsigned edges[4545]
Definition: graph.h:25
Data structure used to store the register binding of variables.
StorageValueInformationRef storage_value_information
data-structure for storage values
Definition: hls.hpp:130
boost::graph_traits< PSGraph >::vertex_descriptor PSVertex
This class specifies the characteristic of a particular operation working on a given functional unit...
std::pair< unsigned int, unsigned int > PSE
unsigned int get_results(PSVertex operand, const std::vector< std::pair< PSVertex, unsigned int >> &results)
This function returns the belonging set of a given vertex.
HLSFlowStep_Type
Definition: hls_step.hpp:95
std::vector< std::pair< PSVertex, unsigned int > > p_swap(PSGraph &g)
This function is the wrapper that executes port_swapping_algorithms and extracts the best solution...
boost::graph_traits< graph >::vertex_descriptor vertex
vertex definition.
Definition: graph.hpp:1303
utility function used to read files.
bool is_commutative_op(const std::string &operation)
This function checks if an operation is commutative or not.
const BehavioralHelperConstRef CGetBehavioralHelper() const
Returns the helper associated with the function.
boost::graph_traits< graph >::vertex_iterator VertexIterator
vertex_iterator definition.
Definition: graph.hpp:1307
const ParameterConstRef parameters
Set of input parameters.
DesignFlowStep_Status
The status of a step.
This package is used by all HLS packages to manage resource constraints and characteristics.
This file collects some utility functions and macros.
PSVertex get_co_tree_vertex(PSVertex vertex, const std::vector< PSE > &edges)
This function selects the right vertex from the co_tree_edges vector.
reg_bindingRef Rreg
Store the refcounted register binding of the variables.
Definition: hls.hpp:133
std::string PrintVariable(unsigned int var) const
Print the name of the variable associated to the index.
boost::adjacency_list< boost::vecS, boost::vecS, boost::undirectedS, boost::no_property, boost::property< boost::edge_color_t, boost::default_color_type > > PSGraph
This package is used to define the storage value scheme adopted by the register allocation algorithms...
const CustomUnorderedSet< std::tuple< HLSFlowStep_Type, HLSFlowStepSpecializationConstRef, HLSFlowStep_Relationship > > ComputeHLSRelationships(const DesignFlowStep::RelationshipType relationship_type) const override
Compute the relationship of this step.
livenessRef Rliv
data-structure containing the variable liveness
Definition: hls.hpp:127
This file collects some utility functions.
void set_ports_are_swapped(vertex v, bool condition)
specify if vertex v have or not its ports swapped
std::string GetPath(std::filesystem::path path)
Definition: fileIO.hpp:140
Data flow graph with feedback.
std::string get_string_name(unsigned int fu_name) const
Returns the name of the functional for debug purpose.
int vertex_distance(const std::vector< PSE > &spt_edges, PSVertex root, PSVertex dest, std::vector< PSVSet > &vset)
This function calculates the distances between two vertices in a spanning tree.
Data structure used to store the functional-unit binding of the vertexes.
const OpGraphConstRef CGetOpGraph(FunctionBehavior::graph_type gt) const
This method returns the operation graphs.
#define INFINITE_UINT
UNSIGNED INT representing infinite.
Definition: utility.hpp:70
const CustomOrderedSet< vertex > & get_state_where_run(vertex op) const
return in which support vertex the operation is running
Definition: liveness.cpp:241
hlsRef HLS
HLS data structure of the function to be analyzed.
virtual unsigned int get_storage_value_index(vertex curr_vertex, unsigned int var_index)=0
Returns the index of the storage value associated with the variable in a given vertex.
TYPE distance(TYPE position_x[nAtoms], TYPE position_y[nAtoms], TYPE position_z[nAtoms], int i, int j)
Definition: md_kernel_test.c:3
Template borrowed from the ANTLR library by Terence Parr (http://www.jGuru.com - Software rights: htt...
Definition: refcount.hpp:94
void update_degree(PSGraph g2, CustomOrderedSet< std::pair< PSVertex, unsigned int >> &dSet)
This function updates the degree of all the vertices.
this class is used to manage the command-line or XML options.
unsigned int functionId
this is the identifier of the function to be implemented
Definition: hls.hpp:87
int debug_level
The debug level.
#define OUTPUT_LEVEL_VERBOSE
verbose debugging print is performed.
refcount< const HLSFlowStepSpecialization > HLSFlowStepSpecializationConstRef
const refcount definition of the class
Definition: hls_step.hpp:93
vertex get_op_where_defined(unsigned int var) const
return which operation defines the variable
Definition: liveness.cpp:154
Implementation of the port swapping algorithm described in the following paper: Hao Cong...
Data structure definition for high-level synthesis flow.
#define SET_B
Superclass include.
#define SET_AB
unsigned int get_index(const vertex &v) const
Returns the index of functional unit assigned to the vertex.
Definition: fu_binding.cpp:261
void vertex_levels(const std::vector< PSE > &spt_edges, PSVertex root, size_t num_vertices_g, std::vector< PSVSet > &vset)
This function calculates the levels of all te vertices starting from root.
A brief description of the C++ Header File.
void port_swapping_algorithm(PSGraph &g, std::vector< PSMultiStart > &vector_sets, size_t num_vertices_g, PSVertex root)
This function computes the port_swapping.
#define THROW_ASSERT(cond, str_expr)
helper function used to check an assert and if needed to throw an error in a standard way ...
Definition: exceptions.hpp:289

Generated on Mon Feb 12 2024 13:02:53 for PandA-2024.02 by doxygen 1.8.13