2 * Copyright (c) 2003-2005 The Regents of The University of Michigan
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met: redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer;
9 * redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution;
12 * neither the name of the copyright holders nor the names of its
13 * contributors may be used to endorse or promote products derived from
14 * this software without specific prior written permission.
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 * Declaration of Statistics objects.
36 * Generalized N-dimensinal vector
40 * -- these both can use the same function that prints out a
41 * specific set of stats
42 * VectorStandardDeviation totals
45 #ifndef __BASE_STATISTICS_HH__
46 #define __BASE_STATISTICS_HH__
57 #include "base/cprintf.hh"
58 #include "base/intmath.hh"
59 #include "base/refcnt.hh"
60 #include "base/str.hh"
61 #include "base/stats/bin.hh"
62 #include "base/stats/flags.hh"
63 #include "base/stats/visit.hh"
64 #include "base/stats/types.hh"
65 #include "config/stats_binning.hh"
66 #include "sim/host.hh"
70 /** The current simulated cycle. */
73 /* A namespace for all of the Statistics */
76 /* Contains the statistic implementation details */
77 //////////////////////////////////////////////////////////////////////
79 // Statistics Framework Base classes
81 //////////////////////////////////////////////////////////////////////
84 /** The name of the stat. */
86 /** The description of the stat. */
88 /** The formatting flags. */
90 /** The display precision. */
92 /** A pointer to a prerequisite Stat. */
93 const StatData *prereq;
95 * A unique stat ID for each stat in the simulator.
96 * Can be used externally for lookups as well as for debugging.
104 * @return true if the stat is binned.
106 virtual bool binned() const = 0;
109 * Reset the corresponding stat to the default state.
111 virtual void reset() = 0;
114 * @return true if this stat has a value and satisfies its
115 * requirement as a prereq
117 virtual bool zero() const = 0;
120 * Check that this stat has been set up properly and is ready for
122 * @return true for success
124 virtual bool check() const = 0;
125 bool baseCheck() const;
128 * Visitor entry for outputing statistics data
130 virtual void visit(Visit &visitor) = 0;
133 * Checks if the first stat's name is alphabetically less than the second.
134 * This function breaks names up at periods and considers each subname
136 * @param stat1 The first stat.
137 * @param stat2 The second stat.
138 * @return stat1's name is alphabetically before stat2's
140 static bool less(StatData *stat1, StatData *stat2);
143 class ScalarData : public StatData
146 virtual Counter value() const = 0;
147 virtual Result result() const = 0;
148 virtual Result total() const = 0;
149 virtual void visit(Visit &visitor) { visitor.visit(*this); }
152 template <class Stat>
153 class ScalarStatData : public ScalarData
159 ScalarStatData(Stat &stat) : s(stat) {}
161 virtual bool binned() const { return s.binned(); }
162 virtual bool check() const { return s.check(); }
163 virtual Counter value() const { return s.value(); }
164 virtual Result result() const { return s.result(); }
165 virtual Result total() const { return s.total(); }
166 virtual void reset() { s.reset(); }
167 virtual bool zero() const { return s.zero(); }
170 struct VectorData : public StatData
172 /** Names and descriptions of subfields. */
173 mutable std::vector<std::string> subnames;
174 mutable std::vector<std::string> subdescs;
176 virtual size_t size() const = 0;
177 virtual const VCounter &value() const = 0;
178 virtual const VResult &result() const = 0;
179 virtual Result total() const = 0;
182 if (!subnames.empty()) {
184 if (subnames.size() < s)
187 if (subdescs.size() < s)
193 template <class Stat>
194 class VectorStatData : public VectorData
198 mutable VCounter cvec;
199 mutable VResult rvec;
202 VectorStatData(Stat &stat) : s(stat) {}
204 virtual bool binned() const { return s.binned(); }
205 virtual bool check() const { return s.check(); }
206 virtual bool zero() const { return s.zero(); }
207 virtual void reset() { s.reset(); }
209 virtual size_t size() const { return s.size(); }
210 virtual VCounter &value() const
215 virtual const VResult &result() const
220 virtual Result total() const { return s.total(); }
221 virtual void visit(Visit &visitor)
225 visitor.visit(*this);
247 struct DistData : public StatData
249 /** Local storage for the entry values, used for printing. */
253 template <class Stat>
254 class DistStatData : public DistData
260 DistStatData(Stat &stat) : s(stat) {}
262 virtual bool binned() const { return s.binned(); }
263 virtual bool check() const { return s.check(); }
264 virtual void reset() { s.reset(); }
265 virtual bool zero() const { return s.zero(); }
266 virtual void visit(Visit &visitor)
269 visitor.visit(*this);
273 struct VectorDistData : public StatData
275 std::vector<DistDataData> data;
277 /** Names and descriptions of subfields. */
278 mutable std::vector<std::string> subnames;
279 mutable std::vector<std::string> subdescs;
281 /** Local storage for the entry values, used for printing. */
282 mutable VResult rvec;
284 virtual size_t size() const = 0;
288 if (subnames.size() < s)
291 if (subdescs.size() < s)
296 template <class Stat>
297 class VectorDistStatData : public VectorDistData
301 typedef typename Stat::bin_t bin_t;
304 VectorDistStatData(Stat &stat) : s(stat) {}
306 virtual bool binned() const { return bin_t::binned; }
307 virtual bool check() const { return s.check(); }
308 virtual void reset() { s.reset(); }
309 virtual size_t size() const { return s.size(); }
310 virtual bool zero() const { return s.zero(); }
311 virtual void visit(Visit &visitor)
315 visitor.visit(*this);
319 struct Vector2dData : public StatData
321 /** Names and descriptions of subfields. */
322 std::vector<std::string> subnames;
323 std::vector<std::string> subdescs;
324 std::vector<std::string> y_subnames;
326 /** Local storage for the entry values, used for printing. */
327 mutable VCounter cvec;
333 if (subnames.size() < x)
338 template <class Stat>
339 class Vector2dStatData : public Vector2dData
343 typedef typename Stat::bin_t bin_t;
346 Vector2dStatData(Stat &stat) : s(stat) {}
348 virtual bool binned() const { return bin_t::binned; }
349 virtual bool check() const { return s.check(); }
350 virtual void reset() { s.reset(); }
351 virtual bool zero() const { return s.zero(); }
352 virtual void visit(Visit &visitor)
356 visitor.visit(*this);
364 StatData *find() const;
365 void map(StatData *data);
367 StatData *statData();
368 const StatData *statData() const;
374 template <class Parent, class Child, template <class> class Data>
375 class Wrap : public Child
378 Parent &self() { return *reinterpret_cast<Parent *>(this); }
381 Data<Child> *statData()
383 StatData *__data = DataAccess::statData();
384 Data<Child> *ptr = dynamic_cast<Data<Child> *>(__data);
390 const Data<Child> *statData() const
392 const StatData *__data = DataAccess::statData();
393 const Data<Child> *ptr = dynamic_cast<const Data<Child> *>(__data);
400 * Copy constructor, copies are not allowed.
402 Wrap(const Wrap &stat);
406 void operator=(const Wrap &);
411 map(new Data<Child>(*this));
415 * Set the name and marks this stat to print at the end of simulation.
416 * @param name The new name.
417 * @return A reference to this stat.
419 Parent &name(const std::string &_name)
421 Data<Child> *data = this->statData();
428 * Set the description and marks this stat to print at the end of
430 * @param desc The new description.
431 * @return A reference to this stat.
433 Parent &desc(const std::string &_desc)
435 this->statData()->desc = _desc;
440 * Set the precision and marks this stat to print at the end of simulation.
441 * @param p The new precision
442 * @return A reference to this stat.
444 Parent &precision(int _precision)
446 this->statData()->precision = _precision;
451 * Set the flags and marks this stat to print at the end of simulation.
452 * @param f The new flags.
453 * @return A reference to this stat.
455 Parent &flags(StatFlags _flags)
457 this->statData()->flags |= _flags;
462 * Set the prerequisite stat and marks this stat to print at the end of
464 * @param prereq The prerequisite stat.
465 * @return A reference to this stat.
467 template <class Stat>
468 Parent &prereq(const Stat &prereq)
470 this->statData()->prereq = prereq.statData();
475 template <class Parent, class Child, template <class Child> class Data>
476 class WrapVec : public Wrap<Parent, Child, Data>
479 // The following functions are specific to vectors. If you use them
480 // in a non vector context, you will get a nice compiler error!
483 * Set the subfield name for the given index, and marks this stat to print
484 * at the end of simulation.
485 * @param index The subfield index.
486 * @param name The new name of the subfield.
487 * @return A reference to this stat.
489 Parent &subname(int index, const std::string &name)
491 std::vector<std::string> &subn = this->statData()->subnames;
492 if (subn.size() <= index)
493 subn.resize(index + 1);
499 * Set the subfield description for the given index and marks this stat to
500 * print at the end of simulation.
501 * @param index The subfield index.
502 * @param desc The new description of the subfield
503 * @return A reference to this stat.
505 Parent &subdesc(int index, const std::string &desc)
507 std::vector<std::string> &subd = this->statData()->subdescs;
508 if (subd.size() <= index)
509 subd.resize(index + 1);
517 template <class Parent, class Child, template <class Child> class Data>
518 class WrapVec2d : public WrapVec<Parent, Child, Data>
522 * @warning This makes the assumption that if you're gonna subnames a 2d
523 * vector, you're subnaming across all y
525 Parent &ysubnames(const char **names)
527 Data<Child> *data = this->statData();
528 data->y_subnames.resize(this->y);
529 for (int i = 0; i < this->y; ++i)
530 data->y_subnames[i] = names[i];
533 Parent &ysubname(int index, const std::string subname)
535 Data<Child> *data = this->statData();
536 assert(index < this->y);
537 data->y_subnames.resize(this->y);
538 data->y_subnames[index] = subname.c_str();
543 //////////////////////////////////////////////////////////////////////
547 //////////////////////////////////////////////////////////////////////
550 * Templatized storage and interface for a simple scalar stat.
555 /** The paramaters for this storage type, none for a scalar. */
559 /** The statistic value. */
564 * Builds this storage element and calls the base constructor of the
567 StatStor(const Params &) : data(Counter()) {}
570 * The the stat to the given value.
571 * @param val The new value.
572 * @param p The paramters of this storage type.
574 void set(Counter val, const Params &p) { data = val; }
576 * Increment the stat by the given value.
577 * @param val The new value.
578 * @param p The paramters of this storage type.
580 void inc(Counter val, const Params &p) { data += val; }
582 * Decrement the stat by the given value.
583 * @param val The new value.
584 * @param p The paramters of this storage type.
586 void dec(Counter val, const Params &p) { data -= val; }
588 * Return the value of this stat as its base type.
589 * @param p The params of this storage type.
590 * @return The value of this stat.
592 Counter value(const Params &p) const { return data; }
594 * Return the value of this stat as a result type.
595 * @param p The parameters of this storage type.
596 * @return The value of this stat.
598 Result result(const Params &p) const { return (Result)data; }
600 * Reset stat value to default
602 void reset() { data = Counter(); }
605 * @return true if zero value
607 bool zero() const { return data == Counter(); }
611 * Templatized storage and interface to a per-cycle average stat. This keeps
612 * a current count and updates a total (count * cycles) when this count
613 * changes. This allows the quick calculation of a per cycle count of the item
614 * being watched. This is good for keeping track of residencies in structures
615 * among other things.
616 * @todo add lateny to the stat and fix binning.
621 /** The paramaters for this storage type */
625 * The current count. We stash this here because the current
626 * value is not a binned value.
632 /** The total count for all cycles. */
633 mutable Result total;
634 /** The cycle that current last changed. */
639 * Build and initializes this stat storage.
641 AvgStor(Params &p) : total(0), last(0) { p.current = Counter(); }
644 * Set the current count to the one provided, update the total and last
646 * @param val The new count.
647 * @param p The parameters for this storage.
649 void set(Counter val, Params &p) {
650 total += p.current * (curTick - last);
656 * Increment the current count by the provided value, calls set.
657 * @param val The amount to increment.
658 * @param p The parameters for this storage.
660 void inc(Counter val, Params &p) { set(p.current + val, p); }
663 * Deccrement the current count by the provided value, calls set.
664 * @param val The amount to decrement.
665 * @param p The parameters for this storage.
667 void dec(Counter val, Params &p) { set(p.current - val, p); }
670 * Return the current count.
671 * @param p The parameters for this storage.
672 * @return The current count.
674 Counter value(const Params &p) const { return p.current; }
677 * Return the current average.
678 * @param p The parameters for this storage.
679 * @return The current average.
681 Result result(const Params &p) const
683 total += p.current * (curTick - last);
685 return (Result)(total + p.current) / (Result)(curTick + 1);
689 * Reset stat value to default
698 * @return true if zero value
700 bool zero() const { return total == 0.0; }
704 * Implementation of a scalar stat. The type of stat is determined by the
705 * Storage template. The storage for this stat is held within the Bin class.
706 * This allows for breaking down statistics across multiple bins easily.
708 template <class Storage, class Bin>
709 class ScalarBase : public DataAccess
712 /** Define the params of the storage class. */
713 typedef typename Storage::Params params_t;
714 /** Define the bin type. */
715 typedef typename Bin::template Bin<Storage> bin_t;
718 /** The bin of this stat. */
720 /** The parameters for this stat. */
725 * Retrieve the storage from the bin.
726 * @return The storage object for this stat.
728 Storage *data() { return bin.data(params); }
730 * Retrieve a const pointer to the storage from the bin.
731 * @return A const pointer to the storage object for this stat.
733 const Storage *data() const
735 bin_t *_bin = const_cast<bin_t *>(&bin);
736 params_t *_params = const_cast<params_t *>(¶ms);
737 return _bin->data(*_params);
742 * Return the current value of this stat as its base type.
743 * @return The current value.
745 Counter value() const { return data()->value(params); }
749 * Create and initialize this stat, register it with the database.
757 // Common operators for stats
759 * Increment the stat by 1. This calls the associated storage object inc
762 void operator++() { data()->inc(1, params); }
764 * Decrement the stat by 1. This calls the associated storage object dec
767 void operator--() { data()->dec(1, params); }
769 /** Increment the stat by 1. */
770 void operator++(int) { ++*this; }
771 /** Decrement the stat by 1. */
772 void operator--(int) { --*this; }
775 * Set the data value to the given value. This calls the associated storage
776 * object set function.
777 * @param v The new value.
779 template <typename U>
780 void operator=(const U &v) { data()->set(v, params); }
783 * Increment the stat by the given value. This calls the associated
784 * storage object inc function.
785 * @param v The value to add.
787 template <typename U>
788 void operator+=(const U &v) { data()->inc(v, params); }
791 * Decrement the stat by the given value. This calls the associated
792 * storage object dec function.
793 * @param v The value to substract.
795 template <typename U>
796 void operator-=(const U &v) { data()->dec(v, params); }
799 * Return the number of elements, always 1 for a scalar.
802 size_t size() const { return 1; }
804 * Return true if stat is binned.
805 *@return True is stat is binned.
807 bool binned() const { return bin_t::binned; }
809 bool check() const { return bin.initialized(); }
812 * Reset stat value to default
814 void reset() { bin.reset(); }
816 Counter value() { return data()->value(params); }
818 Result result() { return data()->result(params); }
820 Result total() { return result(); }
822 bool zero() { return result() == 0.0; }
826 class ProxyData : public ScalarData
829 virtual void visit(Visit &visitor) { visitor.visit(*this); }
830 virtual bool binned() const { return false; }
831 virtual std::string str() const { return to_string(value()); }
832 virtual size_t size() const { return 1; }
833 virtual bool zero() const { return value() == 0; }
834 virtual bool check() const { return true; }
835 virtual void reset() { }
839 class ValueProxy : public ProxyData
845 ValueProxy(T &val) : scalar(&val) {}
846 virtual Counter value() const { return *scalar; }
847 virtual Result result() const { return *scalar; }
848 virtual Result total() const { return *scalar; }
852 class FunctorProxy : public ProxyData
858 FunctorProxy(T &func) : functor(&func) {}
859 virtual Counter value() const { return (*functor)(); }
860 virtual Result result() const { return (*functor)(); }
861 virtual Result total() const { return (*functor)(); }
864 class ValueBase : public DataAccess
870 ValueBase() : proxy(NULL) { }
871 ~ValueBase() { if (proxy) delete proxy; }
874 void scalar(T &value)
876 proxy = new ValueProxy<T>(value);
881 void functor(T &func)
883 proxy = new FunctorProxy<T>(func);
887 Counter value() { return proxy->value(); }
888 Result result() const { return proxy->result(); }
889 Result total() const { return proxy->total(); };
890 size_t size() const { return proxy->size(); }
892 bool binned() const { return proxy->binned(); }
893 std::string str() const { return proxy->str(); }
894 bool zero() const { return proxy->zero(); }
895 bool check() const { return proxy != NULL; }
899 //////////////////////////////////////////////////////////////////////
903 //////////////////////////////////////////////////////////////////////
904 template <class Storage, class Bin>
908 * Implementation of a vector of stats. The type of stat is determined by the
909 * Storage class. @sa ScalarBase
911 template <class Storage, class Bin>
912 class VectorBase : public DataAccess
915 /** Define the params of the storage class. */
916 typedef typename Storage::Params params_t;
917 /** Define the bin type. */
918 typedef typename Bin::template VectorBin<Storage> bin_t;
921 /** The bin of this stat. */
923 /** The parameters for this stat. */
928 * Retrieve the storage from the bin for the given index.
929 * @param index The vector index to access.
930 * @return The storage object at the given index.
932 Storage *data(int index) { return bin.data(index, params); }
934 * Retrieve a const pointer to the storage from the bin
935 * for the given index.
936 * @param index The vector index to access.
937 * @return A const pointer to the storage object at the given index.
939 const Storage *data(int index) const
941 bin_t *_bin = const_cast<bin_t *>(&bin);
942 params_t *_params = const_cast<params_t *>(¶ms);
943 return _bin->data(index, *_params);
947 void value(VCounter &vec) const
950 for (int i = 0; i < size(); ++i)
951 vec[i] = data(i)->value(params);
955 * Copy the values to a local vector and return a reference to it.
956 * @return A reference to a vector of the stat values.
958 void result(VResult &vec) const
961 for (int i = 0; i < size(); ++i)
962 vec[i] = data(i)->result(params);
966 * @return True is stat is binned.
968 bool binned() const { return bin_t::binned; }
971 * Return a total of all entries in this vector.
972 * @return The total of all vector entries.
974 Result total() const {
976 for (int i = 0; i < size(); ++i)
977 total += data(i)->result(params);
982 * @return the number of elements in this vector.
984 size_t size() const { return bin.size(); }
988 for (int i = 0; i < size(); ++i)
994 bool check() const { return bin.initialized(); }
995 void reset() { bin.reset(); }
1000 /** Friend this class with the associated scalar proxy. */
1001 friend class ScalarProxy<Storage, Bin>;
1004 * Return a reference (ScalarProxy) to the stat at the given index.
1005 * @param index The vector index to access.
1006 * @return A reference of the stat.
1008 ScalarProxy<Storage, Bin> operator[](int index);
1010 void update(StatData *data) {}
1013 const StatData * getStatData(const void *stat);
1016 * A proxy class to access the stat at a given index in a VectorBase stat.
1017 * Behaves like a ScalarBase.
1019 template <class Storage, class Bin>
1023 /** Define the params of the storage class. */
1024 typedef typename Storage::Params params_t;
1025 /** Define the bin type. */
1026 typedef typename Bin::template VectorBin<Storage> bin_t;
1029 /** Pointer to the bin in the parent VectorBase. */
1031 /** Pointer to the params in the parent VectorBase. */
1033 /** The index to access in the parent VectorBase. */
1035 /** Keep a pointer to the original stat so was can get data */
1040 * Retrieve the storage from the bin.
1041 * @return The storage from the bin for this stat.
1043 Storage *data() { return bin->data(index, *params); }
1045 * Retrieve a const pointer to the storage from the bin.
1046 * @return A const pointer to the storage for this stat.
1048 const Storage *data() const
1050 bin_t *_bin = const_cast<bin_t *>(bin);
1051 params_t *_params = const_cast<params_t *>(params);
1052 return _bin->data(index, *_params);
1057 * Return the current value of this stat as its base type.
1058 * @return The current value.
1060 Counter value() const { return data()->value(*params); }
1063 * Return the current value of this statas a result type.
1064 * @return The current value.
1066 Result result() const { return data()->result(*params); }
1070 * Create and initialize this proxy, do not register it with the database.
1071 * @param b The bin to use.
1072 * @param p The params to use.
1073 * @param i The index to access.
1075 ScalarProxy(bin_t &b, params_t &p, int i, void *s)
1076 : bin(&b), params(&p), index(i), stat(s) {}
1078 * Create a copy of the provided ScalarProxy.
1079 * @param sp The proxy to copy.
1081 ScalarProxy(const ScalarProxy &sp)
1082 : bin(sp.bin), params(sp.params), index(sp.index), stat(sp.stat) {}
1084 * Set this proxy equal to the provided one.
1085 * @param sp The proxy to copy.
1086 * @return A reference to this proxy.
1088 const ScalarProxy &operator=(const ScalarProxy &sp) {
1097 // Common operators for stats
1099 * Increment the stat by 1. This calls the associated storage object inc
1102 void operator++() { data()->inc(1, *params); }
1104 * Decrement the stat by 1. This calls the associated storage object dec
1107 void operator--() { data()->dec(1, *params); }
1109 /** Increment the stat by 1. */
1110 void operator++(int) { ++*this; }
1111 /** Decrement the stat by 1. */
1112 void operator--(int) { --*this; }
1115 * Set the data value to the given value. This calls the associated storage
1116 * object set function.
1117 * @param v The new value.
1119 template <typename U>
1120 void operator=(const U &v) { data()->set(v, *params); }
1123 * Increment the stat by the given value. This calls the associated
1124 * storage object inc function.
1125 * @param v The value to add.
1127 template <typename U>
1128 void operator+=(const U &v) { data()->inc(v, *params); }
1131 * Decrement the stat by the given value. This calls the associated
1132 * storage object dec function.
1133 * @param v The value to substract.
1135 template <typename U>
1136 void operator-=(const U &v) { data()->dec(v, *params); }
1139 * Return the number of elements, always 1 for a scalar.
1142 size_t size() const { return 1; }
1145 * Return true if stat is binned.
1146 *@return false since Proxies aren't printed/binned
1148 bool binned() const { return false; }
1151 * This stat has no state. Nothing to reset
1156 const StatData *statData() const { return getStatData(stat); }
1157 std::string str() const
1159 return csprintf("%s[%d]", this->statData()->name, index);
1164 template <class Storage, class Bin>
1165 inline ScalarProxy<Storage, Bin>
1166 VectorBase<Storage, Bin>::operator[](int index)
1168 assert (index >= 0 && index < size());
1169 return ScalarProxy<Storage, Bin>(bin, params, index, this);
1172 template <class Storage, class Bin>
1175 template <class Storage, class Bin>
1176 class Vector2dBase : public DataAccess
1179 typedef typename Storage::Params params_t;
1180 typedef typename Bin::template VectorBin<Storage> bin_t;
1189 Storage *data(int index) { return bin.data(index, params); }
1190 const Storage *data(int index) const
1192 bin_t *_bin = const_cast<bin_t *>(&bin);
1193 params_t *_params = const_cast<params_t *>(¶ms);
1194 return _bin->data(index, *_params);
1200 void update(Vector2dData *data)
1202 int size = this->size();
1203 data->cvec.resize(size);
1204 for (int i = 0; i < size; ++i)
1205 data->cvec[i] = this->data(i)->value(params);
1208 std::string ysubname(int i) const { return (*this->y_subnames)[i]; }
1210 friend class VectorProxy<Storage, Bin>;
1211 VectorProxy<Storage, Bin> operator[](int index);
1213 size_t size() const { return bin.size(); }
1214 bool zero() const { return data(0)->value(params) == 0.0; }
1217 * Reset stat value to default
1219 void reset() { bin.reset(); }
1221 bool check() { return bin.initialized(); }
1224 template <class Storage, class Bin>
1228 typedef typename Storage::Params params_t;
1229 typedef typename Bin::template VectorBin<Storage> bin_t;
1239 mutable VResult *vec;
1241 Storage *data(int index) {
1242 assert(index < len);
1243 return bin->data(offset + index, *params);
1246 const Storage *data(int index) const {
1247 bin_t *_bin = const_cast<bin_t *>(bin);
1248 params_t *_params = const_cast<params_t *>(params);
1249 return _bin->data(offset + index, *_params);
1253 const VResult &result() const {
1255 vec->resize(size());
1257 vec = new VResult(size());
1259 for (int i = 0; i < size(); ++i)
1260 (*vec)[i] = data(i)->result(*params);
1265 Result total() const {
1267 for (int i = 0; i < size(); ++i)
1268 total += data(i)->result(*params);
1273 VectorProxy(bin_t &b, params_t &p, int o, int l, void *s)
1274 : bin(&b), params(&p), offset(o), len(l), stat(s), vec(NULL)
1278 VectorProxy(const VectorProxy &sp)
1279 : bin(sp.bin), params(sp.params), offset(sp.offset), len(sp.len),
1280 stat(sp.stat), vec(NULL)
1290 const VectorProxy &operator=(const VectorProxy &sp)
1303 ScalarProxy<Storage, Bin> operator[](int index)
1305 assert (index >= 0 && index < size());
1306 return ScalarProxy<Storage, Bin>(*bin, *params, offset + index, stat);
1309 size_t size() const { return len; }
1312 * Return true if stat is binned.
1313 *@return false since Proxies aren't printed/binned
1315 bool binned() const { return false; }
1318 * This stat has no state. Nothing to reset.
1323 template <class Storage, class Bin>
1324 inline VectorProxy<Storage, Bin>
1325 Vector2dBase<Storage, Bin>::operator[](int index)
1327 int offset = index * y;
1328 assert (index >= 0 && offset < size());
1329 return VectorProxy<Storage, Bin>(bin, params, offset, y, this);
1332 //////////////////////////////////////////////////////////////////////
1334 // Non formula statistics
1336 //////////////////////////////////////////////////////////////////////
1339 * Templatized storage and interface for a distrbution stat.
1344 /** The parameters for a distribution stat. */
1347 /** The minimum value to track. */
1349 /** The maximum value to track. */
1351 /** The number of entries in each bucket. */
1352 Counter bucket_size;
1353 /** The number of buckets. Equal to (max-min)/bucket_size. */
1356 enum { fancy = false };
1359 /** The smallest value sampled. */
1361 /** The largest value sampled. */
1363 /** The number of values sampled less than min. */
1365 /** The number of values sampled more than max. */
1367 /** The current sum. */
1369 /** The sum of squares. */
1371 /** The number of samples. */
1373 /** Counter for each bucket. */
1378 * Construct this storage with the supplied params.
1379 * @param params The parameters.
1381 DistStor(const Params ¶ms)
1382 : min_val(INT_MAX), max_val(INT_MIN), underflow(Counter()),
1383 overflow(Counter()), sum(Counter()), squares(Counter()),
1384 samples(Counter()), cvec(params.size)
1390 * Add a value to the distribution for the given number of times.
1391 * @param val The value to add.
1392 * @param number The number of times to add the value.
1393 * @param params The paramters of the distribution.
1395 void sample(Counter val, int number, const Params ¶ms)
1397 if (val < params.min)
1398 underflow += number;
1399 else if (val > params.max)
1402 int index = (int)floor((val - params.min) / params.bucket_size);
1403 assert(index < size(params));
1404 cvec[index] += number;
1413 Counter sample = val * number;
1415 squares += sample * sample;
1420 * Return the number of buckets in this distribution.
1421 * @return the number of buckets.
1422 * @todo Is it faster to return the size from the parameters?
1424 size_t size(const Params &) const { return cvec.size(); }
1427 * Returns true if any calls to sample have been made.
1428 * @param params The paramters of the distribution.
1429 * @return True if any values have been sampled.
1431 bool zero(const Params ¶ms) const
1433 return samples == Counter();
1436 void update(DistDataData *data, const Params ¶ms)
1438 data->min = params.min;
1439 data->max = params.max;
1440 data->bucket_size = params.bucket_size;
1441 data->size = params.size;
1443 data->min_val = (min_val == INT_MAX) ? 0 : min_val;
1444 data->max_val = (max_val == INT_MIN) ? 0 : max_val;
1445 data->underflow = underflow;
1446 data->overflow = overflow;
1447 data->cvec.resize(params.size);
1448 for (int i = 0; i < params.size; ++i)
1449 data->cvec[i] = cvec[i];
1452 data->squares = squares;
1453 data->samples = samples;
1457 * Reset stat value to default
1466 int size = cvec.size();
1467 for (int i = 0; i < size; ++i)
1468 cvec[i] = Counter();
1471 squares = Counter();
1472 samples = Counter();
1477 * Templatized storage and interface for a distribution that calculates mean
1484 * No paramters for this storage.
1487 enum { fancy = true };
1490 /** The current sum. */
1492 /** The sum of squares. */
1494 /** The number of samples. */
1499 * Create and initialize this storage.
1501 FancyStor(const Params &)
1502 : sum(Counter()), squares(Counter()), samples(Counter())
1506 * Add a value the given number of times to this running average.
1507 * Update the running sum and sum of squares, increment the number of
1508 * values seen by the given number.
1509 * @param val The value to add.
1510 * @param number The number of times to add the value.
1511 * @param p The parameters of this stat.
1513 void sample(Counter val, int number, const Params &p)
1515 Counter value = val * number;
1517 squares += value * value;
1521 void update(DistDataData *data, const Params ¶ms)
1524 data->squares = squares;
1525 data->samples = samples;
1529 * Return the number of entries in this stat, 1
1532 size_t size(const Params &) const { return 1; }
1535 * Return true if no samples have been added.
1536 * @return True if no samples have been added.
1538 bool zero(const Params &) const { return samples == Counter(); }
1541 * Reset stat value to default
1546 squares = Counter();
1547 samples = Counter();
1552 * Templatized storage for distribution that calculates per cycle mean and
1558 /** No parameters for this storage. */
1560 enum { fancy = true };
1563 /** Current total. */
1565 /** Current sum of squares. */
1570 * Create and initialize this storage.
1572 AvgFancy(const Params &) : sum(Counter()), squares(Counter()) {}
1575 * Add a value to the distribution for the given number of times.
1576 * Update the running sum and sum of squares.
1577 * @param val The value to add.
1578 * @param number The number of times to add the value.
1579 * @param p The paramters of the distribution.
1581 void sample(Counter val, int number, const Params &p)
1583 Counter value = val * number;
1585 squares += value * value;
1588 void update(DistDataData *data, const Params ¶ms)
1591 data->squares = squares;
1592 data->samples = curTick;
1596 * Return the number of entries, in this case 1.
1599 size_t size(const Params ¶ms) const { return 1; }
1601 * Return true if no samples have been added.
1602 * @return True if the sum is zero.
1604 bool zero(const Params ¶ms) const { return sum == Counter(); }
1606 * Reset stat value to default
1611 squares = Counter();
1616 * Implementation of a distribution stat. The type of distribution is
1617 * determined by the Storage template. @sa ScalarBase
1619 template <class Storage, class Bin>
1620 class DistBase : public DataAccess
1623 /** Define the params of the storage class. */
1624 typedef typename Storage::Params params_t;
1625 /** Define the bin type. */
1626 typedef typename Bin::template Bin<Storage> bin_t;
1629 /** The bin of this stat. */
1631 /** The parameters for this stat. */
1636 * Retrieve the storage from the bin.
1637 * @return The storage object for this stat.
1639 Storage *data() { return bin.data(params); }
1641 * Retrieve a const pointer to the storage from the bin.
1642 * @return A const pointer to the storage object for this stat.
1644 const Storage *data() const
1646 bin_t *_bin = const_cast<bin_t *>(&bin);
1647 params_t *_params = const_cast<params_t *>(¶ms);
1648 return _bin->data(*_params);
1655 * Add a value to the distribtion n times. Calls sample on the storage
1657 * @param v The value to add.
1658 * @param n The number of times to add it, defaults to 1.
1660 template <typename U>
1661 void sample(const U &v, int n = 1) { data()->sample(v, n, params); }
1664 * Return the number of entries in this stat.
1665 * @return The number of entries.
1667 size_t size() const { return data()->size(params); }
1669 * Return true if no samples have been added.
1670 * @return True if there haven't been any samples.
1672 bool zero() const { return data()->zero(params); }
1674 void update(DistData *base)
1676 base->data.fancy = Storage::fancy;
1677 data()->update(&(base->data), params);
1680 * @return True is stat is binned.
1682 bool binned() const { return bin_t::binned; }
1684 * Reset stat value to default
1691 bool check() { return bin.initialized(); }
1694 template <class Storage, class Bin>
1697 template <class Storage, class Bin>
1698 class VectorDistBase : public DataAccess
1701 typedef typename Storage::Params params_t;
1702 typedef typename Bin::template VectorBin<Storage> bin_t;
1709 Storage *data(int index) { return bin.data(index, params); }
1710 const Storage *data(int index) const
1712 bin_t *_bin = const_cast<bin_t *>(&bin);
1713 params_t *_params = const_cast<params_t *>(¶ms);
1714 return _bin->data(index, *_params);
1720 friend class DistProxy<Storage, Bin>;
1721 DistProxy<Storage, Bin> operator[](int index);
1722 const DistProxy<Storage, Bin> operator[](int index) const;
1724 size_t size() const { return bin.size(); }
1725 bool zero() const { return false; }
1727 * Return true if stat is binned.
1728 *@return True is stat is binned.
1730 bool binned() const { return bin_t::binned; }
1732 * Reset stat value to default
1734 void reset() { bin.reset(); }
1736 bool check() { return bin.initialized(); }
1737 void update(VectorDistData *base)
1739 int size = this->size();
1740 base->data.resize(size);
1741 for (int i = 0; i < size; ++i) {
1742 base->data[i].fancy = Storage::fancy;
1743 data(i)->update(&(base->data[i]), params);
1748 template <class Storage, class Bin>
1752 typedef typename Storage::Params params_t;
1753 typedef typename Bin::template Bin<Storage> bin_t;
1754 typedef VectorDistBase<Storage, Bin> base_t;
1759 const base_t *cstat;
1764 Storage *data() { return stat->data(index); }
1765 const Storage *data() const { return cstat->data(index); }
1768 DistProxy(const VectorDistBase<Storage, Bin> &s, int i)
1769 : cstat(&s), index(i) {}
1770 DistProxy(const DistProxy &sp)
1771 : cstat(sp.cstat), index(sp.index) {}
1772 const DistProxy &operator=(const DistProxy &sp) {
1773 cstat = sp.cstat; index = sp.index; return *this;
1777 template <typename U>
1778 void sample(const U &v, int n = 1) { data()->sample(v, n, cstat->params); }
1780 size_t size() const { return 1; }
1781 bool zero() const { return data()->zero(cstat->params); }
1783 * Return true if stat is binned.
1784 *@return false since Proxies are not binned/printed.
1786 bool binned() const { return false; }
1788 * Proxy has no state. Nothing to reset.
1793 template <class Storage, class Bin>
1794 inline DistProxy<Storage, Bin>
1795 VectorDistBase<Storage, Bin>::operator[](int index)
1797 assert (index >= 0 && index < size());
1798 return DistProxy<Storage, Bin>(*this, index);
1801 template <class Storage, class Bin>
1802 inline const DistProxy<Storage, Bin>
1803 VectorDistBase<Storage, Bin>::operator[](int index) const
1805 assert (index >= 0 && index < size());
1806 return DistProxy<Storage, Bin>(*this, index);
1810 template <class Storage, class Bin>
1812 VectorDistBase<Storage, Bin>::total(int index) const
1815 for (int i=0; i < x_size(); ++i) {
1816 total += data(i)->result(*params);
1821 //////////////////////////////////////////////////////////////////////
1825 //////////////////////////////////////////////////////////////////////
1828 * Base class for formula statistic node. These nodes are used to build a tree
1829 * that represents the formula.
1831 class Node : public RefCounted
1835 * Return the number of nodes in the subtree starting at this node.
1836 * @return the number of nodes in this subtree.
1838 virtual size_t size() const = 0;
1840 * Return the result vector of this subtree.
1841 * @return The result vector of this subtree.
1843 virtual const VResult &result() const = 0;
1845 * Return the total of the result vector.
1846 * @return The total of the result vector.
1848 virtual Result total() const = 0;
1850 * Return true if stat is binned.
1851 *@return True is stat is binned.
1853 virtual bool binned() const = 0;
1858 virtual std::string str() const = 0;
1861 /** Reference counting pointer to a function Node. */
1862 typedef RefCountingPtr<Node> NodePtr;
1864 class ScalarStatNode : public Node
1867 const ScalarData *data;
1868 mutable VResult vresult;
1871 ScalarStatNode(const ScalarData *d) : data(d), vresult(1) {}
1872 virtual const VResult &result() const
1874 vresult[0] = data->result();
1877 virtual Result total() const { return data->result(); };
1879 virtual size_t size() const { return 1; }
1881 * Return true if stat is binned.
1882 *@return True is stat is binned.
1884 virtual bool binned() const { return data->binned(); }
1889 virtual std::string str() const { return data->name; }
1892 template <class Storage, class Bin>
1893 class ScalarProxyNode : public Node
1896 const ScalarProxy<Storage, Bin> proxy;
1897 mutable VResult vresult;
1900 ScalarProxyNode(const ScalarProxy<Storage, Bin> &p)
1901 : proxy(p), vresult(1) { }
1902 virtual const VResult &result() const
1904 vresult[0] = proxy.result();
1907 virtual Result total() const { return proxy.result(); };
1909 virtual size_t size() const { return 1; }
1911 * Return true if stat is binned.
1912 *@return True is stat is binned.
1914 virtual bool binned() const { return proxy.binned(); }
1919 virtual std::string str() const { return proxy.str(); }
1922 class VectorStatNode : public Node
1925 const VectorData *data;
1928 VectorStatNode(const VectorData *d) : data(d) { }
1929 virtual const VResult &result() const { return data->result(); }
1930 virtual Result total() const { return data->total(); };
1932 virtual size_t size() const { return data->size(); }
1934 * Return true if stat is binned.
1935 *@return True is stat is binned.
1937 virtual bool binned() const { return data->binned(); }
1939 virtual std::string str() const { return data->name; }
1943 class ConstNode : public Node
1949 ConstNode(T s) : vresult(1, (Result)s) {}
1950 const VResult &result() const { return vresult; }
1951 virtual Result total() const { return vresult[0]; };
1952 virtual size_t size() const { return 1; }
1955 * Return true if stat is binned.
1956 *@return False since constants aren't binned.
1958 virtual bool binned() const { return false; }
1960 virtual std::string str() const { return to_string(vresult[0]); }
1967 struct OpString<std::plus<Result> >
1969 static std::string str() { return "+"; }
1973 struct OpString<std::minus<Result> >
1975 static std::string str() { return "-"; }
1979 struct OpString<std::multiplies<Result> >
1981 static std::string str() { return "*"; }
1985 struct OpString<std::divides<Result> >
1987 static std::string str() { return "/"; }
1991 struct OpString<std::modulus<Result> >
1993 static std::string str() { return "%"; }
1997 struct OpString<std::negate<Result> >
1999 static std::string str() { return "-"; }
2003 class UnaryNode : public Node
2007 mutable VResult vresult;
2010 UnaryNode(NodePtr &p) : l(p) {}
2012 const VResult &result() const
2014 const VResult &lvec = l->result();
2015 int size = lvec.size();
2019 vresult.resize(size);
2021 for (int i = 0; i < size; ++i)
2022 vresult[i] = op(lvec[i]);
2027 Result total() const {
2029 return op(l->total());
2032 virtual size_t size() const { return l->size(); }
2034 * Return true if child of node is binned.
2035 *@return True if child of node is binned.
2037 virtual bool binned() const { return l->binned(); }
2039 virtual std::string str() const
2041 return OpString<Op>::str() + l->str();
2046 class BinaryNode : public Node
2051 mutable VResult vresult;
2054 BinaryNode(NodePtr &a, NodePtr &b) : l(a), r(b) {}
2056 const VResult &result() const
2059 const VResult &lvec = l->result();
2060 const VResult &rvec = r->result();
2062 assert(lvec.size() > 0 && rvec.size() > 0);
2064 if (lvec.size() == 1 && rvec.size() == 1) {
2066 vresult[0] = op(lvec[0], rvec[0]);
2067 } else if (lvec.size() == 1) {
2068 int size = rvec.size();
2069 vresult.resize(size);
2070 for (int i = 0; i < size; ++i)
2071 vresult[i] = op(lvec[0], rvec[i]);
2072 } else if (rvec.size() == 1) {
2073 int size = lvec.size();
2074 vresult.resize(size);
2075 for (int i = 0; i < size; ++i)
2076 vresult[i] = op(lvec[i], rvec[0]);
2077 } else if (rvec.size() == lvec.size()) {
2078 int size = rvec.size();
2079 vresult.resize(size);
2080 for (int i = 0; i < size; ++i)
2081 vresult[i] = op(lvec[i], rvec[i]);
2087 Result total() const {
2089 return op(l->total(), r->total());
2092 virtual size_t size() const {
2100 assert(ls == rs && "Node vector sizes are not equal");
2105 * Return true if any children of node are binned
2106 *@return True if either child of node is binned.
2108 virtual bool binned() const { return (l->binned() || r->binned()); }
2110 virtual std::string str() const
2112 return csprintf("(%s %s %s)", l->str(), OpString<Op>::str(), r->str());
2117 class SumNode : public Node
2121 mutable VResult vresult;
2124 SumNode(NodePtr &p) : l(p), vresult(1) {}
2126 const VResult &result() const
2128 const VResult &lvec = l->result();
2129 int size = lvec.size();
2135 for (int i = 0; i < size; ++i)
2136 vresult[0] = op(vresult[0], lvec[i]);
2141 Result total() const
2143 const VResult &lvec = l->result();
2144 int size = lvec.size();
2147 Result vresult = 0.0;
2150 for (int i = 0; i < size; ++i)
2151 vresult = op(vresult, lvec[i]);
2156 virtual size_t size() const { return 1; }
2158 * Return true if child of node is binned.
2159 *@return True if child of node is binned.
2161 virtual bool binned() const { return l->binned(); }
2163 virtual std::string str() const
2165 return csprintf("total(%s)", l->str());
2170 //////////////////////////////////////////////////////////////////////
2172 // Visible Statistics Types
2174 //////////////////////////////////////////////////////////////////////
2176 * @defgroup VisibleStats "Statistic Types"
2177 * These are the statistics that are used in the simulator. By default these
2178 * store counters and don't use binning, but are templatized to accept any type
2179 * and any Bin class.
2184 * This is an easy way to assign all your stats to be binned or not
2185 * binned. If the typedef is NoBin, nothing is binned. If it is
2186 * MainBin, then all stats are binned under that Bin.
2189 typedef MainBin DefaultBin;
2191 typedef NoBin DefaultBin;
2195 * This is a simple scalar statistic, like a counter.
2196 * @sa Stat, ScalarBase, StatStor
2198 template <class Bin = DefaultBin>
2200 : public Wrap<Scalar<Bin>,
2201 ScalarBase<StatStor, Bin>,
2205 /** The base implementation. */
2206 typedef ScalarBase<StatStor, Bin> Base;
2214 * Sets the stat equal to the given value. Calls the base implementation
2216 * @param v The new value.
2218 template <typename U>
2219 void operator=(const U &v) { Base::operator=(v); }
2223 : public Wrap<Value,
2228 /** The base implementation. */
2229 typedef ValueBase Base;
2232 Value &scalar(T &value)
2234 Base::scalar(value);
2239 Value &functor(T &func)
2241 Base::functor(func);
2247 * A stat that calculates the per cycle average of a value.
2248 * @sa Stat, ScalarBase, AvgStor
2250 template <class Bin = DefaultBin>
2252 : public Wrap<Average<Bin>,
2253 ScalarBase<AvgStor, Bin>,
2257 /** The base implementation. */
2258 typedef ScalarBase<AvgStor, Bin> Base;
2266 * Sets the stat equal to the given value. Calls the base implementation
2268 * @param v The new value.
2270 template <typename U>
2271 void operator=(const U &v) { Base::operator=(v); }
2275 * A vector of scalar stats.
2276 * @sa Stat, VectorBase, StatStor
2278 template <class Bin = DefaultBin>
2280 : public WrapVec<Vector<Bin>,
2281 VectorBase<StatStor, Bin>,
2285 /** The base implementation. */
2286 typedef ScalarBase<StatStor, Bin> Base;
2289 * Set this vector to have the given size.
2290 * @param size The new size.
2291 * @return A reference to this stat.
2293 Vector &init(size_t size) {
2294 this->bin.init(size, this->params);
2302 * A vector of Average stats.
2303 * @sa Stat, VectorBase, AvgStor
2305 template <class Bin = DefaultBin>
2307 : public WrapVec<AverageVector<Bin>,
2308 VectorBase<AvgStor, Bin>,
2313 * Set this vector to have the given size.
2314 * @param size The new size.
2315 * @return A reference to this stat.
2317 AverageVector &init(size_t size) {
2318 this->bin.init(size, this->params);
2326 * A 2-Dimensional vecto of scalar stats.
2327 * @sa Stat, Vector2dBase, StatStor
2329 template <class Bin = DefaultBin>
2331 : public WrapVec2d<Vector2d<Bin>,
2332 Vector2dBase<StatStor, Bin>,
2336 Vector2d &init(size_t _x, size_t _y) {
2337 this->statData()->x = this->x = _x;
2338 this->statData()->y = this->y = _y;
2339 this->bin.init(this->x * this->y, this->params);
2347 * A simple distribution stat.
2348 * @sa Stat, DistBase, DistStor
2350 template <class Bin = DefaultBin>
2352 : public Wrap<Distribution<Bin>,
2353 DistBase<DistStor, Bin>,
2357 /** Base implementation. */
2358 typedef DistBase<DistStor, Bin> Base;
2359 /** The Parameter type. */
2360 typedef typename DistStor::Params Params;
2364 * Set the parameters of this distribution. @sa DistStor::Params
2365 * @param min The minimum value of the distribution.
2366 * @param max The maximum value of the distribution.
2367 * @param bkt The number of values in each bucket.
2368 * @return A reference to this distribution.
2370 Distribution &init(Counter min, Counter max, Counter bkt) {
2371 this->params.min = min;
2372 this->params.max = max;
2373 this->params.bucket_size = bkt;
2374 this->params.size = (int)rint((max - min) / bkt + 1.0);
2375 this->bin.init(this->params);
2383 * Calculates the mean and variance of all the samples.
2384 * @sa Stat, DistBase, FancyStor
2386 template <class Bin = DefaultBin>
2387 class StandardDeviation
2388 : public Wrap<StandardDeviation<Bin>,
2389 DistBase<FancyStor, Bin>,
2393 /** The base implementation */
2394 typedef DistBase<DistStor, Bin> Base;
2395 /** The parameter type. */
2396 typedef typename DistStor::Params Params;
2400 * Construct and initialize this distribution.
2402 StandardDeviation() {
2403 this->bin.init(this->params);
2409 * Calculates the per cycle mean and variance of the samples.
2410 * @sa Stat, DistBase, AvgFancy
2412 template <class Bin = DefaultBin>
2413 class AverageDeviation
2414 : public Wrap<AverageDeviation<Bin>,
2415 DistBase<AvgFancy, Bin>,
2419 /** The base implementation */
2420 typedef DistBase<DistStor, Bin> Base;
2421 /** The parameter type. */
2422 typedef typename DistStor::Params Params;
2426 * Construct and initialize this distribution.
2430 this->bin.init(this->params);
2436 * A vector of distributions.
2437 * @sa Stat, VectorDistBase, DistStor
2439 template <class Bin = DefaultBin>
2440 class VectorDistribution
2441 : public WrapVec<VectorDistribution<Bin>,
2442 VectorDistBase<DistStor, Bin>,
2446 /** The base implementation */
2447 typedef VectorDistBase<DistStor, Bin> Base;
2448 /** The parameter type. */
2449 typedef typename DistStor::Params Params;
2453 * Initialize storage and parameters for this distribution.
2454 * @param size The size of the vector (the number of distributions).
2455 * @param min The minimum value of the distribution.
2456 * @param max The maximum value of the distribution.
2457 * @param bkt The number of values in each bucket.
2458 * @return A reference to this distribution.
2460 VectorDistribution &init(int size, Counter min, Counter max, Counter bkt) {
2461 this->params.min = min;
2462 this->params.max = max;
2463 this->params.bucket_size = bkt;
2464 this->params.size = (int)rint((max - min) / bkt + 1.0);
2465 this->bin.init(size, this->params);
2473 * This is a vector of StandardDeviation stats.
2474 * @sa Stat, VectorDistBase, FancyStor
2476 template <class Bin = DefaultBin>
2477 class VectorStandardDeviation
2478 : public WrapVec<VectorStandardDeviation<Bin>,
2479 VectorDistBase<FancyStor, Bin>,
2483 /** The base implementation */
2484 typedef VectorDistBase<FancyStor, Bin> Base;
2485 /** The parameter type. */
2486 typedef typename DistStor::Params Params;
2490 * Initialize storage for this distribution.
2491 * @param size The size of the vector.
2492 * @return A reference to this distribution.
2494 VectorStandardDeviation &init(int size) {
2495 this->bin.init(size, this->params);
2503 * This is a vector of AverageDeviation stats.
2504 * @sa Stat, VectorDistBase, AvgFancy
2506 template <class Bin = DefaultBin>
2507 class VectorAverageDeviation
2508 : public WrapVec<VectorAverageDeviation<Bin>,
2509 VectorDistBase<AvgFancy, Bin>,
2513 /** The base implementation */
2514 typedef VectorDistBase<AvgFancy, Bin> Base;
2515 /** The parameter type. */
2516 typedef typename DistStor::Params Params;
2520 * Initialize storage for this distribution.
2521 * @param size The size of the vector.
2522 * @return A reference to this distribution.
2524 VectorAverageDeviation &init(int size) {
2525 this->bin.init(size, this->params);
2533 * A formula for statistics that is calculated when printed. A formula is
2534 * stored as a tree of Nodes that represent the equation to calculate.
2535 * @sa Stat, ScalarStat, VectorStat, Node, Temp
2537 class FormulaBase : public DataAccess
2540 /** The root of the tree which represents the Formula */
2546 * Return the result of the Fomula in a vector. If there were no Vector
2547 * components to the Formula, then the vector is size 1. If there were,
2548 * like x/y with x being a vector of size 3, then the result returned will
2549 * be x[0]/y, x[1]/y, x[2]/y, respectively.
2550 * @return The result vector.
2552 void result(VResult &vec) const;
2555 * Return the total Formula result. If there is a Vector
2556 * component to this Formula, then this is the result of the
2557 * Formula if the formula is applied after summing all the
2558 * components of the Vector. For example, if Formula is x/y where
2559 * x is size 3, then total() will return (x[1]+x[2]+x[3])/y. If
2560 * there is no Vector component, total() returns the same value as
2561 * the first entry in the VResult val() returns.
2562 * @return The total of the result vector.
2564 Result total() const;
2567 * Return the number of elements in the tree.
2569 size_t size() const;
2572 * Return true if Formula is binned. i.e. any of its children
2574 * @return True if Formula is binned.
2576 bool binned() const;
2578 bool check() const { return true; }
2581 * Formulas don't need to be reset
2593 void update(StatData *);
2595 std::string str() const;
2598 class FormulaData : public VectorData
2601 virtual std::string str() const = 0;
2602 virtual bool check() const { return true; }
2605 template <class Stat>
2606 class FormulaStatData : public FormulaData
2610 mutable VResult vec;
2611 mutable VCounter cvec;
2614 FormulaStatData(Stat &stat) : s(stat) {}
2616 virtual bool binned() const { return s.binned(); }
2617 virtual bool zero() const { return s.zero(); }
2618 virtual void reset() { s.reset(); }
2620 virtual size_t size() const { return s.size(); }
2621 virtual const VResult &result() const
2626 virtual Result total() const { return s.total(); }
2627 virtual VCounter &value() const { return cvec; }
2628 virtual void visit(Visit &visitor)
2632 visitor.visit(*this);
2634 virtual std::string str() const { return s.str(); }
2639 : public WrapVec<Formula,
2645 * Create and initialize thie formula, and register it with the database.
2650 * Create a formula with the given root node, register it with the
2652 * @param r The root of the expression tree.
2657 * Set an unitialized Formula to the given root.
2658 * @param r The root of the expression tree.
2659 * @return a reference to this formula.
2661 const Formula &operator=(Temp r);
2664 * Add the given tree to the existing one.
2665 * @param r The root of the expression tree.
2666 * @return a reference to this formula.
2668 const Formula &operator+=(Temp r);
2671 class FormulaNode : public Node
2674 const Formula &formula;
2675 mutable VResult vec;
2678 FormulaNode(const Formula &f) : formula(f) {}
2680 virtual size_t size() const { return formula.size(); }
2681 virtual const VResult &result() const { formula.result(vec); return vec; }
2682 virtual Result total() const { return formula.total(); }
2683 virtual bool binned() const { return formula.binned(); }
2685 virtual std::string str() const { return formula.str(); }
2689 * Helper class to construct formula node trees.
2695 * Pointer to a Node object.
2701 * Copy the given pointer to this class.
2702 * @param n A pointer to a Node object to copy.
2704 Temp(NodePtr n) : node(n) { }
2707 * Return the node pointer.
2708 * @return the node pointer.
2710 operator NodePtr&() { return node;}
2714 * Create a new ScalarStatNode.
2715 * @param s The ScalarStat to place in a node.
2717 template <class Bin>
2718 Temp(const Scalar<Bin> &s)
2719 : node(new ScalarStatNode(s.statData())) { }
2722 * Create a new ScalarStatNode.
2723 * @param s The ScalarStat to place in a node.
2725 Temp(const Value &s)
2726 : node(new ScalarStatNode(s.statData())) { }
2729 * Create a new ScalarStatNode.
2730 * @param s The ScalarStat to place in a node.
2732 template <class Bin>
2733 Temp(const Average<Bin> &s)
2734 : node(new ScalarStatNode(s.statData())) { }
2737 * Create a new VectorStatNode.
2738 * @param s The VectorStat to place in a node.
2740 template <class Bin>
2741 Temp(const Vector<Bin> &s)
2742 : node(new VectorStatNode(s.statData())) { }
2747 Temp(const Formula &f)
2748 : node(new FormulaNode(f)) { }
2751 * Create a new ScalarProxyNode.
2752 * @param p The ScalarProxy to place in a node.
2754 template <class Storage, class Bin>
2755 Temp(const ScalarProxy<Storage, Bin> &p)
2756 : node(new ScalarProxyNode<Storage, Bin>(p)) { }
2759 * Create a ConstNode
2760 * @param value The value of the const node.
2762 Temp(signed char value)
2763 : node(new ConstNode<signed char>(value)) {}
2766 * Create a ConstNode
2767 * @param value The value of the const node.
2769 Temp(unsigned char value)
2770 : node(new ConstNode<unsigned char>(value)) {}
2773 * Create a ConstNode
2774 * @param value The value of the const node.
2776 Temp(signed short value)
2777 : node(new ConstNode<signed short>(value)) {}
2780 * Create a ConstNode
2781 * @param value The value of the const node.
2783 Temp(unsigned short value)
2784 : node(new ConstNode<unsigned short>(value)) {}
2787 * Create a ConstNode
2788 * @param value The value of the const node.
2790 Temp(signed int value)
2791 : node(new ConstNode<signed int>(value)) {}
2794 * Create a ConstNode
2795 * @param value The value of the const node.
2797 Temp(unsigned int value)
2798 : node(new ConstNode<unsigned int>(value)) {}
2801 * Create a ConstNode
2802 * @param value The value of the const node.
2804 Temp(signed long value)
2805 : node(new ConstNode<signed long>(value)) {}
2808 * Create a ConstNode
2809 * @param value The value of the const node.
2811 Temp(unsigned long value)
2812 : node(new ConstNode<unsigned long>(value)) {}
2815 * Create a ConstNode
2816 * @param value The value of the const node.
2818 Temp(signed long long value)
2819 : node(new ConstNode<signed long long>(value)) {}
2822 * Create a ConstNode
2823 * @param value The value of the const node.
2825 Temp(unsigned long long value)
2826 : node(new ConstNode<unsigned long long>(value)) {}
2829 * Create a ConstNode
2830 * @param value The value of the const node.
2833 : node(new ConstNode<float>(value)) {}
2836 * Create a ConstNode
2837 * @param value The value of the const node.
2840 : node(new ConstNode<double>(value)) {}
2850 void registerResetCallback(Callback *cb);
2853 operator+(Temp l, Temp r)
2855 return NodePtr(new BinaryNode<std::plus<Result> >(l, r));
2859 operator-(Temp l, Temp r)
2861 return NodePtr(new BinaryNode<std::minus<Result> >(l, r));
2865 operator*(Temp l, Temp r)
2867 return NodePtr(new BinaryNode<std::multiplies<Result> >(l, r));
2871 operator/(Temp l, Temp r)
2873 return NodePtr(new BinaryNode<std::divides<Result> >(l, r));
2879 return NodePtr(new UnaryNode<std::negate<Result> >(l));
2882 template <typename T>
2886 return NodePtr(new ConstNode<T>(val));
2892 return NodePtr(new SumNode<std::plus<Result> >(val));
2895 /* namespace Stats */ }
2897 #endif // __BASE_STATISTICS_HH__