SST  7.1.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 setup() and run phases of the simulation. */
121  void setup();
122  void run();
123  void finish();
124 
125  bool isIndependentThread() { return independent;}
126 
127  /** Get the run mode of the simulation (e.g. init, run, both etc) */
128  Mode_t getSimulationMode() const { return runMode; };
129  /** Return the current simulation time as a cycle count*/
130  const SimTime_t& getCurrentSimCycle() const;
131  /** Return the end simulation time as a cycle count*/
132  SimTime_t getEndSimCycle() const;
133  /** Return the current priority */
134  int getCurrentPriority() const;
135  /** Return the elapsed simulation time as a time */
136  UnitAlgebra getElapsedSimTime() const;
137  /** Return the end simulation time as a time */
138  UnitAlgebra getFinalSimTime() const;
139  /** Get this instance's parallel rank */
140  RankInfo getRank() const {return my_rank;}
141  /** Get the number of parallel ranks in the simulation */
142  RankInfo getNumRanks() const {return num_ranks;}
143  /** Register a handler to be called on a set frequency */
144  TimeConverter* registerClock(const std::string& freq, Clock::HandlerBase* handler, int priority);
145  TimeConverter* registerClock(const UnitAlgebra& freq, Clock::HandlerBase* handler, int priority);
146  TimeConverter* registerClock(TimeConverter *tcFreq, Clock::HandlerBase* handler, int priority);
147  /** Remove a clock handler from the list of active clock handlers */
148  void unregisterClock(TimeConverter *tc, Clock::HandlerBase* handler, int priority);
149  /** Reactivate an existing clock and handler.
150  * @return time when handler will next fire
151  */
152  Cycle_t reregisterClock(TimeConverter *tc, Clock::HandlerBase* handler, int priority);
153  /** Returns the next Cycle that the TImeConverter would fire. */
154  Cycle_t getNextClockCycle(TimeConverter* tc, int priority = CLOCKPRIORITY);
155 
156  /** Register a OneShot event to be called after a time delay
157  Note: OneShot cannot be canceled, and will always callback after
158  the timedelay.
159  */
160  TimeConverter* registerOneShot(std::string timeDelay, OneShot::HandlerBase* handler, int priority);
161  TimeConverter* registerOneShot(const UnitAlgebra& timeDelay, OneShot::HandlerBase* handler, int priority);
162 
163  /** Insert an activity to fire at a specified time */
164  void insertActivity(SimTime_t time, Activity* ev);
165 
166  /** Return the exit event */
167  Exit* getExit() const { return m_exit; }
168 
169  const std::vector<SimTime_t>& getInterThreadLatencies() const { return interThreadLatencies; }
170  SimTime_t getInterThreadMinLatency() const { return interThreadMinLatency; }
171  static TimeConverter* getMinPartTC() { return minPartTC; }
172 
173  /** Return the TimeLord associated with this Simulation */
174  static TimeLord* getTimeLord(void) { return &timeLord; }
175  /** Return the base simulation Output class instance */
176  static Output& getSimulationOutput() { return sim_output; };
177 
178  uint64_t getTimeVortexMaxDepth() const;
179  uint64_t getTimeVortexCurrentDepth() const;
180  uint64_t getSyncQueueDataSize() const;
181 
182  /** Return the Statistic Processing Engine associated with this Simulation */
183  Statistics::StatisticProcessingEngine* getStatisticsProcessingEngine(void) const;
184 
185  /** Return pointer to map of links for a given component id */
186  LinkMap* getComponentLinkMap(ComponentId_t id) const {
187  ComponentInfo* info = compInfoMap.getByID(id);
188  if ( NULL == info ) {
189  return NULL;
190  } else {
191  return info->getLinkMap();
192  }
193  }
194 
195 
196  // /** Returns reference to the Component Map */
197  // const CompMap_t& getComponentMap(void) const { return compMap; }
198  // /** Returns reference to the Component ID Map */
199  // // const CompIdMap_t& getComponentIdMap(void) const { return compIdMap; }
200  const ComponentInfoMap& getComponentInfoMap(void) { return compInfoMap; }
201 
202 
203  /** returns the component with the given ID */
204  BaseComponent* getComponent(const ComponentId_t &id) const
205  {
206  ComponentInfo* i = compInfoMap.getByID(id);
207  // CompInfoMap_t::const_iterator i = compInfoMap.find(id);
208  if ( NULL != i ) {
209  return i->getComponent();
210  } else {
211  printf("Simulation::getComponent() couldn't find component with id = %" PRIu64 "\n", id);
212  exit(1);
213  }
214  }
215 
216 
217  ComponentInfo* getComponentInfo(const ComponentId_t &id) const
218  {
219  ComponentInfo* i = compInfoMap.getByID(id);
220  // CompInfoMap_t::const_iterator i = compInfoMap.find(id);
221  if ( NULL != i ) {
222  return i;
223  } else {
224  printf("Simulation::getComponentInfo() couldn't find component with id = %" PRIu64 "\n", id);
225  exit(1);
226  }
227  }
228 
229 
230 
231  /**
232  Set the output directory for this simulation
233  @param outDir Path of directory to place simulation outputs in
234  */
235  void setOutputDirectory(std::string& outDir) {
236  output_directory = outDir;
237  }
238 
239  /**
240  Returns the output directory of the simulation
241  @return Directory in which simulation outputs are placed
242  */
243  std::string& getOutputDirectory() {
244  return output_directory;
245  }
246 
247  /** Signifies that an event type is required for this simulation
248  * Causes to Factory to verify that the required event type can be found.
249  * @param name fully qualified libraryName.EventName
250  */
251  void requireEvent(std::string name);
252 
253  /**
254  * Returns the time of the next item to be executed
255  * that is in the TImeVortex of the Simulation
256  */
257  SimTime_t getNextActivityTime() const;
258 
259  /**
260  * Gets the minimum next activity time across all TimeVortices in
261  * the Rank
262  */
263  static SimTime_t getLocalMinimumNextActivityTime();
264 
265  /**
266  * Returns the Simulation's SharedRegionManager
267  */
268  static SharedRegionManager* getSharedRegionManager() { return sharedRegionManager; }
269 
270  /**
271  * Returns true when the Wireup is finished.
272  */
273  bool isWireUpFinished() {return wireUpFinished; }
274 
275 private:
276  friend class Link;
277  friend class Action;
278  friend class Output;
279  // To enable main to set up globals
280  friend int ::main(int argc, char **argv);
281 
282  Simulation(); // Don't call. Only rational way to serialize
283  Simulation(Config* config, RankInfo my_rank, RankInfo num_ranks, SimTime_t min_part);
284  Simulation(Simulation const&); // Don't Implement
285  void operator=(Simulation const&); // Don't implement
286 
287 
288  /** Get a handle to a TimeConverter
289  * @param cycles Frequency which is the base of the TimeConverter
290  */
291  TimeConverter* minPartToTC(SimTime_t cycles) const;
292 
293  /** Factory used to generate the simulation components */
294  static Factory *factory;
295  /** TimeLord of the simulation */
296  static TimeLord timeLord;
297  /** Output */
298  static Output sim_output;
299  static void resizeBarriers(uint32_t nthr);
300  static Core::ThreadSafe::Barrier initBarrier;
301  static Core::ThreadSafe::Barrier setupBarrier;
302  static Core::ThreadSafe::Barrier runBarrier;
303  static Core::ThreadSafe::Barrier exitBarrier;
304  static std::mutex simulationMutex;
305 
306 
307 
308  Component* createComponent(ComponentId_t id, std::string &name,
309  Params &params);
310 
311  TimeVortex* getTimeVortex() const { return timeVortex; }
312 
313  /** Emergency Shutdown
314  * Called when a SIGINT or SIGTERM has been seen
315  */
316  static void emergencyShutdown();
317  /** Normal Shutdown
318  */
319  void endSimulation(void) { endSimulation(currentSimCycle); }
320  void endSimulation(SimTime_t end);
321 
322  typedef enum {
323  SHUTDOWN_CLEAN, /* Normal shutdown */
324  SHUTDOWN_SIGNAL, /* SIGINT or SIGTERM received */
325  SHUTDOWN_EMERGENCY, /* emergencyShutdown() called */
326  } ShutdownMode_t;
327 
328  friend class SyncManager;
329 
330  Mode_t runMode;
331  TimeVortex* timeVortex;
332  TimeConverter* threadMinPartTC;
333  Activity* current_activity;
334  static SimTime_t minPart;
335  static TimeConverter* minPartTC;
336  std::vector<SimTime_t> interThreadLatencies;
337  SimTime_t interThreadMinLatency;
338  SyncManager* syncManager;
339  ThreadSync* threadSync;
340  ComponentInfoMap compInfoMap;
341  clockMap_t clockMap;
342  oneShotMap_t oneShotMap;
343  SimTime_t currentSimCycle;
344  SimTime_t endSimCycle;
345  int currentPriority;
346  static Exit* m_exit;
347  SimulatorHeartbeat* m_heartbeat;
348  bool endSim;
349  RankInfo my_rank;
350  RankInfo num_ranks;
351  bool independent; // true if no links leave thread (i.e. no syncs required)
352  static std::atomic<int> init_msg_count;
353  unsigned int init_phase;
354  volatile sig_atomic_t lastRecvdSignal;
355  ShutdownMode_t shutdown_mode;
356  // std::map<ComponentId_t,LinkMap*> component_links;
357  std::string output_directory;
358  static SharedRegionManager* sharedRegionManager;
359  bool wireUpFinished;
360 
361  static std::unordered_map<std::thread::id, Simulation*> instanceMap;
362  static std::vector<Simulation*> instanceVec;
363 
364  friend void wait_my_turn_start();
365  friend void wait_my_turn_end();
366 
367 };
368 
369 // Function to allow for easy serialization of threads while debugging
370 // code. Can only be used when you can guarantee all threads will be
371 // taking the same code path. If you can't guarantee that, then use a
372 // spinlock to make sure only one person is in a given region at a
373 // time. ONLY FOR DEBUG USE.
374 void wait_my_turn_start(Core::ThreadSafe::Barrier& barrier, int thread, int total_threads);
375 
376 void wait_my_turn_end(Core::ThreadSafe::Barrier& barrier, int thread, int total_threads);
377 
378 
379 } // namespace SST
380 
381 #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:103
Mode_t getSimulationMode() const
Get the run mode of the simulation (e.g.
Definition: simulation.h:128
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:174
BaseComponent * getComponent(const ComponentId_t &id) const
returns the component with the given ID
Definition: simulation.h:204
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:337
Primary Event Queue.
Definition: timeVortex.h:28
std::string & getOutputDirectory()
Returns the output directory of the simulation.
Definition: simulation.h:243
Definition: action.cc:17
Definition: simulation.h:77
void setOutputDirectory(std::string &outDir)
Set the output directory for this simulation.
Definition: simulation.h:235
RankInfo getNumRanks() const
Get the number of parallel ranks in the simulation.
Definition: simulation.h:142
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:125
static Output & getSimulationOutput()
Return the base simulation Output class instance.
Definition: simulation.h:176
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:140
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:186
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:167
static SharedRegionManager * getSharedRegionManager()
Returns the Simulation&#39;s SharedRegionManager.
Definition: simulation.h:268
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:273
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:42
const ComponentInfoMap & getComponentInfoMap(void)
Returns reference to the Component Map.
Definition: simulation.h:200
Definition: sharedRegion.h:56
Functor classes for OneShot handling.
Definition: oneshot.h:39