diff options
Diffstat (limited to 'src/base')
-rw-r--r-- | src/base/SConscript | 2 | ||||
-rw-r--r-- | src/base/statistics.cc | 70 | ||||
-rw-r--r-- | src/base/statistics.hh | 204 | ||||
-rw-r--r-- | src/base/stats/group.cc | 129 | ||||
-rw-r--r-- | src/base/stats/group.hh | 175 | ||||
-rw-r--r-- | src/base/stats/output.hh | 16 | ||||
-rw-r--r-- | src/base/stats/text.cc | 53 | ||||
-rw-r--r-- | src/base/stats/text.hh | 41 |
8 files changed, 617 insertions, 73 deletions
diff --git a/src/base/SConscript b/src/base/SConscript index 9449a3d4e..96f7b5b50 100644 --- a/src/base/SConscript +++ b/src/base/SConscript @@ -81,6 +81,7 @@ Source('loader/object_file.cc') Source('loader/raw_object.cc') Source('loader/symtab.cc') +Source('stats/group.cc') Source('stats/text.cc') GTest('addr_range.test', 'addr_range.test.cc') @@ -101,6 +102,7 @@ DebugFlag('GDBRecv', "Messages received from the remote application") DebugFlag('GDBSend', "Messages sent to the remote application") DebugFlag('GDBWrite', "Writes to the remote address space") DebugFlag('SQL', "SQL queries sent to the server") +DebugFlag('Stats', "Statistics management") DebugFlag('StatEvents', "Statistics event tracking") CompoundFlag('GDBAll', diff --git a/src/base/statistics.cc b/src/base/statistics.cc index 123351b80..a186f9763 100644 --- a/src/base/statistics.cc +++ b/src/base/statistics.cc @@ -1,4 +1,16 @@ /* + * Copyright (c) 2019 Arm Limited + * All rights reserved. + * + * The license below extends only to copyright in the software and shall + * not be construed as granting a license to any other intellectual + * property including but not limited to intellectual property relating + * to a hardware implementation of the functionality of the software + * licensed hereunder. You may use the software subject to the license + * terms below provided that you ensure that this notice is replicated + * unmodified and in its entirety in all distributions of the software, + * modified or unmodified, in source code or in binary form. + * * Copyright (c) 2003-2005 The Regents of The University of Michigan * All rights reserved. * @@ -67,10 +79,18 @@ statsMap() } void -InfoAccess::setInfo(Info *info) +InfoAccess::setInfo(Group *parent, Info *info) { - if (statsMap().find(this) != statsMap().end()) - panic("shouldn't register stat twice!"); + panic_if(statsMap().find(this) != statsMap().end() || + _info != nullptr, + "shouldn't register stat twice!"); + + // New-style stats are reachable through the hierarchy and + // shouldn't be added to the global lists. + if (parent) { + _info = info; + return; + } statsList().push_back(info); @@ -97,17 +117,29 @@ InfoAccess::setInit() Info * InfoAccess::info() { - MapType::const_iterator i = statsMap().find(this); - assert(i != statsMap().end()); - return (*i).second; + if (_info) { + // New-style stats + return _info; + } else { + // Legacy stats + MapType::const_iterator i = statsMap().find(this); + assert(i != statsMap().end()); + return (*i).second; + } } const Info * InfoAccess::info() const { - MapType::const_iterator i = statsMap().find(this); - assert(i != statsMap().end()); - return (*i).second; + if (_info) { + // New-style stats + return _info; + } else { + // Legacy stats + MapType::const_iterator i = statsMap().find(this); + assert(i != statsMap().end()); + return (*i).second; + } } StorageParams::~StorageParams() @@ -224,7 +256,8 @@ Info::baseCheck() const #endif panic("Not all stats have been initialized.\n" "You may need to add <ParentClass>::regStats() to a" - " new SimObject's regStats() function."); + " new SimObject's regStats() function. Name: %s", + name); return false; } @@ -376,19 +409,23 @@ HistStor::add(HistStor *hs) cvec[i] += hs->cvec[i]; } -Formula::Formula() +Formula::Formula(Group *parent, const char *name, const char *desc) + : DataWrapVec<Formula, FormulaInfoProxy>(parent, name, desc) + { } -Formula::Formula(Temp r) + + +Formula::Formula(Group *parent, const char *name, const char *desc, + const Temp &r) + : DataWrapVec<Formula, FormulaInfoProxy>(parent, name, desc) { - root = r.getNodePtr(); - setInit(); - assert(size()); + *this = r; } const Formula & -Formula::operator=(Temp r) +Formula::operator=(const Temp &r) { assert(!root && "Can't change formulas"); root = r.getNodePtr(); @@ -421,6 +458,7 @@ Formula::operator/=(Temp r) return *this; } + void Formula::result(VResult &vec) const { diff --git a/src/base/statistics.hh b/src/base/statistics.hh index 6ddf7ff17..f4fa123e9 100644 --- a/src/base/statistics.hh +++ b/src/base/statistics.hh @@ -1,4 +1,16 @@ /* + * Copyright (c) 2019 Arm Limited + * All rights reserved. + * + * The license below extends only to copyright in the software and shall + * not be construed as granting a license to any other intellectual + * property including but not limited to intellectual property relating + * to a hardware implementation of the functionality of the software + * licensed hereunder. You may use the software subject to the license + * terms below provided that you ensure that this notice is replicated + * unmodified and in its entirety in all distributions of the software, + * modified or unmodified, in source code or in binary form. + * * Copyright (c) 2003-2005 The Regents of The University of Michigan * Copyright (c) 2017, Centre National de la Recherche Scientifique * All rights reserved. @@ -63,6 +75,7 @@ #include <string> #include <vector> +#include "base/stats/group.hh" #include "base/stats/info.hh" #include "base/stats/output.hh" #include "base/stats/types.hh" @@ -172,9 +185,12 @@ struct StorageParams class InfoAccess { + private: + Info *_info; + protected: /** Set up an info class for this statistic */ - void setInfo(Info *info); + void setInfo(Group *parent, Info *info); /** Save Storage class parameters if any */ void setParams(const StorageParams *params); /** Save Storage class parameters if any */ @@ -186,6 +202,9 @@ class InfoAccess const Info *info() const; public: + InfoAccess() + : _info(nullptr) {}; + /** * Reset the stat to the default state. */ @@ -228,21 +247,27 @@ class DataWrap : public InfoAccess return safe_cast<const Info *>(InfoAccess::info()); } - protected: - /** - * Copy constructor, copies are not allowed. - */ - DataWrap(const DataWrap &stat) = delete; + public: + DataWrap() = delete; + DataWrap(const DataWrap &) = delete; + DataWrap &operator=(const DataWrap &) = delete; - /** - * Can't copy stats. - */ - void operator=(const DataWrap &) {} - public: - DataWrap() + DataWrap(Group *parent, const char *name, const char *desc) { - this->setInfo(new Info(self())); + auto info = new Info(self()); + this->setInfo(parent, info); + + if (parent) + parent->addStat(info); + + if (name) { + info->setName(name); + info->flags.set(display); + } + + if (desc) + info->desc = desc; } /** @@ -335,13 +360,9 @@ class DataWrapVec : public DataWrap<Derived, InfoProxyType> public: typedef InfoProxyType<Derived> Info; - DataWrapVec() - {} - - DataWrapVec(const DataWrapVec &ref) - {} - - void operator=(const DataWrapVec &) + DataWrapVec(Group *parent = nullptr, const char *name = nullptr, + const char *desc = nullptr) + : DataWrap<Derived, InfoProxyType>(parent, name, desc) {} // The following functions are specific to vectors. If you use them @@ -420,6 +441,11 @@ class DataWrapVec2d : public DataWrapVec<Derived, InfoProxyType> public: typedef InfoProxyType<Derived> Info; + DataWrapVec2d(Group *parent, const char *name, const char *desc) + : DataWrapVec<Derived, InfoProxyType>(parent, name, desc) + { + } + /** * @warning This makes the assumption that if you're gonna subnames a 2d * vector, you're subnaming across all y @@ -677,7 +703,9 @@ class ScalarBase : public DataWrap<Derived, ScalarInfoProxy> Counter value() const { return data()->value(); } public: - ScalarBase() + ScalarBase(Group *parent = nullptr, const char *name = nullptr, + const char *desc = nullptr) + : DataWrap<Derived, ScalarInfoProxy>(parent, name, desc) { this->doInit(); } @@ -807,7 +835,12 @@ class ValueBase : public DataWrap<Derived, ScalarInfoProxy> ProxyInfo *proxy; public: - ValueBase() : proxy(NULL) { } + ValueBase(Group *parent, const char *name, const char *desc) + : DataWrap<Derived, ScalarInfoProxy>(parent, name, desc), + proxy(NULL) + { + } + ~ValueBase() { if (proxy) delete proxy; } template <class T> @@ -1095,8 +1128,9 @@ class VectorBase : public DataWrapVec<Derived, VectorInfoProxy> } public: - VectorBase() - : storage(nullptr), _size(0) + VectorBase(Group *parent, const char *name, const char *desc) + : DataWrapVec<Derived, VectorInfoProxy>(parent, name, desc), + storage(nullptr), _size(0) {} ~VectorBase() @@ -1235,8 +1269,9 @@ class Vector2dBase : public DataWrapVec2d<Derived, Vector2dInfoProxy> const Storage *data(off_type index) const { return &storage[index]; } public: - Vector2dBase() - : x(0), y(0), _size(0), storage(nullptr) + Vector2dBase(Group *parent, const char *name, const char *desc) + : DataWrapVec2d<Derived, Vector2dInfoProxy>(parent, name, desc), + x(0), y(0), _size(0), storage(nullptr) {} ~Vector2dBase() @@ -1851,7 +1886,10 @@ class DistBase : public DataWrap<Derived, DistInfoProxy> } public: - DistBase() { } + DistBase(Group *parent, const char *name, const char *desc) + : DataWrap<Derived, DistInfoProxy>(parent, name, desc) + { + } /** * Add a value to the distribtion n times. Calls sample on the storage @@ -1945,8 +1983,9 @@ class VectorDistBase : public DataWrapVec<Derived, VectorDistInfoProxy> } public: - VectorDistBase() - : storage(NULL) + VectorDistBase(Group *parent, const char *name, const char *desc) + : DataWrapVec<Derived, VectorDistInfoProxy>(parent, name, desc), + storage(NULL) {} ~VectorDistBase() @@ -2472,6 +2511,12 @@ class Scalar : public ScalarBase<Scalar, StatStor> { public: using ScalarBase<Scalar, StatStor>::operator=; + + Scalar(Group *parent = nullptr, const char *name = nullptr, + const char *desc = nullptr) + : ScalarBase<Scalar, StatStor>(parent, name, desc) + { + } }; /** @@ -2482,10 +2527,22 @@ class Average : public ScalarBase<Average, AvgStor> { public: using ScalarBase<Average, AvgStor>::operator=; + + Average(Group *parent = nullptr, const char *name = nullptr, + const char *desc = nullptr) + : ScalarBase<Average, AvgStor>(parent, name, desc) + { + } }; class Value : public ValueBase<Value> { + public: + Value(Group *parent = nullptr, const char *name = nullptr, + const char *desc = nullptr) + : ValueBase<Value>(parent, name, desc) + { + } }; /** @@ -2494,6 +2551,12 @@ class Value : public ValueBase<Value> */ class Vector : public VectorBase<Vector, StatStor> { + public: + Vector(Group *parent = nullptr, const char *name = nullptr, + const char *desc = nullptr) + : VectorBase<Vector, StatStor>(parent, name, desc) + { + } }; /** @@ -2502,6 +2565,12 @@ class Vector : public VectorBase<Vector, StatStor> */ class AverageVector : public VectorBase<AverageVector, AvgStor> { + public: + AverageVector(Group *parent = nullptr, const char *name = nullptr, + const char *desc = nullptr) + : VectorBase<AverageVector, AvgStor>(parent, name, desc) + { + } }; /** @@ -2510,6 +2579,12 @@ class AverageVector : public VectorBase<AverageVector, AvgStor> */ class Vector2d : public Vector2dBase<Vector2d, StatStor> { + public: + Vector2d(Group *parent = nullptr, const char *name = nullptr, + const char *desc = nullptr) + : Vector2dBase<Vector2d, StatStor>(parent, name, desc) + { + } }; /** @@ -2519,6 +2594,12 @@ class Vector2d : public Vector2dBase<Vector2d, StatStor> class Distribution : public DistBase<Distribution, DistStor> { public: + Distribution(Group *parent = nullptr, const char *name = nullptr, + const char *desc = nullptr) + : DistBase<Distribution, DistStor>(parent, name, desc) + { + } + /** * Set the parameters of this distribution. @sa DistStor::Params * @param min The minimum value of the distribution. @@ -2550,6 +2631,12 @@ class Distribution : public DistBase<Distribution, DistStor> class Histogram : public DistBase<Histogram, HistStor> { public: + Histogram(Group *parent = nullptr, const char *name = nullptr, + const char *desc = nullptr) + : DistBase<Histogram, HistStor>(parent, name, desc) + { + } + /** * Set the parameters of this histogram. @sa HistStor::Params * @param size The number of buckets in the histogram @@ -2576,7 +2663,9 @@ class StandardDeviation : public DistBase<StandardDeviation, SampleStor> /** * Construct and initialize this distribution. */ - StandardDeviation() + StandardDeviation(Group *parent = nullptr, const char *name = nullptr, + const char *desc = nullptr) + : DistBase<StandardDeviation, SampleStor>(parent, name, desc) { SampleStor::Params *params = new SampleStor::Params; this->doInit(); @@ -2594,7 +2683,9 @@ class AverageDeviation : public DistBase<AverageDeviation, AvgSampleStor> /** * Construct and initialize this distribution. */ - AverageDeviation() + AverageDeviation(Group *parent = nullptr, const char *name = nullptr, + const char *desc = nullptr) + : DistBase<AverageDeviation, AvgSampleStor>(parent, name, desc) { AvgSampleStor::Params *params = new AvgSampleStor::Params; this->doInit(); @@ -2609,6 +2700,12 @@ class AverageDeviation : public DistBase<AverageDeviation, AvgSampleStor> class VectorDistribution : public VectorDistBase<VectorDistribution, DistStor> { public: + VectorDistribution(Group *parent = nullptr, const char *name = nullptr, + const char *desc = nullptr) + : VectorDistBase<VectorDistribution, DistStor>(parent, name, desc) + { + } + /** * Initialize storage and parameters for this distribution. * @param size The size of the vector (the number of distributions). @@ -2639,6 +2736,13 @@ class VectorStandardDeviation : public VectorDistBase<VectorStandardDeviation, SampleStor> { public: + VectorStandardDeviation(Group *parent = nullptr, const char *name = nullptr, + const char *desc = nullptr) + : VectorDistBase<VectorStandardDeviation, SampleStor>(parent, name, + desc) + { + } + /** * Initialize storage for this distribution. * @param size The size of the vector. @@ -2662,6 +2766,13 @@ class VectorAverageDeviation : public VectorDistBase<VectorAverageDeviation, AvgSampleStor> { public: + VectorAverageDeviation(Group *parent = nullptr, const char *name = nullptr, + const char *desc = nullptr) + : VectorDistBase<VectorAverageDeviation, AvgSampleStor>(parent, name, + desc) + { + } + /** * Initialize storage for this distribution. * @param size The size of the vector. @@ -2753,7 +2864,10 @@ class SparseHistBase : public DataWrap<Derived, SparseHistInfoProxy> } public: - SparseHistBase() { } + SparseHistBase(Group *parent, const char *name, const char *desc) + : DataWrap<Derived, SparseHistInfoProxy>(parent, name, desc) + { + } /** * Add a value to the distribtion n times. Calls sample on the storage @@ -2870,6 +2984,12 @@ class SparseHistStor class SparseHistogram : public SparseHistBase<SparseHistogram, SparseHistStor> { public: + SparseHistogram(Group *parent = nullptr, const char *name = nullptr, + const char *desc = nullptr) + : SparseHistBase<SparseHistogram, SparseHistStor>(parent, name, desc) + { + } + /** * Set the parameters of this histogram. @sa HistStor::Params * @param size The number of buckets in the histogram @@ -2902,21 +3022,25 @@ class Formula : public DataWrapVec<Formula, FormulaInfoProxy> /** * Create and initialize thie formula, and register it with the database. */ - Formula(); + Formula(Group *parent = nullptr, const char *name = nullptr, + const char *desc = nullptr); - /** - * Create a formula with the given root node, register it with the - * database. - * @param r The root of the expression tree. - */ - Formula(Temp r); + Formula(Group *parent, const char *name, const char *desc, + const Temp &r); /** * Set an unitialized Formula to the given root. * @param r The root of the expression tree. * @return a reference to this formula. */ - const Formula &operator=(Temp r); + const Formula &operator=(const Temp &r); + + template<typename T> + const Formula &operator=(const T &v) + { + *this = Temp(v); + return *this; + } /** * Add the given tree to the existing one. diff --git a/src/base/stats/group.cc b/src/base/stats/group.cc new file mode 100644 index 000000000..2bfc89d00 --- /dev/null +++ b/src/base/stats/group.cc @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2019 Arm Limited + * All rights reserved + * + * The license below extends only to copyright in the software and shall + * not be construed as granting a license to any other intellectual + * property including but not limited to intellectual property relating + * to a hardware implementation of the functionality of the software + * licensed hereunder. You may use the software subject to the license + * terms below provided that you ensure that this notice is replicated + * unmodified and in its entirety in all distributions of the software, + * modified or unmodified, in source code or in binary form. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Andreas Sandberg + */ + +#include "base/stats/group.hh" + +#include <cassert> + +#include "base/stats/info.hh" +#include "base/trace.hh" +#include "debug/Stats.hh" +#include "sim/sim_object.hh" + +namespace Stats { + +Group::Group(Group *parent, const char *name) + : mergedParent(name ? nullptr : parent) +{ + if (parent && name) { + parent->addStatGroup(name, this); + } else if (parent && !name) { + parent->mergeStatGroup(this); + } +} + +Group::~Group() +{ +} + +void +Group::regStats() +{ + for (auto &g : mergedStatGroups) + g->regStats(); + + for (auto &g : statGroups) { + if (DTRACE(Stats)) { + const SimObject *so = dynamic_cast<const SimObject *>(this); + DPRINTF(Stats, "%s: regStats in group %s\n", + so ? so->name() : "?", + g.first); + } + g.second->regStats(); + } +} + +void +Group::resetStats() +{ + for (auto &s : stats) + s->reset(); + + for (auto &g : mergedStatGroups) + g->resetStats(); + + for (auto &g : statGroups) + g.second->resetStats(); +} + +void +Group::addStat(Stats::Info *info) +{ + stats.push_back(info); + if (mergedParent) + mergedParent->addStat(info); +} + +void +Group::addStatGroup(const char *name, Group *block) +{ + assert(statGroups.find(name) == statGroups.end()); + + statGroups[name] = block; +} + +void +Group::mergeStatGroup(Group *block) +{ + mergedStatGroups.push_back(block); +} + +const std::map<std::string, Group *> & +Group::getStatGroups() const +{ + return statGroups; +} + +const std::vector<Info *> & +Group::getStats() const +{ + return stats; +} + +} // namespace Stats diff --git a/src/base/stats/group.hh b/src/base/stats/group.hh new file mode 100644 index 000000000..f65e46448 --- /dev/null +++ b/src/base/stats/group.hh @@ -0,0 +1,175 @@ +/* + * Copyright (c) 2019 Arm Limited + * All rights reserved + * + * The license below extends only to copyright in the software and shall + * not be construed as granting a license to any other intellectual + * property including but not limited to intellectual property relating + * to a hardware implementation of the functionality of the software + * licensed hereunder. You may use the software subject to the license + * terms below provided that you ensure that this notice is replicated + * unmodified and in its entirety in all distributions of the software, + * modified or unmodified, in source code or in binary form. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Andreas Sandberg + */ + +#ifndef __BASE_STATS_GROUP_HH__ +#define __BASE_STATS_GROUP_HH__ + +#include <map> +#include <vector> +#include <string> + +/** + * Convenience macro to add a stat to a statistics group. + * + * This macro is used to add a stat to a Stats::Group in the + * initilization list in the Group's constructor. The macro + * automatically assigns the stat to the current group and gives it + * the same name as in the class. For example: + * + * \code + * struct MyStats : public Stats::Group + * { + * Stats::Scalar scalar0; + * Stats::Scalar scalar1; + * + * Group() + * : ADD_STAT(scalar0, "Description of scalar0"), + * scalar1(this, "scalar1", "Description of scalar1") + * { + * } + * }; + * \endcode + */ +#define ADD_STAT(n, ...) n(this, # n, __VA_ARGS__) + +namespace Stats { + +class Info; + +/** + * Statistics container. + * + * A stat group is a hierarchical structure that contain statistics + * and other groups. Groups are used by the stat system to reflect + * gem5's SimObject hierarchy and to expose internal hierarchy within + * an object. They can also be used to conveniently group stats into + * their own class/struct and then be merged into the parent group + * (typically a SimObject). + */ +class Group +{ + public: + Group() = delete; + Group(const Group &) = delete; + Group &operator=(const Group &) = delete; + + /** + * Construct a new statistics group. + * + * The constructor takes two parameters, a parent and a name. The + * parent group should typically be specified. However, there are + * special cases where the parent group may be null. One such + * special case is SimObjects where the Python code performs late + * binding of the group parent. + * + * If the name parameter is NULL, the group gets merged into the + * parent group instead of creating a sub-group. Stats belonging + * to a merged group behave as if they have been added directly to + * the parent group. + * + * @param parent Parent group to associate this object to. + * @param name Name of this group, can be NULL to merge this group + * with the parent group. + */ + Group(Group *parent, const char *name = nullptr); + + virtual ~Group(); + + /** + * Callback to set stat parameters. + * + * This callback is typically used for complex stats (e.g., + * distributions) that need parameters in addition to a name and a + * description. Stat names and descriptions should typically be + * set from the constructor usingo from the constructor using the + * ADD_STAT macro. + */ + virtual void regStats(); + + /** + * Callback to reset stats. + */ + virtual void resetStats(); + + /** + * Register a stat with this group. This method is normally called + * automatically when a stat is instantiated. + */ + void addStat(Stats::Info *info); + + /** + * Get all child groups associated with this object. + */ + const std::map<std::string, Group *> &getStatGroups() const; + + /** + * Get all stats associated with this object. + */ + const std::vector<Info *> &getStats() const; + + /** + * Add a stat block as a child of this block + * + * This method may only be called from a Group constructor or from + * regStats. It's typically only called explicitly from Python + * when setting up the SimObject hierarchy. + */ + void addStatGroup(const char *name, Group *block); + + private: + /** + * Merge the contents (stats & children) of a block to this block. + * + * This is called on a parent group by the child when it is being + * merged into the parent. + */ + void mergeStatGroup(Group *block); + + private: + /** Parent pointer if merged into parent */ + Group *const mergedParent; + + std::map<std::string, Group *> statGroups; + std::vector<Group *> mergedStatGroups; + std::vector<Info *> stats; +}; + +} // namespace Stats + +#endif // __BASE_STATS_GROUP_HH__ diff --git a/src/base/stats/output.hh b/src/base/stats/output.hh index 9cd33a5f9..fe3860dfb 100644 --- a/src/base/stats/output.hh +++ b/src/base/stats/output.hh @@ -1,4 +1,16 @@ /* + * Copyright (c) 2019 Arm Limited + * All rights reserved. + * + * The license below extends only to copyright in the software and shall + * not be construed as granting a license to any other intellectual + * property including but not limited to intellectual property relating + * to a hardware implementation of the functionality of the software + * licensed hereunder. You may use the software subject to the license + * terms below provided that you ensure that this notice is replicated + * unmodified and in its entirety in all distributions of the software, + * modified or unmodified, in source code or in binary form. + * * Copyright (c) 2004-2005 The Regents of The University of Michigan * All rights reserved. * @@ -48,10 +60,14 @@ class SparseHistInfo; // Sparse histogram struct Output { virtual ~Output() {} + virtual void begin() = 0; virtual void end() = 0; virtual bool valid() const = 0; + virtual void beginGroup(const char *name) = 0; + virtual void endGroup() = 0; + virtual void visit(const ScalarInfo &info) = 0; virtual void visit(const VectorInfo &info) = 0; virtual void visit(const DistInfo &info) = 0; diff --git a/src/base/stats/text.cc b/src/base/stats/text.cc index 10e94a770..da68188bd 100644 --- a/src/base/stats/text.cc +++ b/src/base/stats/text.cc @@ -1,4 +1,16 @@ /* + * Copyright (c) 2019 Arm Limited + * All rights reserved. + * + * The license below extends only to copyright in the software and shall + * not be construed as granting a license to any other intellectual + * property including but not limited to intellectual property relating + * to a hardware implementation of the functionality of the software + * licensed hereunder. You may use the software subject to the license + * terms below provided that you ensure that this notice is replicated + * unmodified and in its entirety in all distributions of the software, + * modified or unmodified, in source code or in binary form. + * * Copyright (c) 2004-2005 The Regents of The University of Michigan * All rights reserved. * @@ -153,6 +165,32 @@ Text::end() stream->flush(); } +std::string +Text::statName(const std::string &name) const +{ + if (path.empty()) + return name; + else + return csprintf("%s.%s", path.top(), name); +} + +void +Text::beginGroup(const char *name) +{ + if (path.empty()) { + path.push(name); + } else { + path.push(csprintf("%s.%s", path.top(), name)); + } +} + +void +Text::endGroup() +{ + assert(!path.empty()); + path.pop(); +} + bool Text::noOutput(const Info &info) { @@ -368,7 +406,7 @@ DistPrint::DistPrint(const Text *text, const VectorDistInfo &info, int i) void DistPrint::init(const Text *text, const Info &info) { - name = info.name; + name = text->statName(info.name); separatorString = info.separatorString; desc = info.desc; flags = info.flags; @@ -511,7 +549,7 @@ Text::visit(const ScalarInfo &info) ScalarPrint print; print.value = info.result(); - print.name = info.name; + print.name = statName(info.name); print.desc = info.desc; print.flags = info.flags; print.descriptions = descriptions; @@ -531,7 +569,7 @@ Text::visit(const VectorInfo &info) size_type size = info.size(); VectorPrint print; - print.name = info.name; + print.name = statName(info.name); print.separatorString = info.separatorString; print.desc = info.desc; print.flags = info.flags; @@ -606,8 +644,9 @@ Text::visit(const Vector2dInfo &info) total += yvec[j]; } - print.name = info.name + "_" + - (havesub ? info.subnames[i] : std::to_string(i)); + print.name = statName( + info.name + "_" + + (havesub ? info.subnames[i] : std::to_string(i))); print.desc = info.desc; print.vec = yvec; print.total = total; @@ -619,7 +658,7 @@ Text::visit(const Vector2dInfo &info) total_subname.push_back("total"); if (info.flags.isSet(::Stats::total) && (info.x > 1)) { - print.name = info.name; + print.name = statName(info.name); print.subnames = total_subname; print.desc = info.desc; print.vec = VResult(1, info.total()); @@ -687,7 +726,7 @@ SparseHistPrint::SparseHistPrint(const Text *text, const SparseHistInfo &info) void SparseHistPrint::init(const Text *text, const Info &info) { - name = info.name; + name = text->statName(info.name); separatorString = info.separatorString; desc = info.desc; flags = info.flags; diff --git a/src/base/stats/text.hh b/src/base/stats/text.hh index 8bb290a99..c8fba5a19 100644 --- a/src/base/stats/text.hh +++ b/src/base/stats/text.hh @@ -1,4 +1,16 @@ /* + * Copyright (c) 2019 Arm Limited + * All rights reserved. + * + * The license below extends only to copyright in the software and shall + * not be construed as granting a license to any other intellectual + * property including but not limited to intellectual property relating + * to a hardware implementation of the functionality of the software + * licensed hereunder. You may use the software subject to the license + * terms below provided that you ensure that this notice is replicated + * unmodified and in its entirety in all distributions of the software, + * modified or unmodified, in source code or in binary form. + * * Copyright (c) 2004-2005 The Regents of The University of Michigan * All rights reserved. * @@ -32,6 +44,7 @@ #define __BASE_STATS_TEXT_HH__ #include <iosfwd> +#include <stack> #include <string> #include "base/stats/output.hh" @@ -46,6 +59,9 @@ class Text : public Output bool mystream; std::ostream *stream; + // Object/group path + std::stack<std::string> path; + protected: bool noOutput(const Info &info); @@ -60,20 +76,25 @@ class Text : public Output void open(std::ostream &stream); void open(const std::string &file); + std::string statName(const std::string &name) const; // Implement Visit - virtual void visit(const ScalarInfo &info); - virtual void visit(const VectorInfo &info); - virtual void visit(const DistInfo &info); - virtual void visit(const VectorDistInfo &info); - virtual void visit(const Vector2dInfo &info); - virtual void visit(const FormulaInfo &info); - virtual void visit(const SparseHistInfo &info); + void visit(const ScalarInfo &info) override; + void visit(const VectorInfo &info) override; + void visit(const DistInfo &info) override; + void visit(const VectorDistInfo &info) override; + void visit(const Vector2dInfo &info) override; + void visit(const FormulaInfo &info) override; + void visit(const SparseHistInfo &info) override; + + // Group handling + void beginGroup(const char *name) override; + void endGroup() override; // Implement Output - virtual bool valid() const; - virtual void begin(); - virtual void end(); + bool valid() const override; + void begin() override; + void end() override; }; std::string ValueToString(Result value, int precision); |