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"
16#include "sparta/log/Tap.hpp"
17#include "sparta/parsers/ConfigParserYAML.hpp"
19#include "sparta/simulation/ParameterTree.hpp"
20#include "sparta/report/ReportRepository.hpp"
25#include "sparta/control/TemporaryRunController.hpp"
26#include "sparta/simulation/State.hpp"
27#include "sparta/pipeViewer/InformationWriter.hpp"
28
29namespace YP = YAML; // Prevent collision with YAML class in ConfigParser namespace.
30
31namespace simdb {
32 class AppManager;
33 class DatabaseManager;
34}
35
36namespace sparta {
37
38class Clock;
39class MemoryProfiler;
40
41namespace python {
42 class PythonInterpreter;
43}
44namespace control {
45 class TemporaryRunControl;
46}
47
48namespace trigger {
49 class SingleTrigger;
50 class CounterTrigger;
51 class TimeTrigger;
52 class CycleTrigger;
53 class Trigger;
54} // namespace trigger
55
59namespace app {
60class LoggingTrigger;
61class ConfigApplicator;
62class FeatureConfiguration;
63
69{
70public:
71
81
83 Simulation() = delete;
84
86 Simulation(const Simulation&) = delete;
87
90
92 Simulation& operator=(const Simulation&) = delete;
93
100 Simulation(const std::string& sim_name, Scheduler * scheduler);
101
105 virtual ~Simulation();
106
114 void setFeatureConfig(const FeatureConfiguration * feature_config) {
115 feature_config_ = feature_config;
116 }
117
128 void configure(const int argc,
129 char ** argv,
130 SimulationConfiguration * configuration,
131 const bool use_pyshell = false);
132
138 void addReport(const ReportDescriptor & rep);
139
149 void installTaps(const log::TapDescVec& taps);
150
152 sparta::RootTreeNode* getRoot() noexcept { return &root_; }
153
155 sparta::app::MetaTreeNode* getMetaParamRoot() const noexcept { return meta_.get(); }
156
158 const sparta::RootTreeNode* getRoot() const noexcept { return &root_; }
159
162
164 const sparta::Scheduler * getScheduler() const { return scheduler_; }
165
167 std::vector<simdb::AppManager*> getAppManagers();
168
170 std::vector<simdb::DatabaseManager*> getDbManagers();
171
173 simdb::AppManager* getAppManager(const std::string & db_file = "sparta.db") const;
174
176 simdb::DatabaseManager* getDbManager(const std::string & db_file = "sparta.db") const;
177
179 std::vector<std::string> getDatabaseFiles() const;
180
185 bool usingFinalConfig() const { return using_final_config_; }
186
188 bool readyToRun() const { return framework_finalized_; }
189
191 sparta::Clock* getRootClock() noexcept { return root_clk_.get(); }
192
194 const sparta::Clock* getRootClock() const noexcept { return root_clk_.get(); }
195
198
201
205 const std::string& getSimName() const noexcept {
206 return sim_name_;
207 }
208
213 return sim_config_;
214 }
215
220 return feature_config_;
221 }
222
227 return report_config_.get();
228 }
229
230
231 // Setup
232
239 void buildTree();
240
248
256
257
264
265
266 // Running
267
276 virtual void run(uint64_t run_time);
277
294 virtual void runRaw(uint64_t run_time);
295
302 virtual void asyncStop();
303
304
305 // Post-processing
306
313 void dumpDebugContentIfAllowed(std::exception_ptr eptr, bool forcec=false) noexcept;
314
319
327
336 "Cannot query findSemanticCounter until Simulation is finalized");
338 "Cannot query findSemanticCounter after Simulation has entered teardown");
339 return findSemanticCounter_(sem);
340 }
341
342
343 // Status
344
350
355 uint64_t numFired() { return num_fired_; }
356
361 validate_post_run_ = true;
362 }
366 std::string getPipelineCollectionPrefix() const {
368 }
369
377 bool usingPyshell() const {
378#ifdef SPARTA_PYTHON_SUPPORT
379 return pyshell_ != nullptr;
380#else
381 return false;
382#endif
383 }
384
392 virtual sparta::control::TemporaryRunControl * getRunControlInterface() {
393 return rc_.get();
394 }
395
400 void dumpMetaParameterTable(std::ostream& out) const;
401
402
403protected:
404
435 {
436 public:
437 virtual ~SimulationController() {}
438
439 void pause();
440 void resume();
441 void terminate();
442
443 void invokeNamedEvent(
444 const std::string & event_name);
445
446 enum class SimulationStatus {
447 Idle,
448 Paused,
449 Simulating,
450 Terminated
451 };
452 SimulationStatus getSimStatus() const {
453 return sim_status_;
454 }
455
456 protected:
457 explicit SimulationController(
458 const sparta::app::Simulation * sim) :
459 sim_(sim)
460 {}
461
462 void addNamedCallback_(
463 const std::string & event_name,
464 SpartaHandler callback_method);
465
466 private:
467 virtual void pause_(const sparta::app::Simulation * sim) {
468 (void) sim;
469 }
470 virtual void resume_(const sparta::app::Simulation * sim) {
471 (void) sim;
472 }
473 virtual void terminate_(const sparta::app::Simulation * sim) {
474 (void) sim;
475 }
476 void verifyFinalized_() const;
477
478 const sparta::app::Simulation * sim_ = nullptr;
479 std::unordered_map<std::string, SpartaHandler> callbacks_;
480 std::set<std::string> invoked_callbacks_;
481 SimulationStatus sim_status_ = SimulationStatus::Idle;
482
483 friend class sparta::app::Simulation;
484 };
485
490 std::shared_ptr<SimulationController> controller);
491
495 void pause_();
496
500 void resume_();
501
506
510 void customEvent_(const std::string & event_name);
511
516
520 std::shared_ptr<SimulationController> controller_;
521
526 std::vector<std::shared_ptr<trigger::ExpressionTrigger>> controller_triggers_;
527
536 uint32_t dumpNonDefaultParameters_(TreeNode* root, std::ostream& out);
537
543
554
560
567 void addTreeNodeExtensionFactory_(const std::string & extension_name,
568 std::function<TreeNode::ExtensionsBase*()> creator);
569
573
577 virtual void buildTree_() = 0;
578
584 virtual void configureTree_() = 0;
585
592 virtual void bindTree_() = 0;
593
596
606 virtual void runControlLoop_(uint64_t run_time);
607
616 virtual void runRaw_(uint64_t run_time);
617
620
629 (void) sem;
630 return nullptr;
631 }
632
644 bool dumpDebugContent_(std::string& filename,
645 const std::string& exception,
646 const std::string& backtrace) noexcept;
647
656 void rootDescendantAdded_(const sparta::TreeNode& node_added);
657
666
676 void attachReportTo_(sparta::ReportRepository::DirectoryHandle directoryH,
677 const ReportDescriptor & rd,
679 const std::vector<std::string>& replacements);
680
688
694 const ReportDescriptor & rd,
695 const bool using_pyshell) const;
696
702
709 ReportDescVec expandReportDescriptor_(const ReportDescriptor & rd) const;
710
715
730
737
741 std::shared_ptr<sparta::MemoryProfiler> memory_profiler_;
742
746 std::unique_ptr<sparta::ReportRepository> report_repository_;
747
752
756 const std::string sim_name_;
757
762 std::vector<std::unique_ptr<sparta::log::Tap>> taps_to_del_;
763
769
774
779 std::unique_ptr<Report> auto_summary_report_;
780
784 std::unique_ptr<sparta::RootTreeNode> clk_root_node_;
785
790 Clock::Handle root_clk_;
791
797
805 std::unique_ptr<MetaTreeNode> meta_;
806
810 std::unordered_map<
811 std::string,
813
818
823 std::vector<std::unique_ptr<sparta::TreeNode>> to_delete_;
824
825
826 // The SimulationConfiguration object
827 SimulationConfiguration * sim_config_{nullptr};
828
829 // The FeatureConfiguration object
830 const FeatureConfiguration * feature_config_{nullptr};
831
832 // Order matters: Taps should die before any other nodes (or after all other
833 // nodes are guaranteed destructed)
834
836
840 std::unique_ptr<sparta::log::Tap> warn_to_file_;
841
842 uint64_t num_fired_;
843
844 bool print_dag_ = false;
845
849 bool validate_post_run_ = false;
850
855
865
870 std::unique_ptr<ReportConfiguration> report_config_;
871
878 ExtensionDescriptorVec extension_descs_;
879 std::set<std::string> nodes_given_extensions_;
880
885 std::vector<ConfigApplicator*> user_configs_;
886
893
898
903
907 std::unique_ptr<trigger::CounterTrigger> pevent_start_trigger_;
908
912 std::unique_ptr<LoggingTrigger> log_trigger_;
913
919 std::unique_ptr<trigger::Trigger> debug_trigger_;
920
925
926private:
927
928#ifdef SPARTA_PYTHON_SUPPORT
932 std::unique_ptr<python::PythonInterpreter> pyshell_;
933#endif
934
941
964 virtual void validateReportDescriptors_(
965 const ReportDescriptorCollection & report_descriptors) const
966 {
967 (void) report_descriptors;
968 }
969
973 std::unique_ptr<control::TemporaryRunControl> rc_;
974
978 void createSimDbApps_();
979 int argc_ = 0;
980 char** argv_ = nullptr;
981
985 struct SimDbManagers
986 {
987 std::shared_ptr<simdb::DatabaseManager> db_mgr;
988 std::shared_ptr<simdb::AppManager> app_mgr;
989
990 SimDbManagers(std::shared_ptr<simdb::DatabaseManager> db_mgr,
991 std::shared_ptr<simdb::AppManager> app_mgr)
992 : db_mgr(db_mgr)
993 , app_mgr(app_mgr)
994 {}
995 };
996
1000 std::map<std::string, std::shared_ptr<SimDbManagers>> simdb_managers_;
1001};
1002
1003} // namespace app
1004} // 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.
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
Base class used to extend TreeNode parameter sets.
Node in a composite tree representing a sparta Tree item.
Definition TreeNode.hpp:205
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.
Simulator which builds a sparta DeviceTree.
std::unordered_map< std::string, std::function< TreeNode::ExtensionsBase *()> > tree_node_extension_factories_
Tree node extension factories by name.
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.
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...
void finalizeFramework()
Finalize framework before running.
void pause_()
Triggered simulation pause callback.
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.
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.
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 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.
void addTreeNodeExtensionFactory_(const std::string &extension_name, std::function< TreeNode::ExtensionsBase *()> creator)
Include an extension factory for this simulation's device tree nodes. They will be given to specific ...
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.
std::vector< simdb::DatabaseManager * > getDbManagers()
Returns all SimDB database managers.
sparta::ResourceSet * getResourceSet() noexcept
Returns the resource set for this Simulation.
std::vector< simdb::AppManager * > getAppManagers()
Returns all SimDB application managers.
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.
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.
std::vector< std::string > getDatabaseFiles() const
Returns all database files managed by this simulation.
sparta::ResourceSet res_list_
Map of of resources available to this simulation. This must outlast destruction of the tree root_ and...
ExtensionDescriptorVec extension_descs_
Keep the extension descriptors alive for the entire simulation. The Simulation base class is meant to...
SimulationConfiguration * getSimulationConfiguration() const
Returns this simulator's configuration.
simdb::DatabaseManager * getDbManager(const std::string &db_file="sparta.db") const
Get a database manager for a specific database file.
sparta::Scheduler * getScheduler()
Returns the simulation's scheduler.
const sparta::RootTreeNode * getRoot() const noexcept
Returns the tree root (const)
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.
simdb::AppManager * getAppManager(const std::string &db_file="sparta.db") const
Get an app manager for a specific database file.
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.