The Sparta Modeling Framework
Loading...
Searching...
No Matches
ArchiveNode.hpp
1// <ArchiveNode> -*- C++ -*-
2
3#pragma once
4
6
7#include <boost/serialization/vector.hpp>
8
9namespace sparta {
10namespace statistics {
11
12class ArchiveNode;
13class ArchiveDataSeries;
14class RootArchiveNode;
15
30{
31public:
37 ArchiveNode() = default;
38
40 ArchiveNode(const std::string & name);
41
48 ArchiveNode(const std::string & name,
49 const StatisticInstance *) :
50 ArchiveNode(name)
51 {}
52
57 ArchiveNode(const std::string & name,
58 const Report *) :
59 ArchiveNode(name)
60 {}
61
62 virtual ~ArchiveNode();
63
65 const std::string & getName() const {
66 return name_;
67 }
68
92 void setLeafIndex(const size_t index) {
93 leaf_index_ = index;
94 }
95
96 std::vector<std::shared_ptr<ArchiveNode>> & getChildren() {
97 return children_;
98 }
99
100 const std::vector<std::shared_ptr<ArchiveNode>> & getChildren() const {
101 return children_;
102 }
103
104 void setParent(std::shared_ptr<ArchiveNode> & parent) {
105 setParent(parent.get());
106 }
107
108 void setParent(ArchiveNode * parent) {
109 sparta_assert(parent_ == nullptr, "Cannot reassign parent archive nodes");
110 parent_ = parent;
111 }
112
122
127 bool isLeaf() const {
128 return children_.empty();
129 }
130
133 bool canAccessDataSeries() const {
134 return isLeaf() && leaf_index_.isValid();
135 }
136
142
161 size_t getTotalNumLeaves() const {
162 size_t num_leaves = (children_.empty() ? 1 : 0);
163 for (const auto & child : children_) {
164 recursGetTotalNumLeaves_(*child, num_leaves);
165 }
166 return num_leaves;
167 }
168
169protected:
174 std::string name_;
175
179 std::vector<std::shared_ptr<ArchiveNode>> children_;
180
181private:
182 void recursGetTotalNumLeaves_(
183 const ArchiveNode & node, size_t & num_leaves) const
184 {
185 if (node.children_.empty()) {
186 ++num_leaves;
187 } else {
188 for (const auto & child : node.children_) {
189 recursGetTotalNumLeaves_(*child, num_leaves);
190 }
191 }
192 }
193
205 template <class Archive>
206 void serialize(Archive & ar, const unsigned int) {
207 //Simple data types like strings and ints can
208 //call the operator& method directly
209 ar & name_;
210
211 //Our children variable is a vector<shared_ptr<ArchiveNode>>
212 //and Boost will call the serialize() method for each of those
213 //shared_ptr's. That method is at the bottom of this file. Shortly
214 //after calling serialize(Archive & ar, std::shared_ptr<ArchiveNode> & node)
215 //Boost will call this method we are in right now.
216 ar & children_;
217
218 //There are only so many serialization routines that you
219 //get for free (std::string, vectors/lists/maps of simple
220 //types, PODs, etc.) but ValidValue<T> is not one of them.
221 //This serialize() method is at the bottom of this file.
222 ar & leaf_index_;
223 }
224
225 RootArchiveNode * cached_root_ = nullptr;
226 ArchiveNode * parent_ = nullptr;
227 utils::ValidValue<size_t> leaf_index_;
228 std::unique_ptr<ArchiveDataSeries> ar_data_series_;
229};
230
238{
239public:
240 ArchiveDataSeries(const size_t leaf_index,
241 RootArchiveNode * root) :
242 leaf_index_(leaf_index),
243 root_(root)
244 {
245 sparta_assert(root_ != nullptr);
246 }
247
250 inline double getValueAt(const size_t idx) {
251 synchronize_();
252 return data_values_.at(idx);
253 }
254
256 const std::vector<double> & getDataReference() {
257 synchronize_();
258 return data_values_;
259 }
260
262 size_t size() {
263 synchronize_();
264 return data_values_.size();
265 }
266
268 bool empty() {
269 synchronize_();
270 return size() == 0;
271 }
272
273private:
274 //Read in the data archive and flip the dirty flag
275 //back to "not dirty"
276 void synchronize_();
277 void readAllDataFromArchive_();
278
279 std::vector<double> data_values_;
280 const size_t leaf_index_;
281 RootArchiveNode * root_ = nullptr;
282};
283
284} // namespace statistics
285} // namespace sparta
286
287namespace boost {
288namespace serialization {
289
291template <class Archive>
292void serialize(Archive & ar,
293 std::shared_ptr<sparta::statistics::ArchiveNode> & node,
294 const unsigned int)
295{
296 if (node == nullptr) {
297 node.reset(new sparta::statistics::ArchiveNode);
298 }
299 ar & *node;
300}
301
303template <class Archive>
304void serialize(Archive & ar,
306 const unsigned int)
307{
308 if (vv.isValid()) {
309 ar & vv.getValue();
310 } else {
311 size_t value = 0;
312 ar & value;
313 vv = value;
314 }
315}
316
317} // namespace serialization
318} // namespace boost
319
Describes reports to instantiate and tracks their instantiations.
#define sparta_assert(...)
Simple variadic assertion that will throw a sparta_exception if the condition fails.
Instance of either a StatisticDef or CounterBase or an Expression. Has a sample window (simulator tic...
Wrapper around a leaf ArchiveNode's data. Owns a back pointer to the top RootArchiveNode in its tree,...
bool empty()
See if there are any SI data values at all.
size_t size()
Get the size of the SI data array.
const std::vector< double > & getDataReference()
Get the entire SI data array.
double getValueAt(const size_t idx)
When a simulation is configured to archive its statistics values, it will build a subset of its devic...
ArchiveNode(const std::string &name, const Report *)
std::vector< std::shared_ptr< ArchiveNode > > children_
ArchiveNode(const std::string &name)
Construct a named node.
void setLeafIndex(const size_t index)
ArchiveDataSeries * createDataSeries()
ArchiveNode(const std::string &name, const StatisticInstance *)
const std::string & getName() const
Return the name that this node was originally created with.
friend class boost::serialization::access
RootArchiveNode * getRoot()
There is one of these root node objects at the top of each report's archive. The hierarchy looks like...
Provides a wrapper around a value to ensure that the value is assigned.
const value_type & getValue() const
Get the value - const version.
bool isValid() const
Is this value valid.
Macros for handling exponential backoff.