The Sparta Modeling Framework
Loading...
Searching...
No Matches
EnumHistogram.hpp
Go to the documentation of this file.
1// <EnumHistogram.hpp> -*- C++ -*-
2
3
9#pragma once
10
11#include <iostream>
12#include <string>
13#include <vector>
14#include "sparta/utils/MathUtils.hpp"
17#include "sparta/statistics/Counter.hpp"
21
22namespace sparta
23{
36template <class EnumType>
37class EnumHistogram : public TreeNode
38{
39public:
40 typedef EnumType value_type;
41
45 EnumHistogram() = delete;
46
50 EnumHistogram(const EnumHistogram&) = delete;
51
56
60 void operator=(const EnumHistogram&) = delete;
61
76 EnumHistogram(TreeNode* parent_treenode,
77 std::string histogram_name,
78 std::string description
79 ) :
80 TreeNode(histogram_name,
81 description),
82 lower_val_(static_cast<uint64_t>(EnumType::__FIRST)),
83 upper_val_(static_cast<uint64_t>(EnumType::__LAST ) - 1),
84 num_vals_per_bin_(1),
85 stats_(this),
86 total_(&stats_,
87 "total",
88 "Total values added to the histogram",
89 Counter::COUNT_NORMAL)
90 {
91 if(parent_treenode){
92 setExpectedParent_(parent_treenode);
93 }
94
95 sparta_assert_context(upper_val_ > lower_val_,
96 "Histogram: upper value must be greater than lower value");
97 sparta_assert_context(utils::is_power_of_2(num_vals_per_bin_),
98 "Histogram: num_vals_per_bin must be power of 2");
99 idx_shift_amount_ = utils::floor_log2(num_vals_per_bin_); // for quick devide
100 double actual_num_bins = (upper_val_ - lower_val_)/num_vals_per_bin_ + 1;
101 num_bins_ = (uint64_t) actual_num_bins;
102 sparta_assert_context(actual_num_bins == num_bins_,
103 "Histogram: Actual number of bins (" << actual_num_bins
104 << ") is not an integer");
105
106 // Reserve to use emplacement without tree child reordering
107 bin_.reserve(num_bins_);
108
109 underflow_bin_ = &stats_.createCounter<sparta::Counter>("UF",
110 "underflow bin",
112 underflow_probability_.reset(new StatisticDef(&stats_,
113 "UF_probability",
114 "Probability of underflow",
115 &stats_,
116 "UF/total"));
117 uint64_t start_val = lower_val_;
118 uint64_t end_val = start_val + num_vals_per_bin_ - 1;
119 for (uint32_t i=0; i<num_bins_; ++i) {
120 if (end_val > upper_val_)
121 end_val = upper_val_;
122 std::stringstream str;
123 str << "bin_" << std::string(typename sparta::utils::Enum<EnumType>::Value(static_cast<EnumType>(start_val))) << "_" << end_val;
124 bin_.emplace_back(sparta::Counter(&stats_,
125 str.str(),
126 str.str() + " histogram bin",
128 probabilities_.emplace_back(new StatisticDef(&stats_,
129 str.str() + "_probability",
130 str.str() + " bin probability",
131 &stats_,
132 str.str() + "/total"));
133 start_val = end_val + 1;
134 end_val += num_vals_per_bin_;
135 }
136 overflow_bin_ = &stats_.createCounter<sparta::Counter>("OF",
137 "overflow bin",
139 overflow_probability_.reset(new StatisticDef(&stats_,
140 "OF_probability",
141 "Probability of overflow",
142 &stats_,
143 "OF/total"));
144
145 if(parent_treenode){
146 parent_treenode->addChild(this);
147 }
148 }
149
156 void addValue(EnumType enum_val)
157 {
158 uint64_t val = static_cast<uint64_t>(enum_val);
159 ++total_;
160
161 if (val < lower_val_) {
162 ++ (*underflow_bin_);
163 }
164 else if (val > upper_val_) {
165 ++ (*overflow_bin_);
166 }
167 else {
168 uint32_t idx = (val - lower_val_) >> idx_shift_amount_;
169 ++ (bin_.at(idx));
170 }
171 }
172
173 uint64_t getHistogramUpperValue() const { return upper_val_; }
174 uint64_t getHistogramLowerValue() const { return lower_val_; }
175 uint32_t getNumBins() const { return num_bins_; }
176 uint32_t getNumValuesPerBin() const { return num_vals_per_bin_; }
177
182 std::string getDisplayStringCumulative() const
183 {
184 std::stringstream str;
185 str << std::dec;
186 uint64_t running_sum = *underflow_bin_;
187 str << "\t" << getName() << "[ UF ] = " << running_sum << std::endl;
188 uint64_t start_val = lower_val_;
189 uint64_t end_val = start_val + num_vals_per_bin_ - 1;
190 for (uint32_t i=0; i<num_bins_; ++i) {
191 if (end_val > upper_val_)
192 end_val = upper_val_;
193 running_sum += (bin_[i]);
194 str << "\t" << getName()
195 << "[ " << std::string(typename sparta::utils::Enum<EnumType>::Value(static_cast<EnumType>(start_val))) << "-"
196 << std::string(typename sparta::utils::Enum<EnumType>::Value(static_cast<EnumType>(end_val))) << " ] = "
197 << running_sum << std::endl;
198 end_val += num_vals_per_bin_;
199 }
200 running_sum += *overflow_bin_;
201 str << "\t" << getName() << "[ OF ] = " << running_sum << std::endl;
202 return str.str();
203 }
204
205private:
206 const uint64_t lower_val_;
207 const uint64_t upper_val_;
208 const uint32_t num_vals_per_bin_;
209
210 sparta::StatisticSet stats_;
211 sparta::Counter total_;
212 sparta::Counter* underflow_bin_;
213 sparta::Counter* overflow_bin_;
214 std::vector<sparta::Counter> bin_;
215 std::unique_ptr<sparta::StatisticDef> underflow_probability_;
216 std::unique_ptr<sparta::StatisticDef> overflow_probability_;
217 std::vector<std::unique_ptr<sparta::StatisticDef>> probabilities_;
218
219 uint32_t num_bins_;
220
224 uint32_t idx_shift_amount_;
225
226}; // class EnumHistogram
227
228} // namespace sparta
File that defines the Resource class. Consider using sparta::Unit instead.
#define sparta_assert_context(e, insertions)
Check condition and throw a sparta exception if condition evaluates to false or 0....
Definition Resource.hpp:402
Set of macros for Sparta assertions. Caught by the framework.
Contains a statistic definition (some useful information which can be computed)
File that defines the StatisticSet class.
Basic Node framework in sparta device tree composite pattern.
@ COUNT_NORMAL
Counter counts the number of times something happens like one would expect. This is a weakly monotoni...
Represents a counter of type counter_type (uint64_t). 2 and greater than 0 with a ceiling specified....
Definition Counter.hpp:27
EnumHistogram class for sparta::utils::Enum.
EnumHistogram(EnumHistogram &&)=delete
Not move-constructable.
void addValue(EnumType enum_val)
Add a value to histogram.
void operator=(const EnumHistogram &)=delete
Not assignable.
std::string getDisplayStringCumulative() const
Render the cumulative values of this histogram for use in standalone model.
EnumHistogram(const EnumHistogram &)=delete
Not copy-constructable.
EnumHistogram(TreeNode *parent_treenode, std::string histogram_name, std::string description)
EnumHistogram constructor.
EnumHistogram()=delete
Not default constructable.
Contains a statistic definition (some useful information which can be computed)
Set of StatisticDef and CounterBase-derived objects for visiblility through a sparta Tree.
CounterT & createCounter(_Args &&... __args)
Allocates a Counter which is owned by this StatisticSet and deleted at its destruction.
Node in a composite tree representing a sparta Tree item.
Definition TreeNode.hpp:205
void addChild(TreeNode *child, bool inherit_phase=true)
Adds a TreeNode to this node as a child.
const std::string & getName() const override
Gets the name of this node.
void setExpectedParent_(const TreeNode *parent)
Tracks a node as an expected parent without actually adding this node as a child. This is used almost...
Macros for handling exponential backoff.