SST 16.1.0
Structural Simulation Toolkit
baseComponent.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_BASECOMPONENT_H
13#define SST_CORE_BASECOMPONENT_H
14
15#include "sst/core/clock.h"
16#include "sst/core/componentInfo.h"
17#include "sst/core/eli/elementinfo.h"
18#include "sst/core/event.h"
19#include "sst/core/factory.h"
20#include "sst/core/portModule.h"
21#include "sst/core/profile/componentProfileTool.h"
22#include "sst/core/serialization/serializable_base.h"
23#include "sst/core/serialization/serialize.h"
24#include "sst/core/sst_types.h"
25#include "sst/core/statapi/statbase.h"
26#include "sst/core/statapi/statengine.h"
27#include "sst/core/timeConverter.h"
28#include "sst/core/warnmacros.h"
29
30#include <cstdarg>
31#include <cstdint>
32#include <functional>
33#include <map>
34#include <set>
35#include <string>
36#include <type_traits>
37#include <utility>
38#include <vector>
39
40using namespace SST::Statistics;
41
42namespace SST {
43
44class Component;
46class Clock;
47class Link;
48class LinkMap;
49class Module;
50class Params;
51class Simulation;
52class Simulation;
53class SubComponent;
55class TimeConverter;
56class UnitAlgebra;
57class WatchPoint;
58
59namespace Core::Serialization::pvt {
61}
62
63namespace pvt {
64
65/**
66 Extracts the owning class from a pointer-to-member-function type.
67 Used to infer classT for the registerClock()/registerOrderedClock()
68 and configureLink()/configureSelfLink() overloads that only require
69 funcT to be specified explicitly.
70*/
71template <typename T>
73
74template <typename classT, typename returnT, typename... Args>
75struct member_function_class<returnT (classT::*)(Args...)>
76{
77 using type = classT;
78};
79
80template <auto funcT>
81using member_function_class_t = typename member_function_class<decltype(funcT)>::type;
82
83/**
84 Restricts the handler-building overloads to calls where obj points to the class that owns funcT (or a class derived
85 from it). This keeps a string-literal timebase from being deduced as obj in the metadata overloads, and allows
86 handlers inherited from a base class.
87*/
88template <auto funcT, typename objT>
89using enable_if_handler_obj_t = std::enable_if_t<std::is_base_of_v<member_function_class_t<funcT>, objT>, int>;
90
91} // namespace pvt
92
93
94/**
95 * Main component object for the simulation.
96 */
98{
99
100 friend class Component;
101 friend class ComponentExtension;
102 friend class ComponentInfo;
103 friend class SubComponent;
104 friend class SubComponentSlotInfo;
105 friend class PortModule;
106
107protected:
108 using StatCreateFunction = std::function<Statistics::StatisticBase*(BaseComponent*,
109 Statistics::StatisticProcessingEngine*, const std::string& /*name*/, const std::string& /*sub_id*/, Params&)>;
110
111 BaseComponent() = default; // For serialization only
112
113public:
114 explicit BaseComponent(ComponentId_t id);
115 virtual ~BaseComponent();
116
117 BaseComponent(const BaseComponent&) = delete;
118 BaseComponent& operator=(const BaseComponent&) = delete;
119
120 /**
121 Gets the ELI type for this BaseComponent
122
123 @return ELI type as a string
124 */
125 const std::string& getType() const { return my_info_->getType(); }
126
127 /**
128 Get the unique component ID
129
130 @return ID of BaseComponent
131 */
132 inline ComponentId_t getId() const { return my_info_->id_; }
133
134 /**
135 Get the BaseComponent Statistic load level
136
137 @return Statistic load level of BaseComponent
138 */
139 inline uint8_t getStatisticLoadLevel() const { return my_info_->statLoadLevel; }
140
141 /**
142 Called when SIGINT or SIGTERM has been seen. Allows components opportunity to clean up external state.
143 */
144 virtual void emergencyShutdown() {}
145
146 /**
147 Get the name of the BaseComponent
148
149 @return BaseComponent's name
150 */
151 inline const std::string& getName() const { return my_info_->getName(); }
152
153 /**
154 Get the name of the parent Component for the Component tree. If called on a Component, returns the name of that
155 Component.
156
157 @return The name of the parent Component for the Component tree.
158 */
159 inline const std::string& getParentComponentName() const { return my_info_->getParentComponentName(); }
160
161 /**
162 Used during the init phase. The method will be called each phase of initialization. Initialization ends when no
163 components have sent any data.
164
165 @param phase Current phase number
166 */
167 virtual void init(unsigned int UNUSED(phase)) {}
168
169 /**
170 Used during the complete phase after the end of simulation. The method will be called each phase of
171 complete. Complete phase ends when no components have sent any data.
172
173 @param phase Current phase number
174 */
175 virtual void complete(unsigned int UNUSED(phase)) {}
176
177 /**
178 Called after all components have been constructed and initialization has completed, but before simulation time
179 has begun.
180 */
181 virtual void setup() {}
182
183 /**
184 Called after complete phase, but before objects are destroyed. A good place to print out statistics.
185 */
186 virtual void finish() {}
187
188 /** Currently unused function */
189 virtual bool Status() { return 0; }
190
191 /**
192 Called by the Simulation to request that the component print its current status. Useful for debugging.
193
194 @param out The Output class which should be used to print component status.
195 */
196 virtual void printStatus(Output& UNUSED(out)) {}
197
198 /**
199 Get the core timebase
200
201 @return Core timebase set at the beginning of the simulation. Returned as a UnitAlgebra
202 */
204
205 /**
206 Get the current simulation time as a cycle count
207
208 @return Current simulation cycle for the simulation
209 */
210 SimTime_t getCurrentSimCycle() const;
211
212 /**
213 Get the current priority
214
215 @return Current priority for the simulation
216 */
217 int getCurrentPriority() const;
218
219 /**
220 get the elapsed simulation time as a UnitAlgebra
221
222 @return Time in seconds as a UnitAlgebra
223 */
225
226 /**
227 Get the end simulation time as a cycle count
228
229 @return End simulation time as cycle count
230 */
231 SimTime_t getEndSimCycle() const;
232
233 /**
234 Get the end simulation time as a UnitAlgebra
235
236 @return End time in seconds as a UnitAlgebra
237 */
239
240 /**
241 Get this instance's parallel rank
242
243 @return Get the rank for this objects partition
244 */
245 RankInfo getRank() const;
246
247 /**
248 Get the number of parallel ranks in the simulation
249
250 @return Number of ranks in simulation
251 */
252 RankInfo getNumRanks() const;
253
254 /**
255 Get the default simulation Output class instance. Elements do not have to use this Output object and can create
256 their own to use instead.
257
258 @return Default Output object for this partition
259 */
260 static Output& getSimulationOutput();
261
262 /**
263 Return the simulated time since the simulation began in the default timebase
264
265 @return Current simulation time in units of the default timebase for the object
266 */
267 inline SimTime_t getCurrentSimTime() const { return getCurrentSimTime(my_info_->defaultTimeBase); }
268
269 /**
270 Get the simulated time since the simulation began in units specified by
271 the parameter.
272
273 @param tc TimeConverter specifying the units
274
275 @return Current time as a cycle count based on the provided timebase
276 */
277 SimTime_t getCurrentSimTime(TimeConverter base) const;
278
279 /**
280 Return the simulated time since the simulation began in the specified timebase.
281
282 NOTE: This version of getCurrentSimTime() can accept a timebase that is not normally representable because it is
283 smaller than the global timebase set by the user. If this happens, the underlying code will use UnitAlgebra to
284 compute the cycle count. Because UnitAlgebra is computationally intense, it is best to avoid this case during
285 the run loop of the simulation.
286
287 @param base Timebase frequency in SI Units
288
289 @return Current time as a cycle count based on the provided timebase
290
291 */
292 SimTime_t getCurrentSimTime(const std::string& base) const;
293
294 /**
295 Return the simulated time since the simulation began in the specified timebase
296
297 NOTE: This version of getCurrentSimTime() exists because both std::string and TimeConverter can be implicitly
298 created with a const char*. Having this implementation removes ambiguity and ensures that a const char* is
299 passed through the std::string version, which can accept timebases that are not representable with TimeConverter
300 due to being smaller than the global timebase.
301
302 @param base Timebase frequency in SI Units
303
304 @return Current time as a cycle count based on the provided timebase
305 */
306 SimTime_t getCurrentSimTime(const char* base) const { return getCurrentSimTime(std::string(base)); }
307
308 /**
309 Utility function to return the time since the simulation began in nanoseconds
310
311 @return Current time as a count of nanoseconds expired in the simulation
312 */
313 SimTime_t getCurrentSimTimeNano() const;
314
315 /**
316 Utility function to return the time since the simulation began in microseconds
317
318 @return Current time as a count of microseconds expired in the simulation
319 */
320 SimTime_t getCurrentSimTimeMicro() const;
321
322 /**
323 Utility function to return the time since the simulation began in milliseconds
324
325 @return Current time as a count of milliseconds expired in the simulation
326 */
327 SimTime_t getCurrentSimTimeMilli() const;
328
329 /**
330 Get the amount of real-time spent executing the run phase of the simulation.
331
332 @return Real time in seconds spent executing the run phase
333 */
334 double getRunPhaseElapsedRealTime() const;
335
336 /**
337 Get the amount of real-time spent executing the init phase of the simulation.
338
339 @return Real time in seconds spent executing the init phase
340 */
341 double getInitPhaseElapsedRealTime() const;
342
343 /**
344 Get the amount of real-time spent executing the complete phase of the simulation.
345
346 @return Real time in seconds spent executing the complete phase
347 */
348 double getCompletePhaseElapsedRealTime() const;
349
350
351 /**
352 Add a watch point to all handlers in the Component Tree
353 */
354 void addWatchPoint(WatchPoint* pt);
355
356 /**
357 Remove a watch point from all handlers in the Component Tree
358 */
360
361
362private:
363 /**
364 Recursively add Watch point to myself and all my children
365 */
366 void addWatchPointRecursive(WatchPoint* pt);
367
368 /**
369 Recursively removes a Watch point from myself and all my children
370 */
371 void removeWatchPointRecursive(WatchPoint* pt);
372
373 /**
374 This function is called by ComponentInfo after all SubComponents have been serialized. Currently only Component
375 uses this functionality to make sure SubComponents are serialized before serializing any ordered clock handlers.
376 */
377 virtual void serialize_final(SST::Core::Serialization::serializer& ser);
378
379
380protected:
381 /**
382 Check to see if the run mode was set to INIT
383
384 @return True if simulation run mode is set to INIT
385 */
386 bool isSimulationRunModeInit() const;
387
388 /**
389 Check to see if the run mode was set to RUN
390
391 @return True if simulation run mode is set to RUN
392 */
393 bool isSimulationRunModeRun() const;
394
395 /**
396 Check to see if the run mode was set to BOTH
397
398 @return True if simulation run mode is set to BOTH
399 */
400 bool isSimulationRunModeBoth() const;
401
402 /**
403 Returns the output directory of the simulation
404
405 @return Directory in which simulation outputs should be placed. Returns empty string if output directory not
406 set by user.
407 */
408 std::string& getOutputDirectory() const;
409
410 /**
411 Signifies that a library is required for this simulation. Causes the Factory to verify that the required library
412 is loaded.
413
414 NOTE: This function should rarely be required, as most dependencies are automatically detected in the simulator
415 core. However, if the component uses an event from another library that is not wholly defined in a header file,
416 this call may be required to ensure that all the code from the event is loaded. Similarly, if you use a class
417 from another library that does not have ELI information, this call may also be required to make sure all
418 dependencies are loaded.
419
420 @param name Name of library this BaseComponent depends on
421 */
422 void requireLibrary(const std::string& name);
423
424
425 /**
426 Determine if a port name is connected to any links
427
428 @param name Name of the port
429
430 @return True if port is connected, false otherwise
431 */
432 bool isPortConnected(const std::string& name) const;
433
434 /**
435 Configure a Link
436
437 @param name Port Name on which the link to configure is attached.
438
439 @param timebase Timebase of the link provided as either a std::string, SST::UnitAlgebra, or
440 SST::TimeConverter
441
442 @param handler Optional Handler to be called when an Event is received
443
444 @return A pointer to the configured link, or nullptr if an error occurred.
445 */
446 Link* configureLink(const std::string& name, TimeConverter timebase, Event::HandlerBase* handler = nullptr)
447 {
448 return configureLink_impl(name, timebase.getFactor(), handler);
449 }
450
451 /**
452 Configure a Link
453
454 @param name Port Name on which the link to configure is attached.
455
456 @param handler Optional Handler to be called when an Event is received
457
458 @return A pointer to the configured link, or nullptr if an error occurred.
459 */
460 Link* configureLink(const std::string& name, Event::HandlerBase* handler = nullptr);
461
462 /**
463 Configure a Link. This version builds the Event::Handler internally, so only funcT needs to be specified
464 explicitly.
465
466 @tparam funcT Function that should be called by the Event::Handler. Must be a member of classT (automatically
467 inferred) and specified as &<classT>::<name_of_function>.
468
469 @param name Port Name on which the link to configure is attached.
470
471 @param timebase Timebase of the link provided as either a std::string, SST::UnitAlgebra, or
472 SST::TimeConverter
473
474 @param obj Pointer to object that the handler function should be called on
475
476 @return A pointer to the configured link, or nullptr if an error occurred.
477 */
478 template <auto funcT, typename objT, pvt::enable_if_handler_obj_t<funcT, objT> = 0>
479 Link* configureLink(const std::string& name, TimeConverter timebase, objT* obj)
480 {
481 auto* handler = new Event::Handler<pvt::member_function_class_t<funcT>, funcT, void>(obj);
482 Link* link = configureLink(name, timebase, handler);
483 if ( nullptr == link ) delete handler;
484 return link;
485 }
486
487 /**
488 Configure a Link with metadata. This version builds the Event::Handler internally, so only funcT and dataT
489 need to be specified explicitly.
490
491 @tparam funcT Function that should be called by the Event::Handler. Must be a member of classT (automatically
492 inferred) and specified as &<classT>::<name_of_function>.
493
494 @tparam dataT Type of metadata to be passed to the handler function
495
496 @param name Port Name on which the link to configure is attached.
497
498 @param timebase Timebase of the link provided as either a std::string, SST::UnitAlgebra, or
499 SST::TimeConverter
500
501 @param obj Pointer to object that the handler function should be called on
502
503 @param data Metadata to associate with the handler
504
505 @return A pointer to the configured link, or nullptr if an error occurred.
506 */
507 template <auto funcT, typename dataT, typename objT, pvt::enable_if_handler_obj_t<funcT, objT> = 0>
508 Link* configureLink(const std::string& name, TimeConverter timebase, objT* obj, dataT data)
509 {
510 auto* handler = new Event::Handler<pvt::member_function_class_t<funcT>, funcT, dataT>(obj, data);
511 Link* link = configureLink(name, timebase, handler);
512 if ( nullptr == link ) delete handler;
513 return link;
514 }
515
516 /**
517 Configure a Link using the component's default timebase. This version builds the Event::Handler internally,
518 so only funcT needs to be specified explicitly.
519
520 @tparam funcT Function that should be called by the Event::Handler. Must be a member of classT (automatically
521 inferred) and specified as &<classT>::<name_of_function>.
522
523 @param name Port Name on which the link to configure is attached.
524
525 @param obj Pointer to object that the handler function should be called on
526
527 @return A pointer to the configured link, or nullptr if an error occurred.
528 */
529 template <auto funcT, typename objT, pvt::enable_if_handler_obj_t<funcT, objT> = 0>
530 Link* configureLink(const std::string& name, objT* obj)
531 {
532 auto* handler = new Event::Handler<pvt::member_function_class_t<funcT>, funcT, void>(obj);
533 Link* link = configureLink(name, handler);
534 if ( nullptr == link ) delete handler;
535 return link;
536 }
537
538 /**
539 Configure a Link with metadata, using the component's default timebase. This version builds the
540 Event::Handler internally, so only funcT and dataT need to be specified explicitly.
541
542 @tparam funcT Function that should be called by the Event::Handler. Must be a member of classT (automatically
543 inferred) and specified as &<classT>::<name_of_function>.
544
545 @tparam dataT Type of metadata to be passed to the handler function
546
547 @param name Port Name on which the link to configure is attached.
548
549 @param obj Pointer to object that the handler function should be called on
550
551 @param data Metadata to associate with the handler
552
553 @return A pointer to the configured link, or nullptr if an error occurred.
554 */
555 template <auto funcT, typename dataT, typename objT, pvt::enable_if_handler_obj_t<funcT, objT> = 0>
556 Link* configureLink(const std::string& name, objT* obj, dataT data)
557 {
558 auto* handler = new Event::Handler<pvt::member_function_class_t<funcT>, funcT, dataT>(obj, data);
559 Link* link = configureLink(name, handler);
560 if ( nullptr == link ) delete handler;
561 return link;
562 }
563
564 /**
565 Configure a SelfLink (Loopback link)
566
567 @param name Name of the self-link port
568
569 @param timebase Timebase of the link. Timebase can be a std::string, SST::UnitAlgebra or SST::TimeConverter
570
571 @param handler Optional Handler to be called when an Event is received
572
573 @return A pointer to the configured link, or nullptr if an error occurred.
574 */
575 Link* configureSelfLink(const std::string& name, TimeConverter timebase, Event::HandlerBase* handler = nullptr)
576 {
577 addSelfLink(name);
578 return configureLink(name, timebase, handler);
579 }
580
581
582 /**
583 Configure a SelfLink (Loopback link) that uses the (Sub)Component's defaultTimeBase
584
585 @param name Name of the self-link port
586
587 @param handler Optional Handler to be called when an Event is received
588
589 @return A pointer to the configured link, or nullptr if an error occurred.
590 */
591 Link* configureSelfLink(const std::string& name, Event::HandlerBase* handler = nullptr);
592
593 /**
594 Configure a SelfLink (Loopback link). This version builds the Event::Handler internally, so only funcT needs
595 to be specified explicitly.
596
597 @tparam funcT Function that should be called by the Event::Handler. Must be a member of classT (automatically
598 inferred) and specified as &<classT>::<name_of_function>.
599
600 @param name Name of the self-link port
601
602 @param timebase Timebase of the link. Timebase can be a std::string, SST::UnitAlgebra or SST::TimeConverter
603
604 @param obj Pointer to object that the handler function should be called on
605
606 @return A pointer to the configured link, or nullptr if an error occurred.
607 */
608 template <auto funcT, typename objT, pvt::enable_if_handler_obj_t<funcT, objT> = 0>
609 Link* configureSelfLink(const std::string& name, TimeConverter timebase, objT* obj)
610 {
611 addSelfLink(name);
612 return configureLink<funcT>(name, timebase, obj);
613 }
614
615 /**
616 Configure a SelfLink (Loopback link) with metadata. This version builds the Event::Handler internally, so
617 only funcT and dataT need to be specified explicitly.
618
619 @tparam funcT Function that should be called by the Event::Handler. Must be a member of classT (automatically
620 inferred) and specified as &<classT>::<name_of_function>.
621
622 @tparam dataT Type of metadata to be passed to the handler function
623
624 @param name Name of the self-link port
625
626 @param timebase Timebase of the link. Timebase can be a std::string, SST::UnitAlgebra or SST::TimeConverter
627
628 @param obj Pointer to object that the handler function should be called on
629
630 @param data Metadata to associate with the handler
631
632 @return A pointer to the configured link, or nullptr if an error occurred.
633 */
634 template <auto funcT, typename dataT, typename objT, pvt::enable_if_handler_obj_t<funcT, objT> = 0>
635 Link* configureSelfLink(const std::string& name, TimeConverter timebase, objT* obj, dataT data)
636 {
637 addSelfLink(name);
638 return configureLink<funcT, dataT>(name, timebase, obj, data);
639 }
640
641 /**
642 Configure a SelfLink (Loopback link) that uses the (Sub)Component's defaultTimeBase. This version builds the
643 Event::Handler internally, so only funcT needs to be specified explicitly.
644
645 @tparam funcT Function that should be called by the Event::Handler. Must be a member of classT (automatically
646 inferred) and specified as &<classT>::<name_of_function>.
647
648 @param name Name of the self-link port
649
650 @param obj Pointer to object that the handler function should be called on
651
652 @return A pointer to the configured link, or nullptr if an error occurred.
653 */
654 template <auto funcT, typename objT, pvt::enable_if_handler_obj_t<funcT, objT> = 0>
655 Link* configureSelfLink(const std::string& name, objT* obj)
656 {
657 addSelfLink(name);
658 return configureLink<funcT>(name, obj);
659 }
660
661 /**
662 Configure a SelfLink (Loopback link) with metadata, that uses the (Sub)Component's defaultTimeBase. This
663 version builds the Event::Handler internally, so only funcT and dataT need to be specified explicitly.
664
665 @tparam funcT Function that should be called by the Event::Handler. Must be a member of classT (automatically
666 inferred) and specified as &<classT>::<name_of_function>.
667
668 @tparam dataT Type of metadata to be passed to the handler function
669
670 @param name Name of the self-link port
671
672 @param obj Pointer to object that the handler function should be called on
673
674 @param data Metadata to associate with the handler
675
676 @return A pointer to the configured link, or nullptr if an error occurred.
677 */
678 template <auto funcT, typename dataT, typename objT, pvt::enable_if_handler_obj_t<funcT, objT> = 0>
679 Link* configureSelfLink(const std::string& name, objT* obj, dataT data)
680 {
681 addSelfLink(name);
682 return configureLink<funcT, dataT>(name, obj, data);
683 }
684
685
686 /**
687 Registers a clock for this component.
688
689 @param tc TimeConverter object specifying the clock frequency. May be specified as a TimeConverter, std::string
690 or UnitAlgebra
691
692 @param handler Pointer to Clock::HandlerBase which is to be invoked at the specified interval
693
694 @param reg_all Should this clock period be used as the default timebase for all of the links connected to this
695 component
696
697 @return The TimeConverter object representing the clock frequency
698 */
699 TimeConverter registerClock(TimeConverter tc, Clock::HandlerBase* handler, bool reg_all = true);
700
701 /**
702 Removes a clock handler from the component
703
704 NOTE: This operation needs to search the list until it finds the specified handler, which can be a slow operation
705 for long lists. Consider using the return value from the clock handler to control whether a handler is removed
706 from the list or not.
707
708 @param tc TimeConverter representing the period of the clock
709
710 @param handler Handler to remove from the list
711 */
713
714 /**
715 Reactivates an existing Clock and Handler
716
717 @return Time of next time clock handler will fire
718
719 Note: If called after the simulation run loop (e.g., in finish() or complete()), will return the next time of the
720 clock past when the simulation ended. There can be a small lag between simulation end and detection of simulation
721 end during which clocks can run a few extra cycles. As a result, the return value just prior to simulation end
722 may be greater than the value returned after simulation end.
723 */
724 Cycle_t reregisterClock(TimeConverter freq, Clock::HandlerBase* handler);
725
726
727 /**
728 Registers a clock handler for this component.
729
730 @tparam funcT Function that should be called by the Clock::Handler. Must be a member of classT (automatically
731 inferred) and specified as &<classT>::<name_of_function>.
732
733 @param tc TimeConverter object specifying the clock frequency. May be specified as a TimeConverter, std::string
734 or UnitAlgebra
735
736 @param obj Pointer to object that the handler function should be called on
737
738 @param reg_all Should this clock period be used as the default timebase for all of the links connected to this
739 component
740
741 @return The Clock::Handler object that encapsulates the function and object pointer
742 */
743 template <auto funcT, typename objT, pvt::enable_if_handler_obj_t<funcT, objT> = 0>
744 Clock::HandlerBase* registerClock(TimeConverter tc, objT* obj, bool reg_all = true)
745 {
746 auto* handler = new Clock::Handler<pvt::member_function_class_t<funcT>, funcT, void>(obj);
747 registerClock_impl(tc, handler, reg_all, false);
748 return handler;
749 }
750
751 /**
752 Registers a clock handler with metadata for this component.
753
754 @tparam funcT Function that should be called by the Clock::Handler. Must be a member of classT (automatically
755 inferred) and specified as &<classT>::<name_of_function>.
756
757 @tparam dataT Type of metadata to be passed to the handler function
758
759 @param tc TimeConverter object specifying the clock frequency. May be specified as a TimeConverter, std::string
760 or UnitAlgebra
761
762 @param obj Pointer to object that the handler function should be called on
763
764 @param metadata Metadata to associate with the handler
765
766 @param reg_all Should this clock period be used as the default timebase for all of the links connected to this
767 component
768
769 @return The Clock::Handler object that encapsulates the function and object pointer
770 */
771 template <auto funcT, typename dataT, typename objT, pvt::enable_if_handler_obj_t<funcT, objT> = 0>
772 Clock::HandlerBase* registerClock(TimeConverter tc, objT* obj, dataT metadata, bool reg_all = true)
773 {
774 auto* handler = new Clock::Handler<pvt::member_function_class_t<funcT>, funcT, dataT>(obj, metadata);
775 registerClock_impl(tc, handler, reg_all, false);
776 return handler;
777 }
778
779
780 /**
781 Registers an ordered clock handler for this component. Active handlers registered with this function are
782 guaranteed to always fire in the order they were registered, for a given clock frequency.
783
784 @tparam funcT Function that should be called by the Clock::Handler. Must be a member of classT (automatically
785 inferred) and specified as &<classT>::<name_of_function>.
786
787 @param tc TimeConverter object specifying the clock frequency. May be specified as a TimeConverter, std::string
788 or UnitAlgebra
789
790 @param order Order clock should fire in relative to other clocks in the Component tree. Lower orders fire before
791 higher orders. Handlers with the same order will fire in the order they were registered,
792
793 @param obj Pointer to object that the handler function should be called on
794
795 @param reg_all Should this clock period be used as the default timebase for all of the links connected to this
796 component
797
798 @return The Clock::Handler object that encapsulates the function and object pointer
799 */
800 template <auto funcT, typename objT, pvt::enable_if_handler_obj_t<funcT, objT> = 0>
801 Clock::HandlerBase* registerOrderedClock(TimeConverter tc, uint16_t order, objT* obj, bool reg_all = true)
802 {
803 auto* handler = new Clock::Handler<pvt::member_function_class_t<funcT>, funcT, void>(obj);
804 registerClock_impl(tc, handler, reg_all, true, order);
805 return handler;
806 }
807
808 /**
809 Registers an ordered clock handler with metadata for this component. Active handlers registered with this
810 function are guaranteed to always fire in the order they were registered, for a given clock frequency.
811
812 @tparam funcT Function that should be called by the Clock::Handler. Must be a member of classT (automatically
813 inferred) and specified as &<classT>::<name_of_function>.
814
815 @tparam dataT Type of metadata to be passed to the handler function
816
817 @param tc TimeConverter object specifying the clock frequency. May be specified as a TimeConverter, std::string
818 or UnitAlgebra
819
820 @param order Order clock should fire in relative to other clocks in the Component tree. Lower orders fire before
821 higher orders. Handlers with the same order will fire in the order they were registered,
822
823 @param obj Pointer to object that the handler function should be called on
824
825 @param metadata Metadata to associate with the handler
826
827 @param reg_all Should this clock period be used as the default timebase for all of the links connected to this
828 component
829
830 @return The Clock::Handler object that encapsulates the function and object pointer
831 */
832 template <auto funcT, typename dataT, typename objT, pvt::enable_if_handler_obj_t<funcT, objT> = 0>
834 TimeConverter tc, uint16_t order, objT* obj, dataT metadata, bool reg_all = true)
835 {
836 auto* handler = new Clock::Handler<pvt::member_function_class_t<funcT>, funcT, dataT>(obj, metadata);
837 registerClock_impl(tc, handler, reg_all, true, order);
838 return handler;
839 }
840
841
842 /**
843 Returns the next Cycle that the TimeConverter would fire. If called prior to the simulation run loop, next Cycle
844 is 0. If called after the simulation run loop completes (e.g., during complete() or finish()), next Cycle is one
845 past the end time of the simulation. See Note in reregisterClock() for additional guidance when calling this
846 function after simulation ends.
847
848 @param freq Frequency of the clock
849
850 @return Cycle count that will be passed into the next call to this clock's handler functions
851 */
852 Cycle_t getNextClockCycle(TimeConverter freq);
853
854 /**
855 Registers a default timebase for the component and optionally
856 sets the the component's links to that timebase. Useful for
857 components which do not have a clock, but would like a default
858 timebase.
859
860 @param base Frequency for the clock in SI units
861
862 @param reg_all Should this clock period be used as the default timebase for all of the links connected to this
863 component
864 */
865 TimeConverter registerTimeBase(const std::string& base, bool reg_all = true);
866
867 TimeConverter getTimeConverter(const std::string& base) const;
868 TimeConverter getTimeConverter(const UnitAlgebra& base) const;
869
870 bool isStatisticShared(const std::string& stat_name, bool include_me = false)
871 {
872 if ( include_me ) {
873 if ( getStatisticValidityAndLevel(stat_name) != 255 ) {
874 return true;
875 }
876 }
877 if ( my_info_->sharesStatistics() ) {
878 return my_info_->parent_info->component->isStatisticShared(stat_name, true);
879 }
880 else {
881 return false;
882 }
883 }
884
885 /**
886 Tell the simulation object to initiate interactive mode (if currently turned on)
887
888 @param msg Message to print when interactive mode is entered
889 */
890 void initiateInteractive(const std::string& msg);
891
892private:
893 ImplementSerializable(SST::BaseComponent)
894 void serialize_order(SST::Core::Serialization::serializer& ser) override;
895
896
897 /**
898 Handles the profile points, default timebase, handler tracking and checkpointing.
899
900 @param tc TimeConverter representing the period of the clock
901
902 @param handler Handler to add to the list
903
904 @param reg_all Should this clock period be used as the default timebase for all of the links connected to this
905 component
906
907 @param group Whether or not this clock is being registered with a group (i.e. is an ordered clock)
908 */
909 void registerClock_impl(
910 TimeConverter tc, Clock::HandlerBase* handler, bool reg_all, bool group = false, uint16_t order = 0);
911
912 /**
913 Handles default timebase setup
914
915 @param name Name of the port on which to configure the link
916
917 @param timebase Default timebase for the Link
918
919 @param handler Handler to call on event delivery. If no handler is provided, this will be a polling link
920 */
921 Link* configureLink_impl(const std::string& name, SimTime_t timebase, Event::HandlerBase* handler = nullptr);
922
923 /**
924 Helper function used to create an enabled statistic. For explicitly-enabled statistics, this must be called on
925 the parent component. For enable-all, it can be called on the enabling component.
926
927 @param cpp_params Any parameters given in C++ specific to this statistic
928
929 @param name The name (different from type) for this statistic
930
931 @param stat_sub_id An optional sub ID for this statistic to differentiate instances of the same stat
932
933 @return The statistic created
934 */
935 template <typename T>
936 Statistics::Statistic<T>* createStatistic(
937 SST::Params& params, StatisticId_t id, const std::string& name, const std::string& stat_sub_id)
938 {
939 /* I would prefer to avoid this std::function with dynamic cast,
940 * but the code is just a lot cleaner and avoids many unnecessary template instantiations
941 * doing it this way. At some point in the future, we would need to clean up
942 * the rule around enabling all statistics to make this better
943 *
944 * Even if we moved the logic around, we'd still have to dyncast anything coming out of
945 * the stat data structures.
946 */
947 StatCreateFunction create = [=](BaseComponent* comp, Statistics::StatisticProcessingEngine* engine,
948 const std::string& name, const std::string& sub_id,
949 SST::Params& params) -> Statistics::StatisticBase* {
950 return engine->createStatistic<T>(comp, name, sub_id, params);
951 };
952
953 // We follow two distinct paths depending on if it is enable all, versus explicitly enabled
954 // Enable all is "scoped" to the (sub)component
955 // Explicitly enabled stats are assigned component-unique IDs and can be shared across subcomponents
956 // so creation and management happens in the parent component
957 Statistics::StatisticBase* base_stat =
958 id == STATALL_ID ? createEnabledAllStatistic(params, name, stat_sub_id, std::move(create))
959 : getParentComponent()->createExplicitlyEnabledStatistic(
960 params, id, name, stat_sub_id, std::move(create));
961
962 // Ugh, dynamic casts hurt my eyes, but I must do this
963 auto* statistic = dynamic_cast<Statistics::Statistic<T>*>(base_stat);
964 if ( statistic ) {
965 return statistic;
966 }
967 else {
968 fatal(__LINE__, __FILE__, "createStatistic", 1, "failed to cast created statistic '%s' to expected type",
969 name.c_str());
970 }
971 }
972
973 /**
974 Internal registration function for statistics. Determines if a statistic is enabled or not.
975 It first locates the component that should "own" the stat based on both ELI and statistic enable parameters.
976 If enabled, it calls createStatistic<T> on the owning component.
977 If disabled, it returns a disabled statistic from the statistic engine.
978 */
979 template <typename T>
980 Statistics::Statistic<T>* registerStatistic_impl(
981 SST::Params& params, const std::string& stat_name, const std::string& stat_sub_id, uint8_t level = 255)
982 {
983 if ( level == 255 ) { // Stat has not yet been found in ELI, search this component's ELI
984 level = getStatisticValidityAndLevel(stat_name);
985 }
986
987 if ( level == 255 ) {
988 // If level is still 255, stat has not been found in any ELI yet, need to check if parent shares their ELI
989 if ( my_info_->parent_info && my_info_->sharesStatistics() ) {
990 return my_info_->parent_info->component->registerStatistic_impl<T>(params, stat_name, stat_sub_id);
991 }
992 else {
993 // not a valid stat and I won't be able to share my parent's statistic
994 fatal(__LINE__, __FILE__, "registerStatistic", 1,
995 "attempting to register a statistic '%s' that is not found in ELI", stat_name.c_str());
996 }
997 }
998
999 // Path 1: Explicitly enabled statistic
1000 if ( my_info_->enabled_stat_names_ ) {
1001 auto iter = my_info_->enabled_stat_names_->find(stat_name);
1002 if ( iter != my_info_->enabled_stat_names_->end() ) {
1003 // valid, enabled statistic
1004 // During initialization, the component should have assigned a mapping between
1005 // the local name and globally unique stat ID
1006 StatisticId_t id = iter->second;
1007 return getParentComponent()->createStatistic<T>(params, id, stat_name, stat_sub_id);
1008 }
1009 }
1010
1011 // Path 2: Enabled all statistic
1012 if ( my_info_->enabled_all_stats_ ) { // I enabled this stat and it is valid
1013 if ( level > getStatisticLoadLevel() ) {
1014 return getStatEngine()->createDisabledStatistic<T>();
1015 }
1016 return createStatistic<T>(params, STATALL_ID, stat_name, stat_sub_id);
1017 }
1018 else if ( my_info_->parent_info && my_info_->canInsertStatistics() ) {
1019 // I did not enable all but my parent may have and will accept my statistics
1020 return my_info_->parent_info->component->registerStatistic_impl<T>(params, stat_name, stat_sub_id, level);
1021 }
1022 else {
1023 // Not enabled
1024 return getStatEngine()->createDisabledStatistic<T>();
1025 }
1026 }
1027
1028protected:
1029 /**
1030 Registers a statistic.
1031
1032 If Statistic is allowed to run (controlled by Python runtime parameters), then a statistic will be created and
1033 returned. If not allowed to run, then a NullStatistic will be returned. In either case, the returned value
1034 should be used for all future Statistic calls. The type of Statistic and the Collection Rate is set by Python
1035 runtime parameters. If no type is defined, then an Accumulator Statistic will be provided by default. If rate
1036 set to 0 or not provided, then the statistic will output results only at end of sim (if output is enabled).
1037
1038 @param params Parameter set to be passed to the statistic constructor.
1039
1040 @param stat_name Primary name of the statistic. This name must match the defined ElementInfoStatistic in the
1041 component, and must also be enabled in the Python input file.
1042
1043 @param stat_sub_id An additional sub name for the statistic
1044
1045 @return Either a created statistic of desired type or a NullStatistic depending upon runtime settings.
1046 */
1047 template <typename T>
1049 SST::Params& params, const std::string& stat_name, const std::string& stat_sub_id = "")
1050 {
1051 return registerStatistic_impl<T>(params, stat_name, stat_sub_id);
1052 }
1053
1054 template <typename T>
1055 Statistics::Statistic<T>* registerStatistic(const std::string& stat_name, const std::string& stat_sub_id = "")
1056 {
1057 SST::Params empty {};
1058 return registerStatistic_impl<T>(empty, stat_name, stat_sub_id);
1059 }
1060
1061 template <typename... Args>
1062 Statistics::Statistic<std::tuple<Args...>>* registerMultiStatistic(
1063 const std::string& stat_name, const std::string& stat_sub_id = "")
1064 {
1065 SST::Params empty {};
1066 return registerStatistic_impl<std::tuple<Args...>>(empty, stat_name, stat_sub_id);
1067 }
1068
1069 template <typename... Args>
1070 Statistics::Statistic<std::tuple<Args...>>* registerMultiStatistic(
1071 SST::Params& params, const std::string& stat_name, const std::string& stat_sub_id = "")
1072 {
1073 return registerStatistic_impl<std::tuple<Args...>>(params, stat_name, stat_sub_id);
1074 }
1075
1076 template <typename T>
1077 Statistics::Statistic<T>* registerStatistic(const char* stat_name, const char* stat_sub_id = "")
1078 {
1079 return registerStatistic<T>(std::string(stat_name), std::string(stat_sub_id));
1080 }
1081
1082 /**
1083 Called by the Components and Subcomponent to perform a statistic Output.
1084
1085 @param stat Pointer to the statistic.
1086 */
1087 void performStatisticOutput(Statistics::StatisticBase* stat);
1088
1089 /**
1090 Performs a global statistic Output.
1091
1092 This routine will force ALL Components and Subcomponents to output their statistic information. This may lead to
1093 unexpected results if the statistic counts or data is reset on output.
1094
1095 NOTE: Currently, this function will only output statistics that are on the same rank.
1096 */
1098
1099 /**
1100 Registers a profiling point.
1101
1102 This function will register a profiling point.
1103
1104 @param point_name Name of point to register
1105
1106 @return Either a pointer to a created T::ProfilePoint or nullptr if not enabled.
1107 */
1108 template <typename T>
1109 typename T::ProfilePoint* registerProfilePoint(const std::string& point_name)
1110 {
1111 std::string full_point_name = getType() + "." + point_name;
1112 auto tools = getComponentProfileTools(full_point_name);
1113 if ( tools.size() == 0 ) return nullptr;
1114
1115 typename T::ProfilePoint* ret = new typename T::ProfilePoint();
1116 for ( auto* x : tools ) {
1117 T* tool = dynamic_cast<T*>(x);
1118 if ( nullptr == tool ) {
1119 // Not the right type, fatal
1120 fatal(CALL_INFO_LONG, 1, "ERROR: wrong type of profiling tool for profiling point %s)\n",
1121 point_name.c_str());
1122 }
1123 ret->registerProfilePoint(tool, point_name, getId(), getName(), getType());
1124 }
1125 return ret;
1126 }
1127
1128 /**
1129 Loads a module from an element Library
1130
1131 @param type Fully Qualified library.moduleName
1132
1133 @param params Parameters the module should use for configuration
1134
1135 @return Handle to new instance of module, or nullptr on failure.
1136 */
1137 template <class T, class... ARGS>
1138 T* loadModule(const std::string& type, Params& params, ARGS... args)
1139 {
1140 // Check to see if this can be loaded with new API or if we have to fallback to old
1141 return Factory::getFactory()->CreateWithParams<T>(type, params, params, args...);
1142 }
1143
1144protected:
1145 // When you direct load, the ComponentExtension does not need any
1146 // ELI information and if it has any, it will be ignored. The
1147 // extension will be loaded as if it were part of the parent
1148 // BaseComponent and will share all that components ELI
1149 // information.
1150 template <class T, class... ARGS>
1151 T* loadComponentExtension(ARGS... args)
1152 {
1153 ComponentExtension* ret = new T(my_info_->id_, args...);
1154 return static_cast<T*>(ret);
1155 }
1156
1157 /**
1158 Check to see if a given element type is loadable with a particular API
1159
1160 @param name Name of element to check in lib.name format
1161
1162 @return True if loadable as the API specified as the template parameter
1163 */
1164 template <class T>
1165 bool isSubComponentLoadableUsingAPI(const std::string& type)
1166 {
1167 return Factory::getFactory()->isSubComponentLoadableUsingAPI<T>(type);
1168 }
1169
1170 /**
1171 Check to see if the element type loaded by the user into the.
1172 specified slot is loadable with a particular API. This will
1173 only check slot index 0. If you need to check other slots,
1174 please use the SubComponentSlotInfo.
1175
1176 @param slot_name Name of slot to check
1177
1178 @return True if loadable as the API specified as the template parameter
1179 */
1180 template <class T>
1181 bool isUserSubComponentLoadableUsingAPI(const std::string& slot_name)
1182 {
1183 // Get list of ComponentInfo objects and make sure that there is
1184 // only one SubComponent put into this slot
1185 // const std::vector<ComponentInfo>& subcomps = my_info_->getSubComponents();
1186 const std::map<ComponentId_t, ComponentInfo>& subcomps = my_info_->getSubComponents();
1187 int sub_count = 0;
1188 int index = -1;
1189 for ( auto& ci : subcomps ) {
1190 if ( ci.second.getSlotName() == slot_name ) {
1191 index = ci.second.getSlotNum();
1192 sub_count++;
1193 }
1194 }
1195
1196 if ( sub_count > 1 ) {
1197 SST::Output outXX("SubComponentSlotWarning: ", 0, 0, Output::STDERR);
1198 outXX.fatal(CALL_INFO, 1,
1199 "Error: ComponentSlot \"%s\" in component \"%s\" only allows for one SubComponent, %d provided.\n",
1200 slot_name.c_str(), my_info_->getType().c_str(), sub_count);
1201 }
1202
1203 return isUserSubComponentLoadableUsingAPIByIndex<T>(slot_name, index);
1204 }
1205
1206 /**
1207 Loads an anonymous subcomponent (not defined in input file to SST run).
1208
1209 @param type type of subcomponent to load in lib.name format
1210
1211 @param slot_name name of the slot to load subcomponent into
1212
1213 @param slot_num index of the slot to load subcomponent into
1214
1215 @param share_flags Share flags to be used by subcomponent
1216
1217 @param params Params object to be passed to subcomponent
1218
1219 @param args Arguments to be passed to constructor. This signature is defined in the API definition
1220
1221 For ease in backward compatibility to old API, this call will try to load using new API and will fallback to old
1222 if unsuccessful.
1223 */
1224 template <class T, class... ARGS>
1225 T* loadAnonymousSubComponent(const std::string& type, const std::string& slot_name, int slot_num,
1226 uint64_t share_flags, Params& params, ARGS... args)
1227 {
1228
1229 share_flags = share_flags & ComponentInfo::USER_FLAGS;
1230 ComponentId_t cid = my_info_->addAnonymousSubComponent(my_info_, type, slot_name, slot_num, share_flags);
1231 ComponentInfo* sub_info = my_info_->findSubComponent(cid);
1232
1233 // This shouldn't happen since we just put it in, but just in case
1234 if ( sub_info == nullptr ) return nullptr;
1235
1236 // Check to see if this can be loaded with new API or if we have to fallback to old
1238 auto ret = Factory::getFactory()->CreateWithParams<T>(type, params, sub_info->id_, params, args...);
1239 return ret;
1240 }
1241 return nullptr;
1242 }
1243
1244 /**
1245 Loads a user defined subcomponent (defined in input file to SST run). This version does not allow share flags
1246 (set to SHARE_NONE) or constructor arguments.
1247
1248 @param slot_name name of the slot to load subcomponent into
1249
1250 For ease in backward compatibility to old API, this call will try to load using new API and will fallback to old
1251 if unsuccessful.
1252 */
1253 template <class T>
1254 T* loadUserSubComponent(const std::string& slot_name)
1255 {
1256 return loadUserSubComponent<T>(slot_name, ComponentInfo::SHARE_NONE);
1257 }
1258
1259 /**
1260 Loads a user defined subcomponent (defined in input file to SST
1261 run).
1262
1263 @param slot_name name of the slot to load subcomponent into
1264
1265 @param share_flags Share flags to be used by subcomponent
1266
1267 @param args Arguments to be passed to constructor. This signature is defined in the API definition
1268
1269 For ease in backward compatibility to old API, this call will try to load using new API and will fallback to old
1270 if unsuccessful.
1271 */
1272 template <class T, class... ARGS>
1273 T* loadUserSubComponent(const std::string& slot_name, uint64_t share_flags, ARGS... args)
1274 {
1275
1276 // Get list of ComponentInfo objects and make sure that there is
1277 // only one SubComponent put into this slot
1278 // const std::vector<ComponentInfo>& subcomps = my_info_->getSubComponents();
1279 const std::map<ComponentId_t, ComponentInfo>& subcomps = my_info_->getSubComponents();
1280 int sub_count = 0;
1281 int index = -1;
1282 for ( auto& ci : subcomps ) {
1283 if ( ci.second.getSlotName() == slot_name ) {
1284 index = ci.second.getSlotNum();
1285 sub_count++;
1286 }
1287 }
1288
1289 if ( sub_count > 1 ) {
1290 SST::Output outXX("SubComponentSlotWarning: ", 0, 0, Output::STDERR);
1291 outXX.fatal(CALL_INFO, 1,
1292 "Error: ComponentSlot \"%s\" in component \"%s\" only allows for one SubComponent, %d provided.\n",
1293 slot_name.c_str(), my_info_->getType().c_str(), sub_count);
1294 }
1295
1296 return loadUserSubComponentByIndex<T, ARGS...>(slot_name, index, share_flags, args...);
1297 }
1298
1299 /**
1300 Convenience function for reporting fatal conditions. The function will create a new Output object and call
1301 fatal() using the supplied parameters. Before calling Output::fatal(), the function will also print other
1302 information about the (sub)component that called fatal and about the simulation state.
1303
1304 From Output::fatal: Message will be sent to the output location and to stderr. The output will be prepended with
1305 the expanded prefix set in the object.
1306
1307 NOTE: fatal() will call MPI_Abort(exit_code) to terminate simulation.
1308
1309 @param line Line number of calling function (use CALL_INFO macro)
1310
1311 @param file File name calling function (use CALL_INFO macro)
1312
1313 @param func Function name calling function (use CALL_INFO macro)
1314
1315 @param exit_code The exit code used for termination of simulation. will be passed to MPI_Abort()
1316
1317 @param format Format string. All valid formats for printf are available.
1318
1319 @param ... Arguments for format.
1320 */
1321 [[noreturn]]
1322 void fatal(uint32_t line, const char* file, const char* func, int exit_code, const char* format, ...) const
1323 __attribute__((format(printf, 6, 7)));
1324
1325 /**
1326 Convenience function for testing for and reporting fatal conditions. If the condition holds, fatal() will be
1327 called, otherwise, the function will return. The function will create a new Output object and call fatal() using
1328 the supplied parameters. Before calling Output::fatal(), the function will also print other information about
1329 the (sub)component that called fatal and about the simulation state.
1330
1331 From Output::fatal: Message will be sent to the output location and to stderr. The output will be prepended with
1332 the expanded prefix set in the object. NOTE: fatal() will call MPI_Abort(exit_code) to terminate simulation.
1333
1334
1335 @param condition on which to call fatal(); fatal() is called if the bool is false.
1336
1337 @param line Line number of calling function (use CALL_INFO macro)
1338
1339 @param file File name calling function (use CALL_INFO macro)
1340
1341 @param func Function name calling function (use CALL_INFO macro)
1342
1343 @param exit_code The exit code used for termination of simulation. will be passed to MPI_Abort()
1344
1345 @param format Format string. All valid formats for printf are available.
1346
1347 @param ... Arguments for format.
1348 */
1349 void sst_assert(bool condition, uint32_t line, const char* file, const char* func, int exit_code,
1350 const char* format, ...) const __attribute__((format(printf, 7, 8)));
1351
1352private:
1353 SimTime_t processCurrentTimeWithUnderflowedBase(const std::string& base) const;
1354
1355 /**
1356 findExplicitlyEnabledStatistic
1357
1358 @param params
1359
1360 @param id
1361
1362 @param name
1363
1364 @param stat_sub_id
1365
1366 @return That matching stat if the stat already was created for the given ID, otherwise nullptr
1367 */
1368 Statistics::StatisticBase* createExplicitlyEnabledStatistic(SST::Params& params, StatisticId_t id,
1369 const std::string& name, const std::string& stat_sub_id, StatCreateFunction create);
1370
1371 Statistics::StatisticBase* createEnabledAllStatistic(
1372 SST::Params& params, const std::string& name, const std::string& stat_sub_id, StatCreateFunction create);
1373
1374 void setDefaultTimeBaseForLinks(TimeConverter tc);
1375
1376 void pushValidParams(Params& params, const std::string& type);
1377
1378 template <class T, class... ARGS>
1379 T* loadUserSubComponentByIndex(const std::string& slot_name, int slot_num, int share_flags, ARGS... args)
1380 {
1381
1382 share_flags = share_flags & ComponentInfo::USER_FLAGS;
1383
1384 // Check to see if the slot exists
1385 ComponentInfo* sub_info = my_info_->findSubComponent(slot_name, slot_num);
1386 if ( sub_info == nullptr ) return nullptr;
1387 sub_info->share_flags = share_flags;
1388 sub_info->parent_info = my_info_;
1389
1390 if ( isSubComponentLoadableUsingAPI<T>(sub_info->type) ) {
1391 auto ret = Factory::getFactory()->CreateWithParams<T>(
1392 sub_info->type, *sub_info->params, sub_info->id_, *sub_info->params, args...);
1393 return ret;
1394 }
1395 return nullptr;
1396 }
1397
1398 template <class T>
1399 bool isUserSubComponentLoadableUsingAPIByIndex(const std::string& slot_name, int slot_num)
1400 {
1401 // Check to see if the slot exists
1402 ComponentInfo* sub_info = my_info_->findSubComponent(slot_name, slot_num);
1403 if ( sub_info == nullptr ) return false;
1404
1405 return isSubComponentLoadableUsingAPI<T>(sub_info->type);
1406 }
1407
1408 // Utility function used by fatal and sst_assert
1409 [[noreturn]]
1410 void vfatal(uint32_t line, const char* file, const char* func, int exit_code, const char* format, va_list arg) const
1411 __attribute__((format(printf, 6, 0)));
1412
1413 // Get the statengine from Simulation
1414 StatisticProcessingEngine* getStatEngine();
1415
1416public:
1417 SubComponentSlotInfo* getSubComponentSlotInfo(const std::string& name, bool fatalOnEmptyIndex = false);
1418
1419 /**
1420 Retrieve the X,Y,Z coordinates of this component
1421 */
1422 const std::vector<double>& getCoordinates() const { return my_info_->coordinates; }
1423
1424protected:
1426 friend class SST::Statistics::StatisticBase;
1427
1428 bool isAnonymous() { return my_info_->isAnonymous(); }
1429
1430 bool isUser() { return my_info_->isUser(); }
1431
1432 /**
1433 Manually set the default defaultTimeBase
1434 */
1435 void setDefaultTimeBase(TimeConverter tc) { my_info_->defaultTimeBase = tc; }
1436
1437 TimeConverter getDefaultTimeBase() { return my_info_->defaultTimeBase; }
1438 const TimeConverter getDefaultTimeBase() const { return my_info_->defaultTimeBase; }
1439
1440 bool doesSubComponentExist(const std::string& type);
1441
1442 // Does the statisticName exist in the ElementInfoStatistic and if so, what is its enable level
1443 uint8_t getStatisticValidityAndLevel(const std::string& statisticName) const;
1444
1445 std::vector<Profile::ComponentProfileTool*> getComponentProfileTools(const std::string& point);
1446
1447 /**** Primary Component API ****/
1448
1449 /**
1450 Register as a primary component, which allows the component to specify when it is and is not OK to end
1451 simulation. The simulator will not end simulation through use of the Exit object while any primary component has
1452 specified primaryComponentDoNotEndSim(). However, it is still possible for Actions other than Exit to end
1453 simulation. Once all primary components have specified primaryComponentOKToEndSim(), the Exit object will
1454 trigger and end simulation.
1455
1456 This must be called during simulation wireup (i.e during the constructor for the component), or a fatal error
1457 will occur.
1458
1459 If no component registers as a primary component, then the Exit object will not be used for that simulation and
1460 simulation termination must be accomplished through some other mechanism (e.g. --stopAt flag, or some other
1461 Action object).
1462
1463 @sa BaseComponent::primaryComponentDoNotEndSim()
1464 @sa BaseComponent::primaryComponentOKToEndSim()
1465 */
1467
1468 /**
1469 Tells the simulation that it should not exit. The component will remain in this state until a call to
1470 primaryComponentOKToEndSim(). A component may reenter the DoNotEndSime state by calling this function after
1471 calling primaryComponentOKToEndSim(), in which case, another call to primaryComponentOKToEndSim() will need to be
1472 called to end the simulation.
1473
1474 Calls to this function when already in the DoNotEndSime state, will be functionally ignored, but will generate a
1475 warning if verbose is turned on.
1476
1477 Calls to this function on non-primary components will be ignored and will generate a warning if verbose is turned
1478 on.
1479
1480 @sa BaseComponent::registerAsPrimaryComponent()
1481 @sa BaseComponent::primaryComponentOKToEndSim()
1482 */
1484
1485 /**
1486 Tells the simulation that it is now OK to end simulation. Simulation will not end until all primary components
1487 that have called primaryComponentDoNotEndSim() have called this function.
1488
1489 Calls to this function when already in the OKToEndSim state, will be functionally ignored, but will generate a
1490 warning if verbose is turned on.
1491
1492 Calls to this function on non-primary components will be ignored and will generate a warning if verbose is turned
1493 on.
1494
1495 @sa BaseComponent::registerAsPrimaryComponent()
1496 @sa BaseComponent::primaryComponentDoNotEndSim()
1497 */
1499
1500
1501private:
1502 enum class ComponentState : uint8_t {
1503 // Primary States
1504 None = 0,
1505 Primary = 1 << 0,
1506 DoNotEndSim = 1 << 1,
1507 OKToEndSim = 1 << 2,
1508
1509 // Whether this is an extension
1510 Extension = 1 << 3,
1511 };
1512
1513 /**
1514 Check for Primary state
1515
1516 @return True if component_state_ includes Primary, false otherwise
1517 */
1518 bool isStatePrimary()
1519 {
1520 return static_cast<uint8_t>(component_state_) & static_cast<uint8_t>(ComponentState::Primary);
1521 }
1522
1523 /**
1524 Check for DoNotEndSim state. This state is mutually exclusive with OKToEndSim
1525
1526 @return True if component_state_ includes DoNotEndSim, false otherwise
1527 */
1528 bool isStateDoNotEndSim()
1529 {
1530 return static_cast<uint8_t>(component_state_) & static_cast<uint8_t>(ComponentState::DoNotEndSim);
1531 }
1532
1533 /**
1534 Check for OKToEndSim state. This state is mutually exclusive with DoNotEndSim
1535
1536 @return True if component_state_ includes OKToEndSim
1537 */
1538 bool isStateOKToEndSim()
1539 {
1540 return static_cast<uint8_t>(component_state_) & static_cast<uint8_t>(ComponentState::OKToEndSim);
1541 }
1542
1543 /**
1544 Check for Extension state
1545
1546 @return True if component_state_ includes Extension, false otherwise
1547 */
1548 bool isExtension()
1549 {
1550 return static_cast<uint8_t>(component_state_) & static_cast<uint8_t>(ComponentState::Extension);
1551 }
1552
1553
1554 /**
1555 Adds Primary to the component_state_
1556
1557 NOTE: This function does not check to see if the component is in the proper stage of simulation, that check
1558 should be done before calling this function.
1559 */
1560 void setStateAsPrimary()
1561 {
1562 component_state_ = static_cast<ComponentState>(
1563 static_cast<uint8_t>(component_state_) | static_cast<uint8_t>(ComponentState::Primary));
1564 }
1565
1566 /**
1567 Adds DoNotEndSim and removes OKToEndSim to/from the component_state_
1568
1569 NOTE: This function does not check to see if registerAsPrimaryComponent() has been properly called, that check
1570 should be done before calling this function.
1571 */
1572 void setStateDoNotEndSim()
1573 {
1574 component_state_ = static_cast<ComponentState>(
1575 static_cast<uint8_t>(component_state_) | static_cast<uint8_t>(ComponentState::DoNotEndSim));
1576 component_state_ = static_cast<ComponentState>(
1577 static_cast<uint8_t>(component_state_) & ~static_cast<uint8_t>(ComponentState::OKToEndSim));
1578 }
1579
1580 /**
1581 Adds OKToEndSim and removes DoNotEndSim to/from the component_state_
1582
1583 NOTE: This function does not check to see if registerAsPrimaryComponent() has been properly called, that check
1584 should be done before calling this function.
1585 */
1586 void setStateOKToEndSim()
1587 {
1588 component_state_ = static_cast<ComponentState>(
1589 static_cast<uint8_t>(component_state_) | static_cast<uint8_t>(ComponentState::OKToEndSim));
1590 component_state_ = static_cast<ComponentState>(
1591 static_cast<uint8_t>(component_state_) & ~static_cast<uint8_t>(ComponentState::DoNotEndSim));
1592 }
1593
1594 /**
1595 Adds Extension to the component_state_
1596 */
1597 void setAsExtension()
1598 {
1599 component_state_ = static_cast<ComponentState>(
1600 static_cast<uint8_t>(component_state_) | static_cast<uint8_t>(ComponentState::Extension));
1601 }
1602
1603
1604 friend class Core::Serialization::pvt::SerializeBaseComponentHelper;
1605
1606
1607 ComponentInfo* my_info_ = nullptr;
1608 Simulation* sim_ = nullptr;
1609
1610 // component_state_ is initialized as NotPrimary and !Extension
1611 ComponentState component_state_ = ComponentState::None;
1612 // bool isExtension = false;
1613
1614 // Need to track clock handlers for checkpointing. We need to know what clock handlers we have registered with the
1615 // core
1616 std::vector<Clock::HandlerBase*> clock_handlers_;
1617
1618 void addSelfLink(const std::string& name);
1619 Link* getLinkFromParentSharedPort(const std::string& port, std::vector<ConfigPortModule>& port_modules);
1620
1621 using StatNameMap = std::map<std::string, std::map<std::string, Statistics::StatisticBase*>>;
1622
1623 ConfigPortModule& getPortModuleConfig(PortModuleId_t);
1624
1625 static thread_local std::pair<ComponentId_t, PortModuleId_t> port_module_id_;
1626
1627 std::vector<PortModule*> port_modules_;
1628
1629 std::map<StatisticId_t, Statistics::StatisticBase*>
1630 explicitly_enabled_shared_stats_; // Lookup structure to determine if an explicitly enabled shared stat has
1631 // already been registered. In this context, a shared stat is one that has
1632 // been piped to a different user-defined name in the config.
1633 std::map<StatisticId_t, StatNameMap>
1634 explicitly_enabled_unique_stats_; // Lookup structure to determine if an explicitly enabled non-shared stat has
1635 // been registered.
1636 StatNameMap enabled_all_stats_;
1637
1638 /**
1639 Get the ultimate parent Component for this BaseComponent. Will return this is caller is a Component
1640 */
1641 BaseComponent* getParentComponent()
1642 {
1643 ComponentInfo* base_info = my_info_;
1644 while ( base_info->parent_info ) {
1645 base_info = base_info->parent_info;
1646 }
1647 return base_info->component;
1648 }
1649
1650 virtual Clock::Group* getClockGroup(TimeConverter tc) { return getParentComponent()->getClockGroup(tc); }
1651};
1652
1653/**
1654 Used to load SubComponents when multiple SubComponents are loaded into a single slot (will also also work when a
1655 single SubComponent is loaded).
1656 */
1657class SubComponentSlotInfo
1658{
1659
1660 BaseComponent* comp;
1661 std::string slot_name;
1662 int max_slot_index;
1663
1664public:
1665 ~SubComponentSlotInfo() {}
1666
1667 SubComponentSlotInfo(BaseComponent* comp, const std::string& slot_name) :
1668 comp(comp),
1669 slot_name(slot_name)
1670 {
1671 const std::map<ComponentId_t, ComponentInfo>& subcomps = comp->my_info_->getSubComponents();
1672
1673 // Look for all subcomponents with the right slot name
1674 max_slot_index = -1;
1675 for ( auto& ci : subcomps ) {
1676 if ( ci.second.getSlotName() == slot_name ) {
1677 if ( ci.second.getSlotNum() > static_cast<int>(max_slot_index) ) {
1678 max_slot_index = ci.second.getSlotNum();
1679 }
1680 }
1681 }
1682 }
1683
1684 const std::string& getSlotName() const { return slot_name; };
1685
1686 bool isPopulated(int slot_num) const
1687 {
1688 if ( slot_num > max_slot_index ) return false;
1689 if ( comp->my_info_->findSubComponent(slot_name, slot_num) == nullptr ) return false;
1690 return true;
1691 }
1692
1693 bool isAllPopulated() const
1694 {
1695 for ( int i = 0; i < max_slot_index; ++i ) {
1696 if ( comp->my_info_->findSubComponent(slot_name, i) == nullptr ) return false;
1697 }
1698 return true;
1699 }
1700
1701 int getMaxPopulatedSlotNumber() const { return max_slot_index; }
1702
1703 /**
1704 Check to see if the element type loaded by the user into the specified slot index is loadable with a particular
1705 API.
1706
1707 @param slot_num Slot index to check
1708
1709 @return True if loadable as the API specified as the template parameter
1710 */
1711 template <class T>
1712 bool isLoadableUsingAPI(int slot_num)
1713 {
1714 return comp->isUserSubComponentLoadableUsingAPIByIndex<T>(slot_name, slot_num);
1715 }
1716
1717 // Create functions that support the new API
1718
1719 /**
1720 Create a user defined subcomponent (defined in input file to SST run). This call will pass SHARE_NONE to the new
1721 subcomponent and will not take constructor arguments. If constructor arguments are needed for the API that is
1722 being loaded, the full call to create will need to be used create(slot_num, share_flags, args...).
1723
1724 @param slot_num Slot index from which to load subcomponent
1725
1726 This function supports the new API, but is identical to an existing API call. It will try to load using new API
1727 and will fallback to old if unsuccessful.
1728 */
1729 template <typename T>
1730 T* create(int slot_num) const
1731 {
1732 Params empty;
1733 return comp->loadUserSubComponentByIndex<T>(slot_name, slot_num, ComponentInfo::SHARE_NONE);
1734 }
1735
1736 /**
1737 Create a user defined subcomponent (defined in input file to SST run).
1738
1739 @param slot_num Slot index from which to load subcomponent
1740
1741 @param share_flags Share flags to be used by subcomponent
1742
1743 @param args Arguments to be passed to constructor. This signature is defined in the API definition
1744
1745 For ease in backward compatibility to old API, this call will try to load using new API and will fallback to old
1746 if unsuccessful.
1747 */
1748 template <class T, class... ARGS>
1749 T* create(int slot_num, uint64_t share_flags, ARGS... args) const
1750 {
1751 return comp->loadUserSubComponentByIndex<T, ARGS...>(slot_name, slot_num, share_flags, args...);
1752 }
1753
1754 /**
1755 Create all user defined subcomponents (defined in input file to SST run) for the slot.
1756
1757 @param vec Vector of T* that will hold the pointers to the new subcomponents. If an index is not occupied, a
1758 nullptr will be put in its place. All components will be added to the end of the vector, so index N will be at
1759 vec.length() + N, where vec.length() is the length of the vector when it is passed to the call.
1760
1761 @param share_flags Share flags to be used by subcomponent
1762
1763 @param args Arguments to be passed to constructor. This signature is defined in the API definition
1764
1765 For ease in backward compatibility to old API, this call will try to load using new API and will fallback to old
1766 if unsuccessful.
1767 */
1768 template <typename T, class... ARGS>
1769 void createAll(std::vector<T*>& vec, uint64_t share_flags, ARGS... args) const
1770 {
1771 for ( int i = 0; i <= getMaxPopulatedSlotNumber(); ++i ) {
1772 T* sub = create<T>(i, share_flags, args...);
1773 vec.push_back(sub);
1774 }
1775 }
1776
1777 /**
1778 Create all user defined subcomponents (defined in input file to SST
1779 run) for the slot.
1780
1781 @param vec Vector of pair<int,T*> that will hold the pointers to the new subcomponents. The int will hold the
1782 index from which the subcomponent was loaded. Unoccupied indexes will be skipped. All components will be added
1783 to the end of the vector.
1784
1785 @param share_flags Share flags to be used by subcomponent
1786
1787 @param args Arguments to be passed to constructor. This signature is defined in the API definition
1788
1789 For ease in backward compatibility to old API, this call will try to load using new API and will fallback to old
1790 if unsuccessful.
1791 */
1792 template <typename T, class... ARGS>
1793 void createAllSparse(std::vector<std::pair<int, T*>>& vec, uint64_t share_flags, ARGS... args) const
1794 {
1795 for ( int i = 0; i <= getMaxPopulatedSlotNumber(); ++i ) {
1796 T* sub = create<T>(i, share_flags, args...);
1797 if ( sub != nullptr ) vec.push_back(i, sub);
1798 }
1799 }
1800
1801 /**
1802 Create all user defined subcomponents (defined in input file to SST run) for the slot.
1803
1804 @param vec Vector of T* that will hold the pointers to the new subcomponents. Unoccupied indexes will be
1805 skipped. All components will be added to the end of the vector.
1806
1807 @param share_flags Share flags to be used by subcomponent
1808
1809 @param args Arguments to be passed to constructor. This signature is defined in the API definition
1810
1811 For ease in backward compatibility to old API, this call will try to load using new API and will fallback to old
1812 if unsuccessful.
1813 */
1814 template <typename T, class... ARGS>
1815 void createAllSparse(std::vector<T*>& vec, uint64_t share_flags, ARGS... args) const
1816 {
1817 for ( int i = 0; i <= getMaxPopulatedSlotNumber(); ++i ) {
1818 T* sub = create<T>(i, share_flags, args...);
1819 if ( sub != nullptr ) vec.push_back(sub);
1820 }
1821 }
1822};
1823
1824namespace Core::Serialization {
1825
1826namespace pvt {
1828{
1829public:
1830 static void size_basecomponent(serializable_base* s, serializer& ser);
1831
1832 static void pack_basecomponent(serializable_base* s, serializer& ser);
1833
1834 static void unpack_basecomponent(serializable_base*& s, serializer& ser);
1835
1836 static void map_basecomponent(serializable_base*& s, serializer& ser, const std::string& name);
1837};
1838
1839} // namespace pvt
1840
1841
1842template <class T>
1843class serialize_impl<T*, std::enable_if_t<std::is_base_of_v<SST::BaseComponent, T>>>
1844{
1845 void operator()(T*& s, serializer& ser, ser_opt_t UNUSED(options))
1846 {
1847 serializable_base* sp = static_cast<serializable_base*>(s);
1848 switch ( ser.mode() ) {
1849 case serializer::SIZER:
1850 pvt::SerializeBaseComponentHelper::size_basecomponent(sp, ser);
1851 break;
1852 case serializer::PACK:
1853 pvt::SerializeBaseComponentHelper::pack_basecomponent(sp, ser);
1854 break;
1855 case serializer::UNPACK:
1856 pvt::SerializeBaseComponentHelper::unpack_basecomponent(sp, ser);
1857 break;
1858 case serializer::MAP:
1859 pvt::SerializeBaseComponentHelper::map_basecomponent(sp, ser, ser.getMapName());
1860 break;
1861 }
1862 s = static_cast<T*>(sp);
1863 }
1864
1865 SST_FRIEND_SERIALIZE();
1866};
1867
1868} // namespace Core::Serialization
1869
1870} // namespace SST
1871
1872#endif // SST_CORE_BASECOMPONENT_H
Main component object for the simulation.
Definition baseComponent.h:98
bool isSimulationRunModeInit() const
Check to see if the run mode was set to INIT.
Definition baseComponent.cc:330
SimTime_t getCurrentSimTimeMilli() const
Utility function to return the time since the simulation began in milliseconds.
Definition baseComponent.cc:211
Link * configureSelfLink(const std::string &name, objT *obj)
Configure a SelfLink (Loopback link) that uses the (Sub)Component's defaultTimeBase.
Definition baseComponent.h:655
Link * configureLink(const std::string &name, objT *obj, dataT data)
Configure a Link with metadata, using the component's default timebase.
Definition baseComponent.h:556
virtual void complete(unsigned int UNUSED(phase))
Used during the complete phase after the end of simulation.
Definition baseComponent.h:175
void requireLibrary(const std::string &name)
Signifies that a library is required for this simulation.
Definition baseComponent.cc:354
bool isSimulationRunModeRun() const
Check to see if the run mode was set to RUN.
Definition baseComponent.cc:336
void setDefaultTimeBase(TimeConverter tc)
Manually set the default defaultTimeBase.
Definition baseComponent.h:1435
bool isPortConnected(const std::string &name) const
Determine if a port name is connected to any links.
Definition baseComponent.cc:361
void fatal(uint32_t line, const char *file, const char *func, int exit_code, const char *format,...) const
Convenience function for reporting fatal conditions.
Definition baseComponent.cc:660
double getRunPhaseElapsedRealTime() const
Get the amount of real-time spent executing the run phase of the simulation.
Definition baseComponent.cc:220
void removeWatchPoint(WatchPoint *pt)
Remove a watch point from all handlers in the Component Tree.
Definition baseComponent.cc:252
T * loadUserSubComponent(const std::string &slot_name)
Loads a user defined subcomponent (defined in input file to SST run).
Definition baseComponent.h:1254
Clock::HandlerBase * registerClock(TimeConverter tc, objT *obj, bool reg_all=true)
Registers a clock handler for this component.
Definition baseComponent.h:744
const std::string & getName() const
Get the name of the BaseComponent.
Definition baseComponent.h:151
TimeConverter registerTimeBase(const std::string &base, bool reg_all=true)
Registers a default timebase for the component and optionally sets the the component's links to that ...
Definition baseComponent.cc:409
void registerAsPrimaryComponent()
Register as a primary component, which allows the component to specify when it is and is not OK to en...
Definition baseComponent.cc:870
TimeConverter registerClock(TimeConverter tc, Clock::HandlerBase *handler, bool reg_all=true)
Registers a clock for this component.
Definition baseComponent.cc:382
virtual void setup()
Called after all components have been constructed and initialization has completed,...
Definition baseComponent.h:181
Link * configureLink(const std::string &name, objT *obj)
Configure a Link using the component's default timebase.
Definition baseComponent.h:530
uint8_t getStatisticLoadLevel() const
Get the BaseComponent Statistic load level.
Definition baseComponent.h:139
UnitAlgebra getCoreTimeBase() const
Get the core timebase.
Definition baseComponent.cc:118
Cycle_t reregisterClock(TimeConverter freq, Clock::HandlerBase *handler)
Reactivates an existing Clock and Handler.
Definition baseComponent.cc:395
void initiateInteractive(const std::string &msg)
Tell the simulation object to initiate interactive mode (if currently turned on).
Definition baseComponent.cc:436
Link * configureSelfLink(const std::string &name, objT *obj, dataT data)
Configure a SelfLink (Loopback link) with metadata, that uses the (Sub)Component's defaultTimeBase.
Definition baseComponent.h:679
Link * configureLink(const std::string &name, TimeConverter timebase, objT *obj)
Configure a Link.
Definition baseComponent.h:479
std::string & getOutputDirectory() const
Returns the output directory of the simulation.
Definition baseComponent.cc:348
double getCompletePhaseElapsedRealTime() const
Get the amount of real-time spent executing the complete phase of the simulation.
Definition baseComponent.cc:232
void performStatisticOutput(Statistics::StatisticBase *stat)
Called by the Components and Subcomponent to perform a statistic Output.
Definition baseComponent.cc:647
int getCurrentPriority() const
Get the current priority.
Definition baseComponent.cc:130
double getInitPhaseElapsedRealTime() const
Get the amount of real-time spent executing the init phase of the simulation.
Definition baseComponent.cc:226
Link * configureSelfLink(const std::string &name, TimeConverter timebase, Event::HandlerBase *handler=nullptr)
Configure a SelfLink (Loopback link).
Definition baseComponent.h:575
void performGlobalStatisticOutput()
Performs a global statistic Output.
Definition baseComponent.cc:653
bool isSubComponentLoadableUsingAPI(const std::string &type)
Check to see if a given element type is loadable with a particular API.
Definition baseComponent.h:1165
const std::vector< double > & getCoordinates() const
Retrieve the X,Y,Z coordinates of this component.
Definition baseComponent.h:1422
const std::string & getParentComponentName() const
Get the name of the parent Component for the Component tree.
Definition baseComponent.h:159
virtual void init(unsigned int UNUSED(phase))
Used during the init phase.
Definition baseComponent.h:167
SimTime_t getCurrentSimTime() const
Return the simulated time since the simulation began in the default timebase.
Definition baseComponent.h:267
UnitAlgebra getElapsedSimTime() const
get the elapsed simulation time as a UnitAlgebra
Definition baseComponent.cc:136
SimTime_t getCurrentSimTimeMicro() const
Utility function to return the time since the simulation began in microseconds.
Definition baseComponent.cc:203
void addWatchPoint(WatchPoint *pt)
Add a watch point to all handlers in the Component Tree.
Definition baseComponent.cc:239
static Output & getSimulationOutput()
Get the default simulation Output class instance.
Definition baseComponent.cc:166
RankInfo getNumRanks() const
Get the number of parallel ranks in the simulation.
Definition baseComponent.cc:160
UnitAlgebra getEndSimTime() const
Get the end simulation time as a UnitAlgebra.
Definition baseComponent.cc:148
void sst_assert(bool condition, uint32_t line, const char *file, const char *func, int exit_code, const char *format,...) const
Convenience function for testing for and reporting fatal conditions.
Definition baseComponent.cc:669
Link * configureSelfLink(const std::string &name, TimeConverter timebase, objT *obj)
Configure a SelfLink (Loopback link).
Definition baseComponent.h:609
T::ProfilePoint * registerProfilePoint(const std::string &point_name)
Registers a profiling point.
Definition baseComponent.h:1109
bool isSimulationRunModeBoth() const
Check to see if the run mode was set to BOTH.
Definition baseComponent.cc:342
RankInfo getRank() const
Get this instance's parallel rank.
Definition baseComponent.cc:154
Link * configureLink(const std::string &name, TimeConverter timebase, objT *obj, dataT data)
Configure a Link with metadata.
Definition baseComponent.h:508
virtual void emergencyShutdown()
Called when SIGINT or SIGTERM has been seen.
Definition baseComponent.h:144
SimTime_t getCurrentSimTime(const char *base) const
Return the simulated time since the simulation began in the specified timebase.
Definition baseComponent.h:306
Clock::HandlerBase * registerClock(TimeConverter tc, objT *obj, dataT metadata, bool reg_all=true)
Registers a clock handler with metadata for this component.
Definition baseComponent.h:772
void primaryComponentOKToEndSim()
Tells the simulation that it is now OK to end simulation.
Definition baseComponent.cc:909
Statistics::Statistic< T > * registerStatistic(SST::Params &params, const std::string &stat_name, const std::string &stat_sub_id="")
Registers a statistic.
Definition baseComponent.h:1048
Clock::HandlerBase * registerOrderedClock(TimeConverter tc, uint16_t order, objT *obj, dataT metadata, bool reg_all=true)
Registers an ordered clock handler with metadata for this component.
Definition baseComponent.h:833
T * loadUserSubComponent(const std::string &slot_name, uint64_t share_flags, ARGS... args)
Loads a user defined subcomponent (defined in input file to SST run).
Definition baseComponent.h:1273
const std::string & getType() const
Gets the ELI type for this BaseComponent.
Definition baseComponent.h:125
SimTime_t getCurrentSimTimeNano() const
Utility function to return the time since the simulation began in nanoseconds.
Definition baseComponent.cc:195
T * loadAnonymousSubComponent(const std::string &type, const std::string &slot_name, int slot_num, uint64_t share_flags, Params &params, ARGS... args)
Loads an anonymous subcomponent (not defined in input file to SST run).
Definition baseComponent.h:1225
Cycle_t getNextClockCycle(TimeConverter freq)
Returns the next Cycle that the TimeConverter would fire.
Definition baseComponent.cc:402
void primaryComponentDoNotEndSim()
Tells the simulation that it should not exit.
Definition baseComponent.cc:889
ComponentId_t getId() const
Get the unique component ID.
Definition baseComponent.h:132
void unregisterClock(TimeConverter tc, Clock::HandlerBase *handler)
Removes a clock handler from the component.
Definition baseComponent.cc:389
bool isUserSubComponentLoadableUsingAPI(const std::string &slot_name)
Check to see if the element type loaded by the user into the.
Definition baseComponent.h:1181
Link * configureLink(const std::string &name, TimeConverter timebase, Event::HandlerBase *handler=nullptr)
Configure a Link.
Definition baseComponent.h:446
virtual void finish()
Called after complete phase, but before objects are destroyed.
Definition baseComponent.h:186
SimTime_t getEndSimCycle() const
Get the end simulation time as a cycle count.
Definition baseComponent.cc:142
virtual bool Status()
Currently unused function.
Definition baseComponent.h:189
Clock::HandlerBase * registerOrderedClock(TimeConverter tc, uint16_t order, objT *obj, bool reg_all=true)
Registers an ordered clock handler for this component.
Definition baseComponent.h:801
Link * configureSelfLink(const std::string &name, TimeConverter timebase, objT *obj, dataT data)
Configure a SelfLink (Loopback link) with metadata.
Definition baseComponent.h:635
SimTime_t getCurrentSimCycle() const
Get the current simulation time as a cycle count.
Definition baseComponent.cc:124
virtual void printStatus(Output &UNUSED(out))
Called by the Simulation to request that the component print its current status.
Definition baseComponent.h:196
T * loadModule(const std::string &type, Params &params, ARGS... args)
Loads a module from an element Library.
Definition baseComponent.h:1138
Base classes for clock handlers.
Definition clock.h:146
A Clock class.
Definition clock.h:40
SSTHandler< bool, Cycle_t, classT, dataT, funcT, HandlerBase > Handler
Used to create handlers for clock.
Definition clock.h:295
ComponentExtension is a class that can be loaded using loadComponentExtension<T>(....
Definition componentExtension.h:29
Definition componentInfo.h:45
Main component object for the simulation.
Definition component.h:32
Definition serializable_base.h:121
Base serialize class.
Definition serialize.h:133
This class is basically a wrapper for objects to declare the order in which their members should be s...
Definition serializer.h:43
SSTHandler< void, Event *, classT, dataT, funcT > Handler
Used to create handlers for event delivery.
Definition event.h:69
SSTHandlerBase< void, Event * > HandlerBase
Base handler for event delivery.
Definition event.h:48
Maps port names to the Links that are connected to it.
Definition linkMap.h:30
Module is a tag class used with the loadModule function.
Definition module.h:26
Output object provides consistent method for outputting data to stdout, stderr and/or sst debug file.
Definition output.h:58
void fatal(uint32_t line, const char *file, const char *func, int exit_code, const char *format,...) const
Output the fatal message with formatting as specified by the format parameter.
Definition output.cc:156
@ STDERR
Definition output.h:65
Parameter store.
Definition params.h:65
Definition rankInfo.h:24
Main control class for a SST Simulation.
Definition simulation.h:121
Forms the base class for statistics gathering within SST.
Definition statbase.h:51
An SST core component that handles timing and event processing informing all registered Statistics to...
Definition statengine.h:55
Forms the template defined base class for statistics gathering within SST.
Definition statbase.h:376
Used to load SubComponents when multiple SubComponents are loaded into a single slot (will also also ...
Definition baseComponent.h:1658
T * create(int slot_num) const
Create a user defined subcomponent (defined in input file to SST run).
Definition baseComponent.h:1730
void createAllSparse(std::vector< std::pair< int, T * > > &vec, uint64_t share_flags, ARGS... args) const
Create all user defined subcomponents (defined in input file to SST run) for the slot.
Definition baseComponent.h:1793
bool isLoadableUsingAPI(int slot_num)
Check to see if the element type loaded by the user into the specified slot index is loadable with a ...
Definition baseComponent.h:1712
void createAll(std::vector< T * > &vec, uint64_t share_flags, ARGS... args) const
Create all user defined subcomponents (defined in input file to SST run) for the slot.
Definition baseComponent.h:1769
T * create(int slot_num, uint64_t share_flags, ARGS... args) const
Create a user defined subcomponent (defined in input file to SST run).
Definition baseComponent.h:1749
void createAllSparse(std::vector< T * > &vec, uint64_t share_flags, ARGS... args) const
Create all user defined subcomponents (defined in input file to SST run) for the slot.
Definition baseComponent.h:1815
SubComponent is a class loadable through the factory which allows dynamic functionality to be added t...
Definition subcomponent.h:29
A class to convert between a component's view of time and the core's view of time.
Definition timeConverter.h:31
SimTime_t getFactor() const
Definition timeConverter.h:91
Performs Unit math in full precision.
Definition unitAlgebra.h:107
Class that can attach to Clock and Event Handlers to monitor the state of variables.
Definition watchPoint.h:29
Extracts the owning class from a pointer-to-member-function type.
Definition baseComponent.h:72