SST  9.1.0
StructuralSimulationToolkit
elementinfo.h
1 // Copyright 2009-2019 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-2019, 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 #include <sst/core/statapi/statfieldinfo.h>
19 
20 #include <sst/core/eli/paramsInfo.h>
21 #include <sst/core/eli/statsInfo.h>
22 #include <sst/core/eli/defaultInfo.h>
23 #include <sst/core/eli/portsInfo.h>
24 #include <sst/core/eli/subcompSlotInfo.h>
25 #include <sst/core/eli/interfaceInfo.h>
26 #include <sst/core/eli/categoryInfo.h>
27 #include <sst/core/eli/elementbuilder.h>
28 
29 #include <string>
30 #include <vector>
31 
32 #include <sst/core/eli/elibase.h>
33 
34 namespace SST {
35 class Component;
36 class Module;
37 class SubComponent;
38 class BaseComponent;
39 namespace Partition {
40 class SSTPartitioner;
41 }
42 namespace Statistics {
43 template <class T> class Statistic;
44 class StatisticBase;
45 }
46 class RankInfo;
48 
49 /****************************************************
50  Base classes for templated documentation classes
51 *****************************************************/
52 
53 namespace ELI {
54 
55 template <class T>
56 class DataBase {
57 public:
58  static T* get(const std::string& elemlib, const std::string& elem){
59  if (!infos_) return nullptr;
60 
61  auto libiter = infos_->find(elemlib);
62  if (libiter != infos_->end()){
63  auto& submap = libiter->second;
64  auto elemiter = submap.find(elem);
65  if (elemiter != submap.end()){
66  return elemiter->second;
67  }
68  }
69  return nullptr;
70  }
71 
72  static void add(const std::string& elemlib, const std::string& elem, T* info){
73  if (!infos_){
74  infos_ = std::unique_ptr<std::map<std::string, std::map<std::string, T*>>>(
75  new std::map<std::string, std::map<std::string, T*>>);
76  }
77 
78  (*infos_)[elemlib][elem] = info;
79  }
80 
81 private:
82  static std::unique_ptr<std::map<std::string, std::map<std::string, T*>>> infos_;
83 };
84 template <class T> std::unique_ptr<std::map<std::string,std::map<std::string,T*>>> DataBase<T>::infos_;
85 
86 
87 template <class Policy, class... Policies>
88 class BuilderInfoImpl : public Policy, public BuilderInfoImpl<Policies...>
89 {
90  using Parent=BuilderInfoImpl<Policies...>;
91 public:
92  template <class... Args> BuilderInfoImpl(const std::string& elemlib,
93  const std::string& elem,
94  Args&&... args)
95  : Policy(args...), Parent(elemlib, elem, args...) //forward as l-values
96  {
97  DataBase<Policy>::add(elemlib,elem,this);
98  }
99 
100  template <class XMLNode> void outputXML(XMLNode* node){
101  Policy::outputXML(node);
102  Parent::outputXML(node);
103  }
104 
105  void toString(std::ostream& os) const {
106  Parent::toString(os);
107  Policy::toString(os);
108  }
109 };
110 
111 template <> class BuilderInfoImpl<void> {
112 protected:
113  template <class... Args> BuilderInfoImpl(Args&&... UNUSED(args))
114  {
115  }
116 
117  template <class XMLNode> void outputXML(XMLNode* UNUSED(node)){}
118 
119  void toString(std::ostream& UNUSED(os)) const {}
120 
121 };
122 
123 template <class Base, class T>
125  static bool isLoaded() {
126  return loaded;
127  }
128 
129  static const bool loaded;
130 };
131 
132 template <class Base> class InfoLibrary
133 {
134 public:
135  using BaseInfo = typename Base::BuilderInfo;
136 
137  InfoLibrary(const std::string& name) :
138  name_(name)
139  {
140  }
141 
142  BaseInfo* getInfo(const std::string& name) {
143  auto iter = infos_.find(name);
144  if (iter == infos_.end()){
145  return nullptr;
146  } else {
147  return iter->second;
148  }
149  }
150 
151  bool hasInfo(const std::string& name) const {
152  return infos_.find(name) != infos_.end();
153  }
154 
155  int numEntries() const {
156  return infos_.size();
157  }
158 
159  const std::map<std::string, BaseInfo*>& getMap() const {
160  return infos_;
161  }
162 
163  void readdInfo(const std::string& name, BaseInfo* info){
164  infos_[name] = info;
165  }
166 
167  bool addInfo(const std::string& elem, BaseInfo* info){
168  readdInfo(elem, info);
169  //dlopen might thrash this later - add a loader to put it back in case
170  addLoader(name_, elem, info);
171  return true;
172  }
173 
174 private:
175  void addLoader(const std::string& lib, const std::string& name, BaseInfo* info);
176 
177  std::map<std::string, BaseInfo*> infos_;
178 
179  std::string name_;
180 };
181 
182 template <class Base>
184 public:
186  using BaseInfo=typename Library::BaseInfo;
187  using Map=std::map<std::string,Library*>;
188 
189  static Library* getLibrary(const std::string& name){
190  if (!libraries){
191  libraries = new Map;
192  }
193  auto iter = libraries->find(name);
194  if (iter == libraries->end()){
195  auto* info = new Library(name);
196  (*libraries)[name] = info;
197  return info;
198  } else {
199  return iter->second;
200  }
201  }
202 
203 private:
204  // Database - needs to be a pointer for static init order
205  static Map* libraries;
206 };
207 
208 template <class Base> typename InfoLibraryDatabase<Base>::Map*
210 
211 template <class Base, class Info>
212 struct InfoLoader : public LibraryLoader {
213  InfoLoader(const std::string& elemlib,
214  const std::string& elem,
215  Info* info) :
216  elemlib_(elemlib), elem_(elem), info_(info)
217  {
218  }
219 
220  void load() override {
221  auto* lib = InfoLibraryDatabase<Base>::getLibrary(elemlib_);
222  if (!lib->hasInfo(elem_)){
223  lib->readdInfo(elem_, info_);
224  }
225  }
226  private:
227  std::string elemlib_;
228  std::string elem_;
229  Info* info_;
230 };
231 
232 template <class Base> void InfoLibrary<Base>::addLoader(const std::string& elemlib, const std::string& elem,
233  BaseInfo* info){
234 
235  auto loader = new InfoLoader<Base,BaseInfo>(elemlib, elem, info);
236  LoadedLibraries::addLoader(elemlib, elem, loader);
237 }
238 
239 
240 template <class Base> struct ElementsInfo
241 {
242  static InfoLibrary<Base>* getLibrary(const std::string& name){
244  }
245 
246  template <class T> static bool add(){
247  return Base::template addDerivedInfo<T>(T::ELI_getLibrary(), T::ELI_getName());
248  }
249 };
250 template <class Base, class T> const bool InstantiateBuilderInfo<Base,T>::loaded
252 
253 
254 struct InfoDatabase {
255  template <class T>
256  static InfoLibrary<T>* getLibrary(const std::string& name){
258  }
259 };
260 
261 } //namespace ELI
262 
263 
264 /**************************************************************************
265  Class and constexpr functions to extract integers from version number.
266 **************************************************************************/
267 
269  const unsigned major;
270  const unsigned minor;
271  const unsigned tertiary;
272 
273  constexpr unsigned getMajor() { return major; }
274  constexpr unsigned getMinor() { return minor; }
275  constexpr unsigned getTertiary() { return tertiary; }
276 };
277 
278 constexpr unsigned SST_ELI_getMajorNumberFromVersion(SST_ELI_element_version_extraction ver) {
279  return ver.getMajor();
280 }
281 
282 constexpr unsigned SST_ELI_getMinorNumberFromVersion(SST_ELI_element_version_extraction ver) {
283  return ver.getMinor();
284 }
285 
286 constexpr unsigned SST_ELI_getTertiaryNumberFromVersion(SST_ELI_element_version_extraction ver) {
287  return ver.getTertiary();
288 }
289 
290 
291 /**************************************************************************
292  Macros used by elements to add element documentation
293 **************************************************************************/
294 
295 #define SST_ELI_DECLARE_INFO(...) \
296  using BuilderInfo = ::SST::ELI::BuilderInfoImpl<__VA_ARGS__,SST::ELI::ProvidesDefaultInfo,void>; \
297  template <class BuilderImpl> static bool addInfo(const std::string& elemlib, const std::string& elem, \
298  BuilderImpl* info){ \
299  return ::SST::ELI::InfoDatabase::getLibrary<__LocalEliBase>(elemlib)->addInfo(elem,info); \
300  } \
301  SST_ELI_DECLARE_INFO_COMMON()
302 
303 
304 #define SST_ELI_DECLARE_DEFAULT_INFO() \
305  using BuilderInfo = ::SST::ELI::BuilderInfoImpl<SST::ELI::ProvidesDefaultInfo,void>; \
306  template <class BuilderImpl> static bool addInfo(const std::string& elemlib, const std::string& elem, \
307  BuilderImpl* info){ \
308  return ::SST::ELI::InfoDatabase::getLibrary<__LocalEliBase>(elemlib)->addInfo(elem,info); \
309  } \
310  SST_ELI_DECLARE_INFO_COMMON()
311 
312 
313 #define SST_ELI_DECLARE_INFO_EXTERN(...) \
314  using BuilderInfo = ::SST::ELI::BuilderInfoImpl<SST::ELI::ProvidesDefaultInfo,__VA_ARGS__,void>; \
315  static bool addInfo(const std::string& elemlib, const std::string& elem, BuilderInfo* info); \
316  SST_ELI_DECLARE_INFO_COMMON()
317 
318 #define SST_ELI_DECLARE_DEFAULT_INFO_EXTERN() \
319  using BuilderInfo = ::SST::ELI::BuilderInfoImpl<SST::ELI::ProvidesDefaultInfo,void>; \
320  static bool addInfo(const std::string& elemlib, const std::string& elem, BuilderInfo* info); \
321  SST_ELI_DECLARE_INFO_COMMON()
322 
323 #define SST_ELI_DEFINE_INFO_EXTERN(base) \
324  bool base::addInfo(const std::string& elemlib, const std::string& elem, BuilderInfo* info){ \
325  return ::SST::ELI::InfoDatabase::getLibrary<__LocalEliBase>(elemlib)->addInfo(elem,info); \
326  }
327 
328 #define SST_ELI_EXTERN_DERIVED(base,cls,lib,name,version,desc) \
329  bool ELI_isLoaded(); \
330  SST_ELI_DEFAULT_INFO(lib,name,ELI_FORWARD_AS_ONE(version),desc)
331 
332 #define SST_ELI_REGISTER_DERIVED(base,cls,lib,name,version,desc) \
333  bool ELI_isLoaded() { \
334  return SST::ELI::InstantiateBuilder<base,cls>::isLoaded() \
335  && SST::ELI::InstantiateBuilderInfo<base,cls>::isLoaded(); \
336  } \
337  SST_ELI_DEFAULT_INFO(lib,name,ELI_FORWARD_AS_ONE(version),desc)
338 
339 #define SST_ELI_REGISTER_EXTERN(base,cls) \
340  bool cls::ELI_isLoaded(){ \
341  return SST::ELI::InstantiateBuilder<base,cls>::isLoaded() \
342  && SST::ELI::InstantiateBuilderInfo<base,cls>::isLoaded(); \
343  }
344 
345 
346 } //namespace SST
347 
348 #endif // SST_CORE_ELEMENTINFO_H
Definition: elementinfo.h:212
Forms the base class for statistics gathering within SST.
Definition: statbase.h:63
Definition: elementinfo.h:124
Definition: elementinfo.h:254
Forms the template defined base class for statistics gathering within SST.
Definition: elementinfo.h:43
Definition: elementinfo.h:183
Definition: elementinfo.h:240
Definition: elementinfo.h:88
Definition: elibase.h:107
Definition: elementinfo.h:132
Definition: rankInfo.h:21
Definition: elementinfo.h:268
Definition: elementinfo.h:56
Base class for python modules in element libraries.
Definition: element_python.h:126
static bool addLoader(const std::string &lib, const std::string &name, LibraryLoader *loader)
Definition: elibase.cc:32