SST 12.1.0
Structural Simulation Toolkit
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
33namespace 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
86namespace 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).
99template <typename T>
100static void
101combineEliInfo(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
126void combineEliInfo(std::vector<ElementInfoAttribute>& base, std::vector<ElementInfoAttribute>& add);
127
128template <class T>
130{
131 using type = void;
132};
133
135{
136 virtual void load() = 0;
137 virtual ~LibraryLoader() {}
138};
139
141{
142public:
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
155private:
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 return addInfo(lib, elem, new BuilderInfo(lib, elem, (__TT*)nullptr)); \
191 }
192
193// This macro can be used to declare a new base class that inherits
194// from another base class. The ELI information will also be
195// inherited (added to whatever the child class declares). Items in
196// the child will overwrite items in the parent. See comment for
197// combineEliInfo() for information about deleting items from the
198// parent API.
199#define SST_ELI_DECLARE_NEW_BASE(OldBase, NewBase) \
200 using __LocalEliBase = NewBase; \
201 using __ParentEliBase = OldBase; \
202 static constexpr int __EliBaseLevel = OldBase::__EliBaseLevel + 2; \
203 SST_ELI_DECLARE_INFO_COMMON() \
204 static const char* ELI_baseName() { return #NewBase; } \
205 template <class InfoImpl> \
206 static bool addInfo(const std::string& elemlib, const std::string& elem, InfoImpl* info) \
207 { \
208 return OldBase::addInfo(elemlib, elem, info) && \
209 ::SST::ELI::InfoDatabase::getLibrary<NewBase>(elemlib)->addInfo(elem, info); \
210 }
211
212#endif // SST_CORE_ELI_ELIBASE_H
Definition: elibase.h:141
static bool addLoader(const std::string &lib, const std::string &name, LibraryLoader *loader)
Definition: elibase.cc:28
Definition: elibase.h:135
Definition: elibase.h:130
Definition: elibase.h:81
Describes Parameters to a Component.
Definition: elibase.h:48
const char * name
Definition: elibase.h:49
const char * description
Definition: elibase.h:50
const char * defaultValue
Definition: elibase.h:51
Describes Ports that the Component can use.
Definition: elibase.h:58
const char * name
Definition: elibase.h:59
const char * description
Definition: elibase.h:61
const std::vector< std::string > validEvents
Definition: elibase.h:63
Definition: elibase.h:74
Describes Statistics used by a Component.
Definition: elibase.h:38
const char * name
Definition: elibase.h:39
const char * units
Definition: elibase.h:41
const uint8_t enableLevel
Definition: elibase.h:42
const char * description
Definition: elibase.h:40
Definition: elibase.h:67