SST  12.0.1
StructuralSimulationToolkit
elibase.h
1 // Copyright 2009-2022 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-2022, 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_ELI_ELIBASE_H
13 #define SST_CORE_ELI_ELIBASE_H
14 
15 #include "sst/core/sst_types.h"
16 
17 #include <cstring>
18 #include <functional>
19 #include <list>
20 #include <map>
21 #include <memory>
22 #include <set>
23 #include <string>
24 #include <vector>
25 
26 // Component Category Definitions
27 #define COMPONENT_CATEGORY_UNCATEGORIZED 0x00
28 #define COMPONENT_CATEGORY_PROCESSOR 0x01
29 #define COMPONENT_CATEGORY_MEMORY 0x02
30 #define COMPONENT_CATEGORY_NETWORK 0x04
31 #define COMPONENT_CATEGORY_SYSTEM 0x08
32 
33 namespace SST {
34 
35 /** Describes Statistics used by a Component.
36  */
38 {
39  const char* name; /*!< Name of the Statistic to be Enabled */
40  const char* description; /*!< Brief description of the Statistic */
41  const char* units; /*!< Units associated with this Statistic value */
42  const uint8_t enableLevel; /*!< Level to meet to enable statistic 0 = disabled */
43 };
44 
45 /** Describes Parameters to a Component.
46  */
48 {
49  const char* name; /*!< Name of the parameter */
50  const char* description; /*!< Brief description of the parameter (ie, what it controls) */
51  const char* defaultValue; /*!< Default value (if any) nullptr == required parameter with no default, "" == optional
52  parameter, blank default, "foo" == default value */
53 };
54 
55 /** Describes Ports that the Component can use
56  */
58 {
59  const char* name; /*!< Name of the port. Can contain %d for a dynamic port, also %(xxx)d for dynamic port with xxx
60  being the controlling component parameter */
61  const char* description; /*!< Brief description of the port (ie, what it is used for) */
62  const std::vector<std::string>
63  validEvents; /*!< List of fully-qualified event types that this Port expects to send or receive */
64 };
65 
67 {
68  const char* name;
69  const char* description;
70  const char* superclass;
71 };
72 
74 
75 namespace ELI {
76 
77 // Function used to combine the parent and child ELI information.
78 // This function only works for items that have a 'name' and a
79 // 'description' field (which is all of them at time of function
80 // writing). You can delete a parent't info by adding an entry in the
81 // child with the same name and a nullptr in the description. Each
82 // info item should include a macro of the format SST_ELI_DELETE_* to
83 // make this easy for the element library writer.
84 //
85 // The function creates a new vector and the uses vector::swap because
86 // the ElementInfo* classes have const data members so deleting from
87 // the vector does not compile (copy constructor is deleted).
88 template <typename T>
89 static void
90 combineEliInfo(std::vector<T>& base, std::vector<T>& add)
91 {
92  std::vector<T> combined;
93  // Add in any item that isn't already defined
94  for ( auto x : add ) {
95  bool add = true;
96  for ( auto y : base ) {
97  if ( !strcmp(x.name, y.name) ) {
98  add = false;
99  break;
100  }
101  }
102  if ( add ) combined.emplace_back(x);
103  }
104 
105  // Now add all the locals. We will skip any one that has nullptr
106  // in the description field
107  for ( auto x : base ) {
108  if ( x.description != nullptr ) { combined.emplace_back(x); }
109  }
110  base.swap(combined);
111 }
112 
113 template <class T>
115 {
116  using type = void;
117 };
118 
120 {
121  virtual void load() = 0;
122  virtual ~LibraryLoader() {}
123 };
124 
126 {
127 public:
128  using InfoMap = std::map<std::string, std::list<LibraryLoader*>>;
129  using LibraryMap = std::map<std::string, InfoMap>;
130 
131  static bool isLoaded(const std::string& name);
132 
133  /**
134  @return A boolean indicated successfully added
135  */
136  static bool addLoader(const std::string& lib, const std::string& name, LibraryLoader* loader);
137 
138  static const LibraryMap& getLoaders();
139 
140 private:
141  static std::unique_ptr<LibraryMap> loaders_;
142 };
143 
144 } // namespace ELI
145 } // namespace SST
146 
147 #define ELI_FORWARD_AS_ONE(...) __VA_ARGS__
148 
149 // This is the macro used to declare a class that will become the base
150 // class for classes that are to be loaded through the ELI.
151 
152 // The __EliBaseLevel and __EliDerivedLevel are used to determine the
153 // ELI parent API. If __EliDerivedLevel is greater than
154 // __EliBaseLevel, then the parent API type is stored in
155 // __LocalEliBase. If not, then the parent API is __ParentEliBase.
156 // In other words, the parent API is __LocalEliBase if, and only if,
157 // the class is a derived class (i.e., calls SST_ELI_REGISTER_DERIVED
158 // either directly or indirectly) and has not called
159 // SST_ELI_DECLARE_BASE or SST_ELI_DECLARE_NEW_BASE. If the class has
160 // called either of the *_BASE macros, then they are APIs and if you
161 // derive a class from it, then you need to use that class also as the
162 // ELI parent.
163 #define SST_ELI_DECLARE_BASE(Base) \
164  using __LocalEliBase = Base; \
165  using __ParentEliBase = void; \
166  static constexpr int __EliBaseLevel = 0; \
167  static constexpr int __EliDerivedLevel = 0; \
168  static const char* ELI_baseName() { return #Base; }
169 
170 #define SST_ELI_DECLARE_INFO_COMMON() \
171  using InfoLibrary = ::SST::ELI::InfoLibrary<__LocalEliBase>; \
172  template <class __TT> \
173  static bool addDerivedInfo(const std::string& lib, const std::string& elem) \
174  { \
175  return addInfo(lib, elem, new BuilderInfo(lib, elem, (__TT*)nullptr)); \
176  }
177 
178 // This macro can be used to declare a new base class that inherits
179 // from another base class. The ELI information will also be
180 // inherited (added to whatever the child class declares). Items in
181 // the child will overwrite items in the parent. See comment for
182 // combineEliInfo() for information about deleting items from the
183 // parent API.
184 #define SST_ELI_DECLARE_NEW_BASE(OldBase, NewBase) \
185  using __LocalEliBase = NewBase; \
186  using __ParentEliBase = OldBase; \
187  static constexpr int __EliBaseLevel = OldBase::__EliBaseLevel + 2; \
188  SST_ELI_DECLARE_INFO_COMMON() \
189  static const char* ELI_baseName() { return #NewBase; } \
190  template <class InfoImpl> \
191  static bool addInfo(const std::string& elemlib, const std::string& elem, InfoImpl* info) \
192  { \
193  return OldBase::addInfo(elemlib, elem, info) && \
194  ::SST::ELI::InfoDatabase::getLibrary<NewBase>(elemlib)->addInfo(elem, info); \
195  }
196 
197 #endif // SST_CORE_ELI_ELIBASE_H
Definition: elibase.h:125
Definition: elibase.h:66
const char * defaultValue
Definition: elibase.h:51
const char * description
Definition: elibase.h:50
Definition: elibase.h:114
Describes Statistics used by a Component.
Definition: elibase.h:37
Definition: elibase.h:119
const char * description
Definition: elibase.h:61
const char * name
Definition: elibase.h:49
const std::vector< std::string > validEvents
Definition: elibase.h:63
const char * name
Definition: elibase.h:39
Describes Parameters to a Component.
Definition: elibase.h:47
const char * description
Definition: elibase.h:40
const char * name
Definition: elibase.h:59
const uint8_t enableLevel
Definition: elibase.h:42
Describes Ports that the Component can use.
Definition: elibase.h:57
static bool addLoader(const std::string &lib, const std::string &name, LibraryLoader *loader)
Definition: elibase.cc:28
const char * units
Definition: elibase.h:41