SST  7.1.0
StructuralSimulationToolkit
baseComponent.h
1 // Copyright 2009-2017 Sandia Corporation. Under the terms
2 // of Contract DE-NA0003525 with Sandia Corporation, the U.S.
3 // Government retains certain rights in this software.
4 //
5 // Copyright (c) 2009-2017, Sandia Corporation
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  /** Called after all components have been constructed and inialization has
131  completed, but before simulation time has begun. */
132  virtual void setup( ) { }
133  /** Called after simulation completes, but before objects are
134  destroyed. A good place to print out statistics. */
135  virtual void finish( ) { }
136 
137  /** Currently unused function */
138  virtual bool Status( ) { return 0; }
139 
140  /**
141  * Called by the Simulation to request that the component
142  * print it's current status. Useful for debugging.
143  * @param out The Output class which should be used to print component status.
144  */
145  virtual void printStatus(Output &UNUSED(out)) { return; }
146 
147  /** Determine if a port name is connected to any links */
148  bool isPortConnected(const std::string &name) const;
149 
150  /** Configure a Link
151  * @param name - Port Name on which the link to configure is attached.
152  * @param time_base - Time Base of the link
153  * @param handler - Optional Handler to be called when an Event is received
154  * @return A pointer to the configured link, or NULL if an error occured.
155  */
156  Link* configureLink( std::string name, TimeConverter* time_base, Event::HandlerBase* handler = NULL);
157  /** Configure a Link
158  * @param name - Port Name on which the link to configure is attached.
159  * @param time_base - Time Base of the link
160  * @param handler - Optional Handler to be called when an Event is received
161  * @return A pointer to the configured link, or NULL if an error occured.
162  */
163  Link* configureLink( std::string name, std::string time_base, Event::HandlerBase* handler = NULL);
164  /** Configure a Link
165  * @param name - Port Name on which the link to configure is attached.
166  * @param handler - Optional Handler to be called when an Event is received
167  * @return A pointer to the configured link, or NULL if an error occured.
168  */
169  Link* configureLink( std::string name, Event::HandlerBase* handler = NULL);
170 
171  /** Configure a SelfLink (Loopback link)
172  * @param name - Name of the self-link port
173  * @param time_base - Time Base of the link
174  * @param handler - Optional Handler to be called when an Event is received
175  * @return A pointer to the configured link, or NULL if an error occured.
176  */
177  Link* configureSelfLink( std::string name, TimeConverter* time_base, Event::HandlerBase* handler = NULL);
178  /** Configure a SelfLink (Loopback link)
179  * @param name - Name of the self-link port
180  * @param time_base - Time Base of the link
181  * @param handler - Optional Handler to be called when an Event is received
182  * @return A pointer to the configured link, or NULL if an error occured.
183  */
184  Link* configureSelfLink( std::string name, std::string time_base, Event::HandlerBase* handler = NULL);
185  /** Configure a SelfLink (Loopback link)
186  * @param name - Name of the self-link port
187  * @param handler - Optional Handler to be called when an Event is received
188  * @return A pointer to the configured link, or NULL if an error occured.
189  */
190  Link* configureSelfLink( std::string name, Event::HandlerBase* handler = NULL);
191 
192  /** Registers a clock for this component.
193  @param freq Frequency for the clock in SI units
194  @param handler Pointer to Clock::HandlerBase which is to be invoked
195  at the specified interval
196  @param regAll Should this clock perioud be used as the default
197  time base for all of the links connected to this component
198  */
199  TimeConverter* registerClock( std::string freq, Clock::HandlerBase* handler,
200  bool regAll = true);
201  TimeConverter* registerClock( const UnitAlgebra& freq, Clock::HandlerBase* handler,
202  bool regAll = true);
203  /** Removes a clock handler from the component */
204  void unregisterClock(TimeConverter *tc, Clock::HandlerBase* handler);
205 
206  /** Reactivates an existing Clock and Handler
207  * @return time of next time clock handler will fire
208  */
209  Cycle_t reregisterClock(TimeConverter *freq, Clock::HandlerBase* handler);
210  /** Returns the next Cycle that the TimeConverter would fire */
211  Cycle_t getNextClockCycle(TimeConverter *freq);
212 
213  /** Registers a OneShot event for this component.
214  Note: OneShot cannot be canceled, and will always callback after
215  the timedelay.
216  @param timeDelay Time delay for the OneShot in SI units
217  @param handler Pointer to OneShot::HandlerBase which is to be invoked
218  at the specified interval
219  */
220  TimeConverter* registerOneShot( std::string timeDelay, OneShot::HandlerBase* handler);
221  TimeConverter* registerOneShot( const UnitAlgebra& timeDelay, OneShot::HandlerBase* handler);
222 
223  /** Registers a default time base for the component and optionally
224  sets the the component's links to that timebase. Useful for
225  components which do not have a clock, but would like a default
226  timebase.
227  @param base Frequency for the clock in SI units
228  @param regAll Should this clock perioud be used as the default
229  time base for all of the links connected to this component
230  */
231  TimeConverter* registerTimeBase( std::string base, bool regAll = true);
232 
233  TimeConverter* getTimeConverter( const std::string& base );
234  TimeConverter* getTimeConverter( const UnitAlgebra& base );
235 
236  /** return the time since the simulation began in units specified by
237  the parameter.
238  @param tc TimeConverter specificing the units */
239  SimTime_t getCurrentSimTime(TimeConverter *tc) const;
240  /** return the time since the simulation began in the default timebase */
241  inline SimTime_t getCurrentSimTime() const{
242  return getCurrentSimTime(defaultTimeBase);
243  }
244  /** return the time since the simulation began in timebase specified
245  @param base Timebase frequency in SI Units */
246  SimTime_t getCurrentSimTime(std::string base);
247 
248  /** Utility function to return the time since the simulation began in nanoseconds */
249  SimTime_t getCurrentSimTimeNano() const;
250  /** Utility function to return the time since the simulation began in microseconds */
251  SimTime_t getCurrentSimTimeMicro() const;
252  /** Utility function to return the time since the simulation began in milliseconds */
253  SimTime_t getCurrentSimTimeMilli() const;
254 
255  /** Registers a statistic.
256  If Statistic is allowed to run (controlled by Python runtime parameters),
257  then a statistic will be created and returned. If not allowed to run,
258  then a NullStatistic will be returned. In either case, the returned
259  value should be used for all future Statistic calls. The type of
260  Statistic and the Collection Rate is set by Python runtime parameters.
261  If no type is defined, then an Accumulator Statistic will be provided
262  by default. If rate set to 0 or not provided, then the statistic will
263  output results only at end of sim (if output is enabled).
264  @param statName Primary name of the statistic. This name must match the
265  defined ElementInfoStatistic in the component, and must also
266  be enabled in the Python input file.
267  @param statSubId An additional sub name for the statistic
268  @return Either a created statistic of desired type or a NullStatistic
269  depending upon runtime settings.
270  */
271  template <typename T>
272  Statistic<T>* registerStatistic(std::string statName, std::string statSubId = "")
273  {
274  // Verify here that name of the stat is one of the registered
275  // names of the component's ElementInfoStatistic.
276  if (false == doesComponentInfoStatisticExist(statName)) {
277  printf("Error: Statistic %s name %s is not found in ElementInfoStatistic, exiting...\n",
278  StatisticBase::buildStatisticFullName(getName().c_str(), statName, statSubId).c_str(),
279  statName.c_str());
280  exit(1);
281  }
282  // Check to see if the Statistic is previously registered with the Statistics Engine
283  StatisticBase* prevStat = StatisticProcessingEngine::getInstance()->isStatisticRegisteredWithEngine<T>(getName(), my_info->getID(), statName, statSubId);
284  if (NULL != prevStat) {
285  // Dynamic cast the base stat to the expected type
286  return dynamic_cast<Statistic<T>*>(prevStat);
287  }
288  return registerStatisticCore<T>(statName, statSubId);
289  }
290 
291  template <typename T>
292  Statistic<T>* registerStatistic(const char* statName, const char* statSubId = "")
293  {
294  return registerStatistic<T>(std::string(statName), std::string(statSubId));
295  }
296 
297 
298  /** Loads a module from an element Library
299  * @param type Fully Qualified library.moduleName
300  * @param params Parameters the module should use for configuration
301  * @return handle to new instance of module, or NULL on failure.
302  */
303  Module* loadModule(std::string type, Params& params);
304 
305  /** Loads a module from an element Library
306  * @param type Fully Qualified library.moduleName
307  * @param comp Pointer to component to pass to Module's constructor
308  * @param params Parameters the module should use for configuration
309  * @return handle to new instance of module, or NULL on failure.
310  */
311  Module* loadModuleWithComponent(std::string type, Component* comp, Params& params);
312 
313  /** Loads a SubComponent from an element Library
314  * @param type Fully Qualified library.moduleName
315  * @param comp Pointer to component to pass to SuBaseComponent's constructor
316  * @param params Parameters the module should use for configuration
317  * @return handle to new instance of SubComponent, or NULL on failure.
318  */
319  SubComponent* loadSubComponent(std::string type, Component* comp, Params& params);
320  /* New ELI style */
321  SubComponent* loadNamedSubComponent(std::string name);
322  SubComponent* loadNamedSubComponent(std::string name, Params& params);
323 
324 private:
325  SubComponent* loadNamedSubComponent(std::string name, int slot_num);
326  SubComponent* loadNamedSubComponent(std::string name, int slot_num, Params& params);
327 public:
328  SubComponentSlotInfo* getSubComponentSlotInfo(std::string name, bool fatalOnEmptyIndex = false);
329 
330  /** Retrieve the X,Y,Z coordinates of this component */
331  const std::vector<double>& getCoordinates() const {
332  return my_info->coordinates;
333  }
334 
335 protected:
337 
338  /** Manually set the default detaulTimeBase */
340  defaultTimeBase = tc;
341  }
342 
343  /** Timebase used if no other timebase is specified for calls like
344  BaseComponent::getCurrentSimTime(). Often set by BaseComponent::registerClock()
345  function */
347 
348  /** Creates a new selfLink */
349  Link* selfLink( std::string name, Event::HandlerBase* handler = NULL );
350 
351 
352  /** Find a lookup table */
353  SharedRegion* getLocalSharedRegion(const std::string &key, size_t size);
354  SharedRegion* getGlobalSharedRegion(const std::string &key, size_t size, SharedRegionMerger *merger = NULL);
355 
356  /* Get the Simulation */
357  Simulation* getSimulation() const { return sim; }
358 
359  // Does the statisticName exist in the ElementInfoStatistic
360  virtual bool doesComponentInfoStatisticExist(const std::string &statisticName) const = 0;
361  // Return the EnableLevel for the statisticName from the ElementInfoStatistic
362  uint8_t getComponentInfoStatisticEnableLevel(const std::string &statisticName) const;
363  // Return the Units for the statisticName from the ElementInfoStatistic
364  std::string getComponentInfoStatisticUnits(const std::string &statisticName) const;
365 
366  virtual Component* getTrueComponent() const = 0;
367  /**
368  * Returns self if Component
369  * If sub-component, returns self if a "modern" subcomponent
370  * otherwise, return base component.
371  */
372  virtual BaseComponent* getStatisticOwner() const = 0;
373 
374 protected:
375  ComponentInfo* my_info;
376  Simulation *sim;
377  ComponentInfo* currentlyLoadingSubComponent;
378 
379 
380 private:
381  void addSelfLink(std::string name);
382 
383  template <typename T>
384  Statistic<T>* registerStatisticCore(std::string statName, std::string statSubId = "")
385  {
386  // NOTE: Templated Code for implementation of Statistic Registration
387  // is in the componentregisterstat_impl.h file. This was done
388  // to avoid code bloat in the .h file.
389  #include "sst/core/statapi/componentregisterstat_impl.h"
390  }
391 
392 
393 };
394 
395 } //namespace SST
396 
397 #endif // SST_CORE_BASECOMPONENT_H
Output object provides consistant method for outputing data to stdout, stderr and/or sst debug file...
Definition: output.h:54
ComponentId_t getId() const
Returns unique component ID.
Definition: baseComponent.h:114
Definition: sharedRegion.h:77
virtual void printStatus(Output &UNUSED(out))
Called by the Simulation to request that the component print it&#39;s current status. ...
Definition: baseComponent.h:145
Main control class for a SST Simulation.
Definition: simulation.h:72
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
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
virtual void finish()
Called after simulation completes, but before objects are destroyed.
Definition: baseComponent.h:135
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
Definition: action.cc:17
Statistic< T > * registerStatistic(std::string statName, std::string statSubId="")
Registers a statistic.
Definition: baseComponent.h:272
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
static Output & getSimulationOutput()
Return the base simulation Output class instance.
Definition: simulation.h:176
virtual void setup()
Called after all components have been constructed and inialization has completed, but before simulati...
Definition: baseComponent.h:132
Module is a tag class used with the loadModule function.
Definition: module.h:20
Definition: baseComponent.cc:33
TimeConverter * defaultTimeBase
Timebase used if no other timebase is specified for calls like BaseComponent::getCurrentSimTime().
Definition: baseComponent.h:346
Functor classes for Clock handling.
Definition: clock.h:44
Main component object for the simulation.
Definition: baseComponent.h:104
SimTime_t getCurrentSimTime() const
return the time since the simulation began in the default timebase
Definition: baseComponent.h:241
virtual bool Status()
Currently unused function.
Definition: baseComponent.h:138
Parameter store.
Definition: params.h:45
Functor classes for Event handling.
Definition: event.h:86
Definition: componentInfo.h:34
Definition: baseComponent.h:47
Definition: componentInfo.h:30
An SST core component that handles timing and event processing informing all registered Statistics to...
Definition: statengine.h:49
Performs Unit math in full precision.
Definition: unitAlgebra.h:104
void setDefaultTimeBase(TimeConverter *tc)
Manually set the default detaulTimeBase.
Definition: baseComponent.h:339
SubComponent is a class loadable through the factory which allows dynamic functionality to be added t...
Definition: subcomponent.h:29
const std::vector< double > & getCoordinates() const
Retrieve the X,Y,Z coordinates of this component.
Definition: baseComponent.h:331
const std::string & getName() const
Returns component Name.
Definition: baseComponent.h:124
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