SST  14.0.0
StructuralSimulationToolkit
baseComponent.h
1 // Copyright 2009-2024 NTESS. Under the terms
2 // of Contract DE-NA0003525 with NTESS, the U.S.
3 // Government retains certain rights in this software.
4 //
5 // Copyright (c) 2009-2024, NTESS
6 // All rights reserved.
7 //
8 // This file is part of the SST software package. For license
9 // information, see the LICENSE file in the top level directory of the
10 // distribution.
11 
12 #ifndef SST_CORE_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/oneshot.h"
21 #include "sst/core/profile/componentProfileTool.h"
22 #include "sst/core/sst_types.h"
23 #include "sst/core/statapi/statbase.h"
24 #include "sst/core/statapi/statengine.h"
25 #include "sst/core/warnmacros.h"
26 
27 #include <map>
28 #include <string>
29 
30 using namespace SST::Statistics;
31 
32 namespace SST {
33 
34 class Component;
35 class ComponentExtension;
36 class Clock;
37 class Link;
38 class LinkMap;
39 class Module;
40 class Params;
41 class Simulation;
42 class Simulation_impl;
43 class SubComponent;
44 class SubComponentSlotInfo;
45 class TimeConverter;
46 class UnitAlgebra;
47 
48 /**
49  * Main component object for the simulation.
50  */
52 {
53 
54  friend class Component;
55  friend class ComponentExtension;
56  friend class ComponentInfo;
57  friend class SubComponent;
58  friend class SubComponentSlotInfo;
59 
60 protected:
61  using StatCreateFunction = std::function<Statistics::StatisticBase*(
62  BaseComponent*, Statistics::StatisticProcessingEngine*, const std::string& /*type*/,
63  const std::string& /*name*/, const std::string& /*subId*/, Params&)>;
64 
65  // For serialization only
66  BaseComponent();
67 
68 public:
69  BaseComponent(ComponentId_t id);
70  virtual ~BaseComponent();
71 
72  const std::string& getType() const { return my_info->getType(); }
73 
74  /** Returns unique component ID */
75  inline ComponentId_t getId() const { return my_info->id; }
76 
77  /** Returns Component Statistic load level */
78  inline uint8_t getStatisticLoadLevel() const { return my_info->statLoadLevel; }
79 
80  /** Called when SIGINT or SIGTERM has been seen.
81  * Allows components opportunity to clean up external state.
82  */
83  virtual void emergencyShutdown(void) {}
84 
85  /** Returns Component/SubComponent Name */
86  inline const std::string& getName() const { return my_info->getName(); }
87 
88  /** Returns the name of the parent Component, or, if called on a
89  * Component, the name of that Component. */
90  inline const std::string& getParentComponentName() const { return my_info->getParentComponentName(); }
91 
92  /** Used during the init phase. The method will be called each
93  phase of initialization. Initialization ends when no components
94  have sent any data. */
95  virtual void init(unsigned int UNUSED(phase)) {}
96  /** Used during the complete phase after the end of simulation.
97  The method will be called each phase of complete. Complete phase
98  ends when no components have sent any data. */
99  virtual void complete(unsigned int UNUSED(phase)) {}
100  /** Called after all components have been constructed and
101  initialization has completed, but before simulation time has
102  begun. */
103  virtual void setup() {}
104  /** Called after complete phase, but before objects are
105  destroyed. A good place to print out statistics. */
106  virtual void finish() {}
107 
108  /** Currently unused function */
109  virtual bool Status() { return 0; }
110 
111  /**
112  * Called by the Simulation to request that the component
113  * print it's current status. Useful for debugging.
114  * @param out The Output class which should be used to print component status.
115  */
116  virtual void printStatus(Output& UNUSED(out)) { return; }
117 
118  /** Get the core timebase */
119  UnitAlgebra getCoreTimeBase() const;
120  /** Return the current simulation time as a cycle count*/
121  SimTime_t getCurrentSimCycle() const;
122  /** Return the current priority */
123  int getCurrentPriority() const;
124  /** Return the elapsed simulation time as a time */
125  UnitAlgebra getElapsedSimTime() const;
126  /** Return the end simulation time as a cycle count*/
127  SimTime_t getEndSimCycle() const;
128  /** Return the end simulation time as a time */
129  UnitAlgebra getEndSimTime() const;
130  /** Get this instance's parallel rank */
131  RankInfo getRank() const;
132  /** Get the number of parallel ranks in the simulation */
133  RankInfo getNumRanks() const;
134  /** Return the base simulation Output class instance */
135  Output& getSimulationOutput() const;
136 
137  /** return the time since the simulation began in units specified by
138  the parameter.
139  @param tc TimeConverter specifying the units */
140  SimTime_t getCurrentSimTime(TimeConverter* tc) const;
141  /** return the time since the simulation began in the default timebase */
142  inline SimTime_t getCurrentSimTime() const { return getCurrentSimTime(my_info->defaultTimeBase); }
143  /** return the time since the simulation began in timebase specified
144  @param base Timebase frequency in SI Units */
145  SimTime_t getCurrentSimTime(const std::string& base) const;
146 
147  /** Utility function to return the time since the simulation began in nanoseconds */
148  SimTime_t getCurrentSimTimeNano() const;
149  /** Utility function to return the time since the simulation began in microseconds */
150  SimTime_t getCurrentSimTimeMicro() const;
151  /** Utility function to return the time since the simulation began in milliseconds */
152  SimTime_t getCurrentSimTimeMilli() const;
153 
154  /** Get the amount of real-time spent executing the run phase of
155  * the simulation.
156  *
157  * @return real-time in seconds spent executing the run phase
158  */
159  double getRunPhaseElapsedRealTime() const;
160 
161  /** Get the amount of real-time spent executing the init phase of
162  * the simulation.
163  *
164  * @return real-time in seconds spent executing the init phase
165  */
166  double getInitPhaseElapsedRealTime() const;
167 
168  /** Get the amount of real-time spent executing the complete phase of
169  * the simulation.
170  *
171  * @return real-time in seconds spent executing the complete phase
172  */
173  double getCompletePhaseElapsedRealTime() const;
174 
175 
176 protected:
177  /** Check to see if the run mode was set to INIT
178  @return true if simulation run mode is set to INIT
179  */
180  bool isSimulationRunModeInit() const;
181 
182  /** Check to see if the run mode was set to RUN
183  @return true if simulation run mode is set to RUN
184  */
185  bool isSimulationRunModeRun() const;
186 
187  /** Check to see if the run mode was set to BOTH
188  @return true if simulation run mode is set to BOTH
189  */
190  bool isSimulationRunModeBoth() const;
191 
192  /** Returns the output directory of the simulation
193  * @return Directory in which simulation outputs should be
194  * placed. Returns empty string if output directory not set by
195  * user.
196  */
197  std::string& getOutputDirectory() const;
198 
199  /** Signifies that a library is required for this simulation.
200  * Causes the Factory to verify that the required library is
201  * loaded.
202  *
203  * NOTE: This function should rarely be required, as most
204  * dependencies are automatically detected in the simulator core.
205  * However, if the component uses an event from another library
206  * that is not wholly defined in a header file, this call may be
207  * required to ensure that all the code from the event is loaded.
208  * Similarly, if you use a class from another library that does
209  * not have ELI information, this call may also be required to
210  * make sure all dependencies are loaded.
211  *
212  * @param name Name of library this BaseComponent depends on
213  */
214  void requireLibrary(const std::string& name);
215 
216 
217  /** Determine if a port name is connected to any links */
218  bool isPortConnected(const std::string& name) const;
219 
220  /** Configure a Link
221  * @param name - Port Name on which the link to configure is attached.
222  * @param time_base - Time Base of the link. If nullptr is passed in, then it
223  * will use the Component defaultTimeBase
224  * @param handler - Optional Handler to be called when an Event is received
225  * @return A pointer to the configured link, or nullptr if an error occured.
226  */
227  Link* configureLink(const std::string& name, TimeConverter* time_base, Event::HandlerBase* handler = nullptr);
228  /** Configure a Link
229  * @param name - Port Name on which the link to configure is attached.
230  * @param time_base - Time Base of the link as a string
231  * @param handler - Optional Handler to be called when an Event is received
232  * @return A pointer to the configured link, or nullptr if an error occured.
233  */
234  Link* configureLink(const std::string& name, const std::string& time_base, Event::HandlerBase* handler = nullptr);
235  /** Configure a Link
236  * @param name - Port Name on which the link to configure is attached.
237  * @param time_base - Time Base of the link as a UnitAlgebra
238  * @param handler - Optional Handler to be called when an Event is received
239  * @return A pointer to the configured link, or nullptr if an error occured.
240  */
241  Link* configureLink(const std::string& name, const UnitAlgebra& time_base, Event::HandlerBase* handler = nullptr);
242  /** Configure a Link
243  * @param name - Port Name on which the link to configure is attached.
244  * @param handler - Optional Handler to be called when an Event is received
245  * @return A pointer to the configured link, or nullptr if an error occured.
246  */
247  Link* configureLink(const std::string& name, Event::HandlerBase* handler = nullptr);
248 
249  /** Configure a SelfLink (Loopback link)
250  * @param name - Name of the self-link port
251  * @param time_base - Time Base of the link. If nullptr is passed in, then it
252  * will use the Component defaultTimeBase
253  * @param handler - Optional Handler to be called when an Event is received
254  * @return A pointer to the configured link, or nullptr if an error occured.
255  */
256  Link* configureSelfLink(const std::string& name, TimeConverter* time_base, Event::HandlerBase* handler = nullptr);
257  /** Configure a SelfLink (Loopback link)
258  * @param name - Name of the self-link port
259  * @param time_base - Time Base of the link as a string
260  * @param handler - Optional Handler to be called when an Event is received
261  * @return A pointer to the configured link, or nullptr if an error occured.
262  */
263  Link*
264  configureSelfLink(const std::string& name, const std::string& time_base, Event::HandlerBase* handler = nullptr);
265  /** Configure a SelfLink (Loopback link)
266  * @param name - Name of the self-link port
267  * @param time_base - Time Base of the link as a UnitAlgebra
268  * @param handler - Optional Handler to be called when an Event is received
269  * @return A pointer to the configured link, or nullptr if an error occured.
270  */
271  Link*
272  configureSelfLink(const std::string& name, const UnitAlgebra& time_base, Event::HandlerBase* handler = nullptr);
273  /** Configure a SelfLink (Loopback link)
274  * @param name - Name of the self-link port
275  * @param handler - Optional Handler to be called when an Event is received
276  * @return A pointer to the configured link, or nullptr if an error occured.
277  */
278  Link* configureSelfLink(const std::string& name, Event::HandlerBase* handler = nullptr);
279 
280  /** Registers a clock for this component.
281  @param freq Frequency for the clock in SI units
282  @param handler Pointer to Clock::HandlerBase which is to be invoked
283  at the specified interval
284  @param regAll Should this clock period be used as the default
285  time base for all of the links connected to this component
286  @return the TimeConverter object representing the clock frequency
287  */
288  TimeConverter* registerClock(const std::string& freq, Clock::HandlerBase* handler, bool regAll = true);
289 
290  /** Registers a clock for this component.
291  @param freq Frequency for the clock as a UnitAlgebra object
292  @param handler Pointer to Clock::HandlerBase which is to be invoked
293  at the specified interval
294  @param regAll Should this clock period be used as the default
295  time base for all of the links connected to this component
296  @return the TimeConverter object representing the clock frequency
297  */
298  TimeConverter* registerClock(const UnitAlgebra& freq, Clock::HandlerBase* handler, bool regAll = true);
299 
300  /** Registers a clock for this component.
301  @param tc TimeConverter object specifying the clock frequency
302  @param handler Pointer to Clock::HandlerBase which is to be invoked
303  at the specified interval
304  @param regAll Should this clock period be used as the default
305  time base for all of the links connected to this component
306  @return the TimeConverter object representing the clock frequency
307  */
308  TimeConverter* registerClock(TimeConverter* tc, Clock::HandlerBase* handler, bool regAll = true);
309 
310  /** Removes a clock handler from the component */
311  void unregisterClock(TimeConverter* tc, Clock::HandlerBase* handler);
312 
313  /** Reactivates an existing Clock and Handler
314  * @return time of next time clock handler will fire
315  *
316  * Note: If called after the simulation run loop (e.g., in finish() or complete()),
317  * will return the next time of the clock past when the simulation ended. There can
318  * be a small lag between simulation end and detection of simulation end during which
319  * clocks can run a few extra cycles. As a result, the return value just prior to
320  * simulation end may be greater than the value returned after simulation end.
321  */
322  Cycle_t reregisterClock(TimeConverter* freq, Clock::HandlerBase* handler);
323 
324  /** Returns the next Cycle that the TimeConverter would fire
325  If called prior to the simulation run loop, next Cycle is 0.
326  If called after the simulation run loop completes (e.g., during
327  complete() or finish()), next Cycle is one past the end time of
328  the simulation. See Note in reregisterClock() for additional guidance
329  when calling this function after simulation ends.
330  */
331  Cycle_t getNextClockCycle(TimeConverter* freq);
332 
333  /** Registers a default time base for the component and optionally
334  sets the the component's links to that timebase. Useful for
335  components which do not have a clock, but would like a default
336  timebase.
337  @param base Frequency for the clock in SI units
338  @param regAll Should this clock period be used as the default
339  time base for all of the links connected to this component
340  */
341  TimeConverter* registerTimeBase(const std::string& base, bool regAll = true);
342 
343  TimeConverter* getTimeConverter(const std::string& base) const;
344  TimeConverter* getTimeConverter(const UnitAlgebra& base) const;
345 
346  bool isStatisticShared(const std::string& statName, bool include_me = false)
347  {
348  if ( include_me ) {
349  if ( doesComponentInfoStatisticExist(statName) ) { return true; }
350  }
351  if ( my_info->sharesStatistics() ) {
352  return my_info->parent_info->component->isStatisticShared(statName, true);
353  }
354  else {
355  return false;
356  }
357  }
358 
359 private:
360  ImplementSerializable(SST::BaseComponent)
361  void serialize_order(SST::Core::Serialization::serializer& ser) override;
362 
363 
364  /**
365  Handles the profile points, default time base, handler tracking
366  and checkpointing.
367  */
368  void registerClock_impl(TimeConverter* tc, Clock::HandlerBase* handler, bool regAll);
369 
370  template <typename T>
371  Statistics::Statistic<T>*
372  createStatistic(SST::Params& params, StatisticId_t id, const std::string& name, const std::string& statSubId)
373  {
374  /* I would prefer to avoid this std::function with dynamic cast,
375  * but the code is just a lot cleaner and avoids many unnecessary template instantiations
376  * doing it this way. At some point in the future, we would need to clean up
377  * the rule around enabling all statistics to make this better
378  */
379 
380  StatCreateFunction create = [=](BaseComponent* comp, Statistics::StatisticProcessingEngine* engine,
381  const std::string& type, const std::string& name, const std::string& subId,
382  SST::Params& params) -> Statistics::StatisticBase* {
383  return engine->createStatistic<T>(comp, type, name, subId, params);
384  };
385 
386  // We follow two distinct paths depending on if it is enable all, versus explicitly enabled
387  // Enable all is "scoped" to the (sub)component
388  // Explicitly enabled stats are assigned component-unique IDs and can be shared across subcomponents
389  // so creation and management happens in the parent component
390  Statistics::StatisticBase* base_stat =
391  id == STATALL_ID ? createEnabledAllStatistic(params, name, statSubId, std::move(create))
392  : getParentComponent()->createExplicitlyEnabledStatistic(
393  params, id, name, statSubId, std::move(create));
394 
395  // Ugh, dynamic casts hurt my eyes, but I must do this
396  auto* statistic = dynamic_cast<Statistics::Statistic<T>*>(base_stat);
397  if ( statistic ) { return statistic; }
398  else {
399  fatal(
400  __LINE__, __FILE__, "createStatistic", 1, "failed to cast created statistic '%s' to expected type",
401  name.c_str());
402  return nullptr; // avoid compiler warnings
403  }
404  }
405 
406  template <typename T>
407  Statistics::Statistic<T>*
408  createNullStatistic(SST::Params& params, const std::string& name, const std::string& statSubId = "")
409  {
410  auto* engine = getStatEngine();
411  return engine->createStatistic<T>(my_info->component, "sst.NullStatistic", name, statSubId, params);
412  }
413 
414  template <typename T>
415  Statistics::Statistic<T>*
416  registerStatistic(SST::Params& params, const std::string& statName, const std::string& statSubId, bool inserting)
417  {
418  if ( my_info->enabledStatNames ) {
419  auto iter = my_info->enabledStatNames->find(statName);
420  if ( iter != my_info->enabledStatNames->end() ) {
421  // valid, enabled statistic
422  // During initialization, the component should have assigned a mapping between
423  // the local name and globally unique stat ID
424  StatisticId_t id = iter->second;
425  return createStatistic<T>(params, id, statName, statSubId);
426  }
427  }
428 
429  // if we got here, this is not a stat we explicitly enabled
430  if ( inserting || doesComponentInfoStatisticExist(statName) ) {
431  // this is a statistic that I registered
432  if ( my_info->enabledAllStats ) { return createStatistic<T>(params, STATALL_ID, statName, statSubId); }
433  else if ( my_info->parent_info && my_info->canInsertStatistics() ) {
434  // I did not explicitly enable nor enable all
435  // but I can insert statistics into my parent
436  // and my parent may have enabled all
437  return my_info->parent_info->component->registerStatistic<T>(params, statName, statSubId, true);
438  }
439  else {
440  // I did not enable, I cannot insert into parent - so send back null stat
441  return my_info->component->createNullStatistic<T>(params, statName, statSubId);
442  }
443  }
444  else if ( my_info->parent_info && my_info->sharesStatistics() ) {
445  // this is not a statistic that I registered
446  // but my parent can share statistics, maybe they enabled
447  return my_info->parent_info->component->registerStatistic<T>(params, statName, statSubId, false);
448  }
449  else {
450  // not a valid stat and I won't be able to share my parent's statistic
451  fatal(
452  __LINE__, __FILE__, "registerStatistic", 1, "attempting to register unknown statistic '%s'",
453  statName.c_str());
454  return nullptr; // get rid of warning
455  }
456  }
457 
458 protected:
459  /** Registers a statistic.
460  If Statistic is allowed to run (controlled by Python runtime parameters),
461  then a statistic will be created and returned. If not allowed to run,
462  then a NullStatistic will be returned. In either case, the returned
463  value should be used for all future Statistic calls. The type of
464  Statistic and the Collection Rate is set by Python runtime parameters.
465  If no type is defined, then an Accumulator Statistic will be provided
466  by default. If rate set to 0 or not provided, then the statistic will
467  output results only at end of sim (if output is enabled).
468  @param params Parameter set to be passed to the statistic constructor.
469  @param statName Primary name of the statistic. This name must match the
470  defined ElementInfoStatistic in the component, and must also
471  be enabled in the Python input file.
472  @param statSubId An additional sub name for the statistic
473  @return Either a created statistic of desired type or a NullStatistic
474  depending upon runtime settings.
475  */
476  template <typename T>
477  Statistics::Statistic<T>*
478  registerStatistic(SST::Params& params, const std::string& statName, const std::string& statSubId = "")
479  {
480  return registerStatistic<T>(params, statName, statSubId, false);
481  }
482 
483  template <typename T>
484  Statistics::Statistic<T>* registerStatistic(const std::string& statName, const std::string& statSubId = "")
485  {
486  SST::Params empty {};
487  return registerStatistic<T>(empty, statName, statSubId, false);
488  }
489 
490  template <typename... Args>
491  Statistics::Statistic<std::tuple<Args...>>*
492  registerMultiStatistic(const std::string& statName, const std::string& statSubId = "")
493  {
494  SST::Params empty {};
495  return registerStatistic<std::tuple<Args...>>(empty, statName, statSubId, false);
496  }
497 
498  template <typename... Args>
499  Statistics::Statistic<std::tuple<Args...>>*
500  registerMultiStatistic(SST::Params& params, const std::string& statName, const std::string& statSubId = "")
501  {
502  return registerStatistic<std::tuple<Args...>>(params, statName, statSubId, false);
503  }
504 
505  template <typename T>
506  Statistics::Statistic<T>* registerStatistic(const char* statName, const char* statSubId = "")
507  {
508  return registerStatistic<T>(std::string(statName), std::string(statSubId));
509  }
510 
511  /** Called by the Components and Subcomponent to perform a statistic Output.
512  * @param stat - Pointer to the statistic.
513  * @param EndOfSimFlag - Indicates that the output is occurring at the end of simulation.
514  */
515  void performStatisticOutput(Statistics::StatisticBase* stat);
516 
517  /** Performs a global statistic Output.
518  * This routine will force ALL Components and Subcomponents to output their statistic information.
519  * This may lead to unexpected results if the statistic counts or data is reset on output.
520  * NOTE: Currently, this function will only output statistics that are on the same rank.
521  */
522  void performGlobalStatisticOutput();
523 
524  /** Registers a profiling point.
525  This function will register a profiling point.
526  @param point Point to resgister
527  @return Either a pointer to a created T::ProfilePoint or nullptr if not enabled.
528  */
529  template <typename T>
530  typename T::ProfilePoint* registerProfilePoint(const std::string& pointName)
531  {
532  std::string full_point_name = getType() + "." + pointName;
533  auto tools = getComponentProfileTools(full_point_name);
534  if ( tools.size() == 0 ) return nullptr;
535 
536  typename T::ProfilePoint* ret = new typename T::ProfilePoint();
537  for ( auto* x : tools ) {
538  T* tool = dynamic_cast<T*>(x);
539  if ( nullptr == tool ) {
540  // Not the right type, fatal
541  fatal(
542  CALL_INFO_LONG, 1, "ERROR: wrong type of profiling tool for profiling point %s)\n",
543  pointName.c_str());
544  }
545  ret->registerProfilePoint(tool, pointName, getId(), getName(), getType());
546  }
547  return ret;
548  }
549 
550  /** Loads a module from an element Library
551  * @param type Fully Qualified library.moduleName
552  * @param params Parameters the module should use for configuration
553  * @return handle to new instance of module, or nullptr on failure.
554  */
555  template <class T, class... ARGS>
556  T* loadModule(const std::string& type, Params& params, ARGS... args)
557  {
558 
559  // Check to see if this can be loaded with new API or if we have to fallback to old
560  return Factory::getFactory()->CreateWithParams<T>(type, params, params, args...);
561  }
562 
563 protected:
564  // When you direct load, the ComponentExtension does not need any
565  // ELI information and if it has any, it will be ignored. The
566  // extension will be loaded as if it were part of the parent
567  // BaseComponent and will share all that components ELI
568  // information.
569  template <class T, class... ARGS>
570  T* loadComponentExtension(ARGS... args)
571  {
572  ComponentExtension* ret = new T(my_info->id, args...);
573  return static_cast<T*>(ret);
574  }
575 
576  /**
577  Check to see if a given element type is loadable with a particular API
578 
579  @param name - Name of element to check in lib.name format
580  @return True if loadable as the API specified as the template parameter
581  */
582  template <class T>
583  bool isSubComponentLoadableUsingAPI(const std::string& type)
584  {
585  return Factory::getFactory()->isSubComponentLoadableUsingAPI<T>(type);
586  }
587 
588  /**
589  Check to see if the element type loaded by the user into the.
590  specified slot is loadable with a particular API. This will
591  only check slot index 0. If you need to check other slots,
592  please use the SubComponentSlotInfo.
593 
594  @param slot_name - Name of slot to check
595  @return True if loadable as the API specified as the template parameter
596  */
597  template <class T>
598  bool isUserSubComponentLoadableUsingAPI(const std::string& slot_name)
599  {
600  // Get list of ComponentInfo objects and make sure that there is
601  // only one SubComponent put into this slot
602  // const std::vector<ComponentInfo>& subcomps = my_info->getSubComponents();
603  const std::map<ComponentId_t, ComponentInfo>& subcomps = my_info->getSubComponents();
604  int sub_count = 0;
605  int index = -1;
606  for ( auto& ci : subcomps ) {
607  if ( ci.second.getSlotName() == slot_name ) {
608  index = ci.second.getSlotNum();
609  sub_count++;
610  }
611  }
612 
613  if ( sub_count > 1 ) {
614  SST::Output outXX("SubComponentSlotWarning: ", 0, 0, Output::STDERR);
615  outXX.fatal(
616  CALL_INFO, 1,
617  "Error: ComponentSlot \"%s\" in component \"%s\" only allows for one SubComponent, %d provided.\n",
618  slot_name.c_str(), my_info->getType().c_str(), sub_count);
619  }
620 
621  return isUserSubComponentLoadableUsingAPIByIndex<T>(slot_name, index);
622  }
623 
624  /**
625  Loads an anonymous subcomponent (not defined in input file to
626  SST run).
627 
628  @param type tyupe of subcomponent to load in lib.name format
629  @param slot_name name of the slot to load subcomponent into
630  @param slot_num index of the slot to load subcomponent into
631  @param share_flags Share flags to be used by subcomponent
632  @param params Params object to be passed to subcomponent
633  @param args Arguments to be passed to constructor. This
634  signature is defined in the API definition
635 
636  For ease in backward compatibility to old API, this call will
637  try to load using new API and will fallback to old if
638  unsuccessful.
639  */
640  template <class T, class... ARGS>
642  const std::string& type, const std::string& slot_name, int slot_num, uint64_t share_flags, Params& params,
643  ARGS... args)
644  {
645 
646  share_flags = share_flags & ComponentInfo::USER_FLAGS;
647  ComponentId_t cid = my_info->addAnonymousSubComponent(my_info, type, slot_name, slot_num, share_flags);
648  ComponentInfo* sub_info = my_info->findSubComponent(cid);
649 
650  // This shouldn't happen since we just put it in, but just in case
651  if ( sub_info == nullptr ) return nullptr;
652 
653  // Check to see if this can be loaded with new API or if we have to fallback to old
654  if ( isSubComponentLoadableUsingAPI<T>(type) ) {
655  auto ret = Factory::getFactory()->CreateWithParams<T>(type, params, sub_info->id, params, args...);
656  return ret;
657  }
658  return nullptr;
659  }
660 
661  /**
662  Loads a user defined subcomponent (defined in input file to SST
663  run). This version does not allow share flags (set to
664  SHARE_NONE) or constructor arguments.
665 
666  @param slot_name name of the slot to load subcomponent into
667 
668  For ease in backward compatibility to old API, this call will
669  try to load using new API and will fallback to old if
670  unsuccessful.
671  */
672  template <class T>
673  T* loadUserSubComponent(const std::string& slot_name)
674  {
675  return loadUserSubComponent<T>(slot_name, ComponentInfo::SHARE_NONE);
676  }
677 
678  /**
679  Loads a user defined subcomponent (defined in input file to SST
680  run).
681 
682  @param slot_name name of the slot to load subcomponent into
683  @param share_flags Share flags to be used by subcomponent
684  @param args Arguments to be passed to constructor. This
685  signature is defined in the API definition
686 
687  For ease in backward compatibility to old API, this call will
688  try to load using new API and will fallback to old if
689  unsuccessful.
690  */
691  template <class T, class... ARGS>
692  T* loadUserSubComponent(const std::string& slot_name, uint64_t share_flags, ARGS... args)
693  {
694 
695  // Get list of ComponentInfo objects and make sure that there is
696  // only one SubComponent put into this slot
697  // const std::vector<ComponentInfo>& subcomps = my_info->getSubComponents();
698  const std::map<ComponentId_t, ComponentInfo>& subcomps = my_info->getSubComponents();
699  int sub_count = 0;
700  int index = -1;
701  for ( auto& ci : subcomps ) {
702  if ( ci.second.getSlotName() == slot_name ) {
703  index = ci.second.getSlotNum();
704  sub_count++;
705  }
706  }
707 
708  if ( sub_count > 1 ) {
709  SST::Output outXX("SubComponentSlotWarning: ", 0, 0, Output::STDERR);
710  outXX.fatal(
711  CALL_INFO, 1,
712  "Error: ComponentSlot \"%s\" in component \"%s\" only allows for one SubComponent, %d provided.\n",
713  slot_name.c_str(), my_info->getType().c_str(), sub_count);
714  }
715 
716  return loadUserSubComponentByIndex<T, ARGS...>(slot_name, index, share_flags, args...);
717  }
718 
719  /** Convenience function for reporting fatal conditions. The
720  function will create a new Output object and call fatal()
721  using the supplied parameters. Before calling
722  Output::fatal(), the function will also print other
723  information about the (sub)component that called fatal and
724  about the simulation state.
725 
726  From Output::fatal: Message will be sent to the output
727  location and to stderr. The output will be prepended with the
728  expanded prefix set in the object.
729  NOTE: fatal() will call MPI_Abort(exit_code) to terminate simulation.
730 
731  @param line Line number of calling function (use CALL_INFO macro)
732  @param file File name calling function (use CALL_INFO macro)
733  @param func Function name calling function (use CALL_INFO macro)
734  @param exit_code The exit code used for termination of simulation.
735  will be passed to MPI_Abort()
736  @param format Format string. All valid formats for printf are available.
737  @param ... Arguments for format.
738  */
739  void fatal(uint32_t line, const char* file, const char* func, int exit_code, const char* format, ...) const
740  __attribute__((format(printf, 6, 7)));
741 
742  /** Convenience function for testing for and reporting fatal
743  conditions. If the condition holds, fatal() will be called,
744  otherwise, the function will return. The function will create
745  a new Output object and call fatal() using the supplied
746  parameters. Before calling Output::fatal(), the function will
747  also print other information about the (sub)component that
748  called fatal and about the simulation state.
749 
750  From Output::fatal: Message will be sent to the output
751  location and to stderr. The output will be prepended with the
752  expanded prefix set in the object.
753  NOTE: fatal() will call MPI_Abort(exit_code) to terminate simulation.
754 
755  @param condition on which to call fatal(); fatal() is called
756  if the bool is false.
757  @param line Line number of calling function (use CALL_INFO macro)
758  @param file File name calling function (use CALL_INFO macro)
759  @param func Function name calling function (use CALL_INFO macro)
760  @param exit_code The exit code used for termination of simulation.
761  will be passed to MPI_Abort()
762  @param format Format string. All valid formats for printf are available.
763  @param ... Arguments for format.
764  */
765  void sst_assert(
766  bool condition, uint32_t line, const char* file, const char* func, int exit_code, const char* format, ...) const
767  __attribute__((format(printf, 7, 8)));
768 
769 private:
770  SimTime_t processCurrentTimeWithUnderflowedBase(const std::string& base) const;
771 
772  void
773  configureCollectionMode(Statistics::StatisticBase* statistic, const SST::Params& params, const std::string& name);
774 
775  /**
776  * @brief findExplicitlyEnabledStatistic
777  * @param params
778  * @param id
779  * @param name
780  * @param statSubId
781  * @return that matching stat if the stat already was created for the given ID, otherwise nullptr
782  */
783  Statistics::StatisticBase* createExplicitlyEnabledStatistic(
784  SST::Params& params, StatisticId_t id, const std::string& name, const std::string& statSubId,
785  StatCreateFunction create);
786 
787  /**
788  * @brief createStatistic Helper function used by both enable all and explicit enable
789  * @param cpp_params Any parameters given in C++ specific to this statistic
790  * @param python_params Any parameters given in Python for this statistic
791  * @param name The name (different from type) for this statistic
792  * @param statSubId An optional sub ID for this statistic if multiple stats might have the same name
793  * @param create A type-erased factory for creating stats of a particulary type T
794  * @return The statistic created
795  */
796  Statistics::StatisticBase* createStatistic(
797  SST::Params& cpp_params, const SST::Params& python_params, const std::string& name,
798  const std::string& statSubId, bool check_load_level, StatCreateFunction create);
799 
800  Statistics::StatisticBase* createEnabledAllStatistic(
801  SST::Params& params, const std::string& name, const std::string& statSubId, StatCreateFunction create);
802 
803  void configureAllowedStatParams(SST::Params& params);
804 
805  void setDefaultTimeBaseForLinks(TimeConverter* tc);
806 
807  void pushValidParams(Params& params, const std::string& type);
808 
809  template <class T, class... ARGS>
810  T* loadUserSubComponentByIndex(const std::string& slot_name, int slot_num, int share_flags, ARGS... args)
811  {
812 
813  share_flags = share_flags & ComponentInfo::USER_FLAGS;
814 
815  // Check to see if the slot exists
816  ComponentInfo* sub_info = my_info->findSubComponent(slot_name, slot_num);
817  if ( sub_info == nullptr ) return nullptr;
818  sub_info->share_flags = share_flags;
819  sub_info->parent_info = my_info;
820 
821  if ( isSubComponentLoadableUsingAPI<T>(sub_info->type) ) {
822  auto ret = Factory::getFactory()->CreateWithParams<T>(
823  sub_info->type, *sub_info->params, sub_info->id, *sub_info->params, args...);
824  return ret;
825  }
826  return nullptr;
827  }
828 
829  template <class T>
830  bool isUserSubComponentLoadableUsingAPIByIndex(const std::string& slot_name, int slot_num)
831  {
832  // Check to see if the slot exists
833  ComponentInfo* sub_info = my_info->findSubComponent(slot_name, slot_num);
834  if ( sub_info == nullptr ) return false;
835 
836  return isSubComponentLoadableUsingAPI<T>(sub_info->type);
837  }
838 
839  // Utility function used by fatal and sst_assert
840  void
841  vfatal(uint32_t line, const char* file, const char* func, int exit_code, const char* format, va_list arg) const;
842 
843  // Get the statengine from Simulation_impl
844  StatisticProcessingEngine* getStatEngine();
845 
846 public:
847  SubComponentSlotInfo* getSubComponentSlotInfo(const std::string& name, bool fatalOnEmptyIndex = false);
848 
849  /** Retrieve the X,Y,Z coordinates of this component */
850  const std::vector<double>& getCoordinates() const { return my_info->coordinates; }
851 
852 protected:
854  friend class SST::Statistics::StatisticBase;
855 
856  bool isAnonymous() { return my_info->isAnonymous(); }
857 
858  bool isUser() { return my_info->isUser(); }
859 
860  /** Manually set the default detaulTimeBase */
861  void setDefaultTimeBase(TimeConverter* tc) { my_info->defaultTimeBase = tc; }
862 
863  TimeConverter* getDefaultTimeBase() { return my_info->defaultTimeBase; }
864 
865  const TimeConverter* getDefaultTimeBase() const { return my_info->defaultTimeBase; }
866 
867  bool doesSubComponentExist(const std::string& type);
868 
869  // Does the statisticName exist in the ElementInfoStatistic
870  bool doesComponentInfoStatisticExist(const std::string& statisticName) const;
871  // Return the EnableLevel for the statisticName from the ElementInfoStatistic
872  uint8_t getComponentInfoStatisticEnableLevel(const std::string& statisticName) const;
873  // Return the Units for the statisticName from the ElementInfoStatistic
874  // std::string getComponentInfoStatisticUnits(const std::string& statisticName) const;
875 
876  std::vector<Profile::ComponentProfileTool*> getComponentProfileTools(const std::string& point);
877 
878 private:
879  ComponentInfo* my_info = nullptr;
880  Simulation_impl* sim_ = nullptr;
881  bool isExtension = false;
882 
883  // Need to track clock handlers for checkpointing. We need to
884  // know what clock handlers we have registered with the core
885  std::vector<Clock::HandlerBase*> clock_handlers;
886 
887  void addSelfLink(const std::string& name);
888  Link* getLinkFromParentSharedPort(const std::string& port);
889 
890  using StatNameMap = std::map<std::string, std::map<std::string, Statistics::StatisticBase*>>;
891 
892  std::map<StatisticId_t, Statistics::StatisticBase*> m_explicitlyEnabledSharedStats;
893  std::map<StatisticId_t, StatNameMap> m_explicitlyEnabledUniqueStats;
894  StatNameMap m_enabledAllStats;
895 
896  BaseComponent* getParentComponent()
897  {
898  ComponentInfo* base_info = my_info;
899  while ( base_info->parent_info ) {
900  base_info = base_info->parent_info;
901  }
902  return base_info->component;
903  }
904 };
905 
906 /**
907  Used to load SubComponents when multiple SubComponents are loaded
908  into a single slot (will also also work when a single SubComponent
909  is loaded).
910  */
912 {
913 
914  BaseComponent* comp;
915  std::string slot_name;
916  int max_slot_index;
917 
918 public:
920 
921  SubComponentSlotInfo(BaseComponent* comp, const std::string& slot_name) : comp(comp), slot_name(slot_name)
922  {
923  const std::map<ComponentId_t, ComponentInfo>& subcomps = comp->my_info->getSubComponents();
924 
925  // Look for all subcomponents with the right slot name
926  max_slot_index = -1;
927  for ( auto& ci : subcomps ) {
928  if ( ci.second.getSlotName() == slot_name ) {
929  if ( ci.second.getSlotNum() > static_cast<int>(max_slot_index) ) {
930  max_slot_index = ci.second.getSlotNum();
931  }
932  }
933  }
934  }
935 
936  const std::string& getSlotName() const { return slot_name; };
937 
938  bool isPopulated(int slot_num) const
939  {
940  if ( slot_num > max_slot_index ) return false;
941  if ( comp->my_info->findSubComponent(slot_name, slot_num) == nullptr ) return false;
942  return true;
943  }
944 
945  bool isAllPopulated() const
946  {
947  for ( int i = 0; i < max_slot_index; ++i ) {
948  if ( comp->my_info->findSubComponent(slot_name, i) == nullptr ) return false;
949  }
950  return true;
951  }
952 
953  int getMaxPopulatedSlotNumber() const { return max_slot_index; }
954 
955  /**
956  Check to see if the element type loaded by the user into the
957  specified slot index is loadable with a particular API.
958 
959  @param slot_num Slot index to check
960  @return True if loadable as the API specified as the template parameter
961  */
962  template <class T>
963  bool isLoadableUsingAPI(int slot_num)
964  {
965  return comp->isUserSubComponentLoadableUsingAPIByIndex<T>(slot_name, slot_num);
966  }
967 
968  // Create functions that support the new API
969 
970  /**
971  Create a user defined subcomponent (defined in input file to
972  SST run). This call will pass SHARE_NONE to the new
973  subcomponent and will not take constructor arguments. If
974  constructor arguments are needed for the API that is being
975  loaded, the full call to create will need to be used
976  create(slot_num, share_flags, args...).
977 
978  @param slot_num Slot index from which to load subcomponent
979 
980  This function supports the new API, but is identical to an
981  existing API call. It will try to load using new API and will
982  fallback to old if unsuccessful.
983  */
984  template <typename T>
985  T* create(int slot_num) const
986  {
987  Params empty;
988  return comp->loadUserSubComponentByIndex<T>(slot_name, slot_num, ComponentInfo::SHARE_NONE);
989  // return private_create<T>(slot_num, empty);
990  }
991 
992  /**
993  Create a user defined subcomponent (defined in input file to SST
994  run).
995 
996  @param slot_num Slot index from which to load subcomponent
997  @param share_flags Share flags to be used by subcomponent
998  @param args Arguments to be passed to constructor. This
999  signature is defined in the API definition
1000 
1001  For ease in backward compatibility to old API, this call will
1002  try to load using new API and will fallback to old if
1003  unsuccessful.
1004  */
1005  template <class T, class... ARGS>
1006  T* create(int slot_num, uint64_t share_flags, ARGS... args) const
1007  {
1008  return comp->loadUserSubComponentByIndex<T, ARGS...>(slot_name, slot_num, share_flags, args...);
1009  }
1010 
1011  /**
1012  Create all user defined subcomponents (defined in input file to SST
1013  run) for the slot.
1014 
1015  @param vec Vector of T* that will hold the pointers to the new
1016  subcomponents. If an index is not occupied, a nullptr will be
1017  put in it's place. All components will be added to the end of
1018  the vector, so index N will be at vec.length() + N, where
1019  vec.length() is the length of the vector when it is passed to
1020  the call.
1021  @param share_flags Share flags to be used by subcomponent
1022  @param args Arguments to be passed to constructor. This
1023  signature is defined in the API definition
1024 
1025  For ease in backward compatibility to old API, this call will
1026  try to load using new API and will fallback to old if
1027  unsuccessful.
1028  */
1029  template <typename T, class... ARGS>
1030  void createAll(std::vector<T*>& vec, uint64_t share_flags, ARGS... args) const
1031  {
1032  for ( int i = 0; i <= getMaxPopulatedSlotNumber(); ++i ) {
1033  T* sub = create<T>(i, share_flags, args...);
1034  vec.push_back(sub);
1035  }
1036  }
1037 
1038  /**
1039  Create all user defined subcomponents (defined in input file to SST
1040  run) for the slot.
1041 
1042  @param vec Vector of pair<int,T*> that will hold the pointers
1043  to the new subcomponents. The int will hold the index from
1044  which the subcomponent wass loaded. Unoccupied indexes will be
1045  skipped. All components will be added to the end of the
1046  vector.
1047  @param share_flags Share flags to be used by subcomponent
1048  @param args Arguments to be passed to constructor. This
1049  signature is defined in the API definition
1050 
1051  For ease in backward compatibility to old API, this call will
1052  try to load using new API and will fallback to old if
1053  unsuccessful.
1054  */
1055  template <typename T, class... ARGS>
1056  void createAllSparse(std::vector<std::pair<int, T*>>& vec, uint64_t share_flags, ARGS... args) const
1057  {
1058  for ( int i = 0; i <= getMaxPopulatedSlotNumber(); ++i ) {
1059  T* sub = create<T>(i, share_flags, args...);
1060  if ( sub != nullptr ) vec.push_back(i, sub);
1061  }
1062  }
1063 
1064  /**
1065  Create all user defined subcomponents (defined in input file to SST
1066  run) for the slot.
1067 
1068  @param vec Vector of T* that will hold the pointers
1069  to the new subcomponents. Unoccupied indexes will be
1070  skipped. All components will be added to the end of the
1071  vector.
1072  @param share_flags Share flags to be used by subcomponent
1073  @param args Arguments to be passed to constructor. This
1074  signature is defined in the API definition
1075 
1076  For ease in backward compatibility to old API, this call will
1077  try to load using new API and will fallback to old if
1078  unsuccessful.
1079  */
1080  template <typename T, class... ARGS>
1081  void createAllSparse(std::vector<T*>& vec, uint64_t share_flags, ARGS... args) const
1082  {
1083  for ( int i = 0; i <= getMaxPopulatedSlotNumber(); ++i ) {
1084  T* sub = create<T>(i, share_flags, args...);
1085  if ( sub != nullptr ) vec.push_back(sub);
1086  }
1087  }
1088 };
1089 
1090 namespace Core {
1091 namespace Serialization {
1092 
1093 template <class T>
1095 {
1096  template <class A>
1097  friend class serialize;
1098  void operator()(Statistic<T>*& s, serializer& ser)
1099  {
1100  // For sizer and pack, only need to get the information needed
1101  // to create a NullStatistic on unpack.
1102  switch ( ser.mode() ) {
1103  case serializer::SIZER:
1104  case serializer::PACK:
1105  {
1106  BaseComponent* comp = s->getComponent();
1107  ser& comp;
1108  break;
1109  }
1110  case serializer::UNPACK:
1111  {
1112  Params params;
1113  BaseComponent* comp;
1114  ser& comp;
1115  s = Factory::getFactory()->CreateWithParams<Statistic<T>>(
1116  "sst.NullStatistic", params, comp, "", "", params);
1117  break;
1118  }
1119  }
1120  }
1121 };
1122 
1123 } // namespace Serialization
1124 } // namespace Core
1125 
1126 } // namespace SST
1127 
1128 #endif // SST_CORE_BASECOMPONENT_H
Output object provides consistent method for outputting data to stdout, stderr and/or sst debug file...
Definition: output.h:53
ComponentId_t getId() const
Returns unique component ID.
Definition: baseComponent.h:75
virtual void complete(unsigned int UNUSED(phase))
Used during the complete phase after the end of simulation.
Definition: baseComponent.h:99
This class is basically a wrapper for objects to declare the order in which their members should be s...
Definition: serializer.h:35
Handlers with 1 handler defined argument to callback from caller.
Definition: ssthandler.h:210
const std::string & getParentComponentName() const
Returns the name of the parent Component, or, if called on a Component, the name of that Component...
Definition: baseComponent.h:90
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:160
virtual void printStatus(Output &UNUSED(out))
Called by the Simulation to request that the component print it&#39;s current status. ...
Definition: baseComponent.h:116
bool isSubComponentLoadableUsingAPI(const std::string &type)
Check to see if a given element type is loadable with a particular API.
Definition: baseComponent.h:583
T::ProfilePoint * registerProfilePoint(const std::string &pointName)
Registers a profiling point.
Definition: baseComponent.h:530
SSTHandlerBase< bool, Cycle_t > HandlerBase
Base handler for clock functions.
Definition: clock.h:42
A class to convert between a component&#39;s view of time and the core&#39;s view of time.
Definition: timeConverter.h:27
Main component object for the simulation.
Definition: component.h:30
virtual void finish()
Called after complete phase, but before objects are destroyed.
Definition: baseComponent.h:106
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:1006
T * loadUserSubComponent(const std::string &slot_name)
Loads a user defined subcomponent (defined in input file to SST run).
Definition: baseComponent.h:673
Base serialize class.
Definition: serialize.h:32
Forms the base class for statistics gathering within SST.
Definition: statbase.h:64
ComponentExtension is a class that can be loaded using loadComponentExtension<T>(...).
Definition: componentExtension.h:28
Definition: action.cc:18
virtual void emergencyShutdown(void)
Called when SIGINT or SIGTERM has been seen.
Definition: baseComponent.h:83
Forms the template defined base class for statistics gathering within SST.
Definition: elementinfo.h:44
Definition: serializable.h:118
virtual void setup()
Called after all components have been constructed and initialization has completed, but before simulation time has begun.
Definition: baseComponent.h:103
bool isUserSubComponentLoadableUsingAPI(const std::string &slot_name)
Check to see if the element type loaded by the user into the.
Definition: baseComponent.h:598
BaseComponent * getComponent() const
Return a pointer to the parent Component.
Definition: statbase.h:144
Serialization "gateway" object.
Definition: serialize.h:110
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:1030
Definition: rankInfo.h:21
T * loadModule(const std::string &type, Params &params, ARGS... args)
Loads a module from an element Library.
Definition: baseComponent.h:556
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:641
Main component object for the simulation.
Definition: baseComponent.h:51
Definition: output.h:61
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:963
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:1056
Statistics::Statistic< T > * registerStatistic(SST::Params &params, const std::string &statName, const std::string &statSubId="")
Registers a statistic.
Definition: baseComponent.h:478
SimTime_t getCurrentSimTime() const
return the time since the simulation began in the default timebase
Definition: baseComponent.h:142
virtual bool Status()
Currently unused function.
Definition: baseComponent.h:109
Parameter store.
Definition: params.h:55
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:692
T * create(int slot_num) const
Create a user defined subcomponent (defined in input file to SST run).
Definition: baseComponent.h:985
Definition: componentInfo.h:40
Used to load SubComponents when multiple SubComponents are loaded into a single slot (will also also ...
Definition: baseComponent.h:911
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:1081
uint8_t getStatisticLoadLevel() const
Returns Component Statistic load level.
Definition: baseComponent.h:78
Definition: componentInfo.h:36
An SST core component that handles timing and event processing informing all registered Statistics to...
Definition: statengine.h:51
Performs Unit math in full precision.
Definition: unitAlgebra.h:106
void setDefaultTimeBase(TimeConverter *tc)
Manually set the default detaulTimeBase.
Definition: baseComponent.h:861
SubComponent is a class loadable through the factory which allows dynamic functionality to be added t...
Definition: subcomponent.h:28
const std::vector< double > & getCoordinates() const
Retrieve the X,Y,Z coordinates of this component.
Definition: baseComponent.h:850
const std::string & getName() const
Returns Component/SubComponent Name.
Definition: baseComponent.h:86
virtual void init(unsigned int UNUSED(phase))
Used during the init phase.
Definition: baseComponent.h:95