SST  7.2.0
StructuralSimulationToolkit
simulation.h
1 // -*- c++ -*-
2 
3 // Copyright 2009-2017 Sandia Corporation. Under the terms
4 // of Contract DE-NA0003525 with Sandia Corporation, the U.S.
5 // Government retains certain rights in this software.
6 //
7 // Copyright (c) 2009-2017, 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 LinkMap;
52 class Params;
53 class SyncBase;
54 class SyncManager;
55 class ThreadSync;
56 class TimeConverter;
57 class TimeLord;
58 class TimeVortex;
59 class UnitAlgebra;
60 class SharedRegionManager;
61 namespace Statistics {
62  class StatisticOutput;
63  class StatisticProcessingEngine;
64 }
65 
66 
67 
68 /**
69  * Main control class for a SST Simulation.
70  * Provides base features for managing the simulation
71  */
72 class Simulation {
73 public:
74  /** Type of Run Modes */
75  typedef enum {
76  UNKNOWN, /*!< Unknown mode - Invalid for running */
77  INIT, /*!< Initialize-only. Useful for debugging initialization and graph generation */
78  RUN, /*!< Run-only. Useful when restoring from a checkpoint */
79  BOTH /*!< Default. Both initialize and Run the simulation */
80  } Mode_t;
81 
82  typedef std::map<std::pair<SimTime_t, int>, Clock*> clockMap_t; /*!< Map of times to clocks */
83  typedef std::map<std::pair<SimTime_t, int>, OneShot*> oneShotMap_t; /*!< Map of times to OneShots */
84  // typedef std::map< unsigned int, Sync* > SyncMap_t; /*!< Map of times to Sync Objects */
85 
86  ~Simulation();
87 
88  /** Create new simulation
89  * @param config - Configuration of the simulation
90  * @param my_rank - Parallel Rank of this simulation object
91  * @param num_ranks - How many Ranks are in the simulation
92  */
93  static Simulation *createSimulation(Config *config, RankInfo my_rank, RankInfo num_ranks, SimTime_t min_part);
94  /**
95  * Used to signify the end of simulation. Cleans up any existing Simulation Objects
96  */
97  static void shutdown();
98  /** Return a pointer to the singleton instance of the Simulation */
99  static Simulation *getSimulation() { return instanceMap.at(std::this_thread::get_id()); }
100  /** Sets an internal flag for signaling the simulation. Used internally */
101  static void setSignal(int signal);
102  /** Causes the current status of the simulation to be printed to stderr.
103  * @param fullStatus - if true, call printStatus() on all components as well
104  * as print the base Simulation's status
105  */
106  void printStatus(bool fullStatus);
107 
108  /** Processes the ConfigGraph to pull out any need information
109  * about relationships among the threads
110  */
111  void processGraphInfo( ConfigGraph& graph, const RankInfo &myRank, SimTime_t min_part );
112 
113  /** Converts a ConfigGraph graph into actual set of links and components */
114  int performWireUp( ConfigGraph& graph, const RankInfo &myRank, SimTime_t min_part );
115 
116  /** Set cycle count, which, if reached, will cause the simulation to halt. */
117  void setStopAtCycle( Config* cfg );
118  /** Perform the init() phase of simulation */
119  void initialize();
120  /** Perform the complete() phase of simulation */
121  void complete();
122  /** Perform the setup() and run phases of the simulation. */
123  void setup();
124  void run();
125  void finish();
126 
127  bool isIndependentThread() { return independent;}
128 
129  /** Get the run mode of the simulation (e.g. init, run, both etc) */
130  Mode_t getSimulationMode() const { return runMode; };
131  /** Return the current simulation time as a cycle count*/
132  const SimTime_t& getCurrentSimCycle() const;
133  /** Return the end simulation time as a cycle count*/
134  SimTime_t getEndSimCycle() const;
135  /** Return the current priority */
136  int getCurrentPriority() const;
137  /** Return the elapsed simulation time as a time */
138  UnitAlgebra getElapsedSimTime() const;
139  /** Return the end simulation time as a time */
140  UnitAlgebra getFinalSimTime() const;
141  /** Get this instance's parallel rank */
142  RankInfo getRank() const {return my_rank;}
143  /** Get the number of parallel ranks in the simulation */
144  RankInfo getNumRanks() const {return num_ranks;}
145  /** Register a handler to be called on a set frequency */
146  TimeConverter* registerClock(const std::string& freq, Clock::HandlerBase* handler, int priority);
147  TimeConverter* registerClock(const UnitAlgebra& freq, Clock::HandlerBase* handler, int priority);
148  TimeConverter* registerClock(TimeConverter *tcFreq, Clock::HandlerBase* handler, int priority);
149  /** Remove a clock handler from the list of active clock handlers */
150  void unregisterClock(TimeConverter *tc, Clock::HandlerBase* handler, int priority);
151  /** Reactivate an existing clock and handler.
152  * @return time when handler will next fire
153  */
154  Cycle_t reregisterClock(TimeConverter *tc, Clock::HandlerBase* handler, int priority);
155  /** Returns the next Cycle that the TImeConverter would fire. */
156  Cycle_t getNextClockCycle(TimeConverter* tc, int priority = CLOCKPRIORITY);
157 
158  /** Register a OneShot event to be called after a time delay
159  Note: OneShot cannot be canceled, and will always callback after
160  the timedelay.
161  */
162  TimeConverter* registerOneShot(std::string timeDelay, OneShot::HandlerBase* handler, int priority);
163  TimeConverter* registerOneShot(const UnitAlgebra& timeDelay, OneShot::HandlerBase* handler, int priority);
164 
165  /** Insert an activity to fire at a specified time */
166  void insertActivity(SimTime_t time, Activity* ev);
167 
168  /** Return the exit event */
169  Exit* getExit() const { return m_exit; }
170 
171  const std::vector<SimTime_t>& getInterThreadLatencies() const { return interThreadLatencies; }
172  SimTime_t getInterThreadMinLatency() const { return interThreadMinLatency; }
173  static TimeConverter* getMinPartTC() { return minPartTC; }
174 
175  /** Return the TimeLord associated with this Simulation */
176  static TimeLord* getTimeLord(void) { return &timeLord; }
177  /** Return the base simulation Output class instance */
178  static Output& getSimulationOutput() { return sim_output; };
179 
180  uint64_t getTimeVortexMaxDepth() const;
181  uint64_t getTimeVortexCurrentDepth() const;
182  uint64_t getSyncQueueDataSize() const;
183 
184  /** Return the Statistic Processing Engine associated with this Simulation */
185  Statistics::StatisticProcessingEngine* getStatisticsProcessingEngine(void) const;
186 
187  /** Return pointer to map of links for a given component id */
188  LinkMap* getComponentLinkMap(ComponentId_t id) const {
189  ComponentInfo* info = compInfoMap.getByID(id);
190  if ( NULL == info ) {
191  return NULL;
192  } else {
193  return info->getLinkMap();
194  }
195  }
196 
197 
198  // /** Returns reference to the Component Map */
199  // const CompMap_t& getComponentMap(void) const { return compMap; }
200  // /** Returns reference to the Component ID Map */
201  // // const CompIdMap_t& getComponentIdMap(void) const { return compIdMap; }
202  const ComponentInfoMap& getComponentInfoMap(void) { return compInfoMap; }
203 
204 
205  /** returns the component with the given ID */
206  BaseComponent* getComponent(const ComponentId_t &id) const
207  {
208  ComponentInfo* i = compInfoMap.getByID(id);
209  // CompInfoMap_t::const_iterator i = compInfoMap.find(id);
210  if ( NULL != i ) {
211  return i->getComponent();
212  } else {
213  printf("Simulation::getComponent() couldn't find component with id = %" PRIu64 "\n", id);
214  exit(1);
215  }
216  }
217 
218 
219  ComponentInfo* getComponentInfo(const ComponentId_t &id) const
220  {
221  ComponentInfo* i = compInfoMap.getByID(id);
222  // CompInfoMap_t::const_iterator i = compInfoMap.find(id);
223  if ( NULL != i ) {
224  return i;
225  } else {
226  printf("Simulation::getComponentInfo() couldn't find component with id = %" PRIu64 "\n", id);
227  exit(1);
228  }
229  }
230 
231 
232 
233  /**
234  Set the output directory for this simulation
235  @param outDir Path of directory to place simulation outputs in
236  */
237  void setOutputDirectory(std::string& outDir) {
238  output_directory = outDir;
239  }
240 
241  /**
242  Returns the output directory of the simulation
243  @return Directory in which simulation outputs are placed
244  */
245  std::string& getOutputDirectory() {
246  return output_directory;
247  }
248 
249  /** Signifies that an event type is required for this simulation
250  * Causes to Factory to verify that the required event type can be found.
251  * @param name fully qualified libraryName.EventName
252  */
253  void requireEvent(std::string name);
254 
255  /**
256  * Returns the time of the next item to be executed
257  * that is in the TImeVortex of the Simulation
258  */
259  SimTime_t getNextActivityTime() const;
260 
261  /**
262  * Gets the minimum next activity time across all TimeVortices in
263  * the Rank
264  */
265  static SimTime_t getLocalMinimumNextActivityTime();
266 
267  /**
268  * Returns the Simulation's SharedRegionManager
269  */
270  static SharedRegionManager* getSharedRegionManager() { return sharedRegionManager; }
271 
272  /**
273  * Returns true when the Wireup is finished.
274  */
275  bool isWireUpFinished() {return wireUpFinished; }
276 
277 private:
278  friend class Link;
279  friend class Action;
280  friend class Output;
281  // To enable main to set up globals
282  friend int ::main(int argc, char **argv);
283 
284  Simulation(); // Don't call. Only rational way to serialize
285  Simulation(Config* config, RankInfo my_rank, RankInfo num_ranks, SimTime_t min_part);
286  Simulation(Simulation const&); // Don't Implement
287  void operator=(Simulation const&); // Don't implement
288 
289 
290  /** Get a handle to a TimeConverter
291  * @param cycles Frequency which is the base of the TimeConverter
292  */
293  TimeConverter* minPartToTC(SimTime_t cycles) const;
294 
295  /** Factory used to generate the simulation components */
296  static Factory *factory;
297  /** TimeLord of the simulation */
298  static TimeLord timeLord;
299  /** Output */
300  static Output sim_output;
301  static void resizeBarriers(uint32_t nthr);
302  static Core::ThreadSafe::Barrier initBarrier;
303  static Core::ThreadSafe::Barrier completeBarrier;
304  static Core::ThreadSafe::Barrier setupBarrier;
305  static Core::ThreadSafe::Barrier runBarrier;
306  static Core::ThreadSafe::Barrier exitBarrier;
307  static Core::ThreadSafe::Barrier finishBarrier;
308  static std::mutex simulationMutex;
309 
310 
311 
312  Component* createComponent(ComponentId_t id, std::string &name,
313  Params &params);
314 
315  TimeVortex* getTimeVortex() const { return timeVortex; }
316 
317  /** Emergency Shutdown
318  * Called when a SIGINT or SIGTERM has been seen
319  */
320  static void emergencyShutdown();
321  /** Normal Shutdown
322  */
323  void endSimulation(void) { endSimulation(currentSimCycle); }
324  void endSimulation(SimTime_t end);
325 
326  typedef enum {
327  SHUTDOWN_CLEAN, /* Normal shutdown */
328  SHUTDOWN_SIGNAL, /* SIGINT or SIGTERM received */
329  SHUTDOWN_EMERGENCY, /* emergencyShutdown() called */
330  } ShutdownMode_t;
331 
332  friend class SyncManager;
333 
334  Mode_t runMode;
335  TimeVortex* timeVortex;
336  TimeConverter* threadMinPartTC;
337  Activity* current_activity;
338  static SimTime_t minPart;
339  static TimeConverter* minPartTC;
340  std::vector<SimTime_t> interThreadLatencies;
341  SimTime_t interThreadMinLatency;
342  SyncManager* syncManager;
343  ThreadSync* threadSync;
344  ComponentInfoMap compInfoMap;
345  clockMap_t clockMap;
346  oneShotMap_t oneShotMap;
347  SimTime_t currentSimCycle;
348  SimTime_t endSimCycle;
349  int currentPriority;
350  static Exit* m_exit;
351  SimulatorHeartbeat* m_heartbeat;
352  bool endSim;
353  RankInfo my_rank;
354  RankInfo num_ranks;
355  bool independent; // true if no links leave thread (i.e. no syncs required)
356  static std::atomic<int> untimed_msg_count;
357  unsigned int untimed_phase;
358  volatile sig_atomic_t lastRecvdSignal;
359  ShutdownMode_t shutdown_mode;
360  std::string output_directory;
361  static SharedRegionManager* sharedRegionManager;
362  bool wireUpFinished;
363 
364  static std::unordered_map<std::thread::id, Simulation*> instanceMap;
365  static std::vector<Simulation*> instanceVec;
366 
367  friend void wait_my_turn_start();
368  friend void wait_my_turn_end();
369 
370 };
371 
372 // Function to allow for easy serialization of threads while debugging
373 // code. Can only be used when you can guarantee all threads will be
374 // taking the same code path. If you can't guarantee that, then use a
375 // spinlock to make sure only one person is in a given region at a
376 // time. ONLY FOR DEBUG USE.
377 void wait_my_turn_start(Core::ThreadSafe::Barrier& barrier, int thread, int total_threads);
378 
379 void wait_my_turn_end(Core::ThreadSafe::Barrier& barrier, int thread, int total_threads);
380 
381 
382 } // namespace SST
383 
384 #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
An Action is a schedulable Activity which is not an Event.
Definition: action.h:30
Definition: syncManager.h:113
Mode_t getSimulationMode() const
Get the run mode of the simulation (e.g.
Definition: simulation.h:130
Main control class for a SST Simulation.
Definition: simulation.h:72
Base class for all Activities in the SST Event Queue.
Definition: activity.h:54
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:176
BaseComponent * getComponent(const ComponentId_t &id) const
returns the component with the given ID
Definition: simulation.h:206
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
A Configuration Graph A graph representing Components and Links.
Definition: configGraph.h:294
Primary Event Queue.
Definition: timeVortex.h:28
std::string & getOutputDirectory()
Returns the output directory of the simulation.
Definition: simulation.h:245
Definition: action.cc:17
Definition: simulation.h:77
void setOutputDirectory(std::string &outDir)
Set the output directory for this simulation.
Definition: simulation.h:237
RankInfo getNumRanks() const
Get the number of parallel ranks in the simulation.
Definition: simulation.h:144
Definition: simulation.h:76
Exit Event Action.
Definition: exit.h:34
std::map< std::pair< SimTime_t, int >, OneShot * > oneShotMap_t
Definition: simulation.h:83
Definition: componentInfo.h:126
static Output & getSimulationOutput()
Return the base simulation Output class instance.
Definition: simulation.h:178
Definition: threadSync.h:35
An optional heartbeat to show progress in a simulation
Definition: heartbeat.h:32
A Clock class.
Definition: clock.h:35
RankInfo getRank() const
Get this instance&#39;s parallel rank.
Definition: simulation.h:142
Definition: rankInfo.h:21
Functor classes for Clock handling.
Definition: clock.h:44
Main component object for the simulation.
Definition: baseComponent.h:104
LinkMap * getComponentLinkMap(ComponentId_t id) const
Return pointer to map of links for a given component id.
Definition: simulation.h:188
static Simulation * getSimulation()
Return a pointer to the singleton instance of the Simulation.
Definition: simulation.h:99
A OneShot Event class.
Definition: oneshot.h:33
Parameter store.
Definition: params.h:45
Class for creating and managing TimeConverter objects.
Definition: timeLord.h:36
Exit * getExit() const
Return the exit event.
Definition: simulation.h:169
static SharedRegionManager * getSharedRegionManager()
Returns the Simulation&#39;s SharedRegionManager.
Definition: simulation.h:270
Class for instantiating Components, Links and the like out of element libraries.
Definition: factory.h:45
bool isWireUpFinished()
Returns true when the Wireup is finished.
Definition: simulation.h:275
Definition: simulation.h:78
Definition: componentInfo.h:34
An SST core component that handles timing and event processing informing all registered Statistics to...
Definition: statengine.h:49
Mode_t
Type of Run Modes.
Definition: simulation.h:75
Performs Unit math in full precision.
Definition: unitAlgebra.h:104
std::map< std::pair< SimTime_t, int >, Clock * > clockMap_t
Definition: simulation.h:82
Definition: threadsafe.h:45
const ComponentInfoMap & getComponentInfoMap(void)
Returns reference to the Component Map.
Definition: simulation.h:202
Definition: sharedRegion.h:56
Functor classes for OneShot handling.
Definition: oneshot.h:39