PandA-2024.02
omp_function_allocation.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) 2015-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 
45 #include "Parameter.hpp"
46 
48 #include "call_graph.hpp"
49 #include "call_graph_manager.hpp"
50 #include "function_behavior.hpp"
51 
53 #include <boost/range/adaptor/reversed.hpp>
54 
56 #include "hls_manager.hpp"
57 
59 #include "omp_functions.hpp"
60 
62 #include "behavioral_helper.hpp"
63 #include "tree_manager.hpp"
64 
66 #include "dbgPrintHelper.hpp"
67 #include "utility.hpp"
68 
70  const DesignFlowManagerConstRef _design_flow_manager)
71  : fun_dominator_allocation(_parameters, _HLSMgr, _design_flow_manager, HLSFlowStep_Type::OMP_FUNCTION_ALLOCATION)
72 {
73  debug_level = parameters->get_class_debug_level(GET_CLASS(*this));
74 }
75 
77 
79 {
80  auto omp_functions = GetPointer<OmpFunctions>(HLSMgr->Rfuns);
81  const auto TM = HLSMgr->get_tree_manager();
83  const auto call_graph_manager = HLSMgr->CGetCallGraphManager();
84  auto root_functions = call_graph_manager->GetRootFunctions();
85  if(parameters->isOption(OPT_top_design_name)) // top design function become the top_vertex
86  {
87  const auto top_rtldesign_function =
88  HLSMgr->get_tree_manager()->GetFunction(parameters->getOption<std::string>(OPT_top_design_name));
89  if(top_rtldesign_function && root_functions.count(top_rtldesign_function->index))
90  {
91  root_functions.clear();
92  root_functions.insert(top_rtldesign_function->index);
93  }
94  }
95  CustomUnorderedSet<vertex> vertex_subset;
96  for(const auto f_id : root_functions)
97  {
98  for(const auto reached_f_id : call_graph_manager->GetReachedFunctionsFrom(f_id))
99  {
100  vertex_subset.insert(call_graph_manager->GetVertex(reached_f_id));
101  }
102  }
103  const auto call_graph = call_graph_manager->CGetCallSubGraph(vertex_subset);
104  std::list<vertex> sorted_functions;
105  call_graph->TopologicalSort(sorted_functions);
106  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "Computing functions to be parallelized");
107  for(const auto function : sorted_functions)
108  {
109  const auto function_id = call_graph_manager->get_function(function);
110  if(HLSMgr->CGetFunctionBehavior(function_id)->CGetBehavioralHelper()->GetOmpForDegree())
111  {
113  "---Found omp for wrapper " +
114  HLSMgr->CGetFunctionBehavior(function_id)->CGetBehavioralHelper()->get_function_name());
115  omp_functions->omp_for_wrappers.insert(function_id);
116  continue;
117  }
118  InEdgeIterator ie, ie_end;
119  for(boost::tie(ie, ie_end) = boost::in_edges(function, *call_graph); ie != ie_end; ie++)
120  {
121  const auto source = boost::source(*ie, *call_graph);
122  const auto source_id = call_graph_manager->get_function(source);
123  if(omp_functions->omp_for_wrappers.find(source_id) != omp_functions->omp_for_wrappers.end() or
124  omp_functions->parallelized_functions.find(source_id) != omp_functions->parallelized_functions.end())
125  {
127  "---Found function to be parallelized: " +
128  HLSMgr->CGetFunctionBehavior(function_id)->CGetBehavioralHelper()->get_function_name());
129  omp_functions->parallelized_functions.insert(function_id);
130  break;
131  }
132  }
133  }
134  const auto panda_pthread_mutex = call_graph_manager->GetVertex(TM->GetFunction("panda_pthread_mutex")->index);
135  InEdgeIterator ie, ie_end;
136  for(boost::tie(ie, ie_end) = boost::in_edges(panda_pthread_mutex, *call_graph); ie != ie_end; ie++)
137  {
138  omp_functions->locking_functions.insert(call_graph_manager->get_function(boost::source(*ie, *call_graph)));
139  }
140  auto current_locks_allocation_candidates = omp_functions->locking_functions;
141  const auto reached_body_functions = call_graph_manager->GetReachedBodyFunctions();
142  for(const auto function : boost::adaptors::reverse(sorted_functions))
143  {
144  const auto function_id = call_graph_manager->get_function(function);
145  if(reached_body_functions.find(function_id) == reached_body_functions.end())
146  {
147  continue;
148  }
150  "-->Analyzing function " +
151  HLSMgr->CGetFunctionBehavior(function_id)->CGetBehavioralHelper()->get_function_name());
152  if(current_locks_allocation_candidates.find(function_id) != current_locks_allocation_candidates.end())
153  {
154  current_locks_allocation_candidates.erase(current_locks_allocation_candidates.find(function_id));
155 #ifndef NDEBUG
156  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "Other locks allocation candidates are:");
157  for(const auto current_locks_allocation_candidate : current_locks_allocation_candidates)
158  {
160  "---" + HLSMgr->CGetFunctionBehavior(current_locks_allocation_candidate)
161  ->CGetBehavioralHelper()
162  ->get_function_name());
163  }
164 #endif
165  if(current_locks_allocation_candidates.size() == 0)
166  {
168  if(omp_functions->parallelized_functions.find(function_id) != omp_functions->parallelized_functions.end())
169  {
170  for(boost::tie(ie, ie_end) = boost::in_edges(function, *call_graph); ie != ie_end; ie++)
171  {
172  const auto source_id = call_graph_manager->get_function(boost::source(*ie, *call_graph));
173  if(reached_body_functions.find(source_id) == reached_body_functions.end())
174  {
175  current_locks_allocation_candidates.insert(source_id);
176  }
177  }
178  if(omp_functions->omp_for_wrappers.find(function_id) != omp_functions->omp_for_wrappers.end())
179  {
180  omp_functions->locks_parallel_comunication.insert(function_id);
181  }
182  else
183  {
184  omp_functions->locks_merge_communication.insert(function_id);
185  }
186  }
187  else
188  {
189  omp_functions->locks_allocation = function_id;
190  }
191  }
192  else
193  {
194  for(boost::tie(ie, ie_end) = boost::in_edges(function, *call_graph); ie != ie_end; ie++)
195  {
196  const auto source_id = call_graph_manager->get_function(boost::source(*ie, *call_graph));
197  if(reached_body_functions.find(source_id) == reached_body_functions.end())
198  {
199  current_locks_allocation_candidates.insert(source_id);
200  }
201  }
202  if(omp_functions->omp_for_wrappers.find(function_id) != omp_functions->omp_for_wrappers.end())
203  {
204  omp_functions->locks_parallel_comunication.insert(function_id);
205  }
206  else
207  {
208  omp_functions->locks_merge_communication.insert(function_id);
209  }
210  }
211  }
213  }
214  if(omp_functions)
215  {
217  }
218 
220 }
221 
223 {
225  HLSMgr->Rfuns = functionsRef(new OmpFunctions(HLSMgr));
226 }
#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;.
virtual void Initialize()
Initialize the step (i.e., like a constructor, but executed just before exec.
File containing functions and utilities to support the printing of debug messagges.
#define GET_CLASS(obj)
Macro returning the actual type of an object.
OmpFunctionAllocation(const ParameterConstRef _parameters, const HLS_managerRef HLSMgr, const DesignFlowManagerConstRef design_flow_manager)
Constructor.
boost::graph_traits< graph >::in_edge_iterator InEdgeIterator
in_edge_iterator definition.
Definition: graph.hpp:1310
refcount< functions > functionsRef
refcount definition of the class
Definition: functions.hpp:159
DesignFlowStep_Status Exec() override
Execute the step.
#define STR(s)
Macro which performs a lexical_cast to a string.
~OmpFunctionAllocation() override
Destructor.
HLSFlowStep_Type
Definition: hls_step.hpp:95
const ParameterConstRef parameters
Set of input parameters.
DesignFlowStep_Status
The status of a step.
This file collects some utility functions and macros.
Call graph hierarchy.
DesignFlowStep_Status Exec() override
Execute the step.
Template borrowed from the ANTLR library by Terence Parr (http://www.jGuru.com - Software rights: htt...
Definition: refcount.hpp:94
Class to allocate function in HLS based on dominators and openmp information.
this class is used to manage the command-line or XML options.
void Initialize() override
Initialize the step (i.e., like a constructor, but executed just before exec.
Wrapper to call graph.
int debug_level
The debug level.
Datastructure to describe functions allocation in high-level synthesis.
Class specification of the manager of the tree structures extracted from the raw file.
A brief description of the C++ Header File.

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