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/simulation/TreeNodeExtensions.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 AppManagers;
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 simdb::AppManagers* getAppManagers() const { return app_managers_.get(); }
168
173 bool usingFinalConfig() const { return using_final_config_; }
174
176 bool readyToRun() const { return framework_finalized_; }
177
179 sparta::Clock* getRootClock() noexcept { return root_clk_.get(); }
180
182 const sparta::Clock* getRootClock() const noexcept { return root_clk_.get(); }
183
186
189
193 const std::string& getSimName() const noexcept {
194 return sim_name_;
195 }
196
201 return sim_config_;
202 }
203
208 return feature_config_;
209 }
210
215 return report_config_.get();
216 }
217
218
219 // Setup
220
227 void buildTree();
228
236
244
245
252
253
254 // Running
255
264 virtual void run(uint64_t run_time);
265
282 virtual void runRaw(uint64_t run_time);
283
290 virtual void asyncStop();
291
292
293 // Post-processing
294
301 void dumpDebugContentIfAllowed(std::exception_ptr eptr, bool forcec=false) noexcept;
302
307
315
324 "Cannot query findSemanticCounter until Simulation is finalized");
326 "Cannot query findSemanticCounter after Simulation has entered teardown");
327 return findSemanticCounter_(sem);
328 }
329
330
331 // Status
332
338
343 uint64_t numFired() { return num_fired_; }
344
349 validate_post_run_ = true;
350 }
354 std::string getPipelineCollectionPrefix() const {
356 }
357
365 bool usingPyshell() const {
366#ifdef SPARTA_PYTHON_SUPPORT
367 return pyshell_ != nullptr;
368#else
369 return false;
370#endif
371 }
372
380 virtual sparta::control::TemporaryRunControl * getRunControlInterface() {
381 return rc_.get();
382 }
383
388 void dumpMetaParameterTable(std::ostream& out) const;
389
390
391protected:
392
423 {
424 public:
425 virtual ~SimulationController() {}
426
427 void pause();
428 void resume();
429 void terminate();
430
431 void invokeNamedEvent(
432 const std::string & event_name);
433
434 enum class SimulationStatus {
435 Idle,
436 Paused,
437 Simulating,
438 Terminated
439 };
440 SimulationStatus getSimStatus() const {
441 return sim_status_;
442 }
443
444 protected:
445 explicit SimulationController(
446 const sparta::app::Simulation * sim) :
447 sim_(sim)
448 {}
449
450 void addNamedCallback_(
451 const std::string & event_name,
452 SpartaHandler callback_method);
453
454 private:
455 virtual void pause_(const sparta::app::Simulation * sim) {
456 (void) sim;
457 }
458 virtual void resume_(const sparta::app::Simulation * sim) {
459 (void) sim;
460 }
461 virtual void terminate_(const sparta::app::Simulation * sim) {
462 (void) sim;
463 }
464 void verifyFinalized_() const;
465
466 const sparta::app::Simulation * sim_ = nullptr;
467 std::unordered_map<std::string, SpartaHandler> callbacks_;
468 std::set<std::string> invoked_callbacks_;
469 SimulationStatus sim_status_ = SimulationStatus::Idle;
470
471 friend class sparta::app::Simulation;
472 };
473
478 std::shared_ptr<SimulationController> controller);
479
483 void pause_();
484
488 void resume_();
489
494
498 void customEvent_(const std::string & event_name);
499
504
508 std::shared_ptr<SimulationController> controller_;
509
514 std::vector<std::shared_ptr<trigger::ExpressionTrigger>> controller_triggers_;
515
524 uint32_t dumpNonDefaultParameters_(TreeNode* root, std::ostream& out);
525
531
542
548
555 void addTreeNodeExtensionFactory_(const std::string & extension_name,
556 std::function<TreeNode::ExtensionsBase*()> factory);
557
561
565 virtual void buildTree_() = 0;
566
572 virtual void configureTree_() = 0;
573
580 virtual void bindTree_() = 0;
581
590 virtual void parameterizeApps_([[maybe_unused]] simdb::AppManager* app_mgr) {}
591
595 virtual void postFinalizeFramework_() {}
596
599
609 virtual void runControlLoop_(uint64_t run_time);
610
619 virtual void runRaw_(uint64_t run_time);
620
623
632 (void) sem;
633 return nullptr;
634 }
635
647 bool dumpDebugContent_(std::string& filename,
648 const std::string& exception,
649 const std::string& backtrace) noexcept;
650
659 void rootDescendantAdded_(const sparta::TreeNode& node_added);
660
669
679 void attachReportTo_(sparta::ReportRepository::DirectoryHandle directoryH,
680 const ReportDescriptor & rd,
682 const std::vector<std::string>& replacements);
683
691
697 const ReportDescriptor & rd,
698 const bool using_pyshell) const;
699
705
712 ReportDescVec expandReportDescriptor_(const ReportDescriptor & rd) const;
713
718
733
740
744 std::shared_ptr<sparta::MemoryProfiler> memory_profiler_;
745
749 std::unique_ptr<sparta::ReportRepository> report_repository_;
750
755
759 const std::string sim_name_;
760
765 std::vector<std::unique_ptr<sparta::log::Tap>> taps_to_del_;
766
772
777
782 std::unique_ptr<Report> auto_summary_report_;
783
787 std::unique_ptr<sparta::RootTreeNode> clk_root_node_;
788
793 Clock::Handle root_clk_;
794
800
808 std::unique_ptr<MetaTreeNode> meta_;
809
814
819 std::vector<std::unique_ptr<sparta::TreeNode>> to_delete_;
820
821
822 // The SimulationConfiguration object
823 SimulationConfiguration * sim_config_{nullptr};
824
825 // The FeatureConfiguration object
826 const FeatureConfiguration * feature_config_{nullptr};
827
828 // Order matters: Taps should die before any other nodes (or after all other
829 // nodes are guaranteed destructed)
830
832
836 std::unique_ptr<sparta::log::Tap> warn_to_file_;
837
838 uint64_t num_fired_;
839
840 bool print_dag_ = false;
841
845 bool validate_post_run_ = false;
846
851
861
866 std::unique_ptr<ReportConfiguration> report_config_;
867
872 std::vector<ConfigApplicator*> user_configs_;
873
880
885
890
894 std::unique_ptr<trigger::CounterTrigger> pevent_start_trigger_;
895
899 std::unique_ptr<LoggingTrigger> log_trigger_;
900
906 std::unique_ptr<trigger::Trigger> debug_trigger_;
907
912
913private:
914
915#ifdef SPARTA_PYTHON_SUPPORT
919 std::unique_ptr<python::PythonInterpreter> pyshell_;
920#endif
921
928
951 virtual void validateReportDescriptors_(
952 const ReportDescriptorCollection & report_descriptors) const
953 {
954 (void) report_descriptors;
955 }
956
960 std::unique_ptr<control::TemporaryRunControl> rc_;
961
965 void createSimDbApps_();
966 int argc_ = 0;
967 char** argv_ = nullptr;
968
972 std::shared_ptr<simdb::AppManagers> app_managers_;
973};
974
975} // namespace app
976} // 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
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.
Simulator which builds a sparta DeviceTree.
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()
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 void parameterizeApps_(simdb::AppManager *app_mgr)
When using SimDB apps, this method gets called when the SimulationConfiguration (SimDbConfig) has bee...
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.
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.
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.
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.
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)
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.