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