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