PandA-2024.02
bash_flow_wrapper.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) 2020-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 "bash_flow_wrapper.hpp"
46 
47 #include "BashBackendFlow.hpp"
48 #include "DesignParameters.hpp"
49 #include "Parameter.hpp"
50 #include "ToolManager.hpp"
51 #include "dbgPrintHelper.hpp" // for DEBUG_LEVEL_
52 #include "fileIO.hpp"
53 #include "string_manipulation.hpp"
54 #include "xml_script_command.hpp"
55 
56 #define PARAM_bash_outdir "bash_outdir"
57 
58 // constructor
59 bash_flow_wrapper::bash_flow_wrapper(const ParameterConstRef& _Param, const std::string& _output_dir,
60  const generic_deviceRef& _device)
61  : SynthesisTool(_Param, BASH_FLOW_TOOL_EXEC, _device, _output_dir, BASH_FLOW_TOOL_ID)
62 {
63  PRINT_DBG_MEX(DEBUG_LEVEL_PEDANTIC, debug_level, "Creating the bash_flow wrapper...");
64 }
65 
66 // destructor
68 
70 {
71  std::string top_id = dp->component_name;
72  dp->assign(PARAM_bash_outdir, output_dir, false);
73  dp->parameter_values[PARAM_bash_backend_report] = output_dir + "/" + top_id + "_report.xml";
74  dp->parameter_values[PARAM_bash_backend_timing_report] = output_dir + "/post_route_timing_summary.rpt";
75 }
76 
77 void bash_flow_wrapper::generate_synthesis_script(const DesignParametersRef& dp, const std::string& file_name)
78 {
79  // Export reserved (constant) values to design parameters
80  for(auto& var : xml_reserved_vars)
81  {
82  dp->assign(var->name, getStringValue(var, dp), false);
83  }
84 
85  // Bare script generation
86  std::ostringstream script;
87  script << "##########################################################" << std::endl;
88  script << "# Automatically generated by the PandA framework #" << std::endl;
89  script << "##########################################################" << std::endl << std::endl;
91 
92  // Replace all reserved variables with their value
93  std::string script_string = script.str();
94  replace_parameters(dp, script_string);
96  remove_escaped(script_string);
97 
98  // Save the generated script
99  if(std::filesystem::exists(file_name))
100  {
101  std::filesystem::remove_all(file_name);
102  }
103  script_name = file_name;
104  std::ofstream file_stream(file_name.c_str());
105  file_stream << script_string << std::endl;
106  file_stream.close();
107 }
108 
110 {
111  switch(node->nodeType)
112  {
113  case NODE_VARIABLE:
114  {
115  std::string result;
116  const xml_set_variable_t* var = GetPointer<xml_set_variable_t>(node);
117  if(var->singleValue)
118  {
119  result += *(var->singleValue);
120  }
121  else if(!var->multiValues.empty())
122  {
123  result += "{";
124  for(auto it = var->multiValues.begin(); it != var->multiValues.end(); ++it)
125  {
126  const xml_set_entry_tRef e = *it;
127  if(it != var->multiValues.begin())
128  {
129  result += " ";
130  }
131  result += toString(e, dp);
132  }
133  result += "}";
134  }
135  else
136  {
137  result += "\"\"";
138  }
139  return result;
140  }
141  case NODE_COMMAND:
142  case NODE_ENTRY:
143  case NODE_FOREACH:
144  case NODE_ITE_BLOCK:
145  case NODE_PARAMETER:
146  case NODE_SHELL:
147  case NODE_UNKNOWN:
148  default:
149  THROW_ERROR("Not supported node type: " + STR(node->nodeType));
150  }
152  return "";
153 }
154 
156 {
157  switch(node->nodeType)
158  {
159  case NODE_ENTRY:
160  {
161  const xml_set_entry_t* ent = GetPointer<xml_set_entry_t>(node);
162  return ent->value;
163  }
164  case NODE_VARIABLE:
165  {
166  const xml_set_variable_t* var = GetPointer<xml_set_variable_t>(node);
167  return "set " + var->name + " " + getStringValue(node, dp) + ";";
168  }
169  case NODE_PARAMETER:
170  {
171  const xml_parameter_t* par = GetPointer<xml_parameter_t>(node);
172  std::string result;
173  if(par->name)
174  {
175  result += *(par->name);
176  }
177  if(par->name && (par->singleValue || !par->multiValues.empty()))
178  {
179  result += par->separator;
180  }
181  if(par->singleValue)
182  {
183  result += *(par->singleValue);
184  }
185  else if(!par->multiValues.empty())
186  {
187  result += par->curlyBrackets ? "{" : "\"";
188  for(auto it = par->multiValues.begin(); it != par->multiValues.end(); ++it)
189  {
190  const xml_set_entry_tRef p = *it;
191  if(it != par->multiValues.begin())
192  {
193  result += " ";
194  }
195  result += toString(p, dp);
196  }
197  result += par->curlyBrackets ? "}" : "\"";
198  }
199  return result;
200  }
201  case NODE_COMMAND:
202  {
203  const xml_command_t* comm = GetPointer<xml_command_t>(node);
204  // TODO: Evaluate the condition
205  std::string result;
206  if(comm->name)
207  {
208  result += *(comm->name);
209  }
210  if(comm->name && comm->value)
211  {
212  result += " ";
213  }
214  if(comm->value)
215  {
216  result += *(comm->value);
217  }
218  if(!comm->parameters.empty())
219  {
220  for(const auto& p : comm->parameters)
221  {
222  result += " " + toString(p, dp);
223  }
224  }
225  if(comm->output)
226  {
227  result += " >> " + *(comm->output);
228  }
229  return result;
230  }
231  case NODE_SHELL:
232  {
233  const xml_shell_t* sh = GetPointer<xml_shell_t>(node);
234  // TODO: Evaluate the condition
235  std::string result = "sh ";
236  if(sh->name)
237  {
238  result += *(sh->name);
239  }
240  if(sh->name && sh->value)
241  {
242  result += " ";
243  }
244  if(sh->value)
245  {
246  result += *(sh->value);
247  }
248  if(!sh->parameters.empty())
249  {
250  for(const auto& p : sh->parameters)
251  {
252  result += " " + toString(p, dp);
253  }
254  }
255  if(sh->output)
256  {
257  result += " >> " + *(sh->output);
258  }
259  return result;
260  }
261  case NODE_ITE_BLOCK:
262  {
263  const xml_ite_block_t* ite = GetPointer<xml_ite_block_t>(node);
264  std::string result;
265  bool conditionValue = xml_ite_block_t::evaluate_condition(&(ite->condition), dp), first = true;
266  const std::vector<xml_script_node_tRef>& block = conditionValue ? ite->thenNodes : ite->elseNodes;
267  for(const auto& n : block)
268  {
269  if(n->checkCondition(dp))
270  {
271  if(!first)
272  {
273  result += "\n";
274  }
275  first = false;
276  result += toString(n, dp);
277  }
278  }
279  return result;
280  }
281  case NODE_UNKNOWN:
282  case NODE_FOREACH:
283  default:
284  THROW_ERROR("Not supported node type: " + STR(node->nodeType));
285  }
287  return "";
288 }
289 
291 {
292  std::ostringstream s;
293  s << get_tool_exec() << " " << script_name;
294  for(const auto& option : xml_tool_options)
295  {
296  if(option->checkCondition(dp))
297  {
298  std::string value = toString(option, dp);
299  replace_parameters(dp, value);
300  s << " " << value;
301  }
302  }
303  s << std::endl;
304  return s.str();
305 }
Command line parameter.
File containing functions and utilities to support the printing of debug messagges.
#define PRINT_DBG_MEX(dbgLevel, curDbgLevel, mex)
We are producing a debug version of the program, so the message is printed;.
void remove_escaped(std::string &ioString)
Function converting all the escaped characters in the associated character.
Wrapper to invoke a generic bash script.
#define DEBUG_LEVEL_PEDANTIC
very verbose debugging print is performed.
#define PARAM_bash_backend_timing_report
std::string * value
int debug_level
debug level of the class
std::vector< xml_parameter_tRef > parameters
std::string * name
int sh
Definition: adpcm.c:176
std::vector< xml_script_node_tRef > elseNodes
std::string output_dir
the output directory
std::string toString(const xml_script_node_tRef node, const DesignParametersRef dp) const override
Returns the string-based representation of the XML element.
#define STR(s)
Macro which performs a lexical_cast to a string.
Auxiliary methods for manipulating string.
static bool evaluate_condition(const std::string *condition)
Evaluates a string condition.
#define BASH_FLOW_TOOL_ID
If/Then/Else block, evaluated at compile-time.
map_t parameter_values
Map between the name of the parameter and the corresponding string-based value.
~bash_flow_wrapper() override
Destructor.
Backend based on a simple bash script.
void generate_synthesis_script(const DesignParametersRef &dp, const std::string &file_name) override
Creates the proper configuration script.
std::vector< xml_script_node_tRef > xml_script_nodes
std::string * name
void assign(const std::string &name, const std::string &value, bool checkExisting)
Assigns a value to a saved parameter.
#define PARAM_bash_backend_report
std::vector< xml_set_variable_tRef > xml_reserved_vars
This file contains the definition of the parameters for the synthesis tools.
std::string script_name
name of the script
std::string * value
utility function used to read files.
std::string get_command_line(const DesignParametersRef &dp) const override
Returns the proper command line.
std::string * output
void replace_parameters(const DesignParametersRef &dp, std::string &script) const
Replaces occurrences of parameters inside a script.
#define THROW_ERROR(str_expr)
helper function used to throw an error in a standard way
Definition: exceptions.hpp:263
#define PARAM_bash_outdir
Header include.
std::vector< xml_parameter_tRef > xml_tool_options
void EvaluateVariables(const DesignParametersRef dp) override
Evaluates the design variables.
int result[SIZE]
Definition: adpcm.c:800
This struct specifies the block node.
Definition: tree_node.hpp:1820
std::vector< xml_parameter_tRef > parameters
Classes for handling configuration files.
#define BASH_FLOW_TOOL_EXEC
Class to manage a wrapped tool.
std::string component_name
Name of the component.
std::string * singleValue
std::string value
std::vector< xml_set_entry_tRef > multiValues
std::vector< xml_set_entry_tRef > multiValues
Variable assignment, either single value or multiple entries set.
Template borrowed from the ANTLR library by Terence Parr (http://www.jGuru.com - Software rights: htt...
Definition: refcount.hpp:94
virtual std::string get_tool_exec() const
Returns the name of the tool executable.
Command line of the synthesis tool.
this class is used to manage the command-line or XML options.
Command line of the native shell.
bash_flow_wrapper(const ParameterConstRef &Param, const std::string &_output_dir, const generic_deviceRef &_device)
Constructor.
std::string * output
std::string getStringValue(const xml_script_node_tRef node, const DesignParametersRef &dp) const override
Returns the string-based representation of the XML element.
std::vector< xml_script_node_tRef > thenNodes
String entry of a multiple values variable (set).
std::string generate_bare_script(const std::vector< xml_script_node_tRef > &nodes, const DesignParametersRef &dp)

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