SST  10.0.0
StructuralSimulationToolkit
baseComponent.h
1 // Copyright 2009-2020 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-2020, 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/sst_types.h"
16 #include "sst/core/warnmacros.h"
17 
18 #include <map>
19 #include <string>
20 
21 #include "sst/core/simulation.h"
22 #include "sst/core/statapi/statengine.h"
23 #include "sst/core/statapi/statbase.h"
24 #include "sst/core/event.h"
25 #include "sst/core/clock.h"
26 #include "sst/core/oneshot.h"
27 #include "sst/core/componentInfo.h"
28 #include "sst/core/eli/elementinfo.h"
29 
30 using namespace SST::Statistics;
31 
32 namespace SST {
33 
34 class Clock;
35 class Link;
36 class LinkMap;
37 class Module;
38 class Params;
39 class SubComponent;
40 class TimeConverter;
41 class UnitAlgebra;
42 class SharedRegion;
43 class SharedRegionMerger;
44 class Component;
45 class ComponentExtension;
46 class SubComponent;
47 class SubComponentSlotInfo;
48 
49 /**
50  * Main component object for the simulation.
51  */
53 
54  friend class SubComponentSlotInfo;
55  friend class SubComponent;
56  friend class ComponentInfo;
57  friend class ComponentExtension;
58 
59 public:
60 
61  BaseComponent(ComponentId_t id);
62  BaseComponent() {}
63  virtual ~BaseComponent();
64 
65  const std::string& getType() const { return my_info->getType(); }
66 
67  /** Returns unique component ID */
68  inline ComponentId_t getId() const { return my_info->id; }
69 
70  /** Called when SIGINT or SIGTERM has been seen.
71  * Allows components opportunity to clean up external state.
72  */
73  virtual void emergencyShutdown(void) {}
74 
75 
76  /** Returns component Name */
77  /* inline const std::string& getName() const { return name; } */
78  inline const std::string& getName() const { return my_info->getName(); }
79 
80 
81  /** Used during the init phase. The method will be called each phase of initialization.
82  Initialization ends when no components have sent any data. */
83  virtual void init(unsigned int UNUSED(phase)) {}
84  /** Used during the init phase. The method will be called each phase of initialization.
85  Initialization ends when no components have sent any data. */
86  virtual void complete(unsigned int UNUSED(phase)) {}
87  /** Called after all components have been constructed and initialization has
88  completed, but before simulation time has begun. */
89  virtual void setup( ) { }
90  /** Called after simulation completes, but before objects are
91  destroyed. A good place to print out statistics. */
92  virtual void finish( ) { }
93 
94  /** Currently unused function */
95  virtual bool Status( ) { return 0; }
96 
97  /**
98  * Called by the Simulation to request that the component
99  * print it's current status. Useful for debugging.
100  * @param out The Output class which should be used to print component status.
101  */
102  virtual void printStatus(Output &UNUSED(out)) { return; }
103 
104 
105  /** Return the current simulation time as a cycle count*/
106  SimTime_t getCurrentSimCycle() const;
107  /** Return the current priority */
108  int getCurrentPriority() const;
109  /** Return the elapsed simulation time as a time */
110  UnitAlgebra getElapsedSimTime() const;
111  /** Return the end simulation time as a time */
112  UnitAlgebra getFinalSimTime() const;
113  /** Get this instance's parallel rank */
114  RankInfo getRank() const;
115  /** Get the number of parallel ranks in the simulation */
116  RankInfo getNumRanks() const;
117  /** Return the base simulation Output class instance */
118  Output& getSimulationOutput() const;
119 
120 
121  /** return the time since the simulation began in units specified by
122  the parameter.
123  @param tc TimeConverter specifying the units */
124  SimTime_t getCurrentSimTime(TimeConverter *tc) const;
125  /** return the time since the simulation began in the default timebase */
126  inline SimTime_t getCurrentSimTime() const {
127  return getCurrentSimTime(my_info->defaultTimeBase);
128  }
129  /** return the time since the simulation began in timebase specified
130  @param base Timebase frequency in SI Units */
131  SimTime_t getCurrentSimTime(const std::string& base) const;
132 
133  /** Utility function to return the time since the simulation began in nanoseconds */
134  SimTime_t getCurrentSimTimeNano() const;
135  /** Utility function to return the time since the simulation began in microseconds */
136  SimTime_t getCurrentSimTimeMicro() const;
137  /** Utility function to return the time since the simulation began in milliseconds */
138  SimTime_t getCurrentSimTimeMilli() const;
139 
140 
141 protected:
142 
143  /** Determine if a port name is connected to any links */
144  bool isPortConnected(const std::string& name) const;
145 
146  /** Configure a Link
147  * @param name - Port Name on which the link to configure is attached.
148  * @param time_base - Time Base of the link. If nullptr is passed in, then it
149  * will use the Component defaultTimeBase
150  * @param handler - Optional Handler to be called when an Event is received
151  * @return A pointer to the configured link, or nullptr if an error occured.
152  */
153  Link* configureLink( const std::string& name, TimeConverter* time_base, Event::HandlerBase* handler = nullptr);
154  /** Configure a Link
155  * @param name - Port Name on which the link to configure is attached.
156  * @param time_base - Time Base of the link as a string
157  * @param handler - Optional Handler to be called when an Event is received
158  * @return A pointer to the configured link, or nullptr if an error occured.
159  */
160  Link* configureLink( const std::string& name, const std::string& time_base, Event::HandlerBase* handler = nullptr);
161  /** Configure a Link
162  * @param name - Port Name on which the link to configure is attached.
163  * @param handler - Optional Handler to be called when an Event is received
164  * @return A pointer to the configured link, or nullptr if an error occured.
165  */
166  Link* configureLink( const std::string& name, Event::HandlerBase* handler = nullptr);
167 
168  /** Configure a SelfLink (Loopback link)
169  * @param name - Name of the self-link port
170  * @param time_base - Time Base of the link. If nullptr is passed in, then it
171  * will use the Component defaultTimeBase
172  * @param handler - Optional Handler to be called when an Event is received
173  * @return A pointer to the configured link, or nullptr if an error occured.
174  */
175  Link* configureSelfLink( const std::string& name, TimeConverter* time_base, Event::HandlerBase* handler = nullptr);
176  /** Configure a SelfLink (Loopback link)
177  * @param name - Name of the self-link port
178  * @param time_base - Time Base of the link
179  * @param handler - Optional Handler to be called when an Event is received
180  * @return A pointer to the configured link, or nullptr if an error occured.
181  */
182  Link* configureSelfLink( const std::string& name, const std::string& time_base, Event::HandlerBase* handler = nullptr);
183  /** Configure a SelfLink (Loopback link)
184  * @param name - Name of the self-link port
185  * @param handler - Optional Handler to be called when an Event is received
186  * @return A pointer to the configured link, or nullptr if an error occured.
187  */
188  Link* configureSelfLink( const std::string& name, Event::HandlerBase* handler = nullptr);
189 
190  /** Registers a clock for this component.
191  @param freq Frequency for the clock in SI units
192  @param handler Pointer to Clock::HandlerBase which is to be invoked
193  at the specified interval
194  @param regAll Should this clock period be used as the default
195  time base for all of the links connected to this component
196  @return the TimeConverter object representing the clock frequency
197  */
198  TimeConverter* registerClock( const std::string& freq, Clock::HandlerBase* handler,
199  bool regAll = true);
200 
201  /** Registers a clock for this component.
202  @param freq Frequency for the clock as a UnitAlgebra object
203  @param handler Pointer to Clock::HandlerBase which is to be invoked
204  at the specified interval
205  @param regAll Should this clock period be used as the default
206  time base for all of the links connected to this component
207  @return the TimeConverter object representing the clock frequency
208  */
209  TimeConverter* registerClock( const UnitAlgebra& freq, Clock::HandlerBase* handler,
210  bool regAll = true);
211 
212  /** Registers a clock for this component.
213  @param tc TimeConverter object specifying the clock frequency
214  @param handler Pointer to Clock::HandlerBase which is to be invoked
215  at the specified interval
216  @param regAll Should this clock period be used as the default
217  time base for all of the links connected to this component
218  @return the TimeConverter object representing the clock frequency
219  */
220  TimeConverter* registerClock( TimeConverter *tc, Clock::HandlerBase* handler, bool regAll = true);
221 
222  /** Removes a clock handler from the component */
223  void unregisterClock(TimeConverter *tc, Clock::HandlerBase* handler);
224 
225  /** Reactivates an existing Clock and Handler
226  * @return time of next time clock handler will fire
227  */
228  Cycle_t reregisterClock(TimeConverter *freq, Clock::HandlerBase* handler);
229  /** Returns the next Cycle that the TimeConverter would fire */
230  Cycle_t getNextClockCycle(TimeConverter *freq);
231 
232  /** Registers a OneShot event for this component.
233  Note: OneShot cannot be canceled, and will always callback after
234  the timedelay.
235  @param timeDelay Time delay for the OneShot in SI units
236  @param handler Pointer to OneShot::HandlerBase which is to be invoked
237  at the specified interval
238  */
239  TimeConverter* registerOneShot( const std::string& timeDelay, OneShot::HandlerBase* handler) __attribute__ ((deprecated("registerOneShot is deprecated and will be removed in SST 11. Please use configureSelfLink to create a mechanism for waking up Component/SubComponents")));
240  TimeConverter* registerOneShot( const UnitAlgebra& timeDelay, OneShot::HandlerBase* handler) __attribute__ ((deprecated("registerOneShot is deprecated and will be removed in SST 11. Please use configureSelfLink to create a mechanism for waking up Component/SubComponents")));
241 
242  /** Registers a default time base for the component and optionally
243  sets the the component's links to that timebase. Useful for
244  components which do not have a clock, but would like a default
245  timebase.
246  @param base Frequency for the clock in SI units
247  @param regAll Should this clock period be used as the default
248  time base for all of the links connected to this component
249  */
250  TimeConverter* registerTimeBase( const std::string& base, bool regAll = true);
251 
252  TimeConverter* getTimeConverter( const std::string& base ) const;
253  TimeConverter* getTimeConverter( const UnitAlgebra& base ) const;
254 
255  TimeConverter* getTimeConverterNano() const;
256  TimeConverter* getTimeConverterMicro() const;
257  TimeConverter* getTimeConverterMilli() const;
258 
259 
260  bool isStatisticShared(const std::string& statName, bool include_me = false) {
261  if ( include_me ) {
262  if ( doesComponentInfoStatisticExist(statName)) {
263  return true;
264  }
265  }
266  if ( my_info->sharesStatistics() ) {
267  return my_info->parent_info->component->isStatisticShared(statName, true);
268  }
269  else {
270  return false;
271  }
272  }
273 
274 
275  /** Registers a statistic.
276  If Statistic is allowed to run (controlled by Python runtime parameters),
277  then a statistic will be created and returned. If not allowed to run,
278  then a NullStatistic will be returned. In either case, the returned
279  value should be used for all future Statistic calls. The type of
280  Statistic and the Collection Rate is set by Python runtime parameters.
281  If no type is defined, then an Accumulator Statistic will be provided
282  by default. If rate set to 0 or not provided, then the statistic will
283  output results only at end of sim (if output is enabled).
284  @param statName Primary name of the statistic. This name must match the
285  defined ElementInfoStatistic in the component, and must also
286  be enabled in the Python input file.
287  @param statSubId An additional sub name for the statistic
288  @return Either a created statistic of desired type or a NullStatistic
289  depending upon runtime settings.
290  */
291  template <typename T>
292  Statistic<T>* registerStatistic(SST::Params& params, const std::string& statName, const std::string& statSubId = "")
293  {
294  // Verify here that name of the stat is one of the registered
295  // names of the component's ElementInfoStatistic.
296  if (false == doesComponentInfoStatisticExist(statName)) {
297  // I don't define this statistic, so it must be inherited (or non-existant)
298  if ( my_info->sharesStatistics() ) {
299  return my_info->parent_info->component->registerStatistic<T>(params, statName, statSubId);
300  }
301  else {
302  printf("Error: Statistic %s name %s is not found in ElementInfoStatistic, exiting...\n",
303  StatisticBase::buildStatisticFullName(getName().c_str(), statName, statSubId).c_str(),
304  statName.c_str());
305  exit(1);
306  }
307  }
308  // Check to see if the Statistic is previously registered with the Statistics Engine
309  auto* engine = StatisticProcessingEngine::getInstance();
310  StatisticBase* stat = engine->isStatisticRegisteredWithEngine(getName(), my_info->getID(), statName, statSubId, StatisticFieldType<T>::id());
311 
312  if (!stat){
313  //stat does not exist yet
314  auto makeInstance = [=](const std::string& type, BaseComponent* comp,
315  const std::string& name, const std::string& subName,
316  SST::Params& params) -> StatisticBase* {
317  return engine->createStatistic<T>(comp, type, name, subName, params);
318  };
319  stat = registerStatisticCore(params, statName, statSubId, StatisticFieldType<T>::id(),
320  std::move(makeInstance));
321  }
322  return dynamic_cast<Statistic<T>*>(stat);
323  }
324 
325  template <typename T>
326  Statistic<T>* registerStatistic(const std::string& statName, const std::string& statSubId = "")
327  {
328  SST::Params empty{};
329  return registerStatistic<T>(empty, statName, statSubId);
330  }
331 
332  template <typename... Args>
333  Statistic<std::tuple<Args...>>* registerMultiStatistic(const std::string& statName, const std::string& statSubId = "")
334  {
335  SST::Params empty{};
336  return registerStatistic<std::tuple<Args...>>(empty, statName, statSubId);
337  }
338 
339  template <typename... Args>
340  Statistic<std::tuple<Args...>>* registerMultiStatistic(SST::Params& params, const std::string& statName,
341  const std::string& statSubId = "")
342  {
343  return registerStatistic<std::tuple<Args...>>(params, statName, statSubId);
344  }
345 
346  template <typename T>
347  Statistic<T>* registerStatistic(const char* statName, const char* statSubId = "")
348  {
349  return registerStatistic<T>(std::string(statName), std::string(statSubId));
350  }
351 
352  /** Called by the Components and Subcomponent to perform a statistic Output.
353  * @param stat - Pointer to the statistic.
354  * @param EndOfSimFlag - Indicates that the output is occurring at the end of simulation.
355  */
356  void performStatisticOutput(StatisticBase* stat);
357 
358  /** Performs a global statistic Output.
359  * This routine will force ALL Components and Subcomponents to output their statistic information.
360  * This may lead to unexpected results if the statistic counts or data is reset on output.
361  * NOTE: Currently, this function will only output statistics that are on the same rank.
362  */
363  void performGlobalStatisticOutput();
364 
365  /** Loads a module from an element Library
366  * @param type Fully Qualified library.moduleName
367  * @param params Parameters the module should use for configuration
368  * @return handle to new instance of module, or nullptr on failure.
369  */
370  Module* loadModule(const std::string& type, Params& params);
371 
372  /** Loads a module from an element Library
373  * @param type Fully Qualified library.moduleName
374  * @param params Parameters the module should use for configuration
375  * @return handle to new instance of module, or nullptr on failure.
376  */
377  template <class T, class... ARGS>
378  T* loadModule(const std::string& type, Params& params, ARGS... args) {
379 
380  // Check to see if this can be loaded with new API or if we have to fallback to old
381  return Factory::getFactory()->Create<T>(type, params, params, args...);
382  }
383 
384 
385 protected:
386  // When you direct load, the ComponentExtension does not need any
387  // ELI information and if it has any, it will be ignored. The
388  // extension will be loaded as if it were part of the part
389  // BaseComponent and will share all that components ELI
390  // information.
391  template <class T, class... ARGS>
392  T* loadComponentExtension(ARGS... args) {
393  ComponentExtension* ret = new T(my_info->id, args...);
394  return static_cast<T*>(ret);
395  }
396 
397  /**
398  Check to see if a given element type is loadable with a particular API
399  @param name - Name of element to check in lib.name format
400  @return True if loadable as the API specified as the template parameter
401  */
402  template <class T>
403  bool isSubComponentLoadableUsingAPI(const std::string& type) {
404  return Factory::getFactory()->isSubComponentLoadableUsingAPI<T>(type);
405  }
406 
407  /**
408  Loads an anonymous subcomponent (not defined in input file to
409  SST run).
410 
411  @param type tyupe of subcomponent to load in lib.name format
412  @param slot_name name of the slot to load subcomponent into
413  @param slot_num index of the slot to load subcomponent into
414  @param share_flags Share flags to be used by subcomponent
415  @param params Params object to be passed to subcomponent
416  @param args Arguments to be passed to constructor. This
417  signature is defined in the API definition
418 
419  For ease in backward compatibility to old API, this call will
420  try to load using new API and will fallback to old if
421  unsuccessful.
422  */
423  template <class T, class... ARGS>
424  T* loadAnonymousSubComponent(const std::string& type, const std::string& slot_name, int slot_num, uint64_t share_flags, Params& params, ARGS... args) {
425 
426  share_flags = share_flags & ComponentInfo::USER_FLAGS;
427  ComponentId_t cid = my_info->addAnonymousSubComponent(my_info, type, slot_name, slot_num, share_flags);
428  ComponentInfo* sub_info = my_info->findSubComponent(cid);
429 
430  //This shouldn't happen since we just put it in, but just in case
431  if ( sub_info == nullptr ) return nullptr;
432 
433  // Check to see if this can be loaded with new API or if we have to fallback to old
434  if ( isSubComponentLoadableUsingAPI<T>(type) ) {
435  auto ret = Factory::getFactory()->Create<T>(type, params, sub_info->id, params, args...);
436  return ret;
437  }
438  return nullptr;
439  }
440 
441 
442  /**
443  Loads a user defined subcomponent (defined in input file to SST
444  run). This version does not allow share flags (set to
445  SHARE_NONE) or constructor arguments.
446 
447  @param slot_name name of the slot to load subcomponent into
448 
449  For ease in backward compatibility to old API, this call will
450  try to load using new API and will fallback to old if
451  unsuccessful.
452  */
453  template <class T>
454  T* loadUserSubComponent(const std::string& slot_name) {
455  return loadUserSubComponent<T>(slot_name, ComponentInfo::SHARE_NONE);
456  }
457 
458  /**
459  Loads a user defined subcomponent (defined in input file to SST
460  run).
461 
462  @param slot_name name of the slot to load subcomponent into
463  @param share_flags Share flags to be used by subcomponent
464  @param args Arguments to be passed to constructor. This
465  signature is defined in the API definition
466 
467  For ease in backward compatibility to old API, this call will
468  try to load using new API and will fallback to old if
469  unsuccessful.
470  */
471  template <class T, class... ARGS>
472  T* loadUserSubComponent(const std::string& slot_name, uint64_t share_flags, ARGS... args) {
473 
474  // Get list of ComponentInfo objects and make sure that there is
475  // only one SubComponent put into this slot
476  // const std::vector<ComponentInfo>& subcomps = my_info->getSubComponents();
477  const std::map<ComponentId_t,ComponentInfo>& subcomps = my_info->getSubComponents();
478  int sub_count = 0;
479  int index = -1;
480  for ( auto &ci : subcomps ) {
481  if ( ci.second.getSlotName() == slot_name ) {
482  index = ci.second.getSlotNum();
483  sub_count++;
484  }
485  }
486 
487  if ( sub_count > 1 ) {
488  SST::Output outXX("SubComponentSlotWarning: ", 0, 0, Output::STDERR);
489  outXX.fatal(CALL_INFO, 1, "Error: ComponentSlot \"%s\" in component \"%s\" only allows for one SubComponent, %d provided.\n",
490  slot_name.c_str(), my_info->getType().c_str(), sub_count);
491  }
492 
493  return loadUserSubComponentByIndex<T,ARGS...>(slot_name, index, share_flags, args...);
494  }
495 
496 
497  /** Convenience function for reporting fatal conditions. The
498  function will create a new Output object and call fatal()
499  using the supplied parameters. Before calling
500  Output::fatal(), the function will also print other
501  information about the (sub)component that called fatal and
502  about the simulation state.
503 
504  From Output::fatal: Message will be sent to the output
505  location and to stderr. The output will be prepended with the
506  expanded prefix set in the object.
507  NOTE: fatal() will call MPI_Abort(exit_code) to terminate simulation.
508 
509  @param line Line number of calling function (use CALL_INFO macro)
510  @param file File name calling function (use CALL_INFO macro)
511  @param func Function name calling function (use CALL_INFO macro)
512  @param exit_code The exit code used for termination of simulation.
513  will be passed to MPI_Abort()
514  @param format Format string. All valid formats for printf are available.
515  @param ... Arguments for format.
516  */
517  void fatal(uint32_t line, const char* file, const char* func,
518  int exit_code,
519  const char* format, ...) const
520  __attribute__ ((format (printf, 6, 7))) ;
521 
522 
523  /** Convenience function for testing for and reporting fatal
524  conditions. If the condition holds, fatal() will be called,
525  otherwise, the function will return. The function will create
526  a new Output object and call fatal() using the supplied
527  parameters. Before calling Output::fatal(), the function will
528  also print other information about the (sub)component that
529  called fatal and about the simulation state.
530 
531  From Output::fatal: Message will be sent to the output
532  location and to stderr. The output will be prepended with the
533  expanded prefix set in the object.
534  NOTE: fatal() will call MPI_Abort(exit_code) to terminate simulation.
535 
536  @param condition on which to call fatal(); fatal() is called
537  if the bool is false.
538  @param line Line number of calling function (use CALL_INFO macro)
539  @param file File name calling function (use CALL_INFO macro)
540  @param func Function name calling function (use CALL_INFO macro)
541  @param exit_code The exit code used for termination of simulation.
542  will be passed to MPI_Abort()
543  @param format Format string. All valid formats for printf are available.
544  @param ... Arguments for format.
545  */
546  void sst_assert(bool condition, uint32_t line, const char* file, const char* func,
547  int exit_code,
548  const char* format, ...) const
549  __attribute__ ((format (printf, 7, 8)));
550 
551 
552 private:
553 
554  void setDefaultTimeBaseForLinks(TimeConverter* tc);
555 
556  void pushValidParams(Params& params, const std::string& type);
557 
558  template <class T, class... ARGS>
559  T* loadUserSubComponentByIndex(const std::string& slot_name, int slot_num, int share_flags, ARGS... args) {
560 
561  share_flags = share_flags & ComponentInfo::USER_FLAGS;
562 
563  // Check to see if the slot exists
564  ComponentInfo* sub_info = my_info->findSubComponent(slot_name,slot_num);
565  if ( sub_info == nullptr ) return nullptr;
566  sub_info->share_flags = share_flags;
567  sub_info->parent_info = my_info;
568 
569  // Check to see if this is documented, and if so, try to load it through the ElementBuilder
570  Params myParams;
571  if ( sub_info->getParams() != nullptr ) {
572  myParams.insert(*sub_info->getParams());
573  }
574 
575  if ( isSubComponentLoadableUsingAPI<T>(sub_info->type) ) {
576  auto ret = Factory::getFactory()->Create<T>(sub_info->type, myParams, sub_info->id, myParams, args...);
577  return ret;
578  }
579  return nullptr;
580  }
581 
582 
583 public:
584  SubComponentSlotInfo* getSubComponentSlotInfo(const std::string& name, bool fatalOnEmptyIndex = false);
585 
586  /** Retrieve the X,Y,Z coordinates of this component */
587  const std::vector<double>& getCoordinates() const {
588  return my_info->coordinates;
589  }
590 
591 protected:
593 
594  bool isAnonymous() {
595  return my_info->isAnonymous();
596  }
597 
598  bool isUser() {
599  return my_info->isUser();
600  }
601 
602  /** Manually set the default detaulTimeBase */
604  my_info->defaultTimeBase = tc;
605  }
606 
607  TimeConverter* getDefaultTimeBase() {
608  return my_info->defaultTimeBase;
609  }
610 
611  bool doesSubComponentExist(const std::string& type);
612 
613 
614  /** Find a lookup table */
615  SharedRegion* getLocalSharedRegion(const std::string& key, size_t size);
616  SharedRegion* getGlobalSharedRegion(const std::string& key, size_t size, SharedRegionMerger *merger = nullptr);
617 
618  /* Get the Simulation */
619  Simulation* getSimulation() const { return sim; }
620 
621  // Does the statisticName exist in the ElementInfoStatistic
622  virtual bool doesComponentInfoStatisticExist(const std::string& statisticName) const;
623  // Return the EnableLevel for the statisticName from the ElementInfoStatistic
624  uint8_t getComponentInfoStatisticEnableLevel(const std::string& statisticName) const;
625  // Return the Units for the statisticName from the ElementInfoStatistic
626  // std::string getComponentInfoStatisticUnits(const std::string& statisticName) const;
627 
628 
629 protected:
630  Simulation *sim;
631 
632 
633 
634 private:
635 
636  ComponentInfo* my_info;
637  bool isExtension;
638 
639  void addSelfLink(const std::string& name);
640  Link* getLinkFromParentSharedPort(const std::string& port);
641 
642  using CreateFxn = std::function<StatisticBase*(const std::string&,
643  BaseComponent*,const std::string&, const std::string&, SST::Params&)>;
644 
645  StatisticBase* registerStatisticCore(SST::Params& params,
646  const std::string& statName, const std::string& statSubId,
647  fieldType_t fieldType, CreateFxn&& fxn);
648 
649 };
650 
651 
652 /**
653  Used to load SubComponents when multiple SubComponents are loaded
654  into a single slot (will also also work when a single SubComponent
655  is loaded).
656  */
658 
659  BaseComponent* comp;
660  std::string slot_name;
661  int max_slot_index;
662 
663 
664 public:
666 
667 
668  SubComponentSlotInfo(BaseComponent* comp, const std::string& slot_name) :
669  comp(comp),
670  slot_name(slot_name)
671  {
672  const std::map<ComponentId_t,ComponentInfo>& subcomps = comp->my_info->getSubComponents();
673 
674  // Look for all subcomponents with the right slot name
675  max_slot_index = -1;
676  for ( auto &ci : subcomps ) {
677  if ( ci.second.getSlotName() == slot_name ) {
678  if ( ci.second.getSlotNum() > static_cast<int>(max_slot_index) ) {
679  max_slot_index = ci.second.getSlotNum();
680  }
681  }
682  }
683  }
684 
685  const std::string& getSlotName() const {
686  return slot_name;
687  };
688 
689  bool isPopulated(int slot_num) const {
690  if ( slot_num > max_slot_index ) return false;
691  if ( comp->my_info->findSubComponent(slot_name,slot_num) == nullptr ) return false;
692  return true;
693  }
694 
695  bool isAllPopulated() const {
696  for ( int i = 0; i < max_slot_index; ++i ) {
697  if ( comp->my_info->findSubComponent(slot_name,i) == nullptr ) return false;
698  }
699  return true;
700  }
701 
702  int getMaxPopulatedSlotNumber() const {
703  return max_slot_index;
704  }
705 
706 
707  // Create functions that support the new API
708 
709  /**
710  Create a user defined subcomponent (defined in input file to
711  SST run). This call will pass SHARE_NONE to the new
712  subcomponent and will not take constructor arguments. If
713  constructor arguments are needed for the API that is being
714  loaded, the full call to create will need to be used
715  create(slot_num, share_flags, args...).
716 
717  @param slot_num Slot index from which to load subcomponent
718 
719  This function supports the new API, but is identical to an
720  existing API call. It will try to load using new API and will
721  fallback to old if unsuccessful.
722  */
723  template <typename T>
724  T* create(int slot_num) const
725  {
726  Params empty;
727  return comp->loadUserSubComponentByIndex<T>(slot_name, slot_num, ComponentInfo::SHARE_NONE);
728  // return private_create<T>(slot_num, empty);
729  }
730 
731 
732  /**
733  Create a user defined subcomponent (defined in input file to SST
734  run).
735 
736  @param slot_num Slot index from which to load subcomponent
737  @param share_flags Share flags to be used by subcomponent
738  @param args Arguments to be passed to constructor. This
739  signature is defined in the API definition
740 
741  For ease in backward compatibility to old API, this call will
742  try to load using new API and will fallback to old if
743  unsuccessful.
744  */
745  template <class T, class... ARGS>
746  T* create(int slot_num, uint64_t share_flags, ARGS... args) const {
747  return comp->loadUserSubComponentByIndex<T,ARGS...>(slot_name,slot_num, share_flags, args...);
748  }
749 
750 
751  /**
752  Create all user defined subcomponents (defined in input file to SST
753  run) for the slot.
754 
755  @param vec Vector of T* that will hold the pointers to the new
756  subcomponents. If an index is not occupied, a nullptr will be
757  put in it's place. All components will be added to the end of
758  the vector, so index N will be at vec.length() + N, where
759  vec.length() is the length of the vector when it is passed to
760  the call.
761  @param share_flags Share flags to be used by subcomponent
762  @param args Arguments to be passed to constructor. This
763  signature is defined in the API definition
764 
765  For ease in backward compatibility to old API, this call will
766  try to load using new API and will fallback to old if
767  unsuccessful.
768  */
769  template <typename T, class... ARGS>
770  void createAll(std::vector<T*>& vec, uint64_t share_flags, ARGS... args) const {
771  for ( int i = 0; i <= getMaxPopulatedSlotNumber(); ++i ) {
772  T* sub = create<T>(i, share_flags, args...);
773  vec.push_back(sub);
774  }
775  }
776 
777  /**
778  Create all user defined subcomponents (defined in input file to SST
779  run) for the slot.
780 
781  @param vec Vector of pair<int,T*> that will hold the pointers
782  to the new subcomponents. The int will hold the index from
783  which the subcomponent wass loaded. Unoccupied indexes will be
784  skipped. All components will be added to the end of the
785  vector.
786  @param share_flags Share flags to be used by subcomponent
787  @param args Arguments to be passed to constructor. This
788  signature is defined in the API definition
789 
790  For ease in backward compatibility to old API, this call will
791  try to load using new API and will fallback to old if
792  unsuccessful.
793  */
794  template <typename T, class... ARGS>
795  void createAllSparse(std::vector<std::pair<int,T*> >& vec, uint64_t share_flags, ARGS... args) const {
796  for ( int i = 0; i <= getMaxPopulatedSlotNumber(); ++i ) {
797  T* sub = create<T>(i, share_flags, args...);
798  if ( sub != nullptr ) vec.push_back(i,sub);
799  }
800  }
801 
802  /**
803  Create all user defined subcomponents (defined in input file to SST
804  run) for the slot.
805 
806  @param vec Vector of T* that will hold the pointers
807  to the new subcomponents. Unoccupied indexes will be
808  skipped. All components will be added to the end of the
809  vector.
810  @param share_flags Share flags to be used by subcomponent
811  @param args Arguments to be passed to constructor. This
812  signature is defined in the API definition
813 
814  For ease in backward compatibility to old API, this call will
815  try to load using new API and will fallback to old if
816  unsuccessful.
817  */
818  template <typename T, class... ARGS>
819  void createAllSparse(std::vector<T*>& vec, uint64_t share_flags, ARGS... args) const {
820  for ( int i = 0; i <= getMaxPopulatedSlotNumber(); ++i ) {
821  T* sub = create<T>(i, share_flags, args...);
822  if ( sub != nullptr ) vec.push_back(sub);
823  }
824  }
825 
826 private:
827 
828 };
829 
830 
831 
832 } //namespace SST
833 
834 #endif // SST_CORE_BASECOMPONENT_H
Output object provides consistent method for outputting data to stdout, stderr and/or sst debug file...
Definition: output.h:54
virtual void complete(unsigned int UNUSED(phase))
Used during the init phase.
Definition: baseComponent.h:86
virtual void printStatus(Output &UNUSED(out))
Called by the Simulation to request that the component print it&#39;s current status. ...
Definition: baseComponent.h:102
bool isSubComponentLoadableUsingAPI(const std::string &type)
Check to see if a given element type is loadable with a particular API.
Definition: baseComponent.h:403
ComponentId_t getId() const
Returns unique component ID.
Definition: baseComponent.h:68
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:746
A class to convert between a component&#39;s view of time and the core&#39;s view of time.
Definition: timeConverter.h:25
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:819
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:770
virtual void finish()
Called after simulation completes, but before objects are destroyed.
Definition: baseComponent.h:92
T * loadUserSubComponent(const std::string &slot_name)
Loads a user defined subcomponent (defined in input file to SST run).
Definition: baseComponent.h:454
Forms the base class for statistics gathering within SST.
Definition: statbase.h:64
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:424
ComponentExtension is a class that can be loaded using loadComponentExtension&lt;T&gt;(...).
Definition: componentExtension.h:29
virtual void emergencyShutdown(void)
Called when SIGINT or SIGTERM has been seen.
Definition: baseComponent.h:73
Forms the template defined base class for statistics gathering within SST.
Definition: elementinfo.h:42
T * loadModule(const std::string &type, Params &params, ARGS...args)
Loads a module from an element Library.
Definition: baseComponent.h:378
const std::vector< double > & getCoordinates() const
Retrieve the X,Y,Z coordinates of this component.
Definition: baseComponent.h:587
virtual void setup()
Called after all components have been constructed and initialization has completed, but before simulation time has begun.
Definition: baseComponent.h:89
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:155
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:472
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:795
Definition: rankInfo.h:21
Functor classes for Clock handling.
Definition: clock.h:41
Main component object for the simulation.
Definition: baseComponent.h:52
Definition: output.h:62
virtual bool Status()
Currently unused function.
Definition: baseComponent.h:95
Parameter store.
Definition: params.h:44
Statistic< T > * registerStatistic(SST::Params &params, const std::string &statName, const std::string &statSubId="")
Registers a statistic.
Definition: baseComponent.h:292
Functor classes for Event handling.
Definition: event.h:86
Definition: componentInfo.h:36
Used to load SubComponents when multiple SubComponents are loaded into a single slot (will also also ...
Definition: baseComponent.h:657
Definition: statfieldinfo.h:52
T * create(int slot_num) const
Create a user defined subcomponent (defined in input file to SST run).
Definition: baseComponent.h:724
An SST core component that handles timing and event processing informing all registered Statistics to...
Definition: statengine.h:52
void insert(const std::string &key, const std::string &value, bool overwrite=true)
Add a key value pair into the param object.
Definition: params.cc:99
const std::string & getName() const
Returns component Name.
Definition: baseComponent.h:78
Performs Unit math in full precision.
Definition: unitAlgebra.h:107
void setDefaultTimeBase(TimeConverter *tc)
Manually set the default detaulTimeBase.
Definition: baseComponent.h:603
SubComponent is a class loadable through the factory which allows dynamic functionality to be added t...
Definition: subcomponent.h:29
SimTime_t getCurrentSimTime() const
return the time since the simulation began in the default timebase
Definition: baseComponent.h:126
virtual void init(unsigned int UNUSED(phase))
Used during the init phase.
Definition: baseComponent.h:83
Functor classes for OneShot handling.
Definition: oneshot.h:39