CppADCodeGen 2.4.3
A C++ Algorithmic Differentiation Package with Source Code Generation
Loading...
Searching...
No Matches
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
20namespace CppAD {
21namespace cg {
22
23template<class Base>
24const unsigned long ModelLibraryCSourceGen<Base>::API_VERSION = 7;
25
26template<class Base>
27const std::string ModelLibraryCSourceGen<Base>::FUNCTION_VERSION = "cppad_cg_version";
28
29template<class Base>
30const std::string ModelLibraryCSourceGen<Base>::FUNCTION_MODELS = "cppad_cg_models";
31
32template<class Base>
33const std::string ModelLibraryCSourceGen<Base>::FUNCTION_ONCLOSE = "cppad_cg_on_close";
34
35template<class Base>
36const std::string ModelLibraryCSourceGen<Base>::FUNCTION_SETTHREADPOOLDISABLED = "cppad_cg_set_thread_pool_disabled";
37
38template<class Base>
39const std::string ModelLibraryCSourceGen<Base>::FUNCTION_ISTHREADPOOLDISABLED = "cppad_cg_is_thread_pool_disabled";
40
41template<class Base>
42const std::string ModelLibraryCSourceGen<Base>::FUNCTION_SETTHREADS = "cppad_cg_set_thread_number";
43
44template<class Base>
45const std::string ModelLibraryCSourceGen<Base>::FUNCTION_GETTHREADS = "cppad_cg_get_thread_number";
46
47template<class Base>
48const std::string ModelLibraryCSourceGen<Base>::FUNCTION_SETTHREADSCHEDULERSTRAT = "cppad_cg_thpool_set_scheduler_strategy";
49
50template<class Base>
51const std::string ModelLibraryCSourceGen<Base>::FUNCTION_GETTHREADSCHEDULERSTRAT = "cppad_cg_thpool_get_scheduler_strategy";
52
53template<class Base>
54const std::string ModelLibraryCSourceGen<Base>::FUNCTION_SETTHREADPOOLVERBOSE = "cppad_cg_thpool_set_verbose";
55
56template<class Base>
57const std::string ModelLibraryCSourceGen<Base>::FUNCTION_ISTHREADPOOLVERBOSE = "cppad_cg_thpool_is_verbose";
58
59template<class Base>
60const std::string ModelLibraryCSourceGen<Base>::FUNCTION_SETTHREADPOOLGUIDEDMAXGROUPWORK = "cppad_cg_thpool_set_guided_maxgroupwork";
61
62template<class Base>
63const std::string ModelLibraryCSourceGen<Base>::FUNCTION_GETTHREADPOOLGUIDEDMAXGROUPWORK = "cppad_cg_thpool_get_guided_maxgroupwork";
64
65template<class Base>
66const std::string ModelLibraryCSourceGen<Base>::FUNCTION_SETTHREADPOOLNUMBEROFTIMEMEAS = "cppad_cg_thpool_set_number_of_time_meas";
67
68template<class Base>
69const std::string ModelLibraryCSourceGen<Base>::FUNCTION_GETTHREADPOOLNUMBEROFTIMEMEAS = "cppad_cg_thpool_get_number_of_time_meas";
70
71template<class Base>
72const std::string ModelLibraryCSourceGen<Base>::CONST = "const";
73
74template<class Base>
75void 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
92template<class Base>
93void 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
105template<class Base>
106const 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
136template<class Base>
137void 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
146template<class Base>
147void 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
168template<class Base>
169void 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
193template<class Base>
194void 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
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={})
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)
void createFolder(const std::string &folder)