SST  10.0.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 
234  auto loader = new InfoLoader<Base,BaseInfo>(elemlib, elem, info);
235  LoadedLibraries::addLoader(elemlib, elem, loader);
236 }
237 
238 
239 template <class Base> struct ElementsInfo
240 {
241  static InfoLibrary<Base>* getLibrary(const std::string& name){
243  }
244 
245  template <class T> static bool add(){
246  return Base::template addDerivedInfo<T>(T::ELI_getLibrary(), T::ELI_getName());
247  }
248 };
249 template <class Base, class T> const bool InstantiateBuilderInfo<Base,T>::loaded
251 
252 
253 struct InfoDatabase {
254  template <class T>
255  static InfoLibrary<T>* getLibrary(const std::string& name){
257  }
258 };
259 
260 } //namespace ELI
261 
262 
263 /**************************************************************************
264  Class and constexpr functions to extract integers from version number.
265 **************************************************************************/
266 
268  const unsigned major;
269  const unsigned minor;
270  const unsigned tertiary;
271 
272  constexpr unsigned getMajor() const { return major; }
273  constexpr unsigned getMinor() const { return minor; }
274  constexpr unsigned getTertiary() const { return tertiary; }
275 };
276 
277 constexpr unsigned SST_ELI_getMajorNumberFromVersion(SST_ELI_element_version_extraction ver) {
278  return ver.getMajor();
279 }
280 
281 constexpr unsigned SST_ELI_getMinorNumberFromVersion(SST_ELI_element_version_extraction ver) {
282  return ver.getMinor();
283 }
284 
285 constexpr unsigned SST_ELI_getTertiaryNumberFromVersion(SST_ELI_element_version_extraction ver) {
286  return ver.getTertiary();
287 }
288 
289 
290 /**************************************************************************
291  Macros used by elements to add element documentation
292 **************************************************************************/
293 
294 #define SST_ELI_DECLARE_INFO(...) \
295  using BuilderInfo = ::SST::ELI::BuilderInfoImpl<__VA_ARGS__,SST::ELI::ProvidesDefaultInfo,void>; \
296  template <class BuilderImpl> static bool addInfo(const std::string& elemlib, const std::string& elem, \
297  BuilderImpl* info){ \
298  return ::SST::ELI::InfoDatabase::getLibrary<__LocalEliBase>(elemlib)->addInfo(elem,info); \
299  } \
300  SST_ELI_DECLARE_INFO_COMMON()
301 
302 
303 #define SST_ELI_DECLARE_DEFAULT_INFO() \
304  using BuilderInfo = ::SST::ELI::BuilderInfoImpl<SST::ELI::ProvidesDefaultInfo,void>; \
305  template <class BuilderImpl> static bool addInfo(const std::string& elemlib, const std::string& elem, \
306  BuilderImpl* info){ \
307  return ::SST::ELI::InfoDatabase::getLibrary<__LocalEliBase>(elemlib)->addInfo(elem,info); \
308  } \
309  SST_ELI_DECLARE_INFO_COMMON()
310 
311 
312 #define SST_ELI_DECLARE_INFO_EXTERN(...) \
313  using BuilderInfo = ::SST::ELI::BuilderInfoImpl<SST::ELI::ProvidesDefaultInfo,__VA_ARGS__,void>; \
314  static bool addInfo(const std::string& elemlib, const std::string& elem, BuilderInfo* info); \
315  SST_ELI_DECLARE_INFO_COMMON()
316 
317 #define SST_ELI_DECLARE_DEFAULT_INFO_EXTERN() \
318  using BuilderInfo = ::SST::ELI::BuilderInfoImpl<SST::ELI::ProvidesDefaultInfo,void>; \
319  static bool addInfo(const std::string& elemlib, const std::string& elem, BuilderInfo* info); \
320  SST_ELI_DECLARE_INFO_COMMON()
321 
322 #define SST_ELI_DEFINE_INFO_EXTERN(base) \
323  bool base::addInfo(const std::string& elemlib, const std::string& elem, BuilderInfo* info){ \
324  return ::SST::ELI::InfoDatabase::getLibrary<__LocalEliBase>(elemlib)->addInfo(elem,info); \
325  }
326 
327 #define SST_ELI_EXTERN_DERIVED(base,cls,lib,name,version,desc) \
328  bool ELI_isLoaded(); \
329  SST_ELI_DEFAULT_INFO(lib,name,ELI_FORWARD_AS_ONE(version),desc)
330 
331 #define SST_ELI_REGISTER_DERIVED(base,cls,lib,name,version,desc) \
332  bool ELI_isLoaded() { \
333  return SST::ELI::InstantiateBuilder<base,cls>::isLoaded() \
334  && SST::ELI::InstantiateBuilderInfo<base,cls>::isLoaded(); \
335  } \
336  SST_ELI_DEFAULT_INFO(lib,name,ELI_FORWARD_AS_ONE(version),desc)
337 
338 #define SST_ELI_REGISTER_EXTERN(base,cls) \
339  bool cls::ELI_isLoaded(){ \
340  return SST::ELI::InstantiateBuilder<base,cls>::isLoaded() \
341  && SST::ELI::InstantiateBuilderInfo<base,cls>::isLoaded(); \
342  }
343 
344 
345 } //namespace SST
346 
347 #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:253
Forms the template defined base class for statistics gathering within SST.
Definition: elementinfo.h:42
Definition: elementinfo.h:182
Definition: elementinfo.h:239
Definition: elementinfo.h:87
Definition: elibase.h:107
Definition: elementinfo.h:131
Definition: rankInfo.h:21
Definition: elementinfo.h:267
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