SST  10.1.0
StructuralSimulationToolkit
elementinfo.h
1 // Copyright 2009-2020 NTESS. Under the terms
2 // of Contract DE-NA0003525 with NTESS, the U.S.
3 // Government retains certain rights in this software.
4 //
5 // Copyright (c) 2009-2020, NTESS
6 // All rights reserved.
7 //
8 // This file is part of the SST software package. For license
9 // information, see the LICENSE file in the top level directory of the
10 // distribution.
11 
12 #ifndef SST_CORE_ELEMENTINFO_H
13 #define SST_CORE_ELEMENTINFO_H
14 
15 #include "sst/core/sst_types.h"
16 #include "sst/core/warnmacros.h"
17 #include "sst/core/params.h"
18 
19 #include "sst/core/eli/paramsInfo.h"
20 #include "sst/core/eli/statsInfo.h"
21 #include "sst/core/eli/defaultInfo.h"
22 #include "sst/core/eli/portsInfo.h"
23 #include "sst/core/eli/subcompSlotInfo.h"
24 #include "sst/core/eli/interfaceInfo.h"
25 #include "sst/core/eli/categoryInfo.h"
26 #include "sst/core/eli/elementbuilder.h"
27 
28 #include <string>
29 #include <vector>
30 
31 #include "sst/core/eli/elibase.h"
32 
33 namespace SST {
34 class Component;
35 class Module;
36 class SubComponent;
37 class BaseComponent;
38 namespace Partition {
39 class SSTPartitioner;
40 }
41 namespace Statistics {
42 template <class T> class Statistic;
43 class StatisticBase;
44 }
45 class RankInfo;
47 
48 /****************************************************
49  Base classes for templated documentation classes
50 *****************************************************/
51 
52 namespace ELI {
53 
54 template <class T>
55 class DataBase {
56 public:
57  static T* get(const std::string& elemlib, const std::string& elem){
58  if (!infos_) return nullptr;
59 
60  auto libiter = infos_->find(elemlib);
61  if (libiter != infos_->end()){
62  auto& submap = libiter->second;
63  auto elemiter = submap.find(elem);
64  if (elemiter != submap.end()){
65  return elemiter->second;
66  }
67  }
68  return nullptr;
69  }
70 
71  static void add(const std::string& elemlib, const std::string& elem, T* info){
72  if (!infos_){
73  infos_ = std::unique_ptr<std::map<std::string, std::map<std::string, T*>>>(
74  new std::map<std::string, std::map<std::string, T*>>);
75  }
76 
77  (*infos_)[elemlib][elem] = info;
78  }
79 
80 private:
81  static std::unique_ptr<std::map<std::string, std::map<std::string, T*>>> infos_;
82 };
83 template <class T> std::unique_ptr<std::map<std::string,std::map<std::string,T*>>> DataBase<T>::infos_;
84 
85 
86 template <class Policy, class... Policies>
87 class BuilderInfoImpl : public Policy, public BuilderInfoImpl<Policies...>
88 {
89  using Parent=BuilderInfoImpl<Policies...>;
90 public:
91  template <class... Args> BuilderInfoImpl(const std::string& elemlib,
92  const std::string& elem,
93  Args&&... args)
94  : Policy(args...), Parent(elemlib, elem, args...) //forward as l-values
95  {
96  DataBase<Policy>::add(elemlib,elem,this);
97  }
98 
99  template <class XMLNode> void outputXML(XMLNode* node){
100  Policy::outputXML(node);
101  Parent::outputXML(node);
102  }
103 
104  void toString(std::ostream& os) const {
105  Parent::toString(os);
106  Policy::toString(os);
107  }
108 };
109 
110 template <> class BuilderInfoImpl<void> {
111 protected:
112  template <class... Args> BuilderInfoImpl(Args&&... UNUSED(args))
113  {
114  }
115 
116  template <class XMLNode> void outputXML(XMLNode* UNUSED(node)){}
117 
118  void toString(std::ostream& UNUSED(os)) const {}
119 
120 };
121 
122 template <class Base, class T>
124  static bool isLoaded() {
125  return loaded;
126  }
127 
128  static const bool loaded;
129 };
130 
131 template <class Base> class InfoLibrary
132 {
133 public:
134  using BaseInfo = typename Base::BuilderInfo;
135 
136  InfoLibrary(const std::string& name) :
137  name_(name)
138  {
139  }
140 
141  BaseInfo* getInfo(const std::string& name) {
142  auto iter = infos_.find(name);
143  if (iter == infos_.end()){
144  return nullptr;
145  } else {
146  return iter->second;
147  }
148  }
149 
150  bool hasInfo(const std::string& name) const {
151  return infos_.find(name) != infos_.end();
152  }
153 
154  int numEntries() const {
155  return infos_.size();
156  }
157 
158  const std::map<std::string, BaseInfo*>& getMap() const {
159  return infos_;
160  }
161 
162  void readdInfo(const std::string& name, BaseInfo* info){
163  infos_[name] = info;
164  }
165 
166  bool addInfo(const std::string& elem, BaseInfo* info){
167  readdInfo(elem, info);
168  //dlopen might thrash this later - add a loader to put it back in case
169  addLoader(name_, elem, info);
170  return true;
171  }
172 
173 private:
174  void addLoader(const std::string& lib, const std::string& name, BaseInfo* info);
175 
176  std::map<std::string, BaseInfo*> infos_;
177 
178  std::string name_;
179 };
180 
181 template <class Base>
183 public:
185  using BaseInfo=typename Library::BaseInfo;
186  using Map=std::map<std::string,Library*>;
187 
188  static Library* getLibrary(const std::string& name){
189  if (!libraries){
190  libraries = new Map;
191  }
192  auto iter = libraries->find(name);
193  if (iter == libraries->end()){
194  auto* info = new Library(name);
195  (*libraries)[name] = info;
196  return info;
197  } else {
198  return iter->second;
199  }
200  }
201 
202 private:
203  // Database - needs to be a pointer for static init order
204  static Map* libraries;
205 };
206 
207 template <class Base> typename InfoLibraryDatabase<Base>::Map*
209 
210 template <class Base, class Info>
211 struct InfoLoader : public LibraryLoader {
212  InfoLoader(const std::string& elemlib,
213  const std::string& elem,
214  Info* info) :
215  elemlib_(elemlib), elem_(elem), info_(info)
216  {
217  }
218 
219  void load() override {
220  auto* lib = InfoLibraryDatabase<Base>::getLibrary(elemlib_);
221  if (!lib->hasInfo(elem_)){
222  lib->readdInfo(elem_, info_);
223  }
224  }
225  private:
226  std::string elemlib_;
227  std::string elem_;
228  Info* info_;
229 };
230 
231 template <class Base> void InfoLibrary<Base>::addLoader(const std::string& elemlib, const std::string& elem,
232  BaseInfo* info){
233  auto loader = new InfoLoader<Base,BaseInfo>(elemlib, elem, info);
234  LoadedLibraries::addLoader(elemlib, elem, loader);
235 }
236 
237 
238 template <class Base> struct ElementsInfo
239 {
240  static InfoLibrary<Base>* getLibrary(const std::string& name){
242  }
243 
244  template <class T> static bool add(){
245  return Base::template addDerivedInfo<T>(T::ELI_getLibrary(), T::ELI_getName());
246  }
247 };
248 template <class Base, class T> const bool InstantiateBuilderInfo<Base,T>::loaded
250 
251 
252 struct InfoDatabase {
253  template <class T>
254  static InfoLibrary<T>* getLibrary(const std::string& name){
256  }
257 };
258 
259 void force_instantiate_bool(bool b, const char* name);
260 
261 template <class T> struct ForceExport {
262  static bool ELI_isLoaded() {
263  return T::ELI_isLoaded();
264  }
265 };
266 
267 } //namespace ELI
268 
269 
270 /**************************************************************************
271  Class and constexpr functions to extract integers from version number.
272 **************************************************************************/
273 
275  const unsigned major;
276  const unsigned minor;
277  const unsigned tertiary;
278 
279  constexpr unsigned getMajor() const { return major; }
280  constexpr unsigned getMinor() const { return minor; }
281  constexpr unsigned getTertiary() const { return tertiary; }
282 };
283 
284 constexpr unsigned SST_ELI_getMajorNumberFromVersion(SST_ELI_element_version_extraction ver) {
285  return ver.getMajor();
286 }
287 
288 constexpr unsigned SST_ELI_getMinorNumberFromVersion(SST_ELI_element_version_extraction ver) {
289  return ver.getMinor();
290 }
291 
292 constexpr unsigned SST_ELI_getTertiaryNumberFromVersion(SST_ELI_element_version_extraction ver) {
293  return ver.getTertiary();
294 }
295 
296 
297 /**************************************************************************
298  Macros used by elements to add element documentation
299 **************************************************************************/
300 
301 #define SST_ELI_DECLARE_INFO(...) \
302  using BuilderInfo = ::SST::ELI::BuilderInfoImpl<__VA_ARGS__,SST::ELI::ProvidesDefaultInfo,void>; \
303  template <class BuilderImpl> static bool addInfo(const std::string& elemlib, const std::string& elem, \
304  BuilderImpl* info){ \
305  return ::SST::ELI::InfoDatabase::getLibrary<__LocalEliBase>(elemlib)->addInfo(elem,info); \
306  } \
307  SST_ELI_DECLARE_INFO_COMMON()
308 
309 
310 #define SST_ELI_DECLARE_DEFAULT_INFO() \
311  using BuilderInfo = ::SST::ELI::BuilderInfoImpl<SST::ELI::ProvidesDefaultInfo,void>; \
312  template <class BuilderImpl> static bool addInfo(const std::string& elemlib, const std::string& elem, \
313  BuilderImpl* info){ \
314  return ::SST::ELI::InfoDatabase::getLibrary<__LocalEliBase>(elemlib)->addInfo(elem,info); \
315  } \
316  SST_ELI_DECLARE_INFO_COMMON()
317 
318 
319 #define SST_ELI_DECLARE_INFO_EXTERN(...) \
320  using BuilderInfo = ::SST::ELI::BuilderInfoImpl<SST::ELI::ProvidesDefaultInfo,__VA_ARGS__,void>; \
321  static bool addInfo(const std::string& elemlib, const std::string& elem, BuilderInfo* info); \
322  SST_ELI_DECLARE_INFO_COMMON()
323 
324 #define SST_ELI_DECLARE_DEFAULT_INFO_EXTERN() \
325  using BuilderInfo = ::SST::ELI::BuilderInfoImpl<SST::ELI::ProvidesDefaultInfo,void>; \
326  static bool addInfo(const std::string& elemlib, const std::string& elem, BuilderInfo* info); \
327  SST_ELI_DECLARE_INFO_COMMON()
328 
329 #define SST_ELI_DEFINE_INFO_EXTERN(base) \
330  bool base::addInfo(const std::string& elemlib, const std::string& elem, BuilderInfo* info){ \
331  return ::SST::ELI::InfoDatabase::getLibrary<__LocalEliBase>(elemlib)->addInfo(elem,info); \
332  }
333 
334 #define SST_ELI_EXTERN_DERIVED(base,cls,lib,name,version,desc) \
335  bool ELI_isLoaded(); \
336  SST_ELI_DEFAULT_INFO(lib,name,ELI_FORWARD_AS_ONE(version),desc)
337 
338 // The Intel compilers do not correctly instantiate symbols
339 // even though they are required. We have to force the instantiation
340 // in source files, header files are not good enough
341 // we do this by creating a static bool that produces an undefined ref
342 // if the instantiate macro is missing in a source file
343 #ifdef __INTEL_COMPILER
344 #define SST_ELI_FORCE_INSTANTIATION(base,cls) \
345  template <class T> \
346  struct ELI_ForceRegister { \
347  ELI_ForceRegister(){ \
348  bool b = SST::ELI::InstantiateBuilder<base,cls>::isLoaded() \
349  && SST::ELI::InstantiateBuilderInfo<base,cls>::isLoaded(); \
350  SST::ELI::force_instantiate_bool(b, #cls); \
351  } \
352  }; \
353  ELI_ForceRegister<cls> force_instantiate;
354 // if the implementation is entirely in a C++ file
355 // the Intel compiler will not generate any code because
356 // it none of the symbols can be observed by other files
357 // this forces the Intel compiler to export symbols self-contained in a C++ file
358 #define SST_ELI_EXPORT(cls) \
359  template class SST::ELI::ForceExport<cls>;
360 #else
361 #define SST_ELI_FORCE_INSTANTIATION(base,cls)
362 #define SST_ELI_EXPORT(cls)
363 #endif
364 
365 
366 #define SST_ELI_REGISTER_DERIVED(base,cls,lib,name,version,desc) \
367  static bool ELI_isLoaded() { \
368  return SST::ELI::InstantiateBuilder<base,cls>::isLoaded() \
369  && SST::ELI::InstantiateBuilderInfo<base,cls>::isLoaded(); \
370  } \
371  SST_ELI_FORCE_INSTANTIATION(base,cls) \
372  SST_ELI_DEFAULT_INFO(lib,name,ELI_FORWARD_AS_ONE(version),desc)
373 
374 #define SST_ELI_REGISTER_EXTERN(base,cls) \
375  bool cls::ELI_isLoaded(){ \
376  return SST::ELI::InstantiateBuilder<base,cls>::isLoaded() \
377  && SST::ELI::InstantiateBuilderInfo<base,cls>::isLoaded(); \
378  }
379 
380 
381 } //namespace SST
382 
383 #endif // SST_CORE_ELEMENTINFO_H
Definition: elementinfo.h:211
Forms the base class for statistics gathering within SST.
Definition: statbase.h:64
Definition: elementinfo.h:123
Definition: elementinfo.h:252
Forms the template defined base class for statistics gathering within SST.
Definition: elementinfo.h:42
Definition: elementinfo.h:182
Definition: elementinfo.h:238
Definition: elementinfo.h:87
Definition: elementinfo.h:261
Definition: elibase.h:107
Definition: elementinfo.h:131
Definition: rankInfo.h:21
Definition: elementinfo.h:274
Definition: elementinfo.h:55
Base class for python modules in element libraries.
Definition: element_python.h:133
static bool addLoader(const std::string &lib, const std::string &name, LibraryLoader *loader)
Definition: elibase.cc:29