PandA-2024.02
design_flow_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  * 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  */
43 #include "design_flow_graph.hpp"
44 #include "Parameter.hpp" // for OPT_dot_directory
45 #include "custom_map.hpp" // for _Rb_tree_const_iter...
46 #include "design_flow_step.hpp" // for DesignFlowStep_Status
47 #include "exceptions.hpp" // for THROW_UNREACHABLE
48 #include <boost/graph/adjacency_list.hpp> // for adjacency_list, source
49 #include <boost/graph/filtered_graph.hpp> // for source, target
50 #include <boost/iterator/iterator_facade.hpp> // for operator!=, operator++
51 #include <filesystem> // for create_directories
52 #include <ostream> // for operator<<, ostream
53 #include <utility> // for pair
54 
55 DesignFlowStepInfo::DesignFlowStepInfo(const DesignFlowStepRef _design_flow_step, const bool _unnecessary)
56  : design_flow_step(_design_flow_step),
58 {
59 }
60 
62 
64 
67 {
68 }
69 
71 
72 vertex DesignFlowGraphsCollection::AddDesignFlowStep(const DesignFlowStepRef design_flow_step, const bool unnecessary)
73 {
74  const DesignFlowStepInfoRef info(new DesignFlowStepInfo(design_flow_step, unnecessary));
75  const vertex new_vertex = AddVertex(RefcountCast<NodeInfo>(info));
76  signature_to_vertex[design_flow_step->GetSignature()] = new_vertex;
77  return new_vertex;
78 }
79 
80 vertex DesignFlowGraphsCollection::GetDesignFlowStep(const std::string& signature) const
81 {
82  if(signature_to_vertex.find(signature) != signature_to_vertex.end())
83  {
84  return signature_to_vertex.find(signature)->second;
85  }
86  else
87  {
88  return NULL_VERTEX;
89  }
90 }
91 
93 
95 
96 const int DesignFlowGraph::AUX_SELECTOR = 4;
97 
99 
100 DesignFlowGraph::DesignFlowGraph(const DesignFlowGraphsCollectionRef design_flow_graphs_collection, const int _selector)
101  : graph(design_flow_graphs_collection.get(), _selector)
102 {
103 }
104 
105 DesignFlowGraph::DesignFlowGraph(const DesignFlowGraphsCollectionRef design_flow_graphs_collection, const int _selector,
106  const CustomUnorderedSet<vertex>& _vertices)
107  : graph(design_flow_graphs_collection.get(), _selector, _vertices)
108 {
109 }
110 
112 
113 vertex DesignFlowGraph::GetDesignFlowStep(const std::string& signature) const
114 {
115  return dynamic_cast<DesignFlowGraphsCollection*>(collection)->GetDesignFlowStep(signature);
116 }
117 
118 void DesignFlowGraph::WriteDot(const std::string& file_name, const int) const
119 {
120  const std::string output_directory =
121  collection->parameters->getOption<std::string>(OPT_dot_directory) + "/design_flow/";
122  if(!std::filesystem::exists(output_directory))
123  {
124  std::filesystem::create_directories(output_directory);
125  }
126  const std::string full_name = output_directory + file_name + ".dot";
127  VertexWriterConstRef design_flow_step_writer(new DesignFlowStepWriter(this));
128  EdgeWriterConstRef design_flow_edge_writer(new DesignFlowEdgeWriter(this));
129  InternalWriteDot<const DesignFlowStepWriter, const DesignFlowEdgeWriter>(full_name, design_flow_step_writer,
130  design_flow_edge_writer);
131 }
132 
133 #ifndef NDEBUG
134 void DesignFlowGraph::WriteDot(const std::string& file_name,
135  const CustomMap<size_t, CustomMap<vertex, DesignFlowStep_Status>>& vertex_history,
136  const CustomMap<size_t, CustomUnorderedMapStable<EdgeDescriptor, int>>& edge_history,
137  const CustomMap<vertex, std::string>& vertex_names,
138  const size_t writing_step_counter) const
139 {
140  const std::string output_directory =
141  collection->parameters->getOption<std::string>(OPT_dot_directory) + "/design_flow/";
142  if(!std::filesystem::exists(output_directory))
143  {
144  std::filesystem::create_directories(output_directory);
145  }
146  const std::string full_name = output_directory + file_name + ".dot";
147  VertexWriterConstRef design_flow_step_writer(
148  new DesignFlowStepWriter(this, vertex_history.find(writing_step_counter)->second, vertex_names));
149  EdgeWriterConstRef design_flow_edge_writer(new DesignFlowEdgeWriter(
150  this, vertex_history.find(writing_step_counter)->second, edge_history.find(writing_step_counter)->second));
151  InternalWriteDot<const DesignFlowStepWriter, const DesignFlowEdgeWriter>(full_name, design_flow_step_writer,
152  design_flow_edge_writer);
153 }
154 #endif
155 
157  const CustomMap<vertex, DesignFlowStep_Status>& _vertex_history,
158  const CustomMap<vertex, std::string>& _actor_names, const int _detail_level)
159  : VertexWriter(design_flow_graph, _detail_level), vertex_history(_vertex_history), actor_names(_actor_names)
160 {
161 }
162 
164 
165 void DesignFlowStepWriter::operator()(std::ostream& out, const vertex& v) const
166 {
167  out << "[";
168  const DesignFlowStepInfoConstRef design_flow_step_info =
169  dynamic_cast<const DesignFlowGraph*>(printing_graph)->CGetDesignFlowStepInfo(v);
170  if(vertex_history.size())
171  {
172  if(vertex_history.find(v) == vertex_history.end())
173  {
174  out << "color=white,label=\"\"";
175  }
176  else
177  {
178  switch(vertex_history.find(v)->second)
179  {
181  {
182  out << " style=filled, fillcolor=red, fontcolor=white,";
183  break;
184  }
186  {
187  out << " style=filled, fillcolor=darkgreen, fontcolor=white, ";
188  break;
189  }
191  {
192  THROW_UNREACHABLE("Status of a step is nonexitent");
193  break;
194  }
196  {
197  out << " style=filled, fillcolor=black, fontcolor=white,";
198  break;
199  }
201  {
202  out << " style=filled, fillcolor=darkgreen, fontcolor=white, ";
203  break;
204  }
206  {
207  out << " style=filled, fillcolor=gold, fontcolor=white, ";
208  break;
209  }
211  {
212  break;
213  }
215  {
216  out << "style=dashed,";
217  break;
218  }
219  default:
220  {
221  THROW_UNREACHABLE("");
222  }
223  }
224  out << "label=\"" << actor_names.find(v)->second << "\"";
225  }
226  }
227  else
228  {
229  if(design_flow_step_info->design_flow_step->IsComposed())
230  {
231  out << " shape=box3d,";
232  }
233  switch(design_flow_step_info->status)
234  {
236  {
237  out << " style=filled, fillcolor=red, fontcolor=white,";
238  break;
239  }
241  {
242  out << " style=filled, fillcolor=darkgreen, fontcolor=white, ";
243  break;
244  }
246  {
247  THROW_UNREACHABLE("Status of a step is nonexitent");
248  break;
249  }
251  {
252  out << " style=filled, fillcolor=black, fontcolor=white,";
253  break;
254  }
256  {
257  out << " style=filled, fillcolor=darkgreen, fontcolor=white, ";
258  break;
259  }
261  {
262  out << " style=filled, fillcolor=gold, fontcolor=white, ";
263  break;
264  }
266  {
267  break;
268  }
270  {
271  out << "style=dashed,";
272  break;
273  }
274  default:
275  {
276  THROW_UNREACHABLE("");
277  }
278  }
279  design_flow_step_info->design_flow_step->WriteDot(out);
280  }
281  out << "]";
282 }
283 
285  const CustomMap<vertex, DesignFlowStep_Status>& _vertex_history,
287  const int _detail_level)
288  : EdgeWriter(design_flow_graph, _detail_level), vertex_history(_vertex_history), edge_history(_edge_history)
289 {
290 }
291 
292 void DesignFlowEdgeWriter::operator()(std::ostream& out, const EdgeDescriptor& edge) const
293 {
294  out << "[";
295  const vertex source = boost::source(edge, *printing_graph);
296  const vertex target = boost::target(edge, *printing_graph);
297  if(edge_history.size())
298  {
299  if(edge_history.find(edge) == edge_history.end())
300  {
301  out << "color=white";
302  }
303  else
304  {
305  const DesignFlowStep_Status source_status = vertex_history.find(source)->second;
306  const DesignFlowStep_Status target_status = vertex_history.find(target)->second;
307  const bool source_executed =
308  source_status == DesignFlowStep_Status::EMPTY or source_status == DesignFlowStep_Status::SKIPPED or
309  source_status == DesignFlowStep_Status::SUCCESS or source_status == DesignFlowStep_Status::UNCHANGED;
310  const bool target_executed =
311  target_status == DesignFlowStep_Status::EMPTY or target_status == DesignFlowStep_Status::SKIPPED or
312  target_status == DesignFlowStep_Status::SUCCESS or target_status == DesignFlowStep_Status::UNCHANGED;
313  const bool source_unnecessary = source_status == DesignFlowStep_Status::UNNECESSARY;
314  const bool target_unnecessary = target_status == DesignFlowStep_Status::UNNECESSARY;
315  const int edge_selector = edge_history.find(edge)->second;
317  {
318  out << "color=red3,";
319  }
320  else if(source_executed and target_executed)
321  {
322  out << "color=darkgreen, ";
323  }
324  if((DesignFlowGraph::PRECEDENCE_SELECTOR & selector & edge_selector) or target_unnecessary or
325  source_unnecessary)
326  {
327  out << "style=dashed";
328  }
329  }
330  }
331  else
332  {
333  const DesignFlowStepInfoConstRef source_info =
334  dynamic_cast<const DesignFlowGraph*>(printing_graph)->CGetDesignFlowStepInfo(source);
335  const DesignFlowStepInfoConstRef target_info =
336  dynamic_cast<const DesignFlowGraph*>(printing_graph)->CGetDesignFlowStepInfo(target);
337  const bool source_executed = source_info->status == DesignFlowStep_Status::EMPTY or
338  source_info->status == DesignFlowStep_Status::SKIPPED or
339  source_info->status == DesignFlowStep_Status::SUCCESS or
340  source_info->status == DesignFlowStep_Status::UNCHANGED;
341  const bool target_executed = target_info->status == DesignFlowStep_Status::EMPTY or
342  target_info->status == DesignFlowStep_Status::SKIPPED or
343  target_info->status == DesignFlowStep_Status::SUCCESS or
344  target_info->status == DesignFlowStep_Status::UNCHANGED;
345  const bool source_unnecessary = source_info->status == DesignFlowStep_Status::UNNECESSARY;
346  const bool target_unnecessary = target_info->status == DesignFlowStep_Status::UNNECESSARY;
348  {
349  out << "color=red3,";
350  }
351  else if(source_executed and target_executed)
352  {
353  out << "color=darkgreen, ";
354  }
355  if((DesignFlowGraph::PRECEDENCE_SELECTOR & selector & printing_graph->GetSelector(edge)) or target_unnecessary or
356  source_unnecessary)
357  {
358  out << "style=dashed";
359  }
360  }
361  out << "]";
362 }
void operator()(std::ostream &out, const EdgeDescriptor &edge) const override
Functor actually called by the boost library to perform the writing.
void WriteDot(const std::string &file_name, const int detail_level=0) const
Write this graph in dot format.
int GetSelector() const
Return the selector of this graph.
Definition: graph.hpp:922
Step does not exits.
const ParameterConstRef parameters
Set of input parameters.
Definition: graph.hpp:291
const graph * printing_graph
The graph to be printed.
Definition: graph.hpp:1410
Step successfully executed.
string target
Definition: lenet_tvm.py:16
vertex AddDesignFlowStep(const DesignFlowStepRef design_flow_step, const bool unnecessary)
Add a design step.
Step successfully executed but without any IR change.
static const int DEPENDENCE_SELECTOR
The dependence selector.
CustomOrderedMap< T, U > CustomMap
Definition: custom_map.hpp:167
exceptions managed by PandA
static const int DEPENDENCE_FEEDBACK_SELECTOR
The dependence feedback selector.
redefinition of map to manage ordered/unordered structures
DesignFlowStepInfo(const DesignFlowStepRef _design_flow_step, const bool unnecessary)
Constructor.
DesignFlowEdgeWriter(const DesignFlowGraph *design_flow_graph, const CustomMap< vertex, DesignFlowStep_Status > &vertex_history=CustomMap< vertex, DesignFlowStep_Status >(), const CustomUnorderedMapStable< EdgeDescriptor, int > &edge_history=CustomUnorderedMapStable< EdgeDescriptor, int >(), const int detail_level=0)
Constructor.
const CustomMap< vertex, DesignFlowStep_Status > & vertex_history
Actors which have to be printed (empty means all)
DesignFlowGraph(const DesignFlowGraphsCollectionRef design_flow_graphs_collection, const int _selector)
Constructor.
const graph * printing_graph
The graph to be printed.
Definition: graph.hpp:1445
const CustomMap< vertex, std::string > & actor_names
The name of the actors (when they cannot be taken from graph.
#define THROW_UNREACHABLE(str_expr)
helper function used to specify that some points should never be reached
Definition: exceptions.hpp:292
Base class for step of design flow.
Functor used to write the content of a vertex to dotty file.
Definition: graph.hpp:1406
Classes to describe design flow graph.
DesignFlowGraphsCollection(const ParameterConstRef parameters)
Constructor.
~DesignFlowStepWriter() override
Destructor.
boost::graph_traits< graph >::vertex_descriptor vertex
vertex definition.
Definition: graph.hpp:1303
const int selector
The selector of the graph to be printed.
Definition: graph.hpp:1448
static const int PRECEDENCE_SELECTOR
The condition selector.
General class used to describe a graph in PandA.
Definition: graph.hpp:771
DesignFlowStep_Status
The status of a step.
void operator()(std::ostream &out, const vertex &v) const override
Functor actually called by the boost library to perform the writing.
~DesignFlowGraphsCollection() override
Destructor.
vertex GetDesignFlowStep(const std::string &signature) const
Return the vertex associated with a design step if exists, NULL_VERTEX otherwise. ...
bulk graph.
Definition: graph.hpp:287
DesignFlowDependenceInfo()
Constructor.
string full_name
Definition: test_panda.py:841
Functor used to write the content of the edges to a dotty file.
Definition: graph.hpp:1441
Functor used to write the content of the design flow edge to dotty file.
DesignFlowStepWriter(const DesignFlowGraph *design_flow_graph, const CustomMap< vertex, DesignFlowStep_Status > &vertex_history=CustomMap< vertex, DesignFlowStep_Status >(), const CustomMap< vertex, std::string > &actor_names=CustomMap< vertex, std::string >(), const int detail_level=0)
Constructor.
CustomUnorderedMap< std::string, vertex > signature_to_vertex
Map a signature of a step to the corresponding vertex.
Template borrowed from the ANTLR library by Terence Parr (http://www.jGuru.com - Software rights: htt...
Definition: refcount.hpp:94
vertex GetDesignFlowStep(const std::string &signature) const
Return the vertex associated with a design step if exists, NULL_VERTEX otherwise. ...
this class is used to manage the command-line or XML options.
~DesignFlowGraph() override
Destructor.
Functor used to write the content of the design flow step to dotty file.
absl::node_hash_map< T, U, Hash, Eq, Alloc > CustomUnorderedMapStable
Definition: custom_map.hpp:152
const CustomUnorderedMapStable< EdgeDescriptor, int > & edge_history
Edges which have to be printed (empty means all)
~DesignFlowDependenceInfo() override
Destructor.
static const int AUX_SELECTOR
The auxiliary selector.
graphs_collection * collection
The graph collection.
Definition: graph.hpp:846
Step is symbolic and it has already been marked.
virtual boost::graph_traits< boost_graphs_collection >::vertex_descriptor AddVertex(const NodeInfoRef info)
Add a vertex to this graph with a property.
Definition: graph.cpp:57
#define NULL_VERTEX
null vertex definition
Definition: graph.hpp:1305
const CustomMap< vertex, DesignFlowStep_Status > & vertex_history
Actors which have to be printed (empty means all)
Step not yet executed.
boost::graph_traits< graph >::edge_descriptor EdgeDescriptor
edge definition.
Definition: graph.hpp:1316

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