SST  6.1.0
StructuralSimulationToolkit
simulation.h
1 // -*- c++ -*-
2 
3 // Copyright 2009-2016 Sandia Corporation. Under the terms
4 // of Contract DE-AC04-94AL85000 with Sandia Corporation, the U.S.
5 // Government retains certain rights in this software.
6 //
7 // Copyright (c) 2009-2016, Sandia Corporation
8 // All rights reserved.
9 //
10 // This file is part of the SST software package. For license
11 // information, see the LICENSE file in the top level directory of the
12 // distribution.
13 
14 #ifndef SST_CORE_SIMULATION_H
15 #define SST_CORE_SIMULATION_H
16 
17 #include "sst/core/sst_types.h"
18 
19 #include <signal.h>
20 #include <atomic>
21 #include <iostream>
22 #include <thread>
23 
24 #include <unordered_map>
25 
26 #include <sst/core/output.h>
27 #include <sst/core/clock.h>
28 #include <sst/core/oneshot.h>
29 #include <sst/core/unitAlgebra.h>
30 #include <sst/core/rankInfo.h>
31 
32 #include <sst/core/componentInfo.h>
33 
34 /* Forward declare for Friendship */
35 extern int main(int argc, char **argv);
36 
37 
38 namespace SST {
39 
40 #define _SIM_DBG( fmt, args...) __DBG( DBG_SIM, Sim, fmt, ## args )
41 #define STATALLFLAG "--ALLSTATS--"
42 
43 class Activity;
44 class Component;
45 class Config;
46 class ConfigGraph;
47 class Exit;
48 class Factory;
49 class SimulatorHeartbeat;
50 //class Graph;
51 class Introspector;
52 class LinkMap;
53 class Params;
54 class SyncBase;
55 class SyncManager;
56 class ThreadSync;
57 class TimeConverter;
58 class TimeLord;
59 class TimeVortex;
60 class UnitAlgebra;
61 class SharedRegionManager;
62 namespace Statistics {
63  class StatisticOutput;
64  class StatisticProcessingEngine;
65 }
66 
67 
68 typedef std::map<std::string, Introspector* > IntroMap_t;
69 
70 
71 /**
72  * Main control class for a SST Simulation.
73  * Provides base features for managing the simulation
74  */
75 class Simulation {
76 public:
77  /** Type of Run Modes */
78  typedef enum {
79  UNKNOWN, /*!< Unknown mode - Invalid for running */
80  INIT, /*!< Initialize-only. Useful for debugging initialization and graph generation */
81  RUN, /*!< Run-only. Useful when restoring from a checkpoint */
82  BOTH /*!< Default. Both initialize and Run the simulation */
83  } Mode_t;
84 
85  typedef std::map<SimTime_t, Clock*> clockMap_t; /*!< Map of times to clocks */
86  typedef std::map<SimTime_t, OneShot*> oneShotMap_t; /*!< Map of times to OneShots */
87  typedef std::vector<std::string> statEnableList_t; /*!< List of Enabled Statistics */
88  typedef std::vector<Params> statParamsList_t; /*!< List of Enabled Statistics Parameters */
89  typedef std::map<ComponentId_t, statEnableList_t*> statEnableMap_t; /*!< Map of Statistics that are requested to be enabled for a component defined in configGraph */
90  typedef std::map<ComponentId_t, statParamsList_t*> statParamsMap_t; /*!< Map of Statistic Params for a component defined in configGraph */
91  // typedef std::map< unsigned int, Sync* > SyncMap_t; /*!< Map of times to Sync Objects */
92 
93  ~Simulation();
94 
95  /** Create new simulation
96  * @param config - Configuration of the simulation
97  * @param my_rank - Parallel Rank of this simulation object
98  * @param num_ranks - How many Ranks are in the simulation
99  */
100  static Simulation *createSimulation(Config *config, RankInfo my_rank, RankInfo num_ranks, SimTime_t min_part);
101  /**
102  * Used to signify the end of simulation. Cleans up any existing Simulation Objects
103  */
104  static void shutdown();
105  /** Return a pointer to the singleton instance of the Simulation */
106  static Simulation *getSimulation() { return instanceMap.at(std::this_thread::get_id()); }
107  /** Sets an internal flag for signaling the simulation. Used internally */
108  static void setSignal(int signal);
109  /** Causes the current status of the simulation to be printed to stderr.
110  * @param fullStatus - if true, call printStatus() on all components as well
111  * as print the base Simulation's status
112  */
113  void printStatus(bool fullStatus);
114 
115  /** Processes the ConfigGraph to pull out any need information
116  * about relationships among the threads
117  */
118  void processGraphInfo( ConfigGraph& graph, const RankInfo &myRank, SimTime_t min_part );
119 
120  /** Converts a ConfigGraph graph into actual set of links and components */
121  int performWireUp( ConfigGraph& graph, const RankInfo &myRank, SimTime_t min_part );
122 
123  /** Set cycle count, which, if reached, will cause the simulation to halt. */
124  void setStopAtCycle( Config* cfg );
125  /** Perform the init() phase of simulation */
126  void initialize();
127  /** Perform the setup() and run phases of the simulation. */
128  void setup();
129  void run();
130  void finish();
131 
132  bool isIndependentThread() { return independent;}
133 
134  /** Get the run mode of the simulation (e.g. init, run, both etc) */
135  Mode_t getSimulationMode() const { return runMode; };
136  /** Return the current simulation time as a cycle count*/
137  const SimTime_t& getCurrentSimCycle() const;
138  /** Return the end simulation time as a cycle count*/
139  SimTime_t getEndSimCycle() const;
140  /** Return the current priority */
141  int getCurrentPriority() const;
142  /** Return the elapsed simulation time as a time */
144  /** Return the end simulation time as a time */
146  /** Get this instance's parallel rank */
147  RankInfo getRank() const {return my_rank;}
148  /** Get the number of parallel ranks in the simulation */
149  RankInfo getNumRanks() const {return num_ranks;}
150  /** Register a handler to be called on a set frequency */
151  TimeConverter* registerClock(std::string freq, Clock::HandlerBase* handler);
153  /** Remove a clock handler from the list of active clock handlers */
155  /** Reactivate an existing clock and handler.
156  * @return time when handler will next fire
157  */
158  Cycle_t reregisterClock(TimeConverter *tc, Clock::HandlerBase* handler);
159  /** Returns the next Cycle that the TImeConverter would fire. */
160  Cycle_t getNextClockCycle(TimeConverter* tc);
161 
162  /** Register a OneShot event to be called after a time delay
163  Note: OneShot cannot be canceled, and will always callback after
164  the timedelay.
165  */
166  TimeConverter* registerOneShot(std::string timeDelay, OneShot::HandlerBase* handler);
167  TimeConverter* registerOneShot(const UnitAlgebra& timeDelay, OneShot::HandlerBase* handler);
168 
169  /** Insert an activity to fire at a specified time */
170  void insertActivity(SimTime_t time, Activity* ev);
171 
172  /** Return the exit event */
173  Exit* getExit() const { return m_exit; }
174 
175  const std::vector<SimTime_t>& getInterThreadLatencies() { return interThreadLatencies; }
176  const SimTime_t getInterThreadMinLatency() { return interThreadMinLatency; }
177  static TimeConverter* getMinPartTC() { return minPartTC; }
178 
179  /** Return the TimeLord associated with this Simulation */
180  static TimeLord* getTimeLord(void) { return &timeLord; }
181  /** Return the base simulation Output class instance */
182  static Output& getSimulationOutput() { return sim_output; };
183 
184  static Statistics::StatisticOutput* getStatisticsOutput() { return statisticsOutput; }
185  static void signalStatisticsBegin();
186  static void signalStatisticsEnd();
187 
188  uint64_t getTimeVortexMaxDepth() const;
189  uint64_t getTimeVortexCurrentDepth() const;
190  uint64_t getSyncQueueDataSize() const;
191 
192 
193  /** Return the Statistic Processing Engine associated with this Simulation */
195 
196  /** Return pointer to map of links for a given component id */
197  LinkMap* getComponentLinkMap(ComponentId_t id) const {
198  ComponentInfo* info = compInfoMap.getByID(id);
199  if ( NULL == info ) {
200  return NULL;
201  } else {
202  return info->getLinkMap();
203  }
204  }
205 
206 
207  // /** Returns reference to the Component Map */
208  // const CompMap_t& getComponentMap(void) const { return compMap; }
209  // /** Returns reference to the Component ID Map */
210  // // const CompIdMap_t& getComponentIdMap(void) const { return compIdMap; }
211  const ComponentInfoMap& getComponentInfoMap(void) { return compInfoMap; }
212 
213 
214  /** Returns the component with a given name */
215  Component* getComponent(const std::string &name) const
216  {
217  ComponentInfo* i = compInfoMap.getByName(name);
218  if (NULL != i) {
219  return i->getComponent();
220  } else {
221  printf("Simulation::getComponent() couldn't find component with name = %s\n",
222  name.c_str());
223  exit(1);
224  }
225  }
226 
227  /** returns the component with the given ID */
228  Component* getComponent(const ComponentId_t &id) const
229  {
230  ComponentInfo* i = compInfoMap.getByID(id);
231  // CompInfoMap_t::const_iterator i = compInfoMap.find(id);
232  if ( NULL != i ) {
233  return i->getComponent();
234  } else {
235  printf("Simulation::getComponent() couldn't find component with id = %lu\n", id);
236  exit(1);
237  }
238  }
239 
240  ComponentInfo* getComponentInfo(const std::string& name) const
241  {
242  ComponentInfo* i = compInfoMap.getByName(name);
243  if (NULL != i) {
244  return i;
245  } else {
246  printf("Simulation::getComponentInfo() couldn't find component with name = %s\n",
247  name.c_str());
248  exit(1);
249  }
250  }
251 
252  ComponentInfo* getComponentInfo(const ComponentId_t &id) const
253  {
254  ComponentInfo* i = compInfoMap.getByID(id);
255  // CompInfoMap_t::const_iterator i = compInfoMap.find(id);
256  if ( NULL != i ) {
257  return i;
258  } else {
259  printf("Simulation::getComponentInfo() couldn't find component with id = %lu\n", id);
260  exit(1);
261  }
262  }
263 
264  statEnableList_t* getComponentStatisticEnableList(const ComponentId_t &id) const
265  {
266  statEnableMap_t::const_iterator i = statisticEnableMap.find(id);
267  if (i != statisticEnableMap.end()) {
268  return i->second;
269  } else {
270  printf("Simulation::getComponentStatisticEnableList() couldn't find component with id = %lu\n", id);
271  exit(1);
272  }
273  return NULL;
274  }
275 
276  statParamsList_t* getComponentStatisticParamsList(const ComponentId_t &id) const
277  {
278  statParamsMap_t::const_iterator i = statisticParamsMap.find(id);
279  if (i != statisticParamsMap.end()) {
280  return i->second;
281  } else {
282  printf("Simulation::getComponentStatisticParamsList() couldn't find component with id = %lu\n", id);
283  exit(1);
284  }
285  return NULL;
286  }
287 
288 
289  /** Returns the Introspector with the given name */
290  Introspector* getIntrospector(const std::string &name) const
291  {
292  IntroMap_t::const_iterator i = introMap.find(name);
293  if (i != introMap.end()) {
294  return i->second;
295  } else {
296  printf("Simulation::getIntrospector() couldn't find introspector with name = %s\n",
297  name.c_str());
298  exit(1);
299  }
300  }
301 
302  /**
303  Set the output directory for this simulation
304  @param outDir Path of directory to place simulation outputs in
305  */
306  void setOutputDirectory(std::string& outDir) {
307  output_directory = outDir;
308  }
309 
310  /**
311  Returns the output directory of the simulation
312  @return Directory in which simulation outputs are placed
313  */
314  std::string& getOutputDirectory() {
315  return output_directory;
316  }
317 
318  /** Signifies that an event type is required for this simulation
319  * Causes to Factory to verify that the required event type can be found.
320  * @param name fully qualified libraryName.EventName
321  */
322  void requireEvent(std::string name);
323 
324  /**
325  * Returns the time of the next item to be executed
326  * that is in the TImeVortex of the Simulation
327  */
328  SimTime_t getNextActivityTime() const;
329 
330  /**
331  * Gets the minimum next activity time across all TimeVortices in
332  * the Rank
333  */
334  static SimTime_t getLocalMinimumNextActivityTime();
335 
336  /**
337  * Returns the Simulation's SharedRegionManager
338  */
339  static SharedRegionManager* getSharedRegionManager() { return sharedRegionManager; }
340 
341  /**
342  * Returns true when the Wireup is finished.
343  */
344  bool isWireUpFinished() {return wireUpFinished; }
345 
346 private:
347  friend class Link;
348  friend class Action;
349  friend class Output;
350  // To enable main to set up globals
351  friend int ::main(int argc, char **argv);
352 
353  Simulation(); // Don't call. Only rational way to serialize
354  Simulation(Config* config, RankInfo my_rank, RankInfo num_ranks, SimTime_t min_part);
355  Simulation(Simulation const&); // Don't Implement
356  void operator=(Simulation const&); // Don't implement
357 
358 
359  /** Get a handle to a TimeConverter
360  * @param cycles Frequency which is the base of the TimeConverter
361  */
362  TimeConverter* minPartToTC(SimTime_t cycles) const;
363  static Core::ThreadSafe::Barrier& getThreadBarrier() { return barrier; }
364 
365  /** Factory used to generate the simulation components */
366  static Factory *factory;
367  /** TimeLord of the simulation */
368  static TimeLord timeLord;
369  /** Statistics Output of the simulation */
370  static Statistics::StatisticOutput* statisticsOutput;
371  /** Output */
372  static Output sim_output;
373  static Core::ThreadSafe::Barrier barrier;
374  static Core::ThreadSafe::Barrier exit_barrier;
375  static std::mutex simulationMutex;
376 
377 
378 
379  Component* createComponent(ComponentId_t id, std::string &name,
380  Params &params);
381  Introspector* createIntrospector(std::string &name,
382  Params &params );
383 
384  TimeVortex* getTimeVortex() const { return timeVortex; }
385 
386  /** Emergency Shutdown
387  * Called when a SIGINT or SIGTERM has been seen
388  */
389  static void emergencyShutdown();
390  /** Normal Shutdown
391  */
392  void endSimulation(void) { endSimulation(currentSimCycle); }
393  void endSimulation(SimTime_t end);
394 
395  typedef enum {
396  SHUTDOWN_CLEAN, /* Normal shutdown */
397  SHUTDOWN_SIGNAL, /* SIGINT or SIGTERM received */
398  SHUTDOWN_EMERGENCY, /* emergencyShutdown() called */
399  } ShutdownMode_t;
400 
401  friend class SyncManager;
402 
403  Mode_t runMode;
404  TimeVortex* timeVortex;
405  TimeConverter* threadMinPartTC;
406  Activity* current_activity;
407  static SyncBase* sync;
408  static SimTime_t minPart;
409  static TimeConverter* minPartTC;
410  std::vector<SimTime_t> interThreadLatencies;
411  SimTime_t interThreadMinLatency;
412  SyncManager* syncManager;
413  ThreadSync* threadSync;
414  ComponentInfoMap compInfoMap;
415  IntroMap_t introMap;
416  clockMap_t clockMap;
417  statEnableMap_t statisticEnableMap;
418  statParamsMap_t statisticParamsMap;
419  oneShotMap_t oneShotMap;
420  SimTime_t currentSimCycle;
421  SimTime_t endSimCycle;
422  int currentPriority;
423  static Exit* m_exit;
424  SimulatorHeartbeat* m_heartbeat;
425  bool endSim;
426  RankInfo my_rank;
427  RankInfo num_ranks;
428  bool independent; // true if no links leave thread (i.e. no syncs required)
429  static std::atomic<int> init_msg_count;
430  unsigned int init_phase;
431  volatile sig_atomic_t lastRecvdSignal;
432  ShutdownMode_t shutdown_mode;
433  // std::map<ComponentId_t,LinkMap*> component_links;
434  std::string output_directory;
435  static SharedRegionManager* sharedRegionManager;
436  bool wireUpFinished;
437  /** Statistics Timing Engine of the simulation */
438  Statistics::StatisticProcessingEngine* statisticsEngine;
439 
440  static std::unordered_map<std::thread::id, Simulation*> instanceMap;
441  static std::vector<Simulation*> instanceVec;
442 
443  friend void wait_my_turn_start();
444  friend void wait_my_turn_end();
445 
446 };
447 
448 // Function to allow for easy serialization of threads while debugging
449 // code. Can only be used when you can guarantee all threads will be
450 // taking the same code path. If you can't guarantee that, then use a
451 // spinlock to make sure only one person is in a given region at a
452 // time. ONLY FOR DEBUG USE.
453 void wait_my_turn_start(Core::ThreadSafe::Barrier& barrier, int thread, int total_threads);
454 
455 // Uses Simulation's barrier
456 void wait_my_turn_start();
457 
458 void wait_my_turn_end(Core::ThreadSafe::Barrier& barrier, int thread, int total_threads);
459 
460 // Uses Simulation's barrier
461 void wait_my_turn_end();
462 
463 
464 } // namespace SST
465 
466 #endif //SST_CORE_SIMULATION_H
Output object provides consistant method for outputing data to stdout, stderr and/or sst debug file...
Definition: output.h:54
Exit * getExit() const
Return the exit event.
Definition: simulation.h:173
An Action is a schedulable Activity which is not an Event.
Definition: action.h:30
static SimTime_t getLocalMinimumNextActivityTime()
Gets the minimum next activity time across all TimeVortices in the Rank.
Definition: simulation.cc:222
TimeConverter * registerOneShot(std::string timeDelay, OneShot::HandlerBase *handler)
Register a OneShot event to be called after a time delay Note: OneShot cannot be canceled, and will always callback after the timedelay.
Definition: simulation.cc:960
UnitAlgebra getFinalSimTime() const
Return the end simulation time as a time.
Definition: simulation.cc:871
Component * getComponent(const ComponentId_t &id) const
returns the component with the given ID
Definition: simulation.h:228
std::map< SimTime_t, Clock * > clockMap_t
Definition: simulation.h:85
Main control class for a SST Simulation.
Definition: simulation.h:75
Base class for all Activities in the SST Event Queue.
Definition: activity.h:53
Maps port names to the Links that are connected to it.
Definition: linkMap.h:28
Class to contain SST Simulation Configuration variables.
Definition: config.h:31
static TimeLord * getTimeLord(void)
Return the TimeLord associated with this Simulation.
Definition: simulation.h:180
RankInfo getNumRanks() const
Get the number of parallel ranks in the simulation.
Definition: simulation.h:149
std::vector< std::string > statEnableList_t
Definition: simulation.h:87
Forms the base class for statistics output generation within the SST core.
Definition: statoutput.h:47
const SimTime_t & getCurrentSimCycle() const
Return the current simulation time as a cycle count.
Definition: simulation.cc:830
A class to convert between a component's view of time and the core's view of time.
Definition: timeConverter.h:25
Mode_t getSimulationMode() const
Get the run mode of the simulation (e.g.
Definition: simulation.h:135
Main component object for the simulation.
Definition: component.h:56
A Configuration Graph A graph representing Components and Links.
Definition: configGraph.h:202
TimeConverter * registerClock(std::string freq, Clock::HandlerBase *handler)
Register a handler to be called on a set frequency.
Definition: simulation.cc:898
static Simulation * createSimulation(Config *config, RankInfo my_rank, RankInfo num_ranks, SimTime_t min_part)
Create new simulation.
Definition: simulation.cc:120
SimTime_t getNextActivityTime() const
Returns the time of the next item to be executed that is in the TImeVortex of the Simulation...
Definition: simulation.cc:216
std::string & getOutputDirectory()
Returns the output directory of the simulation.
Definition: simulation.h:314
std::map< SimTime_t, OneShot * > oneShotMap_t
Definition: simulation.h:86
Definition: action.cc:17
void insertActivity(SimTime_t time, Activity *ev)
Insert an activity to fire at a specified time.
Definition: simulation.cc:983
Definition: simulation.h:80
void setOutputDirectory(std::string &outDir)
Set the output directory for this simulation.
Definition: simulation.h:306
Cycle_t reregisterClock(TimeConverter *tc, Clock::HandlerBase *handler)
Reactivate an existing clock and handler.
Definition: simulation.cc:930
Definition: simulation.h:79
static void setSignal(int signal)
Sets an internal flag for signaling the simulation.
Definition: simulation.cc:876
void setStopAtCycle(Config *cfg)
Set cycle count, which, if reached, will cause the simulation to halt.
Definition: simulation.cc:180
Statistics::StatisticProcessingEngine * getStatisticsProcessingEngine(void) const
Return the Statistic Processing Engine associated with this Simulation.
Definition: simulation.h:194
void initialize()
Perform the init() phase of simulation.
Definition: simulation.cc:618
Exit Event Action.
Definition: exit.h:34
Definition: componentInfo.h:108
static Output & getSimulationOutput()
Return the base simulation Output class instance.
Definition: simulation.h:182
int getCurrentPriority() const
Return the current priority.
Definition: simulation.cc:842
void setup()
Perform the setup() and run phases of the simulation.
Definition: simulation.cc:665
Cycle_t getNextClockCycle(TimeConverter *tc)
Returns the next Cycle that the TImeConverter would fire.
Definition: simulation.cc:941
std::vector< Params > statParamsList_t
Definition: simulation.h:88
Main introspector object for the simulation.
Definition: introspector.h:36
static void shutdown()
Used to signify the end of simulation.
Definition: simulation.cc:133
int performWireUp(ConfigGraph &graph, const RankInfo &myRank, SimTime_t min_part)
Converts a ConfigGraph graph into actual set of links and components.
Definition: simulation.cc:318
void requireEvent(std::string name)
Signifies that an event type is required for this simulation Causes to Factory to verify that the req...
Definition: simulation.cc:210
LinkMap * getComponentLinkMap(ComponentId_t id) const
Return pointer to map of links for a given component id.
Definition: simulation.h:197
RankInfo getRank() const
Get this instance's parallel rank.
Definition: simulation.h:147
UnitAlgebra getElapsedSimTime() const
Return the elapsed simulation time as a time.
Definition: simulation.cc:866
Definition: rankInfo.h:21
Functor classes for Clock handling.
Definition: clock.h:44
Component * getComponent(const std::string &name) const
Returns the component with a given name.
Definition: simulation.h:215
void unregisterClock(TimeConverter *tc, Clock::HandlerBase *handler)
Remove a clock handler from the list of active clock handlers.
Definition: simulation.cc:950
Class for creating and managing TimeConverter objects.
Definition: timeLord.h:36
std::map< ComponentId_t, statParamsList_t * > statParamsMap_t
Definition: simulation.h:90
static SharedRegionManager * getSharedRegionManager()
Returns the Simulation's SharedRegionManager.
Definition: simulation.h:339
bool isWireUpFinished()
Returns true when the Wireup is finished.
Definition: simulation.h:344
Definition: simulation.h:81
void printStatus(bool fullStatus)
Causes the current status of the simulation to be printed to stderr.
Definition: simulation.cc:882
SimTime_t getEndSimCycle() const
Return the end simulation time as a cycle count.
Definition: simulation.cc:836
Definition: simulation.h:82
An SST core component that handles timing and event processing informing all registered Statistics to...
Definition: statengine.h:33
Mode_t
Type of Run Modes.
Definition: simulation.h:78
Performs Unit math in full precision.
Definition: unitAlgebra.h:112
Introspector * getIntrospector(const std::string &name) const
Returns the Introspector with the given name.
Definition: simulation.h:290
Definition: threadsafe.h:42
Definition: componentInfo.h:36
const ComponentInfoMap & getComponentInfoMap(void)
Returns reference to the Component Map.
Definition: simulation.h:211
std::map< ComponentId_t, statEnableList_t * > statEnableMap_t
Definition: simulation.h:89
void processGraphInfo(ConfigGraph &graph, const RankInfo &myRank, SimTime_t min_part)
Processes the ConfigGraph to pull out any need information about relationships among the threads...
Definition: simulation.cc:236
static Simulation * getSimulation()
Return a pointer to the singleton instance of the Simulation.
Definition: simulation.h:106
Definition: sharedRegion.h:56
Functor classes for OneShot handling.
Definition: oneshot.h:39