PandA-2024.02
bambu.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  */
47 #include "config_HAVE_PRAGMA_BUILT.hpp"
49 #include "config_NPROFILE.hpp"
50 
51 #include <filesystem>
52 
54 #include "BambuParameter.hpp"
55 
57 #include "application_manager.hpp"
58 #include "call_graph_manager.hpp"
59 
61 #include "design_flow.hpp"
62 #include "design_flow_factory.hpp"
63 #include "design_flow_manager.hpp"
64 
68 
70 #include "frontend_flow_step.hpp"
72 
74 #include "evaluation.hpp"
75 #include "hls_device.hpp"
77 #include "hls_manager.hpp"
78 #include "hls_step.hpp"
79 
80 #if HAVE_FROM_AADL_ASN_BUILT
83 #endif
84 
85 #if HAVE_PRAGMA_BUILT
86 #include "pragma_manager.hpp"
88 #endif
89 
91 #include <cstdlib>
92 #include <iosfwd>
93 
96 
98 #include "tree_helper.hpp"
99 #include "tree_manager.hpp"
100 #include "tree_node.hpp"
101 
103 #include "cpu_time.hpp"
104 
106 #include "compiler_wrapper.hpp"
107 
114 int main(int argc, char* argv[])
115 {
116  srand(static_cast<unsigned int>(time(nullptr)));
117 
118  // General options register
120 
121  try
122  {
123  // ---------- Initialization ------------ //
124 
125  // Synthesis cpu time
126 
127  // ---------- Parameter parsing ------------ //
128  long cpu_time;
129  START_TIME(cpu_time);
130  parameters = ParameterRef(new BambuParameter(argv[0], argc, argv));
131 
132  switch(parameters->Exec())
133  {
134  case PARAMETER_NOTPARSED:
135  {
137  std::string cat_args;
138  for(int i = 0; i < argc; i++)
139  {
140  cat_args += std::string(argv[i]) + " ";
141  }
142 
143  INDENT_OUT_MEX(OUTPUT_LEVEL_MINIMUM, parameters->getOption<int>(OPT_output_level),
144  " == Bambu executed with: " + cat_args + "\n");
145  THROW_ERROR("Bad Parameters format");
146  break;
147  }
148  case EXIT_SUCCESS:
149  {
150  if(not(parameters->getOption<bool>(OPT_no_clean)))
151  {
152  std::filesystem::remove_all(parameters->getOption<std::string>(OPT_output_temporary_directory));
153  }
154  return EXIT_SUCCESS;
155  }
156  case PARAMETER_PARSED:
157  {
158  exit_code = EXIT_FAILURE;
159  break;
160  }
161  default:
162  {
163  THROW_ERROR("Bad Parameters parsing");
164  }
165  }
166 
167  auto output_level = parameters->getOption<int>(OPT_output_level);
168  if(output_level >= OUTPUT_LEVEL_MINIMUM)
169  {
170  parameters->PrintFullHeader(std::cerr);
171  }
172 
173  // Include sysdir
174  if(parameters->getOption<bool>(OPT_gcc_include_sysdir))
175  {
176  const CompilerWrapperRef compiler_wrapper(new CompilerWrapper(
178  std::vector<std::string> system_includes;
179  compiler_wrapper->GetSystemIncludes(system_includes);
180  std::vector<std::string>::const_iterator system_include, system_include_end = system_includes.end();
181  for(system_include = system_includes.begin(); system_include != system_include_end; ++system_include)
182  {
183  INDENT_OUT_MEX(0, 0, *system_include);
184  }
185  if(not(parameters->getOption<bool>(OPT_no_clean)))
186  {
187  std::filesystem::remove_all(parameters->getOption<std::string>(OPT_output_temporary_directory));
188  }
189  return EXIT_SUCCESS;
190  }
191 
192  if(parameters->getOption<bool>(OPT_gcc_config))
193  {
194  const CompilerWrapperRef compiler_wrapper(new CompilerWrapper(
196  compiler_wrapper->GetCompilerConfig();
197  if(not(parameters->getOption<bool>(OPT_no_clean)))
198  {
199  std::filesystem::remove_all(parameters->getOption<std::string>(OPT_output_temporary_directory));
200  }
201  return EXIT_SUCCESS;
202  }
203  if(!parameters->isOption(OPT_input_file))
204  {
205  PRINT_OUT_MEX(OUTPUT_LEVEL_NONE, output_level, "no input files\n");
206  if(not(parameters->getOption<bool>(OPT_no_clean)))
207  {
208  std::filesystem::remove_all(parameters->getOption<std::string>(OPT_output_temporary_directory));
209  }
210  return EXIT_SUCCESS;
211  }
212  STOP_TIME(cpu_time);
213  PRINT_OUT_MEX(OUTPUT_LEVEL_VERBOSE, output_level,
214  "Parameters parsed in " + print_cpu_time(cpu_time) + " seconds\n");
215 
216  // up to now all parameters have been parsed and data structures created, so synthesis can start
217 
219  HLS_deviceRef HLS_D = HLS_device::factory(parameters);
220 
222  START_TIME(cpu_time);
224  HLS_managerRef HLSMgr = HLS_managerRef(new HLS_manager(parameters, HLS_D));
225  START_TIME(HLSMgr->HLS_execution_time);
226  // create the data-structures (inside application_manager) where the problem specification is contained
227  const DesignFlowManagerRef design_flow_manager(new DesignFlowManager(parameters));
228  const DesignFlowStepFactoryConstRef frontend_flow_step_factory(
229  new FrontendFlowStepFactory(HLSMgr, design_flow_manager, parameters));
230  design_flow_manager->RegisterFactory(frontend_flow_step_factory);
231  const DesignFlowStepFactoryConstRef hls_flow_step_factory(
232  new HLSFlowStepFactory(design_flow_manager, HLSMgr, parameters));
233  design_flow_manager->RegisterFactory(hls_flow_step_factory);
234  const DesignFlowStepFactoryConstRef c_backend_step_factory(
235  new CBackendStepFactory(design_flow_manager, HLSMgr, parameters));
236  design_flow_manager->RegisterFactory(c_backend_step_factory);
237  const DesignFlowStepFactoryConstRef technology_flow_step_factory(
238  new TechnologyFlowStepFactory(HLS_D->get_technology_manager(), HLS_D, design_flow_manager, parameters));
239  design_flow_manager->RegisterFactory(technology_flow_step_factory);
240 #if HAVE_FROM_AADL_ASN_BUILT
241  const DesignFlowStepFactoryConstRef parser_flow_step_factory(
242  new ParserFlowStepFactory(design_flow_manager, HLSMgr, parameters));
243  design_flow_manager->RegisterFactory(parser_flow_step_factory);
244 #endif
245 
246  if(parameters->getOption<Evaluation_Mode>(OPT_evaluation_mode) == Evaluation_Mode::DRY_RUN)
247  {
248  design_flow_manager->AddStep(GetPointer<const HLSFlowStepFactory>(hls_flow_step_factory)
249  ->CreateHLSFlowStep(HLSFlowStep_Type::EVALUATION, 0));
250  design_flow_manager->Exec();
251  return EXIT_SUCCESS;
252  }
253 
254  if(parameters->getOption<bool>(OPT_find_max_transformations))
255  {
256  const DesignFlowStepRef find_max_transformations =
257  GetPointer<const FrontendFlowStepFactory>(frontend_flow_step_factory)
258  ->CreateApplicationFrontendFlowStep(FrontendFlowStepType::FIND_MAX_TRANSFORMATIONS);
259  design_flow_manager->AddStep(find_max_transformations);
260  design_flow_manager->Exec();
261  return EXIT_FAILURE;
262  }
263  if(parameters->isOption(OPT_test_multiple_non_deterministic_flows))
264  {
265  const DesignFlowStepFactoryRef design_flow_factory(new DesignFlowFactory(design_flow_manager, parameters));
266  const DesignFlowStepRef non_deterministic_flows =
267  GetPointer<const DesignFlowFactory>(design_flow_factory)
268  ->CreateDesignFlow(DesignFlow_Type::NON_DETERMINISTIC_FLOWS);
269  design_flow_manager->AddStep(non_deterministic_flows);
270  design_flow_manager->Exec();
271  return EXIT_SUCCESS;
272  }
273 
275  if(parameters->isOption(OPT_pretty_print))
276  {
277  const auto c_backend =
278  GetPointer<const CBackendStepFactory>(c_backend_step_factory)
279  ->CreateCBackendStep(CBackendInformationConstRef(new CBackendInformation(
280  CBackendInformation::CB_SEQUENTIAL, parameters->getOption<std::string>(OPT_pretty_print))));
281  design_flow_manager->AddStep(c_backend);
282  }
283 
284  std::pair<HLSFlowStep_Type, HLSFlowStepSpecializationConstRef> hls_flow_step(
285  parameters->getOption<HLSFlowStep_Type>(OPT_synthesis_flow), HLSFlowStepSpecializationConstRef());
286  design_flow_manager->AddSteps(
287  GetPointer<const HLSFlowStepFactory>(hls_flow_step_factory)->CreateHLSFlowSteps(hls_flow_step));
288  design_flow_manager->Exec();
289  if(not(parameters->getOption<bool>(OPT_no_clean)))
290  {
291  std::filesystem::remove_all(parameters->getOption<std::string>(OPT_output_temporary_directory));
292  }
293  if(parameters->isOption(OPT_serialize_output) && parameters->isOption(OPT_output_file))
294  {
295  std::ofstream ofile(parameters->getOption<std::string>(OPT_output_file), std::ios::out);
296  for(const auto& files : {HLSMgr->aux_files, HLSMgr->hdl_files})
297  {
298  for(const auto& file : files)
299  {
300  std::cerr << "File name: " << file << "\n";
301  std::ifstream ifile(file, std::ios::in);
302  ofile << ifile.rdbuf();
303  }
304  }
305  }
306  return EXIT_SUCCESS; // Bambu tool has completed execution without errors
307  }
308 
309  // exception catching
310  catch(const char* str)
311  {
312  if(EXIT_SUCCESS == exit_code)
313  {
314  exit_code = EXIT_FAILURE;
315  }
316  std::cerr << str << std::endl;
317  }
318  catch(const std::string& str)
319  {
320  if(EXIT_SUCCESS == exit_code)
321  {
322  exit_code = EXIT_FAILURE;
323  }
324  std::cerr << str << std::endl;
325  }
326  catch(std::exception& e)
327  {
328  std::cerr << e.what() << std::endl;
329  if(EXIT_SUCCESS == exit_code)
330  {
331  exit_code = EXIT_FAILURE;
332  }
333  }
334  catch(...)
335  {
336  if(EXIT_SUCCESS == exit_code)
337  {
338  exit_code = EXIT_FAILURE;
339  }
340  std::cerr << "Unknown error type" << std::endl;
341  }
342 
343  switch(exit_code)
344  {
345  case PARAMETER_NOTPARSED:
346  {
347  parameters->PrintUsage(std::cout);
348  break;
349  }
350  case EXIT_FAILURE:
351  {
352  if(parameters)
353  {
354  parameters->PrintBugReport(std::cout);
355  }
356  break;
357  }
358  default:
359  {
360  }
361  }
362  if(parameters && not(parameters->getOption<bool>(OPT_no_clean)))
363  {
364  std::filesystem::remove_all(parameters->getOption<std::string>(OPT_output_temporary_directory));
365  }
366  return exit_code;
367 }
Class to compute evaluations about high-level synthesis.
Data structure representing the entire HLS information.
Factory class to create c backend.
int exit_code
NOTE: this file must be included only by source code of the executable (i.e., the file with the main)...
#define OUTPUT_LEVEL_NONE
no output print is performed.
Definition of the class representing a generic C application.
#define INDENT_OUT_MEX(outLevel, curOutLevel, mex)
#define OUTPUT_LEVEL_MINIMUM
minimum debugging print is performed.
Include a set of utilities used to manage CPU time measures.
Base class to pass information to a c backend.
#define START_TIME(time_var)
Macro used to store the start time into time_var.
Definition: cpu_time.hpp:133
Factory for hls flow step.
Evaluation_Mode
Definition: evaluation.hpp:52
HLSFlowStep_Type
Definition: hls_step.hpp:95
Manager for pragma annotations.
int main(int argc, char *argv[])
Autoheader includes.
Definition: bambu.cpp:114
#define PARAMETER_PARSED
An integer value to return if parameters have been right parsed.
Definition: Parameter.hpp:93
#define STOP_TIME(time_var)
Macro used to store the elapsed time into time_var.
Definition: cpu_time.hpp:136
Factory for technology flow step.
refcount< Parameter > ParameterRef
Definition: Parameter.hpp:758
refcount< const CBackendInformation > CBackendInformationConstRef
refcount< HLS_manager > HLS_managerRef
refcount definition of the class
This class contains the base representation for a generic frontend flow step.
Classes specification of the tree_node data structures.
Factory for parser flow step.
#define THROW_ERROR(str_expr)
helper function used to throw an error in a standard way
Definition: exceptions.hpp:263
Wrapper of design_flow.
This file collects some utility functions.
std::string print_cpu_time(long int t)
massage a long which represents a time interval in milliseconds, into a string suitable for output ...
Definition: cpu_time.hpp:110
Factory for creating design flows.
technology_managerRef get_technology_manager() const
Returns the technology manager.
This class contains the methods to create a frontend flow step.
Template borrowed from the ANTLR library by Terence Parr (http://www.jGuru.com - Software rights: htt...
Definition: refcount.hpp:94
char str[25]
Definition: fixedptc.c:8
This class contains the base representation for design flow.
Main class for wrapping the frontend compiler.
Wrapper to call graph.
#define PRINT_OUT_MEX(profLevel, curprofLevel, mex)
#define OUTPUT_LEVEL_VERBOSE
verbose debugging print is performed.
Base class to pass information to a c backend.
Class specification of the manager of the tree structures extracted from the raw file.
HLS specialization of generic_device.
static HLS_deviceRef factory(const ParameterRef &Param)
Factory method from XML file.
Definition: hls_device.cpp:62
#define PARAMETER_NOTPARSED
Definition: Parameter.hpp:94
Implementation of the wrapper to Gcc for C sources.

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