SST  14.0.0
StructuralSimulationToolkit
elibase.h
1 // Copyright 2009-2024 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-2024, 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  const char* name;
76  const char* description;
77  const char* superclass;
78 };
79 
81 {
82  const char* name;
83  const char* value;
84 };
85 
86 namespace ELI {
87 
88 // Function used to combine the parent and child ELI information.
89 // This function only works for items that have a 'name' and a
90 // 'description' field (which is all of them at time of function
91 // writing). You can delete a parent's info by adding an entry in the
92 // child with the same name and a nullptr in the description. Each
93 // info item should include a macro of the format SST_ELI_DELETE_* to
94 // make this easy for the element library writer.
95 //
96 // The function creates a new vector and the uses vector::swap because
97 // the ElementInfo* classes have const data members so deleting from
98 // the vector does not compile (copy constructor is deleted).
99 template <typename T>
100 static void
101 combineEliInfo(std::vector<T>& base, std::vector<T>& add)
102 {
103  std::vector<T> combined;
104  // Add in any item that isn't already defined
105  for ( auto x : add ) {
106  bool add = true;
107  for ( auto y : base ) {
108  if ( !strcmp(x.name, y.name) ) {
109  add = false;
110  break;
111  }
112  }
113  if ( add ) combined.emplace_back(x);
114  }
115 
116  // Now add all the locals. We will skip any one that has nullptr
117  // in the description field
118  for ( auto x : base ) {
119  if ( x.description != nullptr ) { combined.emplace_back(x); }
120  }
121  base.swap(combined);
122 }
123 
124 // ELI combine function for Attributes which don't have a description
125 // field
126 void combineEliInfo(std::vector<ElementInfoAttribute>& base, std::vector<ElementInfoAttribute>& add);
127 
128 template <class T>
130 {
131  using type = void;
132 };
133 
135 {
136  virtual void load() = 0;
137  virtual ~LibraryLoader() {}
138 };
139 
141 {
142 public:
143  using InfoMap = std::map<std::string, std::list<LibraryLoader*>>;
144  using LibraryMap = std::map<std::string, InfoMap>;
145 
146  static bool isLoaded(const std::string& name);
147 
148  /**
149  @return A boolean indicated successfully added
150  */
151  static bool addLoader(const std::string& lib, const std::string& name, LibraryLoader* loader);
152 
153  static const LibraryMap& getLoaders();
154 
155 private:
156  static std::unique_ptr<LibraryMap> loaders_;
157 };
158 
159 } // namespace ELI
160 } // namespace SST
161 
162 #define ELI_FORWARD_AS_ONE(...) __VA_ARGS__
163 
164 // This is the macro used to declare a class that will become the base
165 // class for classes that are to be loaded through the ELI.
166 
167 // The __EliBaseLevel and __EliDerivedLevel are used to determine the
168 // ELI parent API. If __EliDerivedLevel is greater than
169 // __EliBaseLevel, then the parent API type is stored in
170 // __LocalEliBase. If not, then the parent API is __ParentEliBase.
171 // In other words, the parent API is __LocalEliBase if, and only if,
172 // the class is a derived class (i.e., calls SST_ELI_REGISTER_DERIVED
173 // either directly or indirectly) and has not called
174 // SST_ELI_DECLARE_BASE or SST_ELI_DECLARE_NEW_BASE. If the class has
175 // called either of the *_BASE macros, then they are APIs and if you
176 // derive a class from it, then you need to use that class also as the
177 // ELI parent.
178 #define SST_ELI_DECLARE_BASE(Base) \
179  using __LocalEliBase = Base; \
180  using __ParentEliBase = void; \
181  static constexpr int __EliBaseLevel = 0; \
182  static constexpr int __EliDerivedLevel = 0; \
183  static const char* ELI_baseName() { return #Base; }
184 
185 #define SST_ELI_DECLARE_INFO_COMMON() \
186  using InfoLibrary = ::SST::ELI::InfoLibrary<__LocalEliBase>; \
187  template <class __TT> \
188  static bool addDerivedInfo(const std::string& lib, const std::string& elem) \
189  { \
190  using BuilderInfo = typename __LocalEliBase::BuilderInfo; \
191  return addInfo(lib, elem, new BuilderInfo(lib, elem, (__TT*)nullptr)); \
192  }
193 
194 // This macro can be used to declare a new base class that inherits
195 // from another base class. The ELI information will also be
196 // inherited (added to whatever the child class declares). Items in
197 // the child will overwrite items in the parent. See comment for
198 // combineEliInfo() for information about deleting items from the
199 // parent API.
200 #define SST_ELI_DECLARE_NEW_BASE(OldBase, NewBase) \
201  using __LocalEliBase = NewBase; \
202  using __ParentEliBase = OldBase; \
203  static constexpr int __EliBaseLevel = OldBase::__EliBaseLevel + 2; \
204  SST_ELI_DECLARE_INFO_COMMON() \
205  static const char* ELI_baseName() { return #NewBase; } \
206  template <class InfoImpl> \
207  static bool addInfo(const std::string& elemlib, const std::string& elem, InfoImpl* info) \
208  { \
209  return OldBase::addInfo(elemlib, elem, info) && \
210  ::SST::ELI::InfoDatabase::getLibrary<NewBase>(elemlib)->addInfo(elem, info); \
211  }
212 
213 #endif // SST_CORE_ELI_ELIBASE_H
Definition: elibase.h:140
Definition: elibase.h:66
const char * defaultValue
Definition: elibase.h:51
const char * description
Definition: elibase.h:50
Definition: elibase.h:80
Definition: elibase.h:73
Definition: action.cc:18
Definition: elibase.h:129
Describes Statistics used by a Component.
Definition: elibase.h:37
Definition: elibase.h:134
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