10#include <boost/algorithm/string/replace.hpp>
11#include <boost/any.hpp>
12#include <boost/iterator/iterator_traits.hpp>
13#include <boost/type_index/type_index_facade.hpp>
22#include <unordered_map>
23#include <unordered_set>
28#include "sparta/report/Report.hpp"
29#include "sparta/utils/Utils.hpp"
30#include "sparta/report/format/BaseFormatter.hpp"
37 class SimulationConfiguration;
40namespace sparta::trigger {
41 class SkippedAnnotatorBase;
49 class FormatterFactory;
58 namespace statistics {
58 namespace statistics {
…}
67 typedef std::unordered_map<std::string, boost::any> NamedExtensions;
68 typedef std::unordered_map<std::string, std::string> TriggerKeyValues;
69 typedef std::unordered_map<std::string, std::string> MetaDataKeyValues;
77 typedef std::pair<Report*, report::format::BaseFormatter*> inst_t;
84 std::set<const Report*> triggered_reports_;
94 std::set<const Report*> idle_reports_;
99 std::map<std::string, std::shared_ptr<report::format::BaseFormatter>> formatters_;
105 std::shared_ptr<statistics::ReportStatisticsArchive> report_archive_;
111 std::shared_ptr<statistics::StreamNode> streaming_stats_root_;
119 bool updateReportActiveState_(
const Report * r);
125 std::vector<inst_t> instantiations_;
132 const sparta::report::format::FormatterFactory* fact_;
149 class DescUpdateTracker {
151 void enable(
const Scheduler * scheduler);
152 bool checkIfDuplicateUpdate();
163 DescUpdateTracker update_tracker_;
169 std::shared_ptr<sparta::trigger::SkippedAnnotatorBase> skipped_annotator_;
174 bool report_stopped_ =
false;
180 bool enabled_ =
true;
189 std::string orig_dest_file_;
288 const std::string& _def_file,
289 const std::string& _dest_file,
290 const std::string& _format=
"text");
327 return orig_dest_file_;
337 const std::string & dir);
349 report_stopped_ =
true;
356 std::stringstream ss;
358 <<
"\" -> \"" << (orig_dest_file_.empty() ?
dest_file : orig_dest_file_) <<
"\"";
360 ss <<
" (format=" <<
format <<
")";
388 std::ostream* out=
nullptr);
395 return instantiations_;
405 const std::vector<Report*> & pending_reports =
406 boost::any_cast<const std::vector<Report*>&>(iter->second);
408 return pending_reports;
422 std::unordered_set<Report*> all(pending.begin(), pending.end());
423 for (
const auto & cur : current) {
424 all.insert(cur.first);
426 return std::vector<Report*>(all.begin(), all.end());
501 const std::string& sim_name,
505 typedef std::vector<ReportDescriptor> ReportDescVec;
506 typedef std::vector<std::pair<std::string, std::string>> ReportYamlReplacements;
541 const std::string desc_name = getDescriptorName_(rd);
542 auto iter = indices_by_descriptor_name_.find(desc_name);
543 if (iter != indices_by_descriptor_name_.end()) {
546 if (rep_descs_.at(iter->second).isEnabled()) {
548 desc_name <<
"' already exists in this configuration";
551 indices_by_descriptor_name_[desc_name] = rep_descs_.size();
562 rep_descs_.push_back(rd);
563 rep_descs_.back().enabled_ =
true;
567 template <
class... Args>
575 for (
auto &rd : rep_descs_) {
583 for (
const auto & rep_desc : rep_descs_) {
584 if (rep_desc.isEnabled()) {
598 bool contains(
const std::string & desc_name)
const {
599 auto iter = indices_by_descriptor_name_.find(desc_name);
600 if (iter == indices_by_descriptor_name_.end()) {
603 const auto replaced_desc_name = replaceDotsWithUnderscores_(desc_name);
604 iter = indices_by_descriptor_name_.find(replaced_desc_name);
609 if (iter == indices_by_descriptor_name_.end()) {
615 return rep_descs_.at(iter->second).isEnabled();
620 auto idx = getDescriptorIndexByName_(desc_name);
621 return rep_descs_.at(idx);
633 std::vector<std::string> names;
634 for (
const auto & rd : indices_by_descriptor_name_) {
635 if (rep_descs_.at(rd.second).isEnabled()) {
636 names.push_back(rd.first);
643 std::deque<ReportDescriptor>::iterator
begin() {
644 return rep_descs_.begin();
643 std::deque<ReportDescriptor>::iterator
begin() {
…}
648 std::deque<ReportDescriptor>::const_iterator
begin()
const {
649 return rep_descs_.cbegin();
648 std::deque<ReportDescriptor>::const_iterator
begin()
const {
…}
653 std::deque<ReportDescriptor>::iterator
end() {
654 return rep_descs_.end();
653 std::deque<ReportDescriptor>::iterator
end() {
…}
658 std::deque<ReportDescriptor>::const_iterator
end()
const {
659 return rep_descs_.cend();
658 std::deque<ReportDescriptor>::const_iterator
end()
const {
…}
664 return replaceDotsWithUnderscores_(rd.
dest_file);
667 std::string replaceDotsWithUnderscores_(
const std::string & str)
const {
668 std::string replaced = str;
669 boost::replace_all(replaced,
".",
"_");
673 size_t getDescriptorIndexByName_(
const std::string & desc_name)
const {
674 auto iter = indices_by_descriptor_name_.find(desc_name);
675 if (iter == indices_by_descriptor_name_.end()) {
678 const auto replaced_desc_name = replaceDotsWithUnderscores_(desc_name);
679 iter = indices_by_descriptor_name_.find(replaced_desc_name);
682 if (iter == indices_by_descriptor_name_.end()) {
683 throw SpartaException(
684 "No descriptor named '") << desc_name <<
"' exists";
691 if (!rep_descs_.at(iter->second).isEnabled()) {
692 throw SpartaException(
"The descriptor named '") << desc_name
693 <<
"' has already been disabled";
698 std::deque<ReportDescriptor> rep_descs_;
699 std::unordered_map<std::string, size_t> indices_by_descriptor_name_;
761 void republishReportCollection_();
764 void finishPythonInteraction_();
767 void disallowChangesToDescriptors_();
780 bool allow_descriptor_changes_ =
true;
788 const std::string & replacements_yaml);
796 const std::string & def_file,
822 const std::string & def_file,
824 const ReportYamlReplacements & placeholder_key_value_pairs);
831 const std::string & def_string,
File that defines the Clock class.
Exception class for all of Sparta.
Basic Node framework in sparta device tree composite pattern.
File that defines a ValidValue.
TreeNode which represents the root ("top") of a device tree.
A class that lets you schedule events now and in the future.
Used to construct and throw a standard C++ exception. Inherits from std::exception.
Node in a composite tree representing a sparta Tree item.
Configuration applicator class that is used for configuring a simulator's reports....
void addMemoryReportsFromYaml(const std::string &yaml_file)
const ReportDescriptorCollection * getDescriptors() const
Access the underlying report descriptors.
ReportDescriptorCollection * getDescriptors()
Access the underlying report descriptors.
void showAllReportDescriptorInfo()
Pretty print information about all app::ReportDescriptor's.
void serializeAllDescriptorsToYaml()
void addReportsFromYaml(const std::string &yaml_file)
void removeReportByName(const std::string &rd_name)
void addReport(const ReportDescriptor &rd)
Add one report descriptor to this collection.
This collection of ReportDescriptors is designed to never deallocate memory once it has been allocate...
std::vector< std::string > getAllDescriptorNames() const
bool contains(const std::string &desc_name) const
void removeDescriptorByName(const std::string &desc_name)
std::deque< ReportDescriptor >::const_iterator begin() const
Iterator access.
size_t size() const
Get the number of enabled descriptors in this collection.
ReportDescriptor & getDescriptorByName(const std::string &desc_name)
Access a descriptor by the app::ReportDescriptor's "dest_file".
std::deque< ReportDescriptor >::iterator end()
Iterator access.
std::deque< ReportDescriptor >::iterator begin()
Iterator access.
void push_back(const ReportDescriptor &rd)
Add one report descriptor to this collection.
std::deque< ReportDescriptor >::const_iterator end() const
Iterator access.
void emplace_back(Args &&... args)
Add one report descriptor to this collection.
bool empty() const
See if there are any enabled descriptors in this collection.
void clear()
Remove (disable) all descriptors from this collection.
Describes one or more report to instantiate.
~ReportDescriptor()
Destructor (note that triggered reports are automatically flushed)
MetaDataKeyValues header_metadata_
Metadata to include in report headers.
uint32_t getUsageCount() const
Returns the usage count (incremented by addInstantiation)
const std::string & getDescriptorDefFile() const
Getter for this descriptor's def_file, e.g. "simple_stats.yaml".
std::string format
Optional formatting string (how to write to the file). This is converted to lower-case at constructio...
std::vector< Report * > getAllInstantiations() const
Returns all report instantiations, including those already instantiated (no report start trigger) and...
std::string computeFilename(const Report *r, const std::string &sim_name, uint32_t idx) const
Computes the filename to which this reportdescriptor will be saved using any necessary variables in t...
uint32_t writeOutput(std::ostream *out=nullptr)
Saves all of the instantiations whose formatters do not support 'update' to their respective destinat...
void capUpdatesToOncePerTick(const Scheduler *scheduler)
Instruct this descriptor to automatically ignore any "duplicate" updates that occur at the exact same...
report::format::BaseFormatter * addInstantiation(Report *r, Simulation *sim, std::ostream *out=nullptr)
Tracks a report instantiated based on this descriptor and allocates a new formatter for it....
const std::string & getDescriptorFormat() const
Getter for this descriptor's format, e.g. "json_reduced".
std::string dest_file
Destination filename to which report will be written. Later this will represent other types of destin...
uint32_t getNumWrites() const
Returns the number of writes done on this report descriptor's instantiated report formatters.
uint32_t getNumUpdates() const
Returns the number of updates done on this report descriptor's instantiated report formatters.
std::vector< Report * > getPendingInstantiations() const
Returns a vector of reports that have not been instantiated yet, but will be when this report descrip...
static const char * GLOBAL_KEYWORD
Global search scope node keyword for report locations.
ReportDescriptor & operator=(const ReportDescriptor &)=default
Allow assignment.
std::string loc_pattern
Node location string (pattern) on which report should be generated. Typically "" or top.
ReportDescriptor(const std::string &_loc_pattern, const std::string &_def_file, const std::string &_dest_file, const std::string &_format="text")
Construct a report decsriptor.
void clearDestinationFiles(const Simulation &sim)
Clears all destination files that will be filled with instances of this report descriptor.
ReportDescriptor(const ReportDescriptor &)=default
Allow construction.
void disable()
Calling this method causes the simulation to skip this descriptor when it is setting up its reports....
const std::string & getDescriptorDestFile() const
Getter for this descriptor's dest_file, e.g. "out.json".
const std::string & getDescriptorOrigDestFile() const
This descriptor may have had its dest_file changed when the the Simulation::setupReports() method was...
bool isEnabled() const
See if this descriptor is enabled or not. Disabling a descriptor means that it will be filtered from ...
std::vector< inst_t > getInstantiations() const
Returns the vector of instantiated reports based on this descriptor.
NamedExtensions extensions_
Key-value extensions used by parsers to bind opaque report configurations to descriptors.
static bool isValidFormatName(const std::string &format)
Determines if format is a valid name for formatter. This allows the command line parser to disregard ...
void skipOutput()
Let the descriptor know to skip over one update of data.
std::shared_ptr< statistics::ReportStatisticsArchive > logOutputValuesToArchive(const std::string &dir)
Tell the descriptor to send all of its writeOutput / updateOutput statistics values to a binary archi...
std::string def_file
Filename of report definition. If '@', auto generates reports with all counters and stats of loc_patt...
std::shared_ptr< statistics::StreamNode > createRootStatisticsStream()
Create and return a StreamNode object that sits at the top of a tree hierarchy that describes the Rep...
void ignoreFurtherUpdates()
Report descriptors may be triggered to stop early - ensure no further updates are written to disk.
std::string stringize() const
Represents this descriptor as a string.
const std::string & getDescriptorPattern() const
Getter for this descriptor's pattern, e.g. "_global".
void setSkippedAnnotator(std::shared_ptr< sparta::trigger::SkippedAnnotatorBase > annotator)
Give this descriptor a specific annotator subclass for printing skipped update information to reports...
uint32_t updateOutput(std::ostream *out=nullptr)
Updates all of the instantiations whose formatters support 'update', possibly by writing to the desti...
Configuration applicator class that is used for configuring a simulator. Works in conjunction with sp...
Simulator which builds a sparta DeviceTree.
This class coordinates live SPARTA simulations (source) with binary output archives (sink).
When a simulation is configured to stream its statistics values for asynchronous processing,...
Provides a wrapper around a value to ensure that the value is assigned.
Sparta Application framework.
ReportDescVec createDescriptorsFromFile(const std::string &def_file, TreeNode *context)
Given a multi-report definition YAML file, parse it out into individual descriptors,...
ReportYamlReplacements createReplacementsFromYaml(const std::string &replacements_yaml)
Parse a YAML file containing key-value pairs into a single ReportYamlReplacements data structure.
ReportDescVec createDescriptorsFromDefinitionString(const std::string &def_string, TreeNode *context)
Given a multi-report definition string, parse it out into individual descriptors.
ReportDescVec createDescriptorsFromFileWithPlaceholderReplacements(const std::string &def_file, TreeNode *context, const ReportYamlReplacements &placeholder_key_value_pairs)
This method is similar to "createDescriptorsFromFile()", except that it can be used for report yaml f...
Macros for handling exponential backoff.