CppADCodeGen  HEAD
A C++ Algorithmic Differentiation Package with Source Code Generation
functor_model_library.hpp
1 #ifndef CPPAD_CG_FUNCTOR_MODEL_LIBRARY_INCLUDED
2 #define CPPAD_CG_FUNCTOR_MODEL_LIBRARY_INCLUDED
3 /* --------------------------------------------------------------------------
4  * CppADCodeGen: C++ Algorithmic Differentiation with Source Code Generation:
5  * Copyright (C) 2013 Ciengis
6  * Copyright (C) 2018 Joao Leal
7  *
8  * CppADCodeGen is distributed under multiple licenses:
9  *
10  * - Eclipse Public License Version 1.0 (EPL1), and
11  * - GNU General Public License Version 3 (GPL3).
12  *
13  * EPL1 terms and conditions can be found in the file "epl-v10.txt", while
14  * terms and conditions for the GPL3 can be found in the file "gpl3.txt".
15  * ----------------------------------------------------------------------------
16  * Author: Joao Leal
17  */
18 
19 namespace CppAD {
20 namespace cg {
21 
27 template<class Base>
28 class FunctorModelLibrary : public ModelLibrary<Base> {
29 protected:
30  std::set<std::string> _modelNames;
31  unsigned long _version; // API version
32  void (*_onClose)();
33  void (*_setThreadPoolDisabled)(int);
34  int (*_isThreadPoolDisabled)();
35  void (*_setThreads)(unsigned int);
36  unsigned int (*_getThreads)();
37  void (*_setSchedulerStrategy)(int);
38  int (*_getSchedulerStrategy)();
39  void (*_setThreadPoolVerbose)(int v);
40  int (*_isThreadPoolVerbose)();
41  void (*_setThreadPoolGuidedMaxWork)(float v);
42  float (*_getThreadPoolGuidedMaxWork)();
43  void (*_setThreadPoolNumberOfTimeMeas)(unsigned int n);
44  unsigned int (*_getThreadPoolNumberOfTimeMeas)();
45 public:
46 
47  inline FunctorModelLibrary(FunctorModelLibrary&& other) noexcept:
48  _modelNames(std::move(other._modelNames)),
49  _version(other._version),
50  _onClose(other._onClose),
51  _setThreadPoolDisabled(other._setThreadPoolDisabled),
52  _isThreadPoolDisabled(other._isThreadPoolDisabled),
53  _setThreads(other._setThreads),
54  _getThreads(other._getThreads),
55  _setSchedulerStrategy(other._setSchedulerStrategy),
56  _getSchedulerStrategy(other._getSchedulerStrategy),
57  _setThreadPoolVerbose(other._setThreadPoolVerbose),
58  _isThreadPoolVerbose(other._isThreadPoolVerbose),
59  _setThreadPoolGuidedMaxWork(other._setThreadPoolGuidedMaxWork),
60  _getThreadPoolGuidedMaxWork(other._getThreadPoolGuidedMaxWork),
61  _setThreadPoolNumberOfTimeMeas(other._setThreadPoolNumberOfTimeMeas),
62  _getThreadPoolNumberOfTimeMeas(other._getThreadPoolNumberOfTimeMeas) {
63  other._onClose = nullptr;
64  }
65 
66  std::set<std::string> getModelNames() override {
67  return _modelNames;
68  }
69 
78  virtual std::unique_ptr<FunctorGenericModel<Base>> modelFunctor(const std::string& modelName) = 0;
79 
80  std::unique_ptr<GenericModel<Base>> model(const std::string& modelName) override final {
81  return std::unique_ptr<GenericModel<Base>> (modelFunctor(modelName).release());
82  }
83 
89  virtual unsigned long getAPIVersion() {
90  return _version;
91  }
92 
106  virtual void* loadFunction(const std::string& functionName,
107  bool required = true) = 0;
108 
109  void setThreadPoolDisabled(bool disabled) override {
110  if(_setThreadPoolDisabled != nullptr) {
111  (*_setThreadPoolDisabled)(disabled);
112  }
113  }
114 
115  bool isThreadPoolDisabled() const override {
116  if(_isThreadPoolDisabled != nullptr) {
117  return bool((*_isThreadPoolDisabled)());
118  }
119  return true;
120  }
121 
122  unsigned int getThreadNumber() const override {
123  if (_getThreads != nullptr) {
124  return (*_getThreads)();
125  }
126  return 1;
127  }
128 
129  void setThreadNumber(unsigned int n) override {
130  if (_setThreads != nullptr) {
131  (*_setThreads)(n);
132  }
133  }
134 
135  ThreadPoolScheduleStrategy getThreadPoolSchedulerStrategy() const override {
136  if (_getSchedulerStrategy != nullptr) {
137  return ThreadPoolScheduleStrategy((*_getSchedulerStrategy)());
138  }
139  return ThreadPoolScheduleStrategy::DYNAMIC;
140  }
141 
142  void setThreadPoolSchedulerStrategy(ThreadPoolScheduleStrategy s) override {
143  if (_setSchedulerStrategy != nullptr) {
144  (*_setSchedulerStrategy)(int(s));
145  }
146  }
147 
148  void setThreadPoolVerbose(bool v) override {
149  if (_setThreadPoolVerbose != nullptr) {
150  (*_setThreadPoolVerbose)(int(v));
151  }
152  }
153 
154  bool isThreadPoolVerbose() const override {
155  if (_isThreadPoolVerbose != nullptr) {
156  return bool((*_isThreadPoolVerbose)());
157  }
158  return false;
159  }
160 
161  void setThreadPoolGuidedMaxWork(float v) override {
162  if (_setThreadPoolGuidedMaxWork != nullptr) {
163  (*_setThreadPoolGuidedMaxWork)(v);
164  }
165  }
166 
167  float getThreadPoolGuidedMaxWork() const override {
168  if (_getThreadPoolGuidedMaxWork != nullptr) {
169  return (*_getThreadPoolGuidedMaxWork)();
170  }
171  return 1.0;
172  }
173 
174  void setThreadPoolNumberOfTimeMeas(unsigned int n) override {
175  if (_setThreadPoolNumberOfTimeMeas != nullptr) {
176  (*_setThreadPoolNumberOfTimeMeas)(n);
177  }
178  }
179 
180  unsigned int getThreadPoolNumberOfTimeMeas() const override {
181  if (_getThreadPoolNumberOfTimeMeas != nullptr) {
182  return (*_getThreadPoolNumberOfTimeMeas)();
183  }
184  return 0;
185  }
186 
187  inline virtual ~FunctorModelLibrary() = default;
188 
189 protected:
191  _version(0), // not really required (but it avoids warnings)
192  _onClose(nullptr),
193  _setThreadPoolDisabled(nullptr),
194  _isThreadPoolDisabled(nullptr),
195  _setThreads(nullptr),
196  _getThreads(nullptr),
197  _setSchedulerStrategy(nullptr),
198  _getSchedulerStrategy(nullptr),
199  _setThreadPoolVerbose(nullptr),
200  _isThreadPoolVerbose(nullptr),
201  _setThreadPoolGuidedMaxWork(nullptr),
202  _getThreadPoolGuidedMaxWork(nullptr),
203  _setThreadPoolNumberOfTimeMeas(nullptr),
204  _getThreadPoolNumberOfTimeMeas(nullptr) {
205  }
206 
207  inline void validate() {
211  unsigned long (*versionFunc)();
212  versionFunc = reinterpret_cast<decltype(versionFunc)> (loadFunction(ModelLibraryCSourceGen<Base>::FUNCTION_VERSION));
213 
214  _version = (*versionFunc)();
216  throw CGException("The API version of the dynamic library (", _version,
217  ") is incompatible with the current version (",
219 
223  void (*modelsFunc)(char const *const**, int*);
224  modelsFunc = reinterpret_cast<decltype(modelsFunc)> (loadFunction(ModelLibraryCSourceGen<Base>::FUNCTION_MODELS));
225 
226  char const*const* model_names = nullptr;
227  int model_count;
228  (*modelsFunc)(&model_names, &model_count);
229 
230  for (int i = 0; i < model_count; i++) {
231  _modelNames.insert(model_names[i]);
232  }
233 
237  _onClose = reinterpret_cast<decltype(_onClose)> (loadFunction(ModelLibraryCSourceGen<Base>::FUNCTION_ONCLOSE, false));
238 
242  _setThreadPoolDisabled = reinterpret_cast<decltype(_setThreadPoolDisabled)> (loadFunction(ModelLibraryCSourceGen<Base>::FUNCTION_SETTHREADPOOLDISABLED, false));
243  _isThreadPoolDisabled = reinterpret_cast<decltype(_isThreadPoolDisabled)> (loadFunction(ModelLibraryCSourceGen<Base>::FUNCTION_ISTHREADPOOLDISABLED, false));
244  _setThreads = reinterpret_cast<decltype(_setThreads)> (loadFunction(ModelLibraryCSourceGen<Base>::FUNCTION_SETTHREADS, false));
245  _getThreads = reinterpret_cast<decltype(_getThreads)> (loadFunction(ModelLibraryCSourceGen<Base>::FUNCTION_GETTHREADS, false));
246  _setSchedulerStrategy = reinterpret_cast<decltype(_setSchedulerStrategy)> (this->loadFunction(ModelLibraryCSourceGen<Base>::FUNCTION_SETTHREADSCHEDULERSTRAT, false));
247  _getSchedulerStrategy = reinterpret_cast<decltype(_getSchedulerStrategy)> (this->loadFunction(ModelLibraryCSourceGen<Base>::FUNCTION_GETTHREADSCHEDULERSTRAT, false));
248  _setThreadPoolVerbose = reinterpret_cast<decltype(_setThreadPoolVerbose)> (this->loadFunction(ModelLibraryCSourceGen<Base>::FUNCTION_SETTHREADPOOLVERBOSE, false));
249  _isThreadPoolVerbose = reinterpret_cast<decltype(_isThreadPoolVerbose)> (this->loadFunction(ModelLibraryCSourceGen<Base>::FUNCTION_ISTHREADPOOLVERBOSE, false));
250  _setThreadPoolGuidedMaxWork = reinterpret_cast<decltype(_setThreadPoolGuidedMaxWork)> (this->loadFunction(ModelLibraryCSourceGen<Base>::FUNCTION_SETTHREADPOOLGUIDEDMAXGROUPWORK, false));
251  _getThreadPoolGuidedMaxWork = reinterpret_cast<decltype(_getThreadPoolGuidedMaxWork)> (this->loadFunction(ModelLibraryCSourceGen<Base>::FUNCTION_GETTHREADPOOLGUIDEDMAXGROUPWORK, false));
252  _setThreadPoolNumberOfTimeMeas = reinterpret_cast<decltype(_setThreadPoolNumberOfTimeMeas)> (this->loadFunction(ModelLibraryCSourceGen<Base>::FUNCTION_SETTHREADPOOLNUMBEROFTIMEMEAS, false));
253  _getThreadPoolNumberOfTimeMeas = reinterpret_cast<decltype(_getThreadPoolNumberOfTimeMeas)> (this->loadFunction(ModelLibraryCSourceGen<Base>::FUNCTION_GETTHREADPOOLNUMBEROFTIMEMEAS, false));
254 
255  if(_setThreads != nullptr) {
256  (*_setThreads)(std::thread::hardware_concurrency());
257  }
258  }
259 };
260 
261 } // END cg namespace
262 } // END CppAD namespace
263 
264 #endif
void setThreadPoolNumberOfTimeMeas(unsigned int n) override
bool isThreadPoolDisabled() const override
virtual std::unique_ptr< FunctorGenericModel< Base > > modelFunctor(const std::string &modelName)=0
std::set< std::string > getModelNames() override
void setThreadPoolSchedulerStrategy(ThreadPoolScheduleStrategy s) override
unsigned int getThreadNumber() const override
void setThreadPoolDisabled(bool disabled) override
unsigned int getThreadPoolNumberOfTimeMeas() const override
void setThreadNumber(unsigned int n) override
virtual unsigned long getAPIVersion()
ThreadPoolScheduleStrategy getThreadPoolSchedulerStrategy() const override
std::unique_ptr< GenericModel< Base > > model(const std::string &modelName) override final
virtual void * loadFunction(const std::string &functionName, bool required=true)=0