SST  6.1.0
StructuralSimulationToolkit
component.h
1 // Copyright 2009-2016 Sandia Corporation. Under the terms
2 // of Contract DE-AC04-94AL85000 with Sandia Corporation, the U.S.
3 // Government retains certain rights in this software.
4 //
5 // Copyright (c) 2009-2016, 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_COMPONENT_H
13 #define SST_CORE_COMPONENT_H
14 
15 #include <sst/core/sst_types.h>
16 
17 #include <map>
18 #include <string>
19 
20 #include <sst/core/clock.h>
21 #include <sst/core/oneshot.h>
22 #include <sst/core/event.h>
23 //#include <sst/core/params.h>
24 //#include <sst/core/link.h>
25 //#include <sst/core/timeConverter.h>
26 #include <sst/core/statapi/statoutput.h>
27 #include <sst/core/statapi/statengine.h>
28 #include <sst/core/statapi/statnull.h>
29 #include <sst/core/statapi/stataccumulator.h>
30 #include <sst/core/statapi/stathistogram.h>
31 #include <sst/core/statapi/statuniquecount.h>
32 #include "sst/core/simulation.h"
33 #include "sst/core/unitAlgebra.h"
34 #include "sst/core/statapi/statbase.h"
35 
36 using namespace SST::Statistics;
37 
38 namespace SST {
39 
40 class Link;
41 class LinkMap;
42 class Module;
43 class Params;
44 class SubComponent;
45 class TimeConverter;
46 class UnitAlgebra;
47 class SharedRegion;
48 class SharedRegionMerger;
49 
50 #define _COMP_DBG( fmt, args...) __DBG( DBG_COMP, Component, fmt, ## args )
51 
52 /**
53  * Main component object for the simulation.
54  * All models inherit from this.
55  */
56 class Component {
57 public:
58 
59  static bool isPortValidForComponent(const std::string& comp_name, const std::string& port_name);
60 
61  /* Deprecated typedef */
62 // typedef Params Params_t;
63 
64  /** Constructor. Generally only called by the factory class.
65  @param id Unique component ID
66  */
67  Component( ComponentId_t id );
68  virtual ~Component();
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  /** Returns unique component ID */
76  inline ComponentId_t getId() const { return id; }
77 
78  /** Returns component Name */
79  /* inline const std::string& getName() const { return name; } */
80  inline const std::string& getName() const { return my_info->getName(); }
81 
82 
83  /** Component's type, set by the factory when the object is created.
84  It is identical to the configuration string used to create the
85  component. I.e. the XML "<component id="aFoo"><foo>..." would
86  set component::type to "foo" */
87  /* std::string type; */
88 
89  /** Used during the init phase. The method will be called each phase of initialization.
90  Initialization ends when no components have sent any data. */
91  virtual void init(unsigned int phase) {}
92  /** Called after all components have been constructed and inialization has
93  completed, but before simulation time has begun. */
94  virtual void setup( ) { }
95  /** Called after simulation completes, but before objects are
96  destroyed. A good place to print out statistics. */
97  virtual void finish( ) { }
98 
99  /** Currently unused function */
100  virtual bool Status( ) { return 0; }
101 
102  /**
103  * Called by the Simulation to request that the component
104  * print it's current status. Useful for debugging.
105  * @param out The Output class which should be used to print component status.
106  */
107  virtual void printStatus(Output &out) { return; }
108 
109  /** Determine if a port name is connected to any links */
110  bool isPortConnected(const std::string &name) const;
111 
112  /** Configure a Link
113  * @param name - Port Name on which the link to configure is attached.
114  * @param time_base - Time Base of the link
115  * @param handler - Optional Handler to be called when an Event is received
116  * @return A pointer to the configured link, or NULL if an error occured.
117  */
118  Link* configureLink( std::string name, TimeConverter* time_base, Event::HandlerBase* handler = NULL);
119  /** Configure a Link
120  * @param name - Port Name on which the link to configure is attached.
121  * @param time_base - Time Base of the link
122  * @param handler - Optional Handler to be called when an Event is received
123  * @return A pointer to the configured link, or NULL if an error occured.
124  */
125  Link* configureLink( std::string name, std::string time_base, Event::HandlerBase* handler = NULL);
126  /** Configure a Link
127  * @param name - Port Name on which the link to configure is attached.
128  * @param handler - Optional Handler to be called when an Event is received
129  * @return A pointer to the configured link, or NULL if an error occured.
130  */
131  Link* configureLink( std::string name, Event::HandlerBase* handler = NULL);
132 
133  /** Configure a SelfLink (Loopback link)
134  * @param name - Name of the self-link port
135  * @param time_base - Time Base of the link
136  * @param handler - Optional Handler to be called when an Event is received
137  * @return A pointer to the configured link, or NULL if an error occured.
138  */
139  Link* configureSelfLink( std::string name, TimeConverter* time_base, Event::HandlerBase* handler = NULL);
140  /** Configure a SelfLink (Loopback link)
141  * @param name - Name of the self-link port
142  * @param time_base - Time Base of the link
143  * @param handler - Optional Handler to be called when an Event is received
144  * @return A pointer to the configured link, or NULL if an error occured.
145  */
146  Link* configureSelfLink( std::string name, std::string time_base, Event::HandlerBase* handler = NULL);
147  /** Configure a SelfLink (Loopback link)
148  * @param name - Name of the self-link port
149  * @param handler - Optional Handler to be called when an Event is received
150  * @return A pointer to the configured link, or NULL if an error occured.
151  */
152  Link* configureSelfLink( std::string name, Event::HandlerBase* handler = NULL);
153 
154  /** Registers a clock for this component.
155  @param freq Frequency for the clock in SI units
156  @param handler Pointer to Clock::HandlerBase which is to be invoked
157  at the specified interval
158  @param regAll Should this clock perioud be used as the default
159  time base for all of the links connected to this component
160  */
161  TimeConverter* registerClock( std::string freq, Clock::HandlerBase* handler,
162  bool regAll = true);
163  TimeConverter* registerClock( const UnitAlgebra& freq, Clock::HandlerBase* handler,
164  bool regAll = true);
165  /** Removes a clock handler from the component */
166  void unregisterClock(TimeConverter *tc, Clock::HandlerBase* handler);
167 
168  /** Reactivates an existing Clock and Handler
169  * @return time of next time clock handler will fire
170  */
171  Cycle_t reregisterClock(TimeConverter *freq, Clock::HandlerBase* handler);
172  /** Returns the next Cycle that the TimeConverter would fire */
173  Cycle_t getNextClockCycle(TimeConverter *freq);
174 
175  /** Registers a OneShot event for this component.
176  Note: OneShot cannot be canceled, and will always callback after
177  the timedelay.
178  @param timeDelay Time delay for the OneShot in SI units
179  @param handler Pointer to OneShot::HandlerBase which is to be invoked
180  at the specified interval
181  */
182  TimeConverter* registerOneShot( std::string timeDelay, OneShot::HandlerBase* handler);
183  TimeConverter* registerOneShot( const UnitAlgebra& timeDelay, OneShot::HandlerBase* handler);
184 
185  /** Registers a default time base for the component and optionally
186  sets the the component's links to that timebase. Useful for
187  components which do not have a clock, but would like a default
188  timebase.
189  @param base Frequency for the clock in SI units
190  @param regAll Should this clock perioud be used as the default
191  time base for all of the links connected to this component
192  */
193  TimeConverter* registerTimeBase( std::string base, bool regAll = true);
194 
195  TimeConverter* getTimeConverter( const std::string& base );
196  TimeConverter* getTimeConverter( const UnitAlgebra& base );
197 
198  /** return the time since the simulation began in units specified by
199  the parameter.
200  @param tc TimeConverter specificing the units */
201  SimTime_t getCurrentSimTime(TimeConverter *tc) const;
202  /** return the time since the simulation began in the default timebase */
203  inline SimTime_t getCurrentSimTime() const{
204  return getCurrentSimTime(defaultTimeBase);
205  }
206  /** return the time since the simulation began in timebase specified
207  @param base Timebase frequency in SI Units */
208  SimTime_t getCurrentSimTime(std::string base);
209 
210  /** Utility function to return the time since the simulation began in nanoseconds */
211  SimTime_t getCurrentSimTimeNano() const;
212  /** Utility function to return the time since the simulation began in microseconds */
213  SimTime_t getCurrentSimTimeMicro() const;
214  /** Utility function to return the time since the simulation began in milliseconds */
215  SimTime_t getCurrentSimTimeMilli() const;
216 
217  /** Registers a statistic.
218  If Statistic is allowed to run (controlled by Python runtime parameters),
219  then a statistic will be created and returned. If not allowed to run,
220  then a NullStatistic will be returned. In either case, the returned
221  value should be used for all future Statistic calls. The type of
222  Statistic and the Collection Rate is set by Python runtime parameters.
223  If no type is defined, then an Accumulator Statistic will be provided
224  by default. If rate set to 0 or not provided, then the statistic will
225  output results only at end of sim (if output is enabled).
226  @param statName Primary name of the statistic. This name must match the
227  defined ElementInfoStatistic in the component, and must also
228  be enabled in the Python input file.
229  @param statSubId An additional sub name for the statistic
230  @return Either a created statistic of desired type or a NullStatistic
231  depending upon runtime settings.
232  */
233  template <typename T>
234  Statistic<T>* registerStatisticCore(std::string statName, std::string statSubId = "")
235  {
236  // NOTE: Templated Code for implementation of Statistic Registration
237  // is in the componentregisterstat_impl.h file. This was done
238  // to avoid code bloat in the .h file.
239  #include "sst/core/statapi/componentregisterstat_impl.h"
240  }
241 
242  template <typename T>
243  Statistic<T>* registerStatistic(std::string statName, std::string statSubId = "")
244  {
245  // Verify here that name of the stat is one of the registered
246  // names of the component's ElementInfoStatistic.
247  if (false == doesComponentInfoStatisticExist(statName)) {
248  printf("Error: Statistic %s name %s is not found in ElementInfoStatistic, exiting...\n",
249  StatisticBase::buildStatisticFullName(getName().c_str(), statName, statSubId).c_str(),
250  statName.c_str());
251  exit(1);
252  }
253  return registerStatisticCore<T>(statName, statSubId);
254  }
255 
256  template <typename T>
257  Statistic<T>* registerStatistic(const char* statName, const char* statSubId = "")
258  {
259  return registerStatistic<T>(std::string(statName), std::string(statSubId));
260  }
261 
262  /** Register that the simulation should not end until this
263  component says it is OK to. Calling this function (generally
264  done in Component::setup() or in component constructor)
265  increments a global counter. Calls to
266  Component::unregisterExit() decrements the counter. The
267  simulation cannot end unless this counter reaches zero, or the
268  simulation time limit is reached. This counter is synchonized
269  periodically with the other nodes.
270 
271  @sa Component::unregisterExit()
272  */
273  bool registerExit();
274 
275  /** Indicate permission for the simulation to end. This function is
276  the mirror of Component::registerExit(). It decrements the
277  global counter, which, upon reaching zero, indicates that the
278  simulation can terminate. @sa Component::registerExit() */
279  bool unregisterExit();
280 
281  /** Register as a primary component, which allows the component to
282  specifiy when it is and is not OK to end simulation. The
283  simulator will not end simulation natuarally (through use of
284  the Exit object) while any primary component has specified
285  primaryComponentDoNotEndSim(). However, it is still possible
286  for Actions other than Exit to end simulation. Once all
287  primary components have specified
288  primaryComponentOKToEndSim(), the Exit object will trigger and
289  end simulation.
290 
291  This must be called during simulation wireup (i.e during the
292  constructor for the component). By default, the state of the
293  primary component is set to OKToEndSim.
294 
295  If no component registers as a primary component, then the
296  Exit object will not be used for that simulation and
297  simulation termination must be accomplished through some other
298  mechanism (e.g. --stopAt flag, or some other Action object).
299 
300  @sa Component::primaryComponentDoNotEndSim()
301  @sa Component::primaryComponentOKToEndSim()
302  */
303  void registerAsPrimaryComponent();
304 
305  /** Tells the simulation that it should not exit. The component
306  will remain in this state until a call to
307  primaryComponentOKToEndSim().
308 
309  @sa Component::registerAsPrimaryComponent()
310  @sa Component::primaryComponentOKToEndSim()
311  */
312  void primaryComponentDoNotEndSim();
313 
314  /** Tells the simulation that it is now OK to end simulation.
315  Simulation will not end until all primary components have
316  called this function.
317 
318  @sa Component::registerAsPrimaryComponent()
319  @sa Component::primaryComponentDoNotEndSim()
320  */
321  void primaryComponentOKToEndSim();
322 
323  /** Loads a module from an element Library
324  * @param type Fully Qualified library.moduleName
325  * @param params Parameters the module should use for configuration
326  * @return handle to new instance of module, or NULL on failure.
327  */
328  Module* loadModule(std::string type, Params& params);
329 
330  /** Loads a module from an element Library
331  * @param type Fully Qualified library.moduleName
332  * @param comp Pointer to component to pass to Module's constructor
333  * @param params Parameters the module should use for configuration
334  * @return handle to new instance of module, or NULL on failure.
335  */
336  Module* loadModuleWithComponent(std::string type, Component* comp, Params& params);
337 
338  /** Loads a SubComponent from an element Library
339  * @param type Fully Qualified library.moduleName
340  * @param comp Pointer to component to pass to SuComponent's constructor
341  * @param params Parameters the module should use for configuration
342  * @return handle to new instance of SubComponent, or NULL on failure.
343  */
344  SubComponent* loadSubComponent(std::string type, Component* comp, Params& params);
345 
346 protected:
347  Component(); // For serialization only
348 
349  /** Manually set the default detaulTimeBase */
351  defaultTimeBase = tc;
352  }
353 
354  /** Timebase used if no other timebase is specified for calls like
355  Component::getCurrentSimTime(). Often set by Component::registerClock()
356  function */
358 
359  /** Creates a new selfLink */
360  Link* selfLink( std::string name, Event::HandlerBase* handler = NULL );
361 
362 
363  /** Find a lookup table */
364  SharedRegion* getLocalSharedRegion(const std::string &key, size_t size);
365  SharedRegion* getGlobalSharedRegion(const std::string &key, size_t size, SharedRegionMerger *merger = NULL);
366 
367  /* Get the Simulation */
368  Simulation* getSimulation() const { return sim; }
369 
370 private:
371 
372  friend class SubComponent;
373 
374  void addSelfLink(std::string name);
375 
376  // Does the statisticName exist in the ElementInfoStatistic
377  bool doesComponentInfoStatisticExist(std::string statisticName);
378  // Return the EnableLevel for the statisticName from the ElementInfoStatistic
379  uint8_t getComponentInfoStatisticEnableLevel(std::string statisticName);
380  // Return the Units for the statisticName from the ElementInfoStatistic
381  std::string getComponentInfoStatisticUnits(std::string statisticName);
382 
383  /** Unique ID */
384  ComponentId_t id;
385  /* std::string name; */
386  ComponentInfo* my_info;
387  Simulation *sim;
388 
389  // LinkMap* myLinks;
390  std::string currentlyLoadingSubComponent;
391 
392 
393 
394  template <typename T>
395  Statistic<T>* CreateStatistic(Component* comp, std::string& type, std::string& statName, std::string& statSubId, Params& params)
396  {
397  // Load one of the SST Core provided Statistics
398  // NOTE: This happens here (in simulation) instead of the factory because
399  // it is a templated method. The Component::registerStatistic<T>()
400  // must be defined in the component.h however the the Factory is
401  // not available from the Simulation::::getSimulation() because
402  // Factory is only defined via a forwarded definition. Basically
403  // we have to go through some twists and jumps to make this work.
404 
405  // Names of sst.xxx Statistics
406  if (0 == ::strcasecmp("sst.nullstatistic", type.c_str())) {
407  return new NullStatistic<T>(comp, statName, statSubId, params);
408  }
409 
410  if (0 == ::strcasecmp("sst.accumulatorstatistic", type.c_str())) {
411  return new AccumulatorStatistic<T>(comp, statName, statSubId, params);
412  }
413 
414  if (0 == ::strcasecmp("sst.histogramstatistic", type.c_str())) {
415  return new HistogramStatistic<T>(comp, statName, statSubId, params);
416  }
417 
418  if(0 == ::strcasecmp("sst.uniquecountstatistic", type.c_str())) {
419  return new UniqueCountStatistic<T>(comp, statName, statSubId, params);
420  }
421 
422  // We did not find this statistic
423  printf("ERROR: Statistic %s is not supported by the SST Core...\n", type.c_str());
424 
425  return NULL;
426  }
427 
428 
429 
430 
431 };
432 
433 } //namespace SST
434 
435 #endif // SST_CORE_COMPONENT_H
Output object provides consistant method for outputing data to stdout, stderr and/or sst debug file...
Definition: output.h:54
Definition: sharedRegion.h:77
Main control class for a SST Simulation.
Definition: simulation.h:75
virtual void finish()
Called after simulation completes, but before objects are destroyed.
Definition: component.h:97
virtual bool Status()
Currently unused function.
Definition: component.h:100
A class to convert between a component's view of time and the core's view of time.
Definition: timeConverter.h:25
Main component object for the simulation.
Definition: component.h:56
Creates a Statistic which counts unique values provided to it.
Definition: statuniquecount.h:32
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
Allows the online gathering of statistical information about a single quantity.
Definition: stataccumulator.h:42
TimeConverter * defaultTimeBase
Timebase used if no other timebase is specified for calls like Component::getCurrentSimTime().
Definition: component.h:357
Holder of data grouped into pre-determined width bins.
Definition: stathistogram.h:41
Forms the template defined base class for statistics gathering within SST.
Definition: statbase.h:263
virtual void emergencyShutdown(void)
Called when SIGINT or SIGTERM has been seen.
Definition: component.h:73
SimTime_t getCurrentSimTime() const
return the time since the simulation began in the default timebase
Definition: component.h:203
virtual void init(unsigned int phase)
Component's type, set by the factory when the object is created.
Definition: component.h:91
ComponentId_t getId() const
Returns unique component ID.
Definition: component.h:76
virtual void setup()
Called after all components have been constructed and inialization has completed, but before simulati...
Definition: component.h:94
Statistic< T > * registerStatisticCore(std::string statName, std::string statSubId="")
Registers a statistic.
Definition: component.h:234
Functor classes for Clock handling.
Definition: clock.h:44
const std::string & getName() const
Returns component Name.
Definition: component.h:80
Parameter store.
Definition: params.h:44
Functor classes for Event handling.
Definition: event.h:86
virtual void printStatus(Output &out)
Called by the Simulation to request that the component print it's current status. ...
Definition: component.h:107
Definition: simulation.h:62
Performs Unit math in full precision.
Definition: unitAlgebra.h:112
SubComponent is a class loadable through the factory which allows dynamic functionality to be added t...
Definition: subcomponent.h:27
Definition: componentInfo.h:36
An empty statistic place holder.
Definition: statnull.h:42
void setDefaultTimeBase(TimeConverter *tc)
Manually set the default detaulTimeBase.
Definition: component.h:350
Functor classes for OneShot handling.
Definition: oneshot.h:39