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 sparta {
32
33class Clock;
34class MemoryProfiler;
35class DatabaseAccessor;
36
37namespace python {
38 class PythonInterpreter;
39}
40namespace control {
41 class TemporaryRunControl;
42}
43
44namespace trigger {
45 class SingleTrigger;
46 class CounterTrigger;
47 class TimeTrigger;
48 class CycleTrigger;
49 class Trigger;
50} // namespace trigger
51
55namespace app {
56class LoggingTrigger;
57class ConfigApplicator;
58class FeatureConfiguration;
59
65{
66public:
67
77
79 Simulation() = delete;
80
82 Simulation(const Simulation&) = delete;
83
86
88 Simulation& operator=(const Simulation&) = delete;
89
96 Simulation(const std::string& sim_name, Scheduler * scheduler);
97
101 virtual ~Simulation();
102
110 void setFeatureConfig(const FeatureConfiguration * feature_config) {
111 feature_config_ = feature_config;
112 }
113
149 simdb::DatabaseRoot * getDatabaseRoot() const;
150
159 const DatabaseAccessor * getSimulationDatabaseAccessor() const;
160
171 void configure(const int argc,
172 char ** argv,
173 SimulationConfiguration * configuration,
174 const bool use_pyshell = false);
175
181 void addReport(const ReportDescriptor & rep);
182
192 void installTaps(const log::TapDescVec& taps);
193
195 sparta::RootTreeNode* getRoot() noexcept { return &root_; }
196
198 sparta::app::MetaTreeNode* getMetaParamRoot() const noexcept { return meta_.get(); }
199
201 const sparta::RootTreeNode* getRoot() const noexcept { return &root_; }
202
205
207 const sparta::Scheduler * getScheduler() const { return scheduler_; }
208
213 bool usingFinalConfig() const { return using_final_config_; }
214
216 bool readyToRun() const { return framework_finalized_; }
217
219 sparta::Clock* getRootClock() noexcept { return root_clk_.get(); }
220
222 const sparta::Clock* getRootClock() const noexcept { return root_clk_.get(); }
223
226
229
233 const std::string& getSimName() const noexcept {
234 return sim_name_;
235 }
236
241 return sim_config_;
242 }
243
248 return feature_config_;
249 }
250
255 return report_config_.get();
256 }
257
258
259 // Setup
260
267 void buildTree();
268
276
284
285
292
293
294 // Running
295
304 virtual void run(uint64_t run_time);
305
322 virtual void runRaw(uint64_t run_time);
323
330 virtual void asyncStop();
331
332
333 // Post-processing
334
341 void dumpDebugContentIfAllowed(std::exception_ptr eptr, bool forcec=false) noexcept;
342
347
355
364 "Cannot query findSemanticCounter until Simulation is finalized");
366 "Cannot query findSemanticCounter after Simulation has entered teardown");
367 return findSemanticCounter_(sem);
368 }
369
370
371 // Status
372
378
383 uint64_t numFired() { return num_fired_; }
384
389 validate_post_run_ = true;
390 }
394 std::string getPipelineCollectionPrefix() const {
396 }
397
405 bool usingPyshell() const {
406#ifdef SPARTA_PYTHON_SUPPORT
407 return pyshell_ != nullptr;
408#else
409 return false;
410#endif
411 }
412
420 virtual sparta::control::TemporaryRunControl * getRunControlInterface() {
421 return rc_.get();
422 }
423
428 void dumpMetaParameterTable(std::ostream& out) const;
429
430
431protected:
432
463 {
464 public:
465 virtual ~SimulationController() {}
466
467 void pause();
468 void resume();
469 void terminate();
470
471 void invokeNamedEvent(
472 const std::string & event_name);
473
474 enum class SimulationStatus {
475 Idle,
476 Paused,
477 Simulating,
478 Terminated
479 };
480 SimulationStatus getSimStatus() const {
481 return sim_status_;
482 }
483
484 protected:
485 explicit SimulationController(
486 const sparta::app::Simulation * sim) :
487 sim_(sim)
488 {}
489
490 void addNamedCallback_(
491 const std::string & event_name,
492 SpartaHandler callback_method);
493
494 private:
495 virtual void pause_(const sparta::app::Simulation * sim) {
496 (void) sim;
497 }
498 virtual void resume_(const sparta::app::Simulation * sim) {
499 (void) sim;
500 }
501 virtual void terminate_(const sparta::app::Simulation * sim) {
502 (void) sim;
503 }
504 void verifyFinalized_() const;
505
506 const sparta::app::Simulation * sim_ = nullptr;
507 std::unordered_map<std::string, SpartaHandler> callbacks_;
508 std::set<std::string> invoked_callbacks_;
509 SimulationStatus sim_status_ = SimulationStatus::Idle;
510
511 friend class sparta::app::Simulation;
512 };
513
518 std::shared_ptr<SimulationController> controller);
519
523 void pause_();
524
528 void resume_();
529
534
538 void customEvent_(const std::string & event_name);
539
544
548 std::shared_ptr<SimulationController> controller_;
549
554 std::vector<std::shared_ptr<trigger::ExpressionTrigger>> controller_triggers_;
555
564 uint32_t dumpNonDefaultParameters_(TreeNode* root, std::ostream& out);
565
571
582
588
595 void addTreeNodeExtensionFactory_(const std::string & extension_name,
596 std::function<TreeNode::ExtensionsBase*()> creator);
597
601
605 virtual void buildTree_() = 0;
606
612 virtual void configureTree_() = 0;
613
620 virtual void bindTree_() = 0;
621
624
634 virtual void runControlLoop_(uint64_t run_time);
635
644 virtual void runRaw_(uint64_t run_time);
645
648
657 (void) sem;
658 return nullptr;
659 }
660
672 bool dumpDebugContent_(std::string& filename,
673 const std::string& exception,
674 const std::string& backtrace) noexcept;
675
684 void rootDescendantAdded_(const sparta::TreeNode& node_added);
685
694
704 void attachReportTo_(sparta::ReportRepository::DirectoryHandle directoryH,
705 const ReportDescriptor & rd,
707 const std::vector<std::string>& replacements);
708
716
722 const ReportDescriptor & rd,
723 const bool using_pyshell) const;
724
730
738
745 ReportDescVec expandReportDescriptor_(const ReportDescriptor & rd) const;
746
751
766
773
777 std::shared_ptr<sparta::MemoryProfiler> memory_profiler_;
778
782 std::unique_ptr<sparta::ReportRepository> report_repository_;
783
788
792 const std::string sim_name_;
793
798 std::vector<std::unique_ptr<sparta::log::Tap>> taps_to_del_;
799
805
810
815 std::unique_ptr<Report> auto_summary_report_;
816
820 std::unique_ptr<sparta::RootTreeNode> clk_root_node_;
821
826 Clock::Handle root_clk_;
827
833
841 std::unique_ptr<MetaTreeNode> meta_;
842
846 std::unordered_map<
847 std::string,
849
854
859 std::vector<std::unique_ptr<sparta::TreeNode>> to_delete_;
860
861
862 // The SimulationConfiguration object
863 SimulationConfiguration * sim_config_{nullptr};
864
865 // The FeatureConfiguration object
866 const FeatureConfiguration * feature_config_{nullptr};
867
868 // Order matters: Taps should die before any other nodes (or after all other
869 // nodes are guaranteed destructed)
870
872
876 std::unique_ptr<sparta::log::Tap> warn_to_file_;
877
878 uint64_t num_fired_;
879
880 bool print_dag_ = false;
881
885 bool validate_post_run_ = false;
886
891
901
906 std::unique_ptr<ReportConfiguration> report_config_;
907
914 ExtensionDescriptorVec extension_descs_;
915 std::set<std::string> nodes_given_extensions_;
916
921 std::vector<ConfigApplicator*> user_configs_;
922
929
934
939
943 std::unique_ptr<trigger::CounterTrigger> pevent_start_trigger_;
944
948 std::unique_ptr<LoggingTrigger> log_trigger_;
949
955 std::unique_ptr<trigger::Trigger> debug_trigger_;
956
961
962private:
963
964#ifdef SPARTA_PYTHON_SUPPORT
968 std::unique_ptr<python::PythonInterpreter> pyshell_;
969#endif
970
977
1000 virtual void validateReportDescriptors_(
1001 const ReportDescriptorCollection & report_descriptors) const
1002 {
1003 (void) report_descriptors;
1004 }
1005
1009 std::unique_ptr<control::TemporaryRunControl> rc_;
1010
1022 simdb::ObjectManager * stats_db_ = nullptr;
1023
1031 std::unique_ptr<simdb::DatabaseRoot> db_root_;
1032
1037 std::shared_ptr<DatabaseAccessor> sim_db_accessor_;
1038private:
1041 void inspectFeatureValues_();
1042
1046 bool isReportValidationEnabled_() const;
1047
1050 std::set<std::string> report_verif_failed_fnames_;
1051};
1052
1053} // namespace app
1054} // 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:51
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.
simdb::DatabaseRoot * getDatabaseRoot() const
Get the database root for this simulation.
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 (...
void setupDatabaseTriggers_()
Right before the main sim loop, this method is called in order to create any SimDB triggers the simul...
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 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.
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...
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.
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.
void setupReports_()
Sets up all reports in this simulation. This can be called during finalization or deferred until late...
const DatabaseAccessor * getSimulationDatabaseAccessor() const
There is a 1-to-1 mapping between a running simulation and the database it is using....
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.