CppADCodeGen  HEAD
A C++ Algorithmic Differentiation Package with Source Code Generation
model_library_c_source_gen_impl.hpp
1 #ifndef CPPAD_CG_MODEL_LIBRARY_C_SOURCE_GEN_IMPL_INCLUDED
2 #define CPPAD_CG_MODEL_LIBRARY_C_SOURCE_GEN_IMPL_INCLUDED
3 /* --------------------------------------------------------------------------
4  * CppADCodeGen: C++ Algorithmic Differentiation with Source Code Generation:
5  * Copyright (C) 2012 Ciengis
6  *
7  * CppADCodeGen is distributed under multiple licenses:
8  *
9  * - Eclipse Public License Version 1.0 (EPL1), and
10  * - GNU General Public License Version 3 (GPL3).
11  *
12  * EPL1 terms and conditions can be found in the file "epl-v10.txt", while
13  * terms and conditions for the GPL3 can be found in the file "gpl3.txt".
14  * ----------------------------------------------------------------------------
15  * Author: Joao Leal
16  */
17 
18 #include <typeinfo>
19 
20 namespace CppAD {
21 namespace cg {
22 
23 template<class Base>
24 const unsigned long ModelLibraryCSourceGen<Base>::API_VERSION = 7;
25 
26 template<class Base>
27 const std::string ModelLibraryCSourceGen<Base>::FUNCTION_VERSION = "cppad_cg_version";
28 
29 template<class Base>
30 const std::string ModelLibraryCSourceGen<Base>::FUNCTION_MODELS = "cppad_cg_models";
31 
32 template<class Base>
33 const std::string ModelLibraryCSourceGen<Base>::FUNCTION_ONCLOSE = "cppad_cg_on_close";
34 
35 template<class Base>
36 const std::string ModelLibraryCSourceGen<Base>::FUNCTION_SETTHREADPOOLDISABLED = "cppad_cg_set_thread_pool_disabled";
37 
38 template<class Base>
39 const std::string ModelLibraryCSourceGen<Base>::FUNCTION_ISTHREADPOOLDISABLED = "cppad_cg_is_thread_pool_disabled";
40 
41 template<class Base>
42 const std::string ModelLibraryCSourceGen<Base>::FUNCTION_SETTHREADS = "cppad_cg_set_thread_number";
43 
44 template<class Base>
45 const std::string ModelLibraryCSourceGen<Base>::FUNCTION_GETTHREADS = "cppad_cg_get_thread_number";
46 
47 template<class Base>
48 const std::string ModelLibraryCSourceGen<Base>::FUNCTION_SETTHREADSCHEDULERSTRAT = "cppad_cg_thpool_set_scheduler_strategy";
49 
50 template<class Base>
51 const std::string ModelLibraryCSourceGen<Base>::FUNCTION_GETTHREADSCHEDULERSTRAT = "cppad_cg_thpool_get_scheduler_strategy";
52 
53 template<class Base>
54 const std::string ModelLibraryCSourceGen<Base>::FUNCTION_SETTHREADPOOLVERBOSE = "cppad_cg_thpool_set_verbose";
55 
56 template<class Base>
57 const std::string ModelLibraryCSourceGen<Base>::FUNCTION_ISTHREADPOOLVERBOSE = "cppad_cg_thpool_is_verbose";
58 
59 template<class Base>
60 const std::string ModelLibraryCSourceGen<Base>::FUNCTION_SETTHREADPOOLGUIDEDMAXGROUPWORK = "cppad_cg_thpool_set_guided_maxgroupwork";
61 
62 template<class Base>
63 const std::string ModelLibraryCSourceGen<Base>::FUNCTION_GETTHREADPOOLGUIDEDMAXGROUPWORK = "cppad_cg_thpool_get_guided_maxgroupwork";
64 
65 template<class Base>
66 const std::string ModelLibraryCSourceGen<Base>::FUNCTION_SETTHREADPOOLNUMBEROFTIMEMEAS = "cppad_cg_thpool_set_number_of_time_meas";
67 
68 template<class Base>
69 const std::string ModelLibraryCSourceGen<Base>::FUNCTION_GETTHREADPOOLNUMBEROFTIMEMEAS = "cppad_cg_thpool_get_number_of_time_meas";
70 
71 template<class Base>
72 const std::string ModelLibraryCSourceGen<Base>::CONST = "const";
73 
74 template<class Base>
75 void ModelLibraryCSourceGen<Base>::saveSources(const std::string& sourcesFolder) {
76 
77  // create the folder if it does not exist
78  system::createFolder(sourcesFolder);
79 
80  // save/generate model sources
81  for (const auto& it : _models) {
82  saveSources(sourcesFolder, it.second->getSources());
83  }
84 
85  // save/generate library sources
86  saveSources(sourcesFolder, getLibrarySources());
87 
88  // save custom user sources
89  saveSources(sourcesFolder, getCustomSources());
90 }
91 
92 template<class Base>
93 void ModelLibraryCSourceGen<Base>::saveSources(const std::string& sourcesFolder,
94  const std::map<std::string, std::string>& sources) {
95  for (const auto& it : sources) {
96  // for debugging purposes only
97  std::ofstream sourceFile;
98  std::string file = system::createPath(sourcesFolder, it.first);
99  sourceFile.open(file.c_str());
100  sourceFile << it.second;
101  sourceFile.close();
102  }
103 }
104 
105 template<class Base>
106 const std::map<std::string, std::string>& ModelLibraryCSourceGen<Base>::getLibrarySources() {
107  if (_libSources.empty()) {
108  generateVersionSource(_libSources);
109  generateModelsSource(_libSources);
110  generateOnCloseSource(_libSources);
111  generateThreadPoolSources(_libSources);
112 
113  if(_multiThreading != MultiThreadingType::NONE) {
114  bool usingMultiThreading = false;
115  for (const auto& it : _models) {
116  if (it.second->isJacobianMultiThreadingEnabled() || it.second->isHessianMultiThreadingEnabled()) {
117  usingMultiThreading = true;
118  break;
119  }
120  }
121 
122  if (usingMultiThreading) {
123  if (_multiThreading == MultiThreadingType::PTHREADS) {
124  _libSources["thread_pool.c"] = CPPADCG_PTHREAD_POOL_C_FILE;
125 
126  } else if (_multiThreading == MultiThreadingType::OPENMP) {
127  _libSources["thread_pool.c"] = CPPADCG_OPENMP_C_FILE;
128  }
129  }
130  }
131  }
132 
133  return _libSources;
134 }
135 
136 template<class Base>
137 void ModelLibraryCSourceGen<Base>::generateVersionSource(std::map<std::string, std::string>& sources) {
138  _cache.str("");
139  _cache << "unsigned long " << FUNCTION_VERSION << "() {\n"
140  << " return " << API_VERSION << "u;\n"
141  << "}\n\n";
142 
143  sources[FUNCTION_VERSION + ".c"] = _cache.str();
144 }
145 
146 template<class Base>
147 void ModelLibraryCSourceGen<Base>::generateModelsSource(std::map<std::string, std::string>& sources) {
148  _cache.str("");
149  LanguageC<Base>::printFunctionDeclaration(_cache, "void", FUNCTION_MODELS, {"char const *const** names",
150  "int* count"});
151  _cache << " {\n"
152  " static const char* const models[] = {\n";
153 
154  for (auto it = _models.begin(); it != _models.end(); ++it) {
155  if (it != _models.begin()) {
156  _cache << ",\n";
157  }
158  _cache << " \"" << it->first << "\"";
159  }
160  _cache << "};\n"
161  " *names = models;\n"
162  " *count = " << _models.size() << ";\n"
163  "}\n\n";
164 
165  sources[FUNCTION_MODELS + ".c"] = _cache.str();
166 }
167 
168 template<class Base>
169 void ModelLibraryCSourceGen<Base>::generateOnCloseSource(std::map<std::string, std::string>& sources) {
170  bool pthreads = false;
171  if(_multiThreading == MultiThreadingType::PTHREADS) {
172  for (const auto& it : _models) {
173  if (it.second->isJacobianMultiThreadingEnabled() || it.second->isHessianMultiThreadingEnabled()) {
174  pthreads = true;
175  break;
176  }
177  }
178  }
179 
180  _cache.str("");
181  if (pthreads) {
182  _cache << CPPADCG_PTHREAD_POOL_H_FILE << "\n\n";
183  }
184  _cache << "void " << FUNCTION_ONCLOSE << "() {\n";
185  if (pthreads) {
186  _cache << "cppadcg_thpool_shutdown();\n";
187  }
188  _cache << "}\n\n";
189 
190  sources[FUNCTION_ONCLOSE + ".c"] = _cache.str();
191 }
192 
193 template<class Base>
194 void ModelLibraryCSourceGen<Base>::generateThreadPoolSources(std::map<std::string, std::string>& sources) {
195 
196  bool usingMultiThreading = false;
197  if(_multiThreading != MultiThreadingType::NONE) {
198  for (const auto& it : _models) {
199  if (it.second->isJacobianMultiThreadingEnabled() || it.second->isHessianMultiThreadingEnabled()) {
200  usingMultiThreading = true;
201  break;
202  }
203  }
204  }
205 
206  if (usingMultiThreading && _multiThreading == MultiThreadingType::PTHREADS) {
207  _cache.str("");
208  _cache << CPPADCG_PTHREAD_POOL_H_FILE << "\n\n";
209 
210  _cache << "void " << FUNCTION_SETTHREADPOOLDISABLED << "(int disabled) {\n";
211  _cache << " cppadcg_thpool_set_disabled(disabled);\n";
212  _cache << "}\n\n";
213 
214  _cache << "int " << FUNCTION_ISTHREADPOOLDISABLED << "() {\n";
215  _cache << " return cppadcg_thpool_is_disabled();\n";
216  _cache << "}\n\n";
217 
218  _cache << "void " << FUNCTION_SETTHREADS << "(unsigned int n) {\n";
219  _cache << " cppadcg_thpool_set_threads(n);\n";
220  _cache << "}\n\n";
221 
222  _cache << "unsigned int " << FUNCTION_GETTHREADS << "() {\n";
223  _cache << " return cppadcg_thpool_get_threads();\n";
224  _cache << "}\n\n";
225 
226  _cache << "void " << FUNCTION_SETTHREADSCHEDULERSTRAT << "(enum ScheduleStrategy s) {\n";
227  _cache << " cppadcg_thpool_set_scheduler_strategy(s);\n";
228  _cache << "}\n\n";
229 
230  _cache << "enum ScheduleStrategy " << FUNCTION_GETTHREADSCHEDULERSTRAT << "() {\n";
231  _cache << " return cppadcg_thpool_get_scheduler_strategy();\n";
232  _cache << "}\n\n";
233 
234  _cache << "void " << FUNCTION_SETTHREADPOOLVERBOSE << "(int v) {\n";
235  _cache << " cppadcg_thpool_set_verbose(v);\n";
236  _cache << "}\n\n";
237 
238  _cache << "int " << FUNCTION_ISTHREADPOOLVERBOSE << "() {\n";
239  _cache << " return cppadcg_thpool_is_verbose();\n";
240  _cache << "}\n\n";
241 
242  _cache << "void " << FUNCTION_SETTHREADPOOLGUIDEDMAXGROUPWORK << "(float v) {\n";
243  _cache << " cppadcg_thpool_set_guided_maxgroupwork(v);\n";
244  _cache << "}\n\n";
245 
246  _cache << "float " << FUNCTION_GETTHREADPOOLGUIDEDMAXGROUPWORK << "() {\n";
247  _cache << " return cppadcg_thpool_get_guided_maxgroupwork();\n";
248  _cache << "}\n\n";
249 
250  _cache << "void " << FUNCTION_SETTHREADPOOLNUMBEROFTIMEMEAS << "(unsigned int n) {\n";
251  _cache << " cppadcg_thpool_set_n_time_meas(n);\n";
252  _cache << "}\n\n";
253 
254  _cache << "unsigned int " << FUNCTION_GETTHREADPOOLNUMBEROFTIMEMEAS << "() {\n";
255  _cache << " return cppadcg_thpool_get_n_time_meas();\n";
256  _cache << "}\n\n";
257 
258  sources["thread_pool_access.c"] = _cache.str();
259 
260  } else if(usingMultiThreading && _multiThreading == MultiThreadingType::OPENMP) {
261  _cache.str("");
262  _cache << "#include <omp.h>\n";
263  _cache << CPPADCG_OPENMP_H_FILE << "\n\n";
264 
265  _cache << "void " << FUNCTION_SETTHREADPOOLDISABLED << "(int disabled) {\n";
266  _cache << " cppadcg_openmp_set_disabled(disabled);\n";
267  _cache << "}\n\n";
268 
269  _cache << "int " << FUNCTION_ISTHREADPOOLDISABLED << "() {\n";
270  _cache << " return cppadcg_openmp_is_disabled();\n";
271  _cache << "}\n\n";
272 
273  _cache << "void " << FUNCTION_SETTHREADS << "(unsigned int n) {\n";
274  _cache << " cppadcg_openmp_set_threads(n);\n";
275  _cache << "}\n\n";
276 
277  _cache << "unsigned int " << FUNCTION_GETTHREADS << "() {\n";
278  _cache << " return cppadcg_openmp_get_threads();\n";
279  _cache << "}\n\n";
280 
281  _cache << "void " << FUNCTION_SETTHREADSCHEDULERSTRAT << "(enum ScheduleStrategy s) {\n";
282  _cache << " cppadcg_openmp_set_scheduler_strategy(s);\n";
283  _cache << "}\n\n";
284 
285  _cache << "enum ScheduleStrategy " << FUNCTION_GETTHREADSCHEDULERSTRAT << "() {\n";
286  _cache << " return cppadcg_openmp_get_scheduler_strategy();\n";
287  _cache << "}\n\n";
288 
289  _cache << "void " << FUNCTION_SETTHREADPOOLVERBOSE << "(int v) {\n";
290  _cache << " cppadcg_openmp_set_verbose(v);\n";
291  _cache << "}\n\n";
292 
293  _cache << "int " << FUNCTION_ISTHREADPOOLVERBOSE << "() {\n";
294  _cache << " return cppadcg_openmp_is_verbose();\n";
295  _cache << "}\n\n";
296 
297  _cache << "void " << FUNCTION_SETTHREADPOOLGUIDEDMAXGROUPWORK << "(float v) {\n";
298  _cache << "}\n\n";
299 
300  _cache << "float " << FUNCTION_GETTHREADPOOLGUIDEDMAXGROUPWORK << "() {\n";
301  _cache << " return 1.0;\n";
302  _cache << "}\n\n";
303 
304  _cache << "void " << FUNCTION_SETTHREADPOOLNUMBEROFTIMEMEAS << "(unsigned int n) {\n";
305  _cache << "}\n\n";
306 
307  _cache << "unsigned int " << FUNCTION_GETTHREADPOOLNUMBEROFTIMEMEAS << "() {\n";
308  _cache << " return 0;\n";
309  _cache << "}\n\n";
310 
311  sources["thread_pool_access.c"] = _cache.str();
312 
313  } else {
314  _cache.str("");
315  _cache << "enum ScheduleStrategy {SCHED_STATIC = 1, SCHED_DYNAMIC = 2, SCHED_GUIDED = 3};\n"
316  "\n";
317  _cache << "void " << FUNCTION_SETTHREADPOOLDISABLED << "(int disabled) {\n";
318  _cache << "}\n\n";
319 
320  _cache << "int " << FUNCTION_ISTHREADPOOLDISABLED << "() {\n";
321  _cache << " return 1;\n";
322  _cache << "}\n\n";
323 
324  _cache << "void " << FUNCTION_SETTHREADS << "(unsigned int n) {\n";
325  _cache << "}\n\n";
326 
327  _cache << "unsigned int " << FUNCTION_GETTHREADS << "() {\n";
328  _cache << " return 1;\n";
329  _cache << "}\n\n";
330 
331  _cache << "void " << FUNCTION_SETTHREADSCHEDULERSTRAT << "(enum ScheduleStrategy s) {\n";
332  _cache << "}\n\n";
333 
334  _cache << "enum ScheduleStrategy " << FUNCTION_GETTHREADSCHEDULERSTRAT << "() {\n";
335  _cache << " return SCHED_STATIC;\n";
336  _cache << "}\n\n";
337 
338  _cache << "void " << FUNCTION_SETTHREADPOOLVERBOSE << "(int v) {\n";
339  _cache << "}\n\n";
340 
341  _cache << "int " << FUNCTION_ISTHREADPOOLVERBOSE << "() {\n";
342  _cache << " return 0;\n";
343  _cache << "}\n\n";
344 
345  _cache << "void " << FUNCTION_SETTHREADPOOLGUIDEDMAXGROUPWORK << "(float v) {\n";
346  _cache << "}\n\n";
347 
348  _cache << "float " << FUNCTION_GETTHREADPOOLGUIDEDMAXGROUPWORK << "() {\n";
349  _cache << " return 1.0;\n";
350  _cache << "}\n\n";
351 
352  _cache << "void " << FUNCTION_SETTHREADPOOLNUMBEROFTIMEMEAS << "(unsigned int n) {\n";
353  _cache << "}\n\n";
354 
355  _cache << "unsigned int " << FUNCTION_GETTHREADPOOLNUMBEROFTIMEMEAS << "() {\n";
356  _cache << " return 0;\n";
357  _cache << "}\n\n";
358 
359  sources["thread_pool_access.c"] = _cache.str();
360  }
361 }
362 
363 } // END cg namespace
364 } // END CppAD namespace
365 
366 #endif
virtual const std::map< std::string, std::string > & getLibrarySources()
void saveSources(const std::string &sourcesFolder)
std::string createPath(const std::string &baseFolder, const std::string &file)
static void printFunctionDeclaration(std::ostringstream &out, const std::string &returnType, const std::string &functionName, const std::vector< std::string > &arguments, const std::vector< std::string > &arguments2={})
Definition: language_c.hpp:538
void createFolder(const std::string &folder)