SST  8.0.0
StructuralSimulationToolkit
baseComponent.h
1 // Copyright 2009-2018 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-2018, 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/statapi/statengine.h>
22 #include <sst/core/statapi/statbase.h>
23 #include <sst/core/event.h>
24 #include <sst/core/clock.h>
25 #include <sst/core/oneshot.h>
26 #include <sst/core/componentInfo.h>
27 #include <sst/core/simulation.h>
28 
29 using namespace SST::Statistics;
30 
31 namespace SST {
32 
33 class Clock;
34 class Link;
35 class LinkMap;
36 class Module;
37 class Params;
38 class SubComponent;
39 class TimeConverter;
40 class UnitAlgebra;
41 class SharedRegion;
42 class SharedRegionMerger;
43 class Component;
44 class SubComponent;
45 class SubComponentSlotInfo_impl;
46 
48 
49 protected:
50 
51  virtual SubComponent* protected_create(int slot_num, Params& params) const = 0;
52 
53 public:
54  virtual ~SubComponentSlotInfo() {}
55 
56  virtual const std::string& getSlotName() const = 0;
57  virtual bool isPopulated(int slot_num) const = 0;
58  virtual bool isAllPopulated() const = 0;
59  virtual int getMaxPopulatedSlotNumber() const = 0;
60 
61  template <typename T>
62  T* create(int slot_num, Params& params) const {
63  SubComponent* sub = protected_create(slot_num, params);
64  if ( sub == NULL ) {
65  // Nothing populated at this index, simply return NULL
66  return NULL;
67  }
68  T* cast_sub = dynamic_cast<T*>(sub);
69  if ( cast_sub == NULL ) {
70  // SubComponent not castable to the correct class,
71  // fatal
72  Simulation::getSimulationOutput().fatal(CALL_INFO,1,"Attempt to load SubComponent into slot "
73  "%s, index %d, which is not castable to correct time\n",
74  getSlotName().c_str(),slot_num);
75  }
76  return cast_sub;
77  }
78 
79  template <typename T>
80  void createAll(Params& params, std::vector<T*>& vec, bool insertNulls = true) const {
81  for ( int i = 0; i <= getMaxPopulatedSlotNumber(); ++i ) {
82  T* sub = create<T>(i, params);
83  if ( sub != NULL || insertNulls ) vec.push_back(sub);
84  }
85  }
86 
87  template <typename T>
88  T* create(int slot_num) const {
89  Params empty;
90  return create<T>(slot_num, empty);
91  }
92 
93  template <typename T>
94  void createAll(std::vector<T*>& vec, bool insertNulls = true) const {
95  Params empty;
96  return createAll<T>(empty, vec, insertNulls);
97  }
98 };
99 
100 
101 /**
102  * Main component object for the simulation.
103  */
105 
106  friend class SubComponentSlotInfo_impl;
107 
108 public:
109 
110  BaseComponent();
111  virtual ~BaseComponent();
112 
113  /** Returns unique component ID */
114  inline ComponentId_t getId() const { return my_info->id; }
115 
116  /** Called when SIGINT or SIGTERM has been seen.
117  * Allows components opportunity to clean up external state.
118  */
119  virtual void emergencyShutdown(void) {}
120 
121 
122  /** Returns component Name */
123  /* inline const std::string& getName() const { return name; } */
124  inline const std::string& getName() const { return my_info->getName(); }
125 
126 
127  /** Used during the init phase. The method will be called each phase of initialization.
128  Initialization ends when no components have sent any data. */
129  virtual void init(unsigned int UNUSED(phase)) {}
130  /** Used during the init phase. The method will be called each phase of initialization.
131  Initialization ends when no components have sent any data. */
132  virtual void complete(unsigned int UNUSED(phase)) {}
133  /** Called after all components have been constructed and initialization has
134  completed, but before simulation time has begun. */
135  virtual void setup( ) { }
136  /** Called after simulation completes, but before objects are
137  destroyed. A good place to print out statistics. */
138  virtual void finish( ) { }
139 
140  /** Currently unused function */
141  virtual bool Status( ) { return 0; }
142 
143  /**
144  * Called by the Simulation to request that the component
145  * print it's current status. Useful for debugging.
146  * @param out The Output class which should be used to print component status.
147  */
148  virtual void printStatus(Output &UNUSED(out)) { return; }
149 
150  /** Determine if a port name is connected to any links */
151  bool isPortConnected(const std::string &name) const;
152 
153  /** Configure a Link
154  * @param name - Port Name on which the link to configure is attached.
155  * @param time_base - Time Base of the link
156  * @param handler - Optional Handler to be called when an Event is received
157  * @return A pointer to the configured link, or NULL if an error occured.
158  */
159  Link* configureLink( std::string name, TimeConverter* time_base, Event::HandlerBase* handler = NULL);
160  /** Configure a Link
161  * @param name - Port Name on which the link to configure is attached.
162  * @param time_base - Time Base of the link
163  * @param handler - Optional Handler to be called when an Event is received
164  * @return A pointer to the configured link, or NULL if an error occured.
165  */
166  Link* configureLink( std::string name, std::string time_base, Event::HandlerBase* handler = NULL);
167  /** Configure a Link
168  * @param name - Port Name on which the link to configure is attached.
169  * @param handler - Optional Handler to be called when an Event is received
170  * @return A pointer to the configured link, or NULL if an error occured.
171  */
172  Link* configureLink( std::string name, Event::HandlerBase* handler = NULL);
173 
174  /** Configure a SelfLink (Loopback link)
175  * @param name - Name of the self-link port
176  * @param time_base - Time Base of the link
177  * @param handler - Optional Handler to be called when an Event is received
178  * @return A pointer to the configured link, or NULL if an error occured.
179  */
180  Link* configureSelfLink( std::string name, TimeConverter* time_base, Event::HandlerBase* handler = NULL);
181  /** Configure a SelfLink (Loopback link)
182  * @param name - Name of the self-link port
183  * @param time_base - Time Base of the link
184  * @param handler - Optional Handler to be called when an Event is received
185  * @return A pointer to the configured link, or NULL if an error occured.
186  */
187  Link* configureSelfLink( std::string name, std::string time_base, Event::HandlerBase* handler = NULL);
188  /** Configure a SelfLink (Loopback link)
189  * @param name - Name of the self-link port
190  * @param handler - Optional Handler to be called when an Event is received
191  * @return A pointer to the configured link, or NULL if an error occured.
192  */
193  Link* configureSelfLink( std::string name, Event::HandlerBase* handler = NULL);
194 
195  /** Registers a clock for this component.
196  @param freq Frequency for the clock in SI units
197  @param handler Pointer to Clock::HandlerBase which is to be invoked
198  at the specified interval
199  @param regAll Should this clock period be used as the default
200  time base for all of the links connected to this component
201  */
202  TimeConverter* registerClock( std::string freq, Clock::HandlerBase* handler,
203  bool regAll = true);
204  TimeConverter* registerClock( const UnitAlgebra& freq, Clock::HandlerBase* handler,
205  bool regAll = true);
206  /** Removes a clock handler from the component */
207  void unregisterClock(TimeConverter *tc, Clock::HandlerBase* handler);
208 
209  /** Reactivates an existing Clock and Handler
210  * @return time of next time clock handler will fire
211  */
212  Cycle_t reregisterClock(TimeConverter *freq, Clock::HandlerBase* handler);
213  /** Returns the next Cycle that the TimeConverter would fire */
214  Cycle_t getNextClockCycle(TimeConverter *freq);
215 
216  /** Registers a OneShot event for this component.
217  Note: OneShot cannot be canceled, and will always callback after
218  the timedelay.
219  @param timeDelay Time delay for the OneShot in SI units
220  @param handler Pointer to OneShot::HandlerBase which is to be invoked
221  at the specified interval
222  */
223  TimeConverter* registerOneShot( std::string timeDelay, OneShot::HandlerBase* handler);
224  TimeConverter* registerOneShot( const UnitAlgebra& timeDelay, OneShot::HandlerBase* handler);
225 
226  /** Registers a default time base for the component and optionally
227  sets the the component's links to that timebase. Useful for
228  components which do not have a clock, but would like a default
229  timebase.
230  @param base Frequency for the clock in SI units
231  @param regAll Should this clock period be used as the default
232  time base for all of the links connected to this component
233  */
234  TimeConverter* registerTimeBase( std::string base, bool regAll = true);
235 
236  TimeConverter* getTimeConverter( const std::string& base );
237  TimeConverter* getTimeConverter( const UnitAlgebra& base );
238 
239  /** return the time since the simulation began in units specified by
240  the parameter.
241  @param tc TimeConverter specifying the units */
242  SimTime_t getCurrentSimTime(TimeConverter *tc) const;
243  /** return the time since the simulation began in the default timebase */
244  inline SimTime_t getCurrentSimTime() const{
245  return getCurrentSimTime(defaultTimeBase);
246  }
247  /** return the time since the simulation began in timebase specified
248  @param base Timebase frequency in SI Units */
249  SimTime_t getCurrentSimTime(std::string base);
250 
251  /** Utility function to return the time since the simulation began in nanoseconds */
252  SimTime_t getCurrentSimTimeNano() const;
253  /** Utility function to return the time since the simulation began in microseconds */
254  SimTime_t getCurrentSimTimeMicro() const;
255  /** Utility function to return the time since the simulation began in milliseconds */
256  SimTime_t getCurrentSimTimeMilli() const;
257 
258  /** Registers a statistic.
259  If Statistic is allowed to run (controlled by Python runtime parameters),
260  then a statistic will be created and returned. If not allowed to run,
261  then a NullStatistic will be returned. In either case, the returned
262  value should be used for all future Statistic calls. The type of
263  Statistic and the Collection Rate is set by Python runtime parameters.
264  If no type is defined, then an Accumulator Statistic will be provided
265  by default. If rate set to 0 or not provided, then the statistic will
266  output results only at end of sim (if output is enabled).
267  @param statName Primary name of the statistic. This name must match the
268  defined ElementInfoStatistic in the component, and must also
269  be enabled in the Python input file.
270  @param statSubId An additional sub name for the statistic
271  @return Either a created statistic of desired type or a NullStatistic
272  depending upon runtime settings.
273  */
274  template <typename T>
275  Statistic<T>* registerStatistic(std::string statName, std::string statSubId = "")
276  {
277  // Verify here that name of the stat is one of the registered
278  // names of the component's ElementInfoStatistic.
279  if (false == doesComponentInfoStatisticExist(statName)) {
280  printf("Error: Statistic %s name %s is not found in ElementInfoStatistic, exiting...\n",
281  StatisticBase::buildStatisticFullName(getName().c_str(), statName, statSubId).c_str(),
282  statName.c_str());
283  exit(1);
284  }
285  // Check to see if the Statistic is previously registered with the Statistics Engine
286  StatisticBase* prevStat = StatisticProcessingEngine::getInstance()->isStatisticRegisteredWithEngine<T>(getName(), my_info->getID(), statName, statSubId);
287  if (NULL != prevStat) {
288  // Dynamic cast the base stat to the expected type
289  return dynamic_cast<Statistic<T>*>(prevStat);
290  }
291  return registerStatisticCore<T>(statName, statSubId);
292  }
293 
294  template <typename T>
295  Statistic<T>* registerStatistic(const char* statName, const char* statSubId = "")
296  {
297  return registerStatistic<T>(std::string(statName), std::string(statSubId));
298  }
299 
300 
301  /** Loads a module from an element Library
302  * @param type Fully Qualified library.moduleName
303  * @param params Parameters the module should use for configuration
304  * @return handle to new instance of module, or NULL on failure.
305  */
306  Module* loadModule(std::string type, Params& params);
307 
308  /** Loads a module from an element Library
309  * @param type Fully Qualified library.moduleName
310  * @param comp Pointer to component to pass to Module's constructor
311  * @param params Parameters the module should use for configuration
312  * @return handle to new instance of module, or NULL on failure.
313  */
314  Module* loadModuleWithComponent(std::string type, Component* comp, Params& params);
315 
316  /** Loads a SubComponent from an element Library
317  * @param type Fully Qualified library.moduleName
318  * @param comp Pointer to component to pass to SuBaseComponent's constructor
319  * @param params Parameters the module should use for configuration
320  * @return handle to new instance of SubComponent, or NULL on failure.
321  */
322  SubComponent* loadSubComponent(std::string type, Component* comp, Params& params);
323  /* New ELI style */
324  SubComponent* loadNamedSubComponent(std::string name);
325  SubComponent* loadNamedSubComponent(std::string name, Params& params);
326 
327 private:
328  SubComponent* loadNamedSubComponent(std::string name, int slot_num);
329  SubComponent* loadNamedSubComponent(std::string name, int slot_num, Params& params);
330 public:
331  SubComponentSlotInfo* getSubComponentSlotInfo(std::string name, bool fatalOnEmptyIndex = false);
332 
333  /** Retrieve the X,Y,Z coordinates of this component */
334  const std::vector<double>& getCoordinates() const {
335  return my_info->coordinates;
336  }
337 
338 protected:
340 
341  /** Manually set the default detaulTimeBase */
343  defaultTimeBase = tc;
344  }
345 
346  /** Timebase used if no other timebase is specified for calls like
347  BaseComponent::getCurrentSimTime(). Often set by BaseComponent::registerClock()
348  function */
350 
351  /** Creates a new selfLink */
352  Link* selfLink( std::string name, Event::HandlerBase* handler = NULL );
353 
354 
355  /** Find a lookup table */
356  SharedRegion* getLocalSharedRegion(const std::string &key, size_t size);
357  SharedRegion* getGlobalSharedRegion(const std::string &key, size_t size, SharedRegionMerger *merger = NULL);
358 
359  /* Get the Simulation */
360  Simulation* getSimulation() const { return sim; }
361 
362  // Does the statisticName exist in the ElementInfoStatistic
363  virtual bool doesComponentInfoStatisticExist(const std::string &statisticName) const = 0;
364  // Return the EnableLevel for the statisticName from the ElementInfoStatistic
365  uint8_t getComponentInfoStatisticEnableLevel(const std::string &statisticName) const;
366  // Return the Units for the statisticName from the ElementInfoStatistic
367  std::string getComponentInfoStatisticUnits(const std::string &statisticName) const;
368 
369  virtual Component* getTrueComponent() const = 0;
370  /**
371  * Returns self if Component
372  * If sub-component, returns self if a "modern" subcomponent
373  * otherwise, return base component.
374  */
375  virtual BaseComponent* getStatisticOwner() const = 0;
376 
377 protected:
378  ComponentInfo* my_info;
379  Simulation *sim;
380  ComponentInfo* currentlyLoadingSubComponent;
381 
382 
383 private:
384  void addSelfLink(std::string name);
385 
386  template <typename T>
387  Statistic<T>* registerStatisticCore(std::string statName, std::string statSubId = "")
388  {
389  // NOTE: Templated Code for implementation of Statistic Registration
390  // is in the componentregisterstat_impl.h file. This was done
391  // to avoid code bloat in the .h file.
392  #include "sst/core/statapi/componentregisterstat_impl.h"
393  }
394 
395 
396 };
397 
398 } //namespace SST
399 
400 #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
Definition: sharedRegion.h:77
virtual void complete(unsigned int UNUSED(phase))
Used during the init phase.
Definition: baseComponent.h:132
virtual void printStatus(Output &UNUSED(out))
Called by the Simulation to request that the component print it&#39;s current status. ...
Definition: baseComponent.h:148
Main control class for a SST Simulation.
Definition: simulation.h:72
ComponentId_t getId() const
Returns unique component ID.
Definition: baseComponent.h:114
A class to convert between a component&#39;s view of time and the core&#39;s view of time.
Definition: timeConverter.h:25
Main component object for the simulation.
Definition: component.h:32
virtual void finish()
Called after simulation completes, but before objects are destroyed.
Definition: baseComponent.h:138
Forms the base class for statistics gathering within SST.
Definition: statbase.h:61
Utility class to define how to merge multiple pieces of shared memory regions Useful in the multi-MPI...
Definition: sharedRegion.h:30
Statistic< T > * registerStatistic(std::string statName, std::string statSubId="")
Registers a statistic.
Definition: baseComponent.h:275
virtual void emergencyShutdown(void)
Called when SIGINT or SIGTERM has been seen.
Definition: baseComponent.h:119
Forms the template defined base class for statistics gathering within SST.
Definition: statbase.h:294
const std::vector< double > & getCoordinates() const
Retrieve the X,Y,Z coordinates of this component.
Definition: baseComponent.h:334
static Output & getSimulationOutput()
Return the base simulation Output class instance.
Definition: simulation.h:178
virtual void setup()
Called after all components have been constructed and initialization has completed, but before simulation time has begun.
Definition: baseComponent.h:135
Definition: baseComponent.cc:33
TimeConverter * defaultTimeBase
Timebase used if no other timebase is specified for calls like BaseComponent::getCurrentSimTime().
Definition: baseComponent.h:349
Functor classes for Clock handling.
Definition: clock.h:44
Main component object for the simulation.
Definition: baseComponent.h:104
virtual bool Status()
Currently unused function.
Definition: baseComponent.h:141
Parameter store.
Definition: params.h:45
Functor classes for Event handling.
Definition: event.h:86
void fatal(uint32_t line, const char *file, const char *func, uint32_t exit_code, const char *format,...) const
Output the fatal message with formatting as specified by the format parameter.
Definition: output.cc:155
Definition: componentInfo.h:34
Definition: baseComponent.h:47
An SST core component that handles timing and event processing informing all registered Statistics to...
Definition: statengine.h:49
const std::string & getName() const
Returns component Name.
Definition: baseComponent.h:124
Performs Unit math in full precision.
Definition: unitAlgebra.h:104
void setDefaultTimeBase(TimeConverter *tc)
Manually set the default detaulTimeBase.
Definition: baseComponent.h:342
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:244
virtual void init(unsigned int UNUSED(phase))
Used during the init phase.
Definition: baseComponent.h:129
Functor classes for OneShot handling.
Definition: oneshot.h:39