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;
38 class ReportStatsCollector;
41namespace sparta::trigger {
42 class SkippedAnnotatorBase;
50 class FormatterFactory;
59 namespace statistics {
68 typedef std::unordered_map<std::string, boost::any> NamedExtensions;
69 typedef std::unordered_map<std::string, std::string> TriggerKeyValues;
70 typedef std::unordered_map<std::string, std::string> MetaDataKeyValues;
78 typedef std::pair<Report*, report::format::BaseFormatter*> inst_t;
85 std::set<const Report*> triggered_reports_;
95 std::set<const Report*> idle_reports_;
100 std::map<std::string, std::shared_ptr<report::format::BaseFormatter>> formatters_;
106 std::shared_ptr<statistics::ReportStatisticsArchive> report_archive_;
112 std::shared_ptr<statistics::StreamNode> streaming_stats_root_;
120 bool updateReportActiveState_(
const Report * r);
126 std::vector<inst_t> instantiations_;
133 const sparta::report::format::FormatterFactory* fact_;
150 class DescUpdateTracker {
152 void enable(
const Scheduler * scheduler);
153 bool checkIfDuplicateUpdate();
164 DescUpdateTracker update_tracker_;
170 std::shared_ptr<sparta::trigger::SkippedAnnotatorBase> skipped_annotator_;
175 bool report_stopped_ =
false;
181 bool enabled_ =
true;
190 std::string orig_dest_file_;
206 bool legacy_reports_enabled_ =
true;
214 void sweepSimDbStats_();
222 void skipSimDbStats_();
321 const std::string& _def_file,
322 const std::string& _dest_file,
323 const std::string& _format=
"text");
360 return orig_dest_file_;
370 const std::string & dir);
387 report_stopped_ =
true;
394 std::stringstream ss;
396 <<
"\" -> \"" << (orig_dest_file_.empty() ?
dest_file : orig_dest_file_) <<
"\"";
398 ss <<
" (format=" <<
format <<
")";
426 std::ostream* out=
nullptr);
433 return instantiations_;
443 const std::vector<Report*> & pending_reports =
444 boost::any_cast<const std::vector<Report*>&>(iter->second);
446 return pending_reports;
460 std::unordered_set<Report*> all(pending.begin(), pending.end());
461 for (
const auto & cur : current) {
462 all.insert(cur.first);
464 return std::vector<Report*>(all.begin(), all.end());
482 legacy_reports_enabled_ =
false;
562 const std::string& sim_name,
566 typedef std::vector<ReportDescriptor> ReportDescVec;
567 typedef std::vector<std::pair<std::string, std::string>> ReportYamlReplacements;
602 const std::string desc_name = getDescriptorName_(rd);
603 auto iter = indices_by_descriptor_name_.find(desc_name);
604 if (iter != indices_by_descriptor_name_.end()) {
607 if (rep_descs_.at(iter->second).isEnabled()) {
609 desc_name <<
"' already exists in this configuration";
612 indices_by_descriptor_name_[desc_name] = rep_descs_.size();
623 rep_descs_.push_back(rd);
624 rep_descs_.back().enabled_ =
true;
628 template <
class... Args>
636 for (
auto &rd : rep_descs_) {
644 for (
const auto & rep_desc : rep_descs_) {
645 if (rep_desc.isEnabled()) {
659 bool contains(
const std::string & desc_name)
const {
660 auto iter = indices_by_descriptor_name_.find(desc_name);
661 if (iter == indices_by_descriptor_name_.end()) {
664 const auto replaced_desc_name = replaceDotsWithUnderscores_(desc_name);
665 iter = indices_by_descriptor_name_.find(replaced_desc_name);
670 if (iter == indices_by_descriptor_name_.end()) {
676 return rep_descs_.at(iter->second).isEnabled();
681 auto idx = getDescriptorIndexByName_(desc_name);
682 return rep_descs_.at(idx);
694 std::vector<std::string> names;
695 for (
const auto & rd : indices_by_descriptor_name_) {
696 if (rep_descs_.at(rd.second).isEnabled()) {
697 names.push_back(rd.first);
704 std::deque<ReportDescriptor>::iterator
begin() {
705 return rep_descs_.begin();
709 std::deque<ReportDescriptor>::const_iterator
begin()
const {
710 return rep_descs_.cbegin();
714 std::deque<ReportDescriptor>::iterator
end() {
715 return rep_descs_.end();
719 std::deque<ReportDescriptor>::const_iterator
end()
const {
720 return rep_descs_.cend();
725 return replaceDotsWithUnderscores_(rd.
dest_file);
728 std::string replaceDotsWithUnderscores_(
const std::string & str)
const {
729 std::string replaced = str;
730 boost::replace_all(replaced,
".",
"_");
734 size_t getDescriptorIndexByName_(
const std::string & desc_name)
const {
735 auto iter = indices_by_descriptor_name_.find(desc_name);
736 if (iter == indices_by_descriptor_name_.end()) {
739 const auto replaced_desc_name = replaceDotsWithUnderscores_(desc_name);
740 iter = indices_by_descriptor_name_.find(replaced_desc_name);
743 if (iter == indices_by_descriptor_name_.end()) {
744 throw SpartaException(
745 "No descriptor named '") << desc_name <<
"' exists";
752 if (!rep_descs_.at(iter->second).isEnabled()) {
753 throw SpartaException(
"The descriptor named '") << desc_name
754 <<
"' has already been disabled";
759 std::deque<ReportDescriptor> rep_descs_;
760 std::unordered_map<std::string, size_t> indices_by_descriptor_name_;
822 void republishReportCollection_();
825 void finishPythonInteraction_();
828 void disallowChangesToDescriptors_();
841 bool allow_descriptor_changes_ =
true;
849 const std::string & replacements_yaml);
857 const std::string & def_file,
883 const std::string & def_file,
885 const ReportYamlReplacements & placeholder_key_value_pairs);
892 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...
bool configSimDbReports(app::ReportStatsCollector *collector)
Get ready for SimDB report collection.
void disableLegacyReports()
In MAP v2.1, we provide report systems for both legacy reports and SimDB-exported reports....
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.
void teardown()
Called when the ReportRepository is shutting down.
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.