The Sparta Modeling Framework
Loading...
Searching...
No Matches
ReportStatisticsArchive.hpp
1// <ReportStatisticsArchive> -*- C++ -*-
2
3#pragma once
4
5#include "sparta/statistics/dispatch/archives/ReportStatisticsAggregator.hpp"
6#include "sparta/statistics/dispatch/archives/ArchiveDispatcher.hpp"
7#include "sparta/statistics/dispatch/archives/ArchiveController.hpp"
8#include "sparta/statistics/dispatch/archives/BinaryIArchive.hpp"
9#include "sparta/statistics/dispatch/archives/BinaryOArchive.hpp"
10
11namespace sparta {
12namespace statistics {
13
14class RootArchiveNode;
15
21{
22public:
23 ReportStatisticsArchive(const std::string & db_directory,
24 const std::string & db_subdirectory,
25 const Report & report)
26 {
27 dispatcher_.reset(new ReportStatisticsDispatcher(
28 db_directory, db_subdirectory, report));
29 }
30
31 //Metadata will be forwarded along to the underlying RootArchiveNode.
32 //You can get this root node object by calling getRoot()
33 void setArchiveMetadata(const app::NamedExtensions & metadata) {
34 dispatcher_->setArchiveMetadata(metadata);
35 }
36
37 //One-time initialization of the output binary archive
38 void initialize() {
39 dispatcher_->configureBinaryArchive(this);
40 }
41
42 //Access the underlying root node for our archive tree
43 std::shared_ptr<RootArchiveNode> getRoot() const {
44 return dispatcher_->getRoot();
45 }
46
47 //Send out all of the report's StatisticInstance current
48 //values to the binary sink
49 void dispatchAll() {
50 dispatcher_->dispatch();
51 dirty_ = true;
52 }
53
54 //Synchronize the data source with the binary sink. Returns
55 //true if the flush was made, and false if the archive was
56 //already in sync. Returning false is NOT a sign of an error.
57 bool flushAll() {
58 if (!dirty_) {
59 return false;
60 }
61
62 dispatcher_->flush();
63 dirty_ = false;
64 return true;
65 }
66
67 //Make a deep copy of the archive, sending it to the
68 //given directory. This does not invalidate the current
69 //ongoing/live archive. This call can safely be made during
70 //simulation.
71 void saveTo(const std::string & db_directory) {
72 dispatcher_->flush();
73 const auto & sinks = dispatcher_->getSinks();
74 for (const auto & sink : sinks) {
75 copyArchiveToDirectory_(*sink, db_directory);
76 }
77 }
78
79private:
84 class ReportStatisticsDispatcher : public ArchiveDispatcher
85 {
86 public:
87 ReportStatisticsDispatcher(const std::string & db_directory,
88 const std::string & db_subdirectory,
89 const Report & report) :
90 db_directory_(db_directory),
91 db_subdirectory_(db_subdirectory)
92 {
93 std::unique_ptr<ReportStatisticsAggregator> source(
94 new ReportStatisticsAggregator(report));
95
96 source->initialize();
97 root_ = source->getRoot();
98 setStatisticsSource(std::move(source));
99 }
100
101 void setArchiveMetadata(const app::NamedExtensions & metadata) {
102 root_->setMetadata(metadata);
103
104 //All archives should have a "triggers" property, even
105 //if there were no triggers used to generate the report.
106 //This is to support Python, so we can give a user friendly
107 //message like this:
108 //
109 // >>> foo.bar.triggers.showInfo()
110 // "No triggers have been set"
111 if (!root_->tryGetMetadataValue<app::TriggerKeyValues>("trigger")) {
112 app::TriggerKeyValues no_triggers;
113 root_->setMetadataValue("trigger", no_triggers);
114 }
115 }
116
117 void configureBinaryArchive(ReportStatisticsArchive * source)
118 {
119 //Give the root archive node a controller it can use to
120 //save the archive to another directory, synchronize the
121 //data source / data sink, etc.
122 std::shared_ptr<ArchiveController> controller(
124
125 root_->setArchiveController(controller);
126 root_->initialize();
127
128 //Append a time stamp to the database directory we were given.
129 //This is a static string which will be the same for all archive
130 //sinks in the tempdir for this simulation.
131 const std::string & time_stamp = ArchiveDispatcher::getSimulationTimeStamp_();
132
133 std::unique_ptr<BinaryOArchive> sink(new BinaryOArchive);
134 sink->setPath(db_directory_ + "/" + time_stamp);
135 sink->setSubpath(db_subdirectory_);
136 sink->setRoot(root_);
137 sink->initialize();
138 addStatisticsSink(std::move(sink));
139 }
140
141 std::shared_ptr<RootArchiveNode> getRoot() {
142 return root_;
143 }
144
145 private:
146 const std::string db_directory_;
147 const std::string db_subdirectory_;
148 std::shared_ptr<RootArchiveNode> root_;
149 };
150
151 //Copy all archive files that belong to an ongoing data sink,
152 //and put the copies in the given directory. This does not
153 //invalidate the ongoing sink, or change any internal state
154 //in any way.
155 void copyArchiveToDirectory_(const ArchiveSink & original_sink,
156 const std::string & destination_dir) const
157 {
158 BinaryIArchive binary_source;
159 binary_source.setPath(original_sink.getPath());
160 binary_source.setSubpath(original_sink.getSubpath());
161 binary_source.initialize();
162
163 BinaryOArchive copied_sink;
164 copied_sink.setPath(destination_dir);
165 copied_sink.setSubpath(original_sink.getSubpath());
166 copied_sink.initialize();
167
168 while (true) {
169 const std::vector<double> & binary_data = binary_source.readFromSource();
170 if (binary_data.empty()) {
171 break;
172 }
173 copied_sink.sendToSink(binary_data);
174 }
175
176 copied_sink.copyMetadataFrom(&original_sink);
177 }
178
179 std::unique_ptr<ReportStatisticsDispatcher> dispatcher_;
180 bool dirty_ = true;
181};
182
183} // namespace statistics
184} // namespace sparta
185
This class holds exactly one generic ArchiveSource, and any number of generic ArchiveSink's.
Generic statistic sink base class for report archives.
Use a binary archive file as a source of statistics values.
Use a binary archive file as a destination for statistics values.
Controller used when SPARTA simulations are directly feeding data into a tempdir archive.
This class is a source of statistics values used by SPARTA simulators. It takes a sparta::Report obje...
This class coordinates live SPARTA simulations (source) with binary output archives (sink).
Macros for handling exponential backoff.