PandA-2024.02
state_transition_graph.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  e 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 */
47 
48 #include "config_HAVE_HOST_PROFILING_BUILT.hpp"
49 
50 #include <filesystem>
51 
53 #include "Parameter.hpp"
54 
56 #if HAVE_HOST_PROFILING_BUILT
58 #endif
59 #include "op_graph.hpp"
60 #include "var_pp_functor.hpp"
61 
63 #include "hls.hpp"
64 #include "hls_manager.hpp"
65 
67 #include "schedule.hpp"
68 
70 #include "behavioral_helper.hpp"
71 
73 #include "simple_indent.hpp"
74 
75 void StateInfo::print(std::ostream& os, const int detail_level) const
76 {
77  const auto function_behavior = HLSMgr.lock()->CGetFunctionBehavior(funId);
78  const auto schedule = HLSMgr.lock()->get_HLS(funId)->Rsch;
79  const auto critical_paths = schedule->ComputeCriticalPath(StateInfoConstRef(this, null_deleter()));
80  const auto op_function_graph = function_behavior->CGetOpGraph(FunctionBehavior::CFG);
81  const BehavioralHelperConstRef BH = op_function_graph->CGetOpGraphInfo()->BH;
83 
84  std::list<vertex>::const_iterator i, i_end;
85  i_end = executing_operations.end();
86  i = executing_operations.begin();
87 
88  if(i != i_end && GET_TYPE(op_function_graph, *i) == TYPE_ENTRY)
89  {
90  os << "START";
91  return;
92  }
93 
94  if(i != i_end && GET_TYPE(op_function_graph, *i) == TYPE_EXIT)
95  {
96  os << "END";
97  return;
98  }
99 
100  os << "< " << name << " | { ";
101 
102  for(const auto& op : executing_operations)
103  {
104  const auto first_index = op_function_graph->CGetOpNodeInfo(op)->GetNodeId();
105 
106  const bool critical = critical_paths.find(first_index) != critical_paths.end();
107  if(detail_level == 0)
108  {
109  if(std::find(ending_operations.begin(), ending_operations.end(), op) == ending_operations.end())
110  {
111  os << "<font color=\"gold2\">";
112  }
113  else if(critical)
114  {
115  os << "<font color=\"red3\">";
116  }
117  else if(GET_TYPE(op_function_graph, op) & TYPE_STORE)
118  {
119  os << "<font color=\"blue\">";
120  }
121  }
122  const auto first_starting_time = schedule->GetStartingTime(first_index);
123  const auto first_ending_time = schedule->GetEndingTime(first_index);
124  if(detail_level == 0)
125  {
126  os << GET_NAME(op_function_graph, op) << " [" << NumberToString(first_starting_time, 2, 7) << "---"
127  << NumberToString(first_ending_time, 2, 7) << "("
128  << NumberToString(first_ending_time - first_starting_time, 2, 7) << ")"
129  << "] --&gt; ";
130  }
131  std::string vertex_print = BH->print_vertex(op_function_graph, op, vpp, true);
132  boost::replace_all(vertex_print, "&", "&amp;");
133  boost::replace_all(vertex_print, "|", "\\|");
134  boost::replace_all(vertex_print, ">", "&gt;");
135  boost::replace_all(vertex_print, "<", "&lt;");
136  boost::replace_all(vertex_print, R"(\\")", "&#92;&quot;");
137  boost::replace_all(vertex_print, "\\\"", "&quot;");
138  boost::replace_all(vertex_print, ":", "&#58;");
139  boost::replace_all(vertex_print, "\\n", "");
140  boost::replace_all(vertex_print, "{", "\\{");
141  boost::replace_all(vertex_print, "}", "\\}");
142  os << vertex_print;
143  if(detail_level == 0)
144  {
145  if(critical or std::find(ending_operations.begin(), ending_operations.end(), op) == ending_operations.end() or
146  GET_TYPE(op_function_graph, op) & TYPE_STORE)
147  {
148  os << " </font>";
149  }
150  }
151  os << "<br align=\"left\"/>";
152  }
153  if(!detail_level)
154  {
155  os << " | ";
156  for(const auto& op : ending_operations)
157  {
158  const auto first_index = op_function_graph->CGetOpNodeInfo(op)->GetNodeId();
159  const auto critical = critical_paths.find(first_index) != critical_paths.end();
160  if(std::find(executing_operations.begin(), executing_operations.end(), op) == executing_operations.end())
161  {
162  os << "<font color=\"green2\">";
163  }
164  else if(critical)
165  {
166  os << "<font color=\"red3\">";
167  }
168  else if(GET_TYPE(op_function_graph, op) & TYPE_STORE)
169  {
170  os << "<font color=\"blue\">";
171  }
172  const auto first_starting_time = schedule->GetStartingTime(first_index);
173  const auto first_ending_time = schedule->GetEndingTime(first_index);
174  os << GET_NAME(op_function_graph, op) << " [" << NumberToString(first_starting_time, 2, 7) << "---"
175  << NumberToString(first_ending_time, 2, 7) << "("
176  << NumberToString(first_ending_time - first_starting_time, 2, 7) << ")"
177  << "] --&gt; ";
178  std::string vertex_print = BH->print_vertex(op_function_graph, op, vpp, true);
179  boost::replace_all(vertex_print, "&", "&amp;");
180  boost::replace_all(vertex_print, "|", "\\|");
181  boost::replace_all(vertex_print, ">", "&gt;");
182  boost::replace_all(vertex_print, "<", "&lt;");
183  boost::replace_all(vertex_print, R"(\\")", "&#92;&quot;");
184  boost::replace_all(vertex_print, "\\\"", "&quot;");
185  boost::replace_all(vertex_print, "\\n", "");
186  boost::replace_all(vertex_print, ":", "&#58;");
187  boost::replace_all(vertex_print, "{", "\\{");
188  boost::replace_all(vertex_print, "}", "\\}");
189  os << vertex_print;
190  if(critical or
191  std::find(executing_operations.begin(), executing_operations.end(), op) == executing_operations.end() or
192  GET_TYPE(op_function_graph, op) & TYPE_STORE)
193  {
194  os << " </font>";
195  }
196  os << "<br align=\"left\"/>";
197  }
198  }
199 
200  os << " } | ";
201 
202  if(BB_ids.size())
203  {
204  os << "BB";
205  for(const auto& bb_i : BB_ids)
206  {
207  os << bb_i << " <br align=\"left\"/>";
208  }
209  }
210  else
211  {
212  os << "none";
213  }
214 #if HAVE_HOST_PROFILING_BUILT
215  if(function_behavior->CGetProfilingInformation() and BB_ids.size() == 1 && detail_level == 0)
216  {
217  const auto BB_id = *(BB_ids.begin());
218  const auto BB_vertex =
219  function_behavior->CGetBBGraph(FunctionBehavior::BB)->CGetBBGraphInfo()->bb_index_map.find(BB_id)->second;
220  const auto bb_executions = function_behavior->CGetProfilingInformation()->GetBBExecutions(BB_vertex);
221  if(bb_executions)
222  {
223  os << "<br/>Executed " << STR(bb_executions) << " times";
224  }
225  }
226 #endif
227 
228  os << ">";
229 }
230 
231 void TransitionInfo::print(std::ostream& os, const int detail_level) const
232 {
233  const BehavioralHelperConstRef BH = op_function_graph->CGetOpGraphInfo()->BH;
234  if(t == DONTCARE_COND)
235  {
236  ; // nothing to print
237  }
238  else if(t == TRUE_COND)
239  {
240  if(detail_level == 0)
241  {
242  os << GET_NAME(op_function_graph, get_operation()) << "(T)\\n";
243  }
244  else
245  {
246  os << "(T)\\n";
247  }
248  }
249  else if(t == FALSE_COND)
250  {
251  if(detail_level == 0)
252  {
253  os << GET_NAME(op_function_graph, get_operation()) << "(F)\\n";
254  }
255  else
256  {
257  os << "(F)\\n";
258  }
259  }
260  else if(t == CASE_COND)
261  {
262  auto op = get_operation();
263  if(detail_level == 0)
264  {
265  os << GET_NAME(op_function_graph, op);
266  }
267  os << " (";
269  bool first = true;
270  for(auto label : labels)
271  {
272  if(first)
273  {
274  os << BH->PrintNode(label, op, std);
275  first = false;
276  }
277  else
278  {
279  os << "," << BH->PrintNode(label, op, std);
280  }
281  }
282  if(has_default)
283  {
284  if(first)
285  {
286  os << "default\\n";
287  }
288  else
289  {
290  os << ",default\\n";
291  }
292  }
293  os << ")";
294  }
295  else if(t == ALL_FINISHED)
296  {
297  bool first = true;
298  for(auto op : ops)
299  {
300  if(first)
301  {
302  os << GET_NAME(op_function_graph, op);
303  first = false;
304  }
305  else
306  {
307  os << "," << GET_NAME(op_function_graph, op);
308  }
309  }
310  os << "(ALL_FINISHED)\\n";
311  }
312  else if(t == NOT_ALL_FINISHED)
313  {
314  bool first = true;
315  for(auto op : ops)
316  {
317  if(first)
318  {
319  os << GET_NAME(op_function_graph, op);
320  first = false;
321  }
322  else
323  {
324  os << "," << GET_NAME(op_function_graph, op);
325  }
326  }
327  os << "(NOT_ALL_FINISHED)\\n";
328  }
329  else
330  {
331  THROW_ERROR("transition type not yet supported");
332  }
333  if(epp_incrementValid)
334  {
335  os << "epp: " << epp_increment << "\\n";
336  }
337 }
338 
340 {
341  THROW_ASSERT(ops.size() == 1, "unexpected condition");
342  return *ops.begin();
343 }
344 
346 {
347  THROW_ASSERT((t == ALL_FINISHED || t == NOT_ALL_FINISHED) && ref_state != NULL_VERTEX, "unexpected condition");
348  return ref_state;
349 }
350 
352  : op_function_graph(_op_function_graph),
353  entry_node(NULL_VERTEX),
354  exit_node(NULL_VERTEX),
355  is_a_dag(true),
356  bounded(false),
357  min_cycles(0),
358  max_cycles(0)
359 {
360 }
361 
363  const StateTransitionGraphInfoRef state_transition_graph_info, const ParameterConstRef _parameters)
364  : graphs_collection(state_transition_graph_info, _parameters)
365 {
366 }
367 
369 
371  int _selector)
372  : graph(state_transition_graphs_collection.get(), _selector)
373 {
374 }
375 
377  int _selector, CustomUnorderedSet<vertex>& _sub)
378  : graph(state_transition_graphs_collection.get(), _selector, _sub)
379 {
380 }
381 
383 
384 void StateTransitionGraph::WriteDot(const std::string& file_name, const int detail_level) const
385 {
386  const auto output_directory = collection->parameters->getOption<std::string>(OPT_dot_directory);
387  CustomSet<unsigned int> critical_paths;
388  VertexIterator state, state_end;
389  for(boost::tie(state, state_end) = boost::vertices(*this); state != state_end; state++)
390  {
391  StateInfoConstRef si = CGetStateInfo(*state);
392  const auto critical_path =
393  si->HLSMgr.lock()->get_HLS(si->funId)->Rsch->ComputeCriticalPath(CGetStateInfo(*state));
394  critical_paths.insert(critical_path.begin(), critical_path.end());
395  }
396  if(!std::filesystem::exists(output_directory))
397  {
398  std::filesystem::create_directories(output_directory);
399  }
400  const OpGraphConstRef op_function_graph = CGetStateTransitionGraphInfo()->op_function_graph;
401  const std::string function_name = op_function_graph->CGetOpGraphInfo()->BH->get_function_name();
402  const std::string complete_file_name = output_directory + function_name + "/";
403  if(!std::filesystem::exists(complete_file_name))
404  {
405  std::filesystem::create_directories(complete_file_name);
406  }
407  const VertexWriterConstRef state_writer(new StateWriter(this, op_function_graph, detail_level));
408  const EdgeWriterConstRef transition_writer(new TransitionWriter(this, op_function_graph, detail_level));
409  InternalWriteDot<const StateWriter, const TransitionWriter>(complete_file_name + file_name, state_writer,
410  transition_writer);
411 #if 0
412  for(boost::tie(state, state_end) = boost::vertices(*this); state != state_end; state++)
413  {
414  if(*state == CGetStateTransitionGraphInfo()->entry_node or *state == CGetStateTransitionGraphInfo()->exit_node)
415  {
416  continue;
417  }
418  const auto state_info = CGetStateInfo(*state);
419  OpVertexSet state_ops = OpVertexSet(op_function_graph);
420  state_ops.insert(state_info->starting_operations.begin(), state_info->starting_operations.end());
421  state_ops.insert(state_info->ending_operations.begin(), state_info->ending_operations.end());
422  const auto st_op_graph = state_info->HLSMgr.lock()->CGetFunctionBehavior(state_info->funId)->CGetOpGraph(FunctionBehavior::DFG, state_ops);
423  auto st_file_name = file_name.substr(0, file_name.find(".dot"));
424  st_op_graph->WriteDot(st_file_name + "_" + state_info->name + ".dot", state_info->HLSMgr.lock()->get_HLS(state_info->funId), state_info->HLSMgr.lock()->get_HLS(state_info->funId)->Rsch->ComputeCriticalPath(state_info));
425  }
426 #endif
427 }
428 
429 StateWriter::StateWriter(const graph* _stg, const OpGraphConstRef _op_function_graph, int _detail_level)
430  : VertexWriter(_stg, _detail_level),
431  BH(_op_function_graph->CGetOpGraphInfo()->BH),
432  op_function_graph(_op_function_graph),
433  entry_node(GetPointer<const StateTransitionGraphInfo>(_stg->CGetGraphInfo())->entry_node),
434  exit_node(GetPointer<const StateTransitionGraphInfo>(_stg->CGetGraphInfo())->exit_node)
435 {
436 }
437 
438 void StateWriter::operator()(std::ostream& out, const vertex& v) const
439 {
440  const auto* temp = Cget_node_info<StateInfo>(v, *printing_graph);
441  out << "[";
442  if(v == entry_node or v == exit_node)
443  {
444  out << "color=blue,shape=Msquare,";
445  }
446  else
447  {
448  out << "shape=record,";
449  }
450  out << "label=";
451  temp->print(out, detail_level);
452  out << "]";
453 }
454 
455 TransitionWriter::TransitionWriter(const graph* _stg, const OpGraphConstRef _op_function_graph, int _detail_level)
456  : EdgeWriter(_stg, _detail_level),
457  BH(_op_function_graph->CGetOpGraphInfo()->BH),
458  op_function_graph(_op_function_graph)
459 {
460 }
461 
462 void TransitionWriter::operator()(std::ostream& out, const EdgeDescriptor& e) const
463 {
464  const auto* temp = Cget_edge_info<TransitionInfo>(e, *printing_graph);
465  if(TransitionInfo::StateTransitionType::ST_EDGE_NORMAL & printing_graph->GetSelector(e))
466  {
467  out << "[color=red3";
468  }
469  else if(TransitionInfo::StateTransitionType::ST_EDGE_FEEDBACK & printing_graph->GetSelector(e))
470  {
471  out << "[color=green2";
472  }
473  else if(TransitionInfo::StateTransitionType::ST_EDGE_EPP & printing_graph->GetSelector(e))
474  {
475  out << "[color=blue";
476  }
477  else
478  {
479  THROW_UNREACHABLE("InconsistentDataStructure");
480  }
481  out << ",label=\"";
482  temp->print(out, detail_level);
483  out << "\"]";
484 }
CustomOrderedSet< unsigned int > BB_ids
set of BB ids associated with the state
int GetSelector() const
Return the selector of this graph.
Definition: graph.hpp:922
Data structure representing the entire HLS information.
virtual std::string PrintNode(const tree_nodeConstRef &node, vertex v, const var_pp_functorConstRef vppf) const
Print the operations corresponding to the node.
#define GET_TYPE(data, vertex_index)
Helper macro returning the type associated with a node.
const int detail_level
The detail level.
Definition: graph.hpp:1413
void operator()(std::ostream &out, const EdgeDescriptor &e) const override
Functor actually called by the boost library to perform the writing.
Basic block control flow graph.
const ParameterConstRef parameters
Set of input parameters.
Definition: graph.hpp:291
const graph * printing_graph
The graph to be printed.
Definition: graph.hpp:1410
vertex exit_node
vertex that contains exit node
Simple pretty print functor.
void print(std::ostream &os, const int detail_level) const override
Implementation of print method for this kind of node.
vertex entry_node
vertex that contains entry node
StateTransitionGraphInfo(const OpGraphConstRef op_function_graph)
Constructor.
#define GET_NAME(data, vertex_index)
Helper macro returning the name associated with a node.
std::string NumberToString(const T number, const size_t precision, const size_t size)
Function with print number in desired format.
Definition of hash function for EdgeDescriptor.
Definition: graph.hpp:1321
~StateTransitionGraph() override
Destructor.
~StateTransitionGraphsCollection() override
Destructor.
const OpGraphConstRef op_function_graph
reference to operation graph
A set of operation vertices.
Definition: op_graph.hpp:654
vertex get_ref_state() const
std::list< vertex > executing_operations
set of operation vertices which require inputs in this state
#define STR(s)
Macro which performs a lexical_cast to a string.
unsigned int funId
function identifier of the function from which the state has been derived
StateTransitionGraphsCollection(const StateTransitionGraphInfoRef state_transition_graph_info, const ParameterConstRef parameters)
Constructor.
const graph * printing_graph
The graph to be printed.
Definition: graph.hpp:1445
#define TYPE_EXIT
constant identifying the node type of an exit node.
#define THROW_UNREACHABLE(str_expr)
helper function used to specify that some points should never be reached
Definition: exceptions.hpp:292
Class specification for storing profiling information.
Standard functor that returns the name of a variable.
Data structure used to store the schedule of the operations.
refcount< const StateInfo > StateInfoConstRef
Functor used to write the content of a vertex to dotty file.
Definition: graph.hpp:1406
Control flow graph.
const StateTransitionGraphInfoConstRef CGetStateTransitionGraphInfo() const
Return the info associated with the graph.
vertex get_operation() const
const OpGraphInfoConstRef CGetOpGraphInfo() const
Returns the property associated with the graph.
Definition: op_graph.hpp:871
#define TYPE_STORE
Constant string identifying a memory store operation.
Definition: op_graph.hpp:177
boost::graph_traits< graph >::vertex_descriptor vertex
vertex definition.
Definition: graph.hpp:1303
This file contains the structures needed to manage a graph that will represent the state transition g...
General class used to describe a graph in PandA.
Definition: graph.hpp:771
Functor used to write the content of the edges to a dotty file and it is used to write specific edge ...
boost::graph_traits< graph >::vertex_iterator VertexIterator
vertex_iterator definition.
Definition: graph.hpp:1307
const int detail_level
The detail level.
Definition: graph.hpp:1451
#define THROW_ERROR(str_expr)
helper function used to throw an error in a standard way
Definition: exceptions.hpp:263
void print(std::ostream &os, const int detail_level) const
Print the information associated with the edge of the graph.
void WriteDot(const std::string &file_name, const int detail_level=0) const
Writes this graph in dot format.
null deleter
Definition: refcount.hpp:51
StateWriter(const graph *_stg, const OpGraphConstRef _op_function_graph, int _detail_level)
Constructor.
std::string print_vertex(const OpGraphConstRef g, const vertex v, const var_pp_functorConstRef vppf, const bool dot=false) const
Print the operations corrisponding to the vertex.
bulk graph.
Definition: graph.hpp:287
refcount< T > lock() const
Definition: refcount.hpp:212
std::string name
string used to give a label to the state
Functor used to write the content of the edges to a dotty file.
Definition: graph.hpp:1441
const GraphInfoConstRef CGetGraphInfo() const
FIXME: this method should become protected and called by equivalent method in subclasses Get the grap...
Definition: graph.hpp:1062
std::list< vertex > ending_operations
set of operation vertices completing their execution in this state
T * GetPointer(const refcount< U > &t)
Template function used to hide dynamic_cast The template parameter T represents a type of an object h...
Definition: refcount.hpp:237
Data structures used in operations graph.
Wrefcount< const HLS_manager > HLSMgr
Weak Reference to function behavior.
StateTransitionGraph(const StateTransitionGraphsCollectionRef state_transition_graphs_collection, int selector)
Standard constructor.
this class is used to manage the command-line or XML options.
void operator()(std::ostream &out, const vertex &v) const override
Functor actually called by the boost library to perform the writing.
#define TYPE_ENTRY
constant identifying the node type of an entry node.
graphs_collection * collection
The graph collection.
Definition: graph.hpp:846
refcount< const var_pp_functor > var_pp_functorConstRef
TransitionWriter(const graph *stg, const OpGraphConstRef op_function_graph, int _detail_level)
Constructor.
const BehavioralHelperConstRef BH
this is the helper associated to the actual module
Data structure definition for high-level synthesis flow.
Structure holding information about the whole graph.
const StateInfoConstRef CGetStateInfo(const vertex state) const
Return the info associated with a state.
#define NULL_VERTEX
null vertex definition
Definition: graph.hpp:1305
Functor template used to write the content of the nodes to a dotty file.
boost::graph_traits< graph >::edge_descriptor EdgeDescriptor
edge definition.
Definition: graph.hpp:1316
#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:54 for PandA-2024.02 by doxygen 1.8.13