summaryrefslogtreecommitdiff
path: root/src/util/statistics_registry.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/util/statistics_registry.h')
-rw-r--r--src/util/statistics_registry.h273
1 files changed, 171 insertions, 102 deletions
diff --git a/src/util/statistics_registry.h b/src/util/statistics_registry.h
index 098d88c07..7a714012e 100644
--- a/src/util/statistics_registry.h
+++ b/src/util/statistics_registry.h
@@ -1,6 +1,6 @@
/******************************************************************************
* Top contributors (to current version):
- * Morgan Deters, Gereon Kremer, Tim King
+ * Gereon Kremer
*
* This file is part of the cvc5 project.
*
@@ -10,26 +10,9 @@
* directory for licensing information.
* ****************************************************************************
*
- * Statistics utility classes
- *
- * Statistics utility classes, including classes for holding (and referring
- * to) statistics, the statistics registry, and some other associated
- * classes.
- *
- * This file is somewhat unique in that it is a "cvc5_private_library.h"
- * header. Because of this, most classes need to be marked as CVC4_EXPORT.
- * This is because CVC4_EXPORT is connected to the visibility of the linkage
- * in the object files for the class. It does not dictate what headers are
- * installed.
- * Because the StatisticsRegistry and associated classes are built into
- * libutil, which is used by libcvc4, and then later used by the libmain
- * without referring to libutil as well. Thus the without marking these as
- * CVC4_EXPORT the symbols would be external in libutil, internal in libcvc4,
- * and not be visible to libmain and linking would fail.
- * You can debug this using "nm" on the .so and .o files in the builds/
- * directory. See
- * http://eli.thegreenplace.net/2013/07/09/library-order-in-static-linking
- * for a longer discussion on symbol visibility.
+ * Central statistics registry.
+ *
+ * The StatisticsRegistry that issues statistic proxy objects.
*/
/**
@@ -85,117 +68,203 @@
#ifndef CVC5__STATISTICS_REGISTRY_H
#define CVC5__STATISTICS_REGISTRY_H
-#include <ctime>
-#include <iomanip>
+#include <iostream>
#include <map>
-#include <sstream>
-#include <vector>
-
-#ifdef CVC5_STATISTICS_ON
-#define CVC5_USE_STATISTICS true
-#else
-#define CVC5_USE_STATISTICS false
-#endif
+#include <memory>
+#include <typeinfo>
-#include "base/exception.h"
-#include "cvc4_export.h"
-#include "util/safe_print.h"
-#include "util/statistics.h"
-#include "util/stats_base.h"
+#include "base/check.h"
+#include "util/statistics_stats.h"
+#include "util/statistics_value.h"
namespace cvc5 {
-/** A statistic that contains a SExpr. */
-class SExprStat : public Stat {
-private:
- SExpr d_data;
+struct StatisticBaseValue;
-public:
+/**
+ * The central registry for statistics.
+ * Internally stores statistic data objects and issues corresponding proxy
+ * objects to modules that want to expose statistics.
+ * Provides registration methods (e.g. `registerAverage` or
+ * `registerHistogram<T>`) that return the proxy object.
+ * The different statistics are explained in more detail in statistics_stats.h
+ *
+ * Every statistic is identified by a name. If a statistic with the given
+ * name is already registered, the registry issues another proxy object
+ * for that name using the same data it already holds for this name.
+ * While this makes perfect sense for most statistic types, it may lead to
+ * unexpected (though not undefined) behaviour for others. For a reference
+ * statistic, for example, the internal data will simply point to the object
+ * registered last.
+ * Note that the type of the re-registered statistic must always match
+ * the type of the previously registered statistic with the same name.
+ *
+ * We generally distinguish between public (non-expert) and private (expert)
+ * statistics. By default, `--stats` only shows public statistics. Private
+ * ones are printed as well if `--all-statistics` is set.
+ * All registration methods have a trailing argument `expert`, defaulting to
+ * true.
+ *
+ * If statistics are disabled entirely (i.e. the cmake option
+ * `ENABLE_STATISTICS` is not set), the registry still issues proxy objects
+ * that can be used normally.
+ * However, no data is stored in the registry and the modification functions
+ * of the proxy objects do nothing.
+ */
+class StatisticsRegistry
+{
+ public:
+ friend std::ostream& operator<<(std::ostream& os,
+ const StatisticsRegistry& sr);
+
+ using Snapshot = std::map<std::string, StatExportData>;
/**
- * Construct a SExpr-valued statistic with the given name and
- * initial value.
+ * If `registerPublic` is true, all statistics that are public are
+ * pre-registered as such. This argument mostly exists so that unit tests
+ * can disable this pre-registration.
*/
- SExprStat(const std::string& name, const SExpr& init) :
- Stat(name), d_data(init){}
+ StatisticsRegistry(bool registerPublic = true);
- void flushInformation(std::ostream& out) const override
+ /** Register a new running average statistic for `name` */
+
+ AverageStat registerAverage(const std::string& name, bool expert = true);
+ /** Register a new histogram statistic for `name` */
+ template <typename T>
+ HistogramStat<T> registerHistogram(const std::string& name,
+ bool expert = true)
{
- out << d_data;
+ return registerStat<HistogramStat<T>>(name, expert);
}
- void safeFlushInformation(int fd) const override
+ /** Register a new integer statistic for `name` */
+ IntStat registerInt(const std::string& name, bool expert = true);
+
+ /** Register a new reference statistic for `name` */
+ template <typename T>
+ ReferenceStat<T> registerReference(const std::string& name,
+ bool expert = true)
{
- // SExprStat is only used in statistics.cpp in copyFrom, which we cannot
- // do in a signal handler anyway.
- safe_print(fd, "<unsupported>");
+ return registerStat<ReferenceStat<T>>(name, expert);
+ }
+ /**
+ * Register a new reference statistic for `name` and initialize it to
+ * refer to `t`.
+ */
+ template <typename T>
+ ReferenceStat<T> registerReference(const std::string& name,
+ const T& t,
+ bool expert = true)
+ {
+ ReferenceStat<T> res = registerStat<ReferenceStat<T>>(name, expert);
+ res.set(t);
+ return res;
}
- SExpr getValue() const override { return d_data; }
-
-};/* class SExprStat */
+ /**
+ * Register a new container size statistic for `name` and initialize it
+ * to refer to `t`.
+ */
+ template <typename T>
+ SizeStat<T> registerSize(const std::string& name,
+ const T& t,
+ bool expert = true)
+ {
+ SizeStat<T> res = registerStat<SizeStat<T>>(name, expert);
+ res.set(t);
+ return res;
+ }
-/****************************************************************************/
-/* Statistics Registry */
-/****************************************************************************/
+ /** Register a new timer statistic for `name` */
+ TimerStat registerTimer(const std::string& name, bool expert = true);
-/**
- * The main statistics registry. This registry maintains the list of
- * currently active statistics and is able to "flush" them all.
- */
-class CVC4_EXPORT StatisticsRegistry : public StatisticsBase
-{
- private:
- /** Private copy constructor undefined (no copy permitted). */
- StatisticsRegistry(const StatisticsRegistry&) = delete;
+ /** Register a new value statistic for `name`. */
+ template <typename T>
+ ValueStat<T> registerValue(const std::string& name, bool expert = true)
+ {
+ return registerStat<ValueStat<T>>(name, expert);
+ }
-public:
+ /** Register a new value statistic for `name` and set it to `init`. */
+ template <typename T>
+ ValueStat<T> registerValue(const std::string& name,
+ const T& init,
+ bool expert = true)
+ {
+ ValueStat<T> res = registerStat<ValueStat<T>>(name, expert);
+ res.set(init);
+ return res;
+ }
- /** Construct an nameless statistics registry */
- StatisticsRegistry() {}
+ /** begin iteration */
+ auto begin() const { return d_stats.begin(); }
+ /** end iteration */
+ auto end() const { return d_stats.end(); }
- void flushStat(std::ostream& out) const;
+ /**
+ * Obtain the current state of all statistics.
+ */
+ void storeSnapshot();
- void flushInformation(std::ostream& out) const;
+ /**
+ * Obtain a single statistic by name. Returns nullptr if no statistic has
+ * been registered for this name.
+ */
+ StatisticBaseValue* get(const std::string& name) const;
- void safeFlushInformation(int fd) const;
+ /**
+ * Print all statistics to the given output stream.
+ */
+ void print(std::ostream& os) const;
+ /**
+ * Print all statistics in a safe manner to the given file descriptor.
+ */
+ void printSafe(int fd) const;
+ /**
+ * Print all statistics as a diff to the last stored snapshot.
+ */
+ void printDiff(std::ostream& os) const;
- SExpr getValue() const
+ private:
+ /**
+ * Helper method to register a new statistic.
+ * If the name was already used, a new proxy object is created.
+ * We check whether the type matches the type of the originally registered
+ * statistic using `typeid`.
+ */
+ template <typename Stat>
+ Stat registerStat(const std::string& name, bool expert)
{
- std::vector<SExpr> v;
- for(StatSet::iterator i = d_stats.begin(); i != d_stats.end(); ++i) {
- std::vector<SExpr> w;
- w.push_back(SExpr((*i)->getName()));
- w.push_back((*i)->getValue());
- v.push_back(SExpr(w));
+ if constexpr (Configuration::isStatisticsBuild())
+ {
+ auto it = d_stats.find(name);
+ if (it == d_stats.end())
+ {
+ it = d_stats.emplace(name, std::make_unique<typename Stat::stat_type>())
+ .first;
+ it->second->d_expert = expert;
+ }
+ auto* ptr = it->second.get();
+ Assert(typeid(*ptr) == typeid(typename Stat::stat_type))
+ << "Statistic value " << name
+ << " was registered again with a different type.";
+ it->second->d_expert = it->second->d_expert && expert;
+ return Stat(static_cast<typename Stat::stat_type*>(ptr));
}
- return SExpr(v);
+ return Stat(nullptr);
}
- /** Register a new statistic */
- void registerStat(Stat* s);
-
- /** Unregister a new statistic */
- void unregisterStat(Stat* s);
-
-}; /* class StatisticsRegistry */
-
-/**
- * Resource-acquisition-is-initialization idiom for statistics
- * registry. Useful for stack-based statistics (like in the driver).
- * This RAII class only does registration and unregistration.
- */
-class CVC4_EXPORT RegisterStatistic
-{
- public:
- RegisterStatistic(StatisticsRegistry* reg, Stat* stat);
- ~RegisterStatistic();
+ /**
+ * Holds (and owns) all statistic values, indexed by the name they were
+ * registered for.
+ */
+ std::map<std::string, std::unique_ptr<StatisticBaseValue>> d_stats;
-private:
- StatisticsRegistry* d_reg;
- Stat* d_stat;
+ std::unique_ptr<Snapshot> d_lastSnapshot;
+};
-}; /* class RegisterStatistic */
+/** Calls `sr.print(os)`. */
+std::ostream& operator<<(std::ostream& os, const StatisticsRegistry& sr);
} // namespace cvc5
generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback