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