SST 16.0.0
Structural Simulation Toolkit
elementinfo.h
1// Copyright 2009-2026 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-2026, 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_ELEMENTINFO_H
13#define SST_CORE_ELI_ELEMENTINFO_H
14
15#include "sst/core/eli/attributeInfo.h"
16#include "sst/core/eli/categoryInfo.h"
17#include "sst/core/eli/checkpointableInfo.h"
18#include "sst/core/eli/defaultInfo.h"
19#include "sst/core/eli/elementbuilder.h"
20#include "sst/core/eli/elibase.h"
21#include "sst/core/eli/interfaceInfo.h"
22#include "sst/core/eli/paramsInfo.h"
23#include "sst/core/eli/portsInfo.h"
24#include "sst/core/eli/profilePointInfo.h"
25#include "sst/core/eli/simpleInfo.h"
26#include "sst/core/eli/statsInfo.h"
27#include "sst/core/eli/subcompSlotInfo.h"
28#include "sst/core/sst_types.h"
29#include "sst/core/warnmacros.h"
30
31#include <map>
32#include <ostream>
33#include <string>
34#include <vector>
35
36namespace SST {
37class Component;
38class Module;
39class SubComponent;
40class BaseComponent;
41class RealTimeAction;
42namespace Partition {
43class SSTPartitioner;
44}
45namespace Statistics {
46template <class T>
47class Statistic;
48class StatisticBase;
49} // namespace Statistics
50class RankInfo;
52
53/****************************************************
54 Base classes for templated documentation classes
55*****************************************************/
56
57namespace ELI {
58
59template <class T>
61{
62public:
63 static T* get(const std::string& elemlib, const std::string& elem)
64 {
65 auto libiter = infos().find(elemlib);
66 if ( libiter != infos().end() ) {
67 auto& submap = libiter->second;
68 auto elemiter = submap.find(elem);
69 if ( elemiter != submap.end() ) {
70 return elemiter->second;
71 }
72 }
73 return nullptr;
74 }
75
76 static void add(const std::string& elemlib, const std::string& elem, T* info) { infos()[elemlib][elem] = info; }
77
78private:
79 static std::map<std::string, std::map<std::string, T*>>& infos()
80 {
81 static std::map<std::string, std::map<std::string, T*>> infos_;
82 return infos_;
83 }
84};
85
86template <class Policy, class... Policies>
87class BuilderInfoImpl : public Policy, public BuilderInfoImpl<Policies...>
88{
89 using Parent = BuilderInfoImpl<Policies...>;
90
91public:
92 template <class... Args>
93 BuilderInfoImpl(const std::string& elemlib, const std::string& elem, Args&&... args) :
94 Policy(args...),
95 Parent(elemlib, elem, args...) // forward as l-values
96 {
97 DataBase<Policy>::add(elemlib, elem, this);
98 }
99
100 template <class XMLNode>
101 void outputXML(XMLNode* node)
102 {
103 Policy::outputXML(node);
104 Parent::outputXML(node);
105 }
106
107 void toString(std::ostream& os) const
108 {
109 Policy::toString(os);
110 Parent::toString(os);
111 }
112
113 BuilderInfoImpl(const BuilderInfoImpl&) = delete;
114 BuilderInfoImpl& operator=(const BuilderInfoImpl&) = delete;
115};
116
117template <>
118class BuilderInfoImpl<void>
119{
120protected:
121 template <class... Args>
122 explicit BuilderInfoImpl(Args&&... UNUSED(args))
123 {}
124
125 template <class XMLNode>
126 void outputXML(XMLNode* UNUSED(node))
127 {}
128
129 void toString(std::ostream& UNUSED(os)) const {}
130
131 BuilderInfoImpl(const BuilderInfoImpl&) = delete;
132 BuilderInfoImpl& operator=(const BuilderInfoImpl&) = delete;
133};
134
135template <class Base>
136class InfoLibrary
137{
138public:
139 using BaseInfo = typename Base::BuilderInfo;
140
141 explicit InfoLibrary(const std::string& name) :
142 name_(name)
143 {}
144
145 BaseInfo* getInfo(const std::string& name)
146 {
147 auto iter = infos_.find(name);
148 if ( iter == infos_.end() ) {
149 return nullptr;
150 }
151 else {
152 return iter->second;
153 }
154 }
155
156 bool hasInfo(const std::string& name) const { return infos_.find(name) != infos_.end(); }
157
158 int numEntries(bool exclude_aliases = false) const
159 {
160 if ( !exclude_aliases ) return infos_.size();
161 int count = 0;
162 for ( auto x : infos_ ) {
163 if ( x.first != x.second->getAlias() ) ++count;
164 }
165 return count;
166 }
167
168 const std::map<std::string, BaseInfo*>& getMap() const { return infos_; }
169
170 void readdInfo(const std::string& name, BaseInfo* info)
171 {
172 infos_[name] = info;
173
174 // Add the alias
175 const std::string& alias = info->getAlias();
176 if ( !alias.empty() ) infos_[alias] = info;
177 }
178
179 bool addInfo(const std::string& elem, BaseInfo* info)
180 {
181 readdInfo(elem, info);
182 // dlopen might thrash this later - add a loader to put it back in case
183 addLoader(name_, elem, info);
184 return true;
185 }
186
187private:
188 void addLoader(const std::string& lib, const std::string& name, BaseInfo* info);
189
190 std::map<std::string, BaseInfo*> infos_;
191
192 std::string name_;
193};
194
195template <class Base>
197{
198public:
199 using Library = InfoLibrary<Base>;
200 using BaseInfo = typename Library::BaseInfo;
201 using Map = std::map<std::string, Library*>;
202
203 static std::vector<std::string> getRegisteredElementNames()
204 {
205 // Need to pull out all the elements from the libraries that
206 // have an element of this type
207
208 std::vector<std::string> ret;
209 // First iterate over libraries
210 for ( auto& [name, lib] : libraries() ) {
211 for ( auto& [elemlib, info] : lib->getMap() ) {
212 ret.push_back(name + "." + elemlib);
213 }
214 }
215 return ret;
216 }
217
218 static Library* getLibrary(const std::string& name)
219 {
220 auto& lib = libraries()[name];
221 if ( !lib ) lib = new Library(name);
222 return lib;
223 }
224
225private:
226 // Database
227 static Map& libraries()
228 {
229 static Map libs;
230 return libs;
231 }
232};
233
234template <class Base, class Info>
235struct InfoLoader : public LibraryLoader
236{
237 InfoLoader(const std::string& elemlib, const std::string& elem, Info* info) :
238 elemlib_(elemlib),
239 elem_(elem),
240 info_(info)
241 {}
242
243 void load() override
244 {
245 auto* lib = InfoLibraryDatabase<Base>::getLibrary(elemlib_);
246 if ( !lib->hasInfo(elem_) ) {
247 lib->readdInfo(elem_, info_);
248 }
249 }
250
251private:
252 std::string elemlib_;
253 std::string elem_;
254 Info* info_;
255
256 InfoLoader(const InfoLoader&) = delete;
257 InfoLoader& operator=(const InfoLoader&) = delete;
258};
259
260template <class Base>
261void
262InfoLibrary<Base>::addLoader(const std::string& elemlib, const std::string& elem, BaseInfo* info)
263{
264 auto loader = new InfoLoader<Base, BaseInfo>(elemlib, elem, info);
265 LoadedLibraries::addLoader(elemlib, elem, info->getAlias(), loader);
266}
267
268template <class Base>
270{
271 static InfoLibrary<Base>* getLibrary(const std::string& name)
272 {
273 return InfoLibraryDatabase<Base>::getLibrary(name);
274 }
275
276 template <class T>
277 static bool add()
278 {
279 return Base::template addDerivedInfo<T>(T::ELI_getLibrary(), T::ELI_getName());
280 }
281};
282
283template <class Base, class T>
285{
286 static bool isLoaded() { return loaded; }
287
288 static inline const bool loaded = ElementsInfo<Base>::template add<T>();
289};
290
292{
293 template <class T>
294 static InfoLibrary<T>* getLibrary(const std::string& name)
295 {
296 return InfoLibraryDatabase<T>::getLibrary(name);
297 }
298
299 template <class T>
300 static std::vector<std::string> getRegisteredElementNames()
301 {
302 return InfoLibraryDatabase<T>::getRegisteredElementNames();
303 }
304};
305
306void force_instantiate_bool(bool b, const char* name);
307
308template <class T>
310{
311 static bool ELI_isLoaded() { return T::ELI_isLoaded(); }
312};
313
314} // namespace ELI
315
316/**************************************************************************
317 Class and constexpr functions to extract integers from version number.
318**************************************************************************/
319
321{
322 const unsigned major;
323 const unsigned minor;
324 const unsigned tertiary;
325
326 constexpr unsigned getMajor() const { return major; }
327 constexpr unsigned getMinor() const { return minor; }
328 constexpr unsigned getTertiary() const { return tertiary; }
329};
330
331constexpr unsigned
332SST_ELI_getMajorNumberFromVersion(SST_ELI_element_version_extraction ver)
333{
334 return ver.getMajor();
335}
336
337constexpr unsigned
338SST_ELI_getMinorNumberFromVersion(SST_ELI_element_version_extraction ver)
339{
340 return ver.getMinor();
341}
342
343constexpr unsigned
344SST_ELI_getTertiaryNumberFromVersion(SST_ELI_element_version_extraction ver)
345{
346 return ver.getTertiary();
347}
348
349/**************************************************************************
350 Macros used by elements to add element documentation
351**************************************************************************/
352
353#define SST_ELI_DECLARE_INFO(...) \
354 using BuilderInfo = ::SST::ELI::BuilderInfoImpl<__VA_ARGS__, SST::ELI::ProvidesDefaultInfo, void>; \
355 static bool addInfo(const std::string& elemlib, const std::string& elem, BuilderInfo* info) \
356 { \
357 return ::SST::ELI::InfoDatabase::getLibrary<__LocalEliBase>(elemlib)->addInfo(elem, info); \
358 } \
359 SST_ELI_DECLARE_INFO_COMMON()
360
361#define SST_ELI_DECLARE_DEFAULT_INFO() \
362 using BuilderInfo = ::SST::ELI::BuilderInfoImpl<SST::ELI::ProvidesDefaultInfo, void>; \
363 template <class BuilderImpl> \
364 static bool addInfo(const std::string& elemlib, const std::string& elem, BuilderImpl* info) \
365 { \
366 return ::SST::ELI::InfoDatabase::getLibrary<__LocalEliBase>(elemlib)->addInfo(elem, info); \
367 } \
368 SST_ELI_DECLARE_INFO_COMMON()
369
370#define SST_ELI_DECLARE_INFO_EXTERN(...) \
371 using BuilderInfo = ::SST::ELI::BuilderInfoImpl<SST::ELI::ProvidesDefaultInfo, __VA_ARGS__, void>; \
372 static bool addInfo(const std::string& elemlib, const std::string& elem, BuilderInfo* info); \
373 SST_ELI_DECLARE_INFO_COMMON()
374
375#define SST_ELI_DECLARE_DEFAULT_INFO_EXTERN() \
376 using BuilderInfo = ::SST::ELI::BuilderInfoImpl<SST::ELI::ProvidesDefaultInfo, void>; \
377 static bool addInfo(const std::string& elemlib, const std::string& elem, BuilderInfo* info); \
378 SST_ELI_DECLARE_INFO_COMMON()
379
380#define SST_ELI_DEFINE_INFO_EXTERN(base) \
381 bool base::addInfo(const std::string& elemlib, const std::string& elem, BuilderInfo* info) \
382 { \
383 return ::SST::ELI::InfoDatabase::getLibrary<__LocalEliBase>(elemlib)->addInfo(elem, info); \
384 }
385
386#define SST_ELI_EXTERN_DERIVED(base, cls, lib, name, version, desc) \
387 bool ELI_isLoaded(); \
388 SST_ELI_DEFAULT_INFO(lib, name, ELI_FORWARD_AS_ONE(version), desc)
389
390// The Intel compilers do not correctly instantiate symbols
391// even though they are required. We have to force the instantiation
392// in source files, header files are not good enough
393// we do this by creating a static bool that produces an undefined ref
394// if the instantiate macro is missing in a source file
395#ifdef __INTEL_COMPILER
396#define SST_ELI_FORCE_INSTANTIATION(base, cls) \
397 template <class T> \
398 struct ELI_ForceRegister \
399 { \
400 ELI_ForceRegister() \
401 { \
402 bool b = SST::ELI::InstantiateBuilder<base, cls>::isLoaded() && \
403 SST::ELI::InstantiateBuilderInfo<base, cls>::isLoaded(); \
404 SST::ELI::force_instantiate_bool(b, #cls); \
405 } \
406 }; \
407 ELI_ForceRegister<cls> force_instantiate;
408// if the implementation is entirely in a C++ file
409// the Intel compiler will not generate any code because
410// it none of the symbols can be observed by other files
411// this forces the Intel compiler to export symbols self-contained in a C++ file
412#define SST_ELI_EXPORT(cls) template class SST::ELI::ForceExport<cls>;
413#else
414#define SST_ELI_FORCE_INSTANTIATION(base, cls)
415#define SST_ELI_EXPORT(cls)
416#endif
417
418// This call needs to be made for classes that will acually be
419// instanced, as opposed to only be declared as an API (using
420// SST_ELI_DECLARE_BASE or SST_ELI_DECLARE_NEW_BASE). This class will
421// inherit the ELI information from it's parent ELI API classes (the
422// informatin in the parent APIs will be added to the ELI declared in
423// this class. Any local information will overwrite any inherited
424// information. See comment for SST_ELI_DECLARE_BASE in elibase.h for
425// info on how __EliDerivedLevel is used.
426#define SST_ELI_REGISTER_DERIVED(base, cls, lib, name, version, desc) \
427 [[maybe_unused]] \
428 static constexpr int __EliDerivedLevel = std::is_same_v<base, cls> ? __EliBaseLevel : __EliBaseLevel + 1; \
429 static bool ELI_isLoaded() \
430 { \
431 return SST::ELI::InstantiateBuilder<base, cls>::isLoaded() && \
432 SST::ELI::InstantiateBuilderInfo<base, cls>::isLoaded(); \
433 } \
434 SST_ELI_FORCE_INSTANTIATION(base, cls) \
435 SST_ELI_DEFAULT_INFO(lib, name, ELI_FORWARD_AS_ONE(version), desc)
436
437#define SST_ELI_REGISTER_EXTERN(base, cls) \
438 bool cls::ELI_isLoaded() \
439 { \
440 return SST::ELI::InstantiateBuilder<base, cls>::isLoaded() && \
441 SST::ELI::InstantiateBuilderInfo<base, cls>::isLoaded(); \
442 }
443
444} // namespace SST
445
446#endif // SST_CORE_ELI_ELEMENTINFO_H
Main component object for the simulation.
Definition baseComponent.h:67
Main component object for the simulation.
Definition component.h:32
Definition elementinfo.h:61
Definition elementinfo.h:197
Definition elementinfo.h:137
Module is a tag class used with the loadModule function.
Definition module.h:26
Base class for Partitioning graphs.
Definition sstpart.h:32
Definition rankInfo.h:24
An event to trigger at a real-time interval.
Definition realtimeAction.h:32
Base class for python modules in element libraries.
Definition element_python.h:133
Forms the base class for statistics gathering within SST.
Definition statbase.h:51
Forms the template defined base class for statistics gathering within SST.
Definition statbase.h:369
SubComponent is a class loadable through the factory which allows dynamic functionality to be added t...
Definition subcomponent.h:29
Definition elementinfo.h:270
Definition elementinfo.h:310
Definition elementinfo.h:292
Definition elementinfo.h:236
Definition elementinfo.h:285
Definition elibase.h:125
Definition elementinfo.h:321