The Sparta Modeling Framework
Loading...
Searching...
No Matches
Simulation.hpp
Go to the documentation of this file.
1// <Simulation.h> -*- C++ -*-
2
3
8#pragma once
9
10#include <vector>
11
13#include "sparta/simulation/ResourceFactory.hpp"
15#include "sparta/log/Tap.hpp"
16#include "sparta/parsers/ConfigParserYAML.hpp"
18#include "sparta/simulation/ParameterTree.hpp"
19#include "sparta/report/ReportRepository.hpp"
24#include "sparta/control/TemporaryRunController.hpp"
25#include "sparta/simulation/State.hpp"
26#include "sparta/pipeViewer/InformationWriter.hpp"
27
28namespace YP = YAML; // Prevent collision with YAML class in ConfigParser namespace.
29
30namespace simdb {
31 class AppManager;
32 class AppManagers;
33 class AppRegistrations;
34}
35
36namespace sparta {
37
38class Clock;
39class MemoryProfiler;
40class TreeNodeExtensionManager;
41
42namespace python {
43 class PythonInterpreter;
44}
45namespace control {
46 class TemporaryRunControl;
47}
48
49namespace trigger {
50 class SingleTrigger;
51 class CounterTrigger;
52 class TimeTrigger;
53 class CycleTrigger;
54 class Trigger;
55} // namespace trigger
56
60namespace app {
61class LoggingTrigger;
62class ConfigApplicator;
63class FeatureConfiguration;
64
77{
78public:
79
89
91 Simulation() = delete;
92
94 Simulation(const Simulation&) = delete;
95
98
100 Simulation& operator=(const Simulation&) = delete;
101
108 Simulation(const std::string& sim_name, Scheduler * scheduler);
109
113 virtual ~Simulation();
114
122 void setFeatureConfig(const FeatureConfiguration * feature_config) {
123 feature_config_ = feature_config;
124 }
125
136 void configure(const int argc,
137 char ** argv,
138 SimulationConfiguration * configuration,
139 const bool use_pyshell = false);
140
146 void addReport(const ReportDescriptor & rep);
147
157 void installTaps(const log::TapDescVec& taps);
158
160 sparta::RootTreeNode* getRoot() noexcept { return &root_; }
161
163 sparta::app::MetaTreeNode* getMetaParamRoot() const noexcept { return meta_.get(); }
164
166 const sparta::RootTreeNode* getRoot() const noexcept { return &root_; }
167
170
172 const sparta::Scheduler * getScheduler() const { return scheduler_; }
173
175 simdb::AppManagers* getAppManagers() const { return app_managers_.get(); }
176
181 bool usingFinalConfig() const { return using_final_config_; }
182
184 bool readyToRun() const { return framework_finalized_; }
185
187 sparta::Clock* getRootClock() noexcept { return root_clk_.get(); }
188
190 const sparta::Clock* getRootClock() const noexcept { return root_clk_.get(); }
191
194
197
201 const std::string& getSimName() const noexcept {
202 return sim_name_;
203 }
204
209 return sim_config_;
210 }
211
215 const TreeNodeExtensionManager * getExtensionManager(bool must_exist = true) const {
216 return root_.getExtensionManager(must_exist);
217 }
218
222 TreeNodeExtensionManager * getExtensionManager(bool must_exist = true) {
223 return root_.getExtensionManager(must_exist);
224 }
225
230 return feature_config_;
231 }
232
237 return report_config_.get();
238 }
239
240
241 // Setup
242
249 void buildTree();
250
258
266
267
274
275
276 // Running
277
286 virtual void run(uint64_t run_time);
287
304 virtual void runRaw(uint64_t run_time);
305
312 virtual void asyncStop();
313
314
315 // Post-processing
316
323 void dumpDebugContentIfAllowed(std::exception_ptr eptr, bool forcec=false) noexcept;
324
329
337
346 "Cannot query findSemanticCounter until Simulation is finalized");
348 "Cannot query findSemanticCounter after Simulation has entered teardown");
349 return findSemanticCounter_(sem);
350 }
351
352
353 // Status
354
360
365 uint64_t numFired() { return num_fired_; }
366
371 validate_post_run_ = true;
372 }
376 std::string getPipelineCollectionPrefix() const {
378 }
379
387 bool usingPyshell() const {
388#ifdef SPARTA_PYTHON_SUPPORT
389 return pyshell_ != nullptr;
390#else
391 return false;
392#endif
393 }
394
402 virtual sparta::control::TemporaryRunControl * getRunControlInterface() {
403 return rc_.get();
404 }
405
410 void dumpMetaParameterTable(std::ostream& out) const;
411
412
413protected:
414
445 {
446 public:
447 virtual ~SimulationController() {}
448
449 void pause();
450 void resume();
451 void terminate();
452
453 void invokeNamedEvent(
454 const std::string & event_name);
455
456 enum class SimulationStatus {
457 Idle,
458 Paused,
459 Simulating,
460 Terminated
461 };
462 SimulationStatus getSimStatus() const {
463 return sim_status_;
464 }
465
466 protected:
467 explicit SimulationController(
468 const sparta::app::Simulation * sim) :
469 sim_(sim)
470 {}
471
472 void addNamedCallback_(
473 const std::string & event_name,
474 SpartaHandler callback_method);
475
476 private:
477 virtual void pause_(const sparta::app::Simulation * sim) {
478 (void) sim;
479 }
480 virtual void resume_(const sparta::app::Simulation * sim) {
481 (void) sim;
482 }
483 virtual void terminate_(const sparta::app::Simulation * sim) {
484 (void) sim;
485 }
486 void verifyFinalized_() const;
487
488 const sparta::app::Simulation * sim_ = nullptr;
489 std::unordered_map<std::string, SpartaHandler> callbacks_;
490 std::set<std::string> invoked_callbacks_;
491 SimulationStatus sim_status_ = SimulationStatus::Idle;
492
493 friend class sparta::app::Simulation;
494 };
495
500 std::shared_ptr<SimulationController> controller);
501
505 void pause_();
506
510 void resume_();
511
516
520 void customEvent_(const std::string & event_name);
521
526
530 std::shared_ptr<SimulationController> controller_;
531
536 std::vector<std::shared_ptr<trigger::ExpressionTrigger>> controller_triggers_;
537
546 uint32_t dumpNonDefaultParameters_(TreeNode* root, std::ostream& out);
547
553
564
570
577 void addTreeNodeExtensionFactory_(const std::string & extension_name,
578 std::function<TreeNode::ExtensionsBase*()> factory);
579
590 void setTreeNodeExtensionManager_(TreeNodeExtensionManager* mgr);
591
595
599 virtual void buildTree_() = 0;
600
606 virtual void configureTree_() = 0;
607
614 virtual void bindTree_() = 0;
615
620 virtual void registerSimDbApps_([[maybe_unused]] simdb::AppRegistrations* app_registrations) {}
621
630 virtual void parameterizeSimDbApps_([[maybe_unused]] simdb::AppManager* app_mgr) {}
631
636 virtual void postFinalizeFramework_() {}
637
642 virtual void onSimDbAppsReady_() {}
643
646
656 virtual void runControlLoop_(uint64_t run_time);
657
666 virtual void runRaw_(uint64_t run_time);
667
670
679 (void) sem;
680 return nullptr;
681 }
682
694 bool dumpDebugContent_(std::string& filename,
695 const std::string& exception,
696 const std::string& backtrace) noexcept;
697
706 void rootDescendantAdded_(const sparta::TreeNode& node_added);
707
716
726 void attachReportTo_(sparta::ReportRepository::DirectoryHandle directoryH,
727 const ReportDescriptor & rd,
729 const std::vector<std::string>& replacements);
730
738
744 const ReportDescriptor & rd,
745 const bool using_pyshell) const;
746
752
759 ReportDescVec expandReportDescriptor_(const ReportDescriptor & rd) const;
760
765
780
787
791 std::shared_ptr<sparta::MemoryProfiler> memory_profiler_;
792
796 std::unique_ptr<sparta::ReportRepository> report_repository_;
797
802
806 const std::string sim_name_;
807
812 std::vector<std::unique_ptr<sparta::log::Tap>> taps_to_del_;
813
819
824
829 std::unique_ptr<Report> auto_summary_report_;
830
834 std::unique_ptr<sparta::RootTreeNode> clk_root_node_;
835
840 Clock::Handle root_clk_;
841
847
855 std::unique_ptr<MetaTreeNode> meta_;
856
861
866 std::vector<std::unique_ptr<sparta::TreeNode>> to_delete_;
867
868 // The SimulationConfiguration object
869 SimulationConfiguration * sim_config_{nullptr};
870
871 // The FeatureConfiguration object
872 const FeatureConfiguration * feature_config_{nullptr};
873
874 // Order matters: Taps should die before any other nodes (or after all other
875 // nodes are guaranteed destructed)
876
878
882 std::unique_ptr<sparta::log::Tap> warn_to_file_;
883
884 uint64_t num_fired_;
885
886 bool print_dag_ = false;
887
891 bool validate_post_run_ = false;
892
897
907
912 std::unique_ptr<ReportConfiguration> report_config_;
913
918 std::vector<ConfigApplicator*> user_configs_;
919
926
931
936
940 std::unique_ptr<trigger::CounterTrigger> pevent_start_trigger_;
941
945 std::unique_ptr<LoggingTrigger> log_trigger_;
946
952 std::unique_ptr<trigger::Trigger> debug_trigger_;
953
958
959private:
960
961#ifdef SPARTA_PYTHON_SUPPORT
965 std::unique_ptr<python::PythonInterpreter> pyshell_;
966#endif
967
974
997 virtual void validateReportDescriptors_(
998 const ReportDescriptorCollection & report_descriptors) const
999 {
1000 (void) report_descriptors;
1001 }
1002
1006 std::unique_ptr<control::TemporaryRunControl> rc_;
1007
1011 void createSimDbApps_();
1012 int argc_ = 0;
1013 char** argv_ = nullptr;
1014
1018 std::shared_ptr<simdb::AppManagers> app_managers_;
1019};
1020
1021} // namespace app
1022} // namespace sparta
Handles writing backtraces on errors.
Manages building a clock tree.
Configuration Applicators.
Describes reports to instantiate and tracks their instantiations.
File that defines the Resource class. Consider using sparta::Unit instead.
#define sparta_assert(...)
Simple variadic assertion that will throw a sparta_exception if the condition fails.
Basic Node framework in sparta device tree composite pattern.
Manages building a clock tree.
A representation of simulated time.
Definition Clock.hpp:44
The base class for all Counters.
Virtual Parameter Tree. This represents a tree of parameters read from some source but does not neces...
virtual bool isTearingDown() const
Is this node (and thus the entire tree above it) in the "teardown" phase.
virtual bool isFinalized() const
Is this node (and thus the entire tree above it) "finalized".
Set of published ResourceFactories which can be referenced by name.
TreeNode which represents the root ("top") of a device tree.
const TreeNodeExtensionManager * getExtensionManager(bool must_exist=true) const
Get the TreeNodeExtensionsManager.
A class that lets you schedule events now and in the future.
The State class for watching transition between enum states.
Definition State.hpp:123
Node in a composite tree representing a sparta Tree item.
Definition TreeNode.hpp:204
Backtrace printer. Registers a handler for certain fatal signals and dumps the backtrace if they occu...
Definition Backtrace.hpp:82
Collection of named feature values.
Configuration applicator class that is used for configuring a simulator's reports....
This collection of ReportDescriptors is designed to never deallocate memory once it has been allocate...
Describes one or more report to instantiate.
Configuration applicator class that is used for configuring a simulator. Works in conjunction with sp...
This class is used for simulation control callbacks.
Class that is the "top level" or starting point for simulation.
void addReport(const ReportDescriptor &rep)
Add a report.
std::vector< std::unique_ptr< sparta::TreeNode > > to_delete_
Vector of TreeNodes to delete automatically at destruction. Add any nodes allocated to this list to a...
Backtrace backtrace_
Backtracing utility for error signals.
bool dumpDebugContent_(std::string &filename, const std::string &exception, const std::string &backtrace) noexcept
Dump debug content to a timestamped file regardless of debug-dumping control flags.
simdb::AppManagers * getAppManagers() const
Get access to the SimDB AppManagers and their associated DatabaseManagers.
uint32_t dumpNonDefaultParameters_(TreeNode *root, std::ostream &out)
Print and count the number of Parameters which have had their values changed to something different t...
void setupStreamControllers_()
If report statistics are being streamed out of this simulation, share the run controllers's stream co...
virtual void postFinalizeFramework_()
Hook which is called at the end of finalizeFramework() but right before SimDB app pipelines/threads a...
void finalizeFramework()
Finalize framework before running.
void pause_()
Triggered simulation pause callback.
TreeNodeExtensionManager * getExtensionManager(bool must_exist=true)
Returns this simulator's extensions manager.
uint64_t num_fired_
Total number of scheduler events firerd.
std::vector< std::unique_ptr< sparta::log::Tap > > taps_to_del_
User-specified Taps to delete at teardown. These should outlast the entire tree so that they can inte...
void saveReports()
Writes all reports to their respective files.
void finalizeTree()
Finalizes the device tree.
std::unique_ptr< sparta::RootTreeNode > clk_root_node_
Root node containing the clock tree (called "clocks")
bool readyToRun() const
Is the framework ready to run.
virtual void bindTree_()=0
Allows implementer to bind ports to gether.
void addTreeNodeExtensionFactory_(const std::string &extension_name, std::function< TreeNode::ExtensionsBase *()> factory)
Include an extension factory for this simulation's device tree nodes. They will be given to specific ...
virtual ~Simulation()
Virtual destructor.
sparta::log::Tap warn_to_cerr_
Tap which warns to cerr.
CounterSemantic
Types of semantics attached to certain counters. It is the responsibility of subclasses to implement ...
@ CSEM_INSTRUCTIONS
Instruction count semantic (usually core0)
uint64_t numFired()
return the number of events fired on the scheduler during simulation.
void customEvent_(const std::string &event_name)
Triggered simulation custom named event.
std::unique_ptr< Report > auto_summary_report_
Default automaticly generated report containing the entire simulation.
std::unique_ptr< sparta::ReportRepository > report_repository_
Repository of all reports for this simulation.
void buildTree()
Builds hard-coded device tree.
const sparta::Scheduler * getScheduler() const
Returns the simulation's scheduler.
bool simulationSuccessful() const
Was simulation successful?
const sparta::Clock * getRootClock() const noexcept
Returns the root clock (const)
bool simulation_successful_
Was simulation successful? I.e. no exceptions were thrown.
std::shared_ptr< SimulationController > controller_
Custom controller to handle various simulation events.
bool framework_finalized_
Has the framework been finalized.
ReportDescVec expandReportDescriptor_(const ReportDescriptor &rd) const
In the case where a comma-separated list of file formats was used to specify the output file format (...
Simulation & operator=(const Simulation &)=delete
Not assignable.
sparta::RootTreeNode * getRoot() noexcept
Returns the tree root.
std::unique_ptr< trigger::Trigger > debug_trigger_
A trigger used to turn on debug useful options at a given cycle, right now this only turns on pipelin...
void dumpDebugContentIfAllowed(std::exception_ptr eptr, bool forcec=false) noexcept
Determine if debug content needs to be dumped and dump if so. Uses dumpDebugContent to dump.
const CounterBase * findSemanticCounter(CounterSemantic sem) const
Get a counter by its semantic (if such a counter exists).
void configureTree()
Configure the tree with some node-local config files, params, and node-specific parameters.
sparta::app::MetaTreeNode * getMetaParamRoot() const noexcept
Returns the Meta TreeNode root.
void installTaps(const log::TapDescVec &taps)
Add new taps the the simulation immediately IF possible.
bool usingFinalConfig() const
Returns whether or not the simulator was configured using a final configuration option,...
sparta::RootTreeNode root_
Root of device tree: "top". Destruct after all non-root nodes (see to_delete_)
void setupControllerTriggers_()
Initialization of custom simulation event triggers.
void setTreeNodeExtensionManager_(TreeNodeExtensionManager *mgr)
The typical flow is to let the SimulationConfiguration own the TreeNodeExtensionManager,...
sparta::ClockManager & getClockManager() noexcept
Returns the clock manager.
std::unique_ptr< LoggingTrigger > log_trigger_
Trigger for starting logging.
std::shared_ptr< sparta::MemoryProfiler > memory_profiler_
Heap profiler(s), if any.
std::unique_ptr< sparta::log::Tap > warn_to_file_
Tap which, if constructed, will write all warnings to a file.
void attachReportTo_(sparta::ReportRepository::DirectoryHandle directoryH, const ReportDescriptor &rd, sparta::TreeNode *n, const std::vector< std::string > &replacements)
Creates and attaches a report to a node based on its descriptor.
void setFeatureConfig(const FeatureConfiguration *feature_config)
Set a collection of feature name-value pairs.
ReportDescriptorCollection rep_descs_
Vector of Report descriptors applicable to the simulation. These descriptors are used as the tree is ...
Simulation(const std::string &sim_name, Scheduler *scheduler)
Deferred configuration constructor. Subsequent call to configure must be made before building/configu...
void terminate_()
Triggered simulation terminate callback.
Simulation()=delete
Not default-constructable.
virtual void onSimDbAppsReady_()
Hook which is called after SimDB apps are created, pipelines are opened, threads are running,...
virtual void run(uint64_t run_time)
Run for specified "time" or less.
bool usingPyshell() const
Was this simulation configured with a Python shell?
void enablePostRunValidation()
Enable post-run validation explicity.
void setupReports_(ReportStatsCollector *collector)
Sets up all reports in this simulation. This can be called during finalization or deferred until late...
void configure(const int argc, char **argv, SimulationConfiguration *configuration, const bool use_pyshell=false)
Configures the simulator after construction. Necessary only when using the simple constructor.
const FeatureConfiguration * getFeatureConfiguration() const
Returns this simulator's feature configuration.
void resume_()
Triggered simulation resume callback.
const std::string sim_name_
Simulation name.
std::unique_ptr< trigger::CounterTrigger > pevent_start_trigger_
An instruction trigger for observing pevent warmup.
virtual sparta::control::TemporaryRunControl * getRunControlInterface()
Get the run control interface for this simulation. This must exist for the lifetime of this simulatio...
Simulation(const Simulation &)=delete
Not copy-constructable.
std::vector< std::shared_ptr< trigger::ExpressionTrigger > > controller_triggers_
Expression triggers to invoke custom simulation events via the SimulationController object.
Scheduler *const scheduler_
Scheduler this simulation will use.
uint64_t pevent_warmup_icount_
Warmup period in instructions before logging pevents.
std::string getPipelineCollectionPrefix() const
Gets the pipeline collection path.
void setSimulationController_(std::shared_ptr< SimulationController > controller)
Set a controller to handle custom simulation events.
virtual void configureTree_()=0
Allows implementer to manually configure the tree if required.
virtual void asyncStop()
Asynchronously stop the run.
sparta::ResourceSet * getResourceSet() noexcept
Returns the resource set for this Simulation.
virtual void runRaw_(uint64_t run_time)
Run for specified "time".
sparta::Clock * getRootClock() noexcept
Returns the root clock.
virtual void runControlLoop_(uint64_t run_time)
Enter run-control loop causing the simulator to run or give control to an interactive shell.
virtual void parameterizeSimDbApps_(simdb::AppManager *app_mgr)
When using SimDB apps, this method gets called when the SimulationConfiguration (SimDbConfig) has bee...
const std::string & getSimName() const noexcept
Returns this simulator's name.
void rootDescendantAdded_(const sparta::TreeNode &node_added)
Notification callback invoked when a new node is attached as a descendant of this simulator's root no...
virtual void runRaw(uint64_t run_time)
Runs the simulation for a limited run time, returning when done.
std::unique_ptr< ReportConfiguration > report_config_
Report configuration object which wraps the simulation's ReportDescriptorCollection.
void dumpMetaParameterTable(std::ostream &out) const
Write meta-data tree parameters to given ostream.
void attachTapTo_(const log::TapDescriptor &td, sparta::TreeNode *n)
Creates and attaches a tap to a node based on its descriptor.
void delayedPeventStart_()
a Callback that officially starts pevent collection.
uint32_t reapplyVolatileParameters_(TreeNode *root)
Re-read volatile parameter values from the virtual tree and write them to the parmeters....
bool print_dag_
Should the DAG be printed after it is built.
bool using_final_config_
tells the simulator that we are using the final config option and need to prevent parameter set callb...
uint32_t countNonDefaultParameters_(TreeNode *root)
Same counting behavior as dumpNonDefaultParameters_ but does not print.
const TreeNodeExtensionManager * getExtensionManager(bool must_exist=true) const
Returns this simulator's extensions manager.
sparta::ResourceSet res_list_
Map of of resources available to this simulation. This must outlast destruction of the tree root_ and...
SimulationConfiguration * getSimulationConfiguration() const
Returns this simulator's configuration.
sparta::Scheduler * getScheduler()
Returns the simulation's scheduler.
const sparta::RootTreeNode * getRoot() const noexcept
Returns the tree root (const)
virtual void registerSimDbApps_(simdb::AppRegistrations *app_registrations)
Override this method to register your SimDB apps prior to parameterizing them and instantiating them.
Clock::Handle root_clk_
Root of clock tree (direct child of clk_root_node_). Represents hypercycles. Destruct after all nodes...
bool validate_post_run_
Validate after running.
void checkAllVirtualParamsRead_(const ParameterTree &pt)
Check that all virtual parameters have been read from a given tree.
uint32_t reapplyAllParameters_(TreeNode *root)
Re-read all parameter values from the virtual tree.
std::unique_ptr< MetaTreeNode > meta_
Meta-tree containing simulation meta-information in parameters in "meta.params.fizbin"....
std::string pipeline_collection_prefix_
Pipeline collection prefix.
virtual void buildTree_()=0
Allows implementer to create new nodes in the tree.
ReportConfiguration * getReportConfiguration() const
Get this simulator's report configuration.
void validateDescriptorCanBeAdded_(const ReportDescriptor &rd, const bool using_pyshell) const
Verify that the given report descriptor can be added to this simulation.
std::vector< ConfigApplicator * > user_configs_
User configuration vector stored at "preprocessParameters".
void setupProfilers_()
Sets up any heap profiler(s) used in this simulation.
sparta::ClockManager clk_manager_
Clock manager for all clocks in simulation.
virtual const CounterBase * findSemanticCounter_(CounterSemantic sem) const
Implements findSemanticCounter.
Simulation(Simulation &&)=delete
Not move-constructable.
SpartaHandler pevent_start_handler_
Callback for pevent startup.
void postProcessingLastCall()
After CommandLineSimulator runs the simulation and calls all post-processing APIs,...
Describes a tap.
Definition Tap.hpp:258
Logging Tap. Attach to a TreeNode to intercept logging messages from any NotificationSource nodes in ...
Definition Tap.hpp:28
Macros for handling exponential backoff.