Jason Lowe-Power has uploaded this change for review. ( https://gem5-review.googlesource.com/c/public/gem5/+/35575 )

Change subject: base: Add JSON output for stats
......................................................................

base: Add JSON output for stats

This patch adds the initial code to allow JSON file output for stats.
No options, yet. All "new style" stats are correctly nested under their
parents, but the "old style" are just keys containing their entire
name. Only scalar stats are currently supported.

Change-Id: If6f98fbad7f61dd6f87ac9c409e54e2724807de6
Signed-off-by: Jason Lowe-Power <ja...@lowepower.com>
---
M src/base/SConscript
A src/base/stats/json.cc
A src/base/stats/json.hh
M src/python/m5/stats/__init__.py
M src/python/pybind11/stats.cc
5 files changed, 262 insertions(+), 0 deletions(-)



diff --git a/src/base/SConscript b/src/base/SConscript
index e04d84a..c464ab2 100644
--- a/src/base/SConscript
+++ b/src/base/SConscript
@@ -76,6 +76,7 @@
 GTest('uncontended_mutex.test', 'uncontended_mutex.test.cc')

 Source('stats/group.cc')
+Source('stats/json.cc')
 Source('stats/text.cc')
 if env['USE_HDF5']:
     if main['GCC']:
diff --git a/src/base/stats/json.cc b/src/base/stats/json.cc
new file mode 100644
index 0000000..0dc5472
--- /dev/null
+++ b/src/base/stats/json.cc
@@ -0,0 +1,161 @@
+/* Copyright (c) 2020 The Regents of The University of California
+ * All rights reserved.
+ *
+ * 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.
+ */
+
+
+#include "base/stats/json.hh"
+
+#include "base/logging.hh"
+#include "base/stats/info.hh"
+#include "base/str.hh"
+
+namespace Stats
+{
+
+void
+Json::begin()
+{
+    ccprintf(*stream, "{");
+}
+
+void
+Json::end()
+{
+    ccprintf(*stream, "}");
+}
+
+void
+Json::printComma()
+{
+    // Note: json doesn't allow trailing commas. So, we are going to put a
+    // comma *before* every entry except the first
+    if (!_first.top()) {
+        ccprintf(*stream, ",");
+    } else {
+ // If this is the first element in the section, replace the top "true"
+        // with false.
+        _first.pop();
+        _first.push(false);
+    }
+}
+
+void
+Json::beginGroup(const char *name)
+{
+    printComma();
+
+    _first.push(true);
+
+    ccprintf(*stream, "\"%s\":{", name);
+}
+
+void
+Json::endGroup()
+{
+    _first.pop();
+    ccprintf(*stream, "}");
+}
+
+void
+Json::visit(const ScalarInfo &info)
+{
+    if (noOutput(info))
+        return;
+
+    printComma();
+
+    ccprintf(*stream, "\"%s\":%s", info.name,
+             ValueToString(info.result(), info.precision));
+}
+
+void
+Json::visit(const VectorInfo &info)
+{
+    if (noOutput(info))
+        return;
+
+    warn_once("json output does not support vectors");
+}
+
+void
+Json::visit(const DistInfo &info)
+{
+    if (noOutput(info))
+        return;
+
+    warn_once("json output does not support distributions");
+}
+
+void
+Json::visit(const VectorDistInfo &info)
+{
+    if (noOutput(info))
+        return;
+
+    warn_once("json output does not support vector distributions");
+}
+
+void
+Json::visit(const Vector2dInfo &info)
+{
+    if (noOutput(info))
+        return;
+
+    warn_once("json output does not support 2D vectors");
+}
+
+void
+Json::visit(const FormulaInfo &info)
+{
+    if (noOutput(info))
+        return;
+
+    warn_once("json output does not support formulas");
+}
+
+void
+Json::visit(const SparseHistInfo &info)
+{
+    if (noOutput(info))
+        return;
+
+    warn_once("json output does not support sparse histograms");
+}
+
+Output *initJson(const std::string &filename)
+{
+    static Json json;
+    static bool connected = false;
+
+    if (!connected) {
+        json.open(*simout.findOrCreate(filename)->stream());
+        connected = true;
+    }
+
+    return &json;
+}
+
+} // namespace stats
diff --git a/src/base/stats/json.hh b/src/base/stats/json.hh
new file mode 100644
index 0000000..9723211
--- /dev/null
+++ b/src/base/stats/json.hh
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2004-2005 The Regents of The University of California
+ * All rights reserved.
+ *
+ * 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.
+ */
+
+#ifndef __BASE_STATS_JSON_HH__
+#define __BASE_STATS_JSON_HH__
+
+#include <iosfwd>
+#include <stack>
+
+#include "base/stats/output.hh"
+#include "base/stats/text.hh"
+#include "base/stats/types.hh"
+
+namespace Stats {
+
+class Json : public Text
+{
+  private:
+
+    /// Stack to know if this is the first member in an object
+    std::stack<bool> _first;
+
+    /**
+     * Helper function to print commas only after the first member and not
+     * after the last.
+     */
+    void printComma();
+
+  public:
+    Json(): Text() { _first.push(true); }
+    Json(std::ostream &stream): Text(stream) { _first.push(true); }
+    Json(const std::string &file): Text(file) { _first.push(true); }
+
+    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
+    void begin() override;
+    void end() override;
+
+};
+
+Output *initJson(const std::string &filename);
+
+} // namespace stats
+
+#endif // __BASE_STATS_JSON_HH__
diff --git a/src/python/m5/stats/__init__.py b/src/python/m5/stats/__init__.py
index 6c4a42c..20867da 100644
--- a/src/python/m5/stats/__init__.py
+++ b/src/python/m5/stats/__init__.py
@@ -149,6 +149,23 @@

     return _m5.stats.initText(fn, desc, spaces)

+@_url_factory([ "json", ])
+def _textFactory(fn):
+    """Output stats in json format.
+
+ Simple json file for stat output. No options, yet. All "new style" stats + are correctly nested under their parents, but the "old style" are just keys + containing their entire name. Only scalar stats are currently supported.
+
+    Parameters:
+
+    Example:
+      json://stats.json
+
+    """
+
+    return _m5.stats.initJson(fn)
+
 @_url_factory([ "h5", ], enable=hasattr(_m5.stats, "initHDF5"))
 def _hdf5Factory(fn, chunking=10, desc=True, formulas=True):
     """Output stats in HDF5 format.
diff --git a/src/python/pybind11/stats.cc b/src/python/pybind11/stats.cc
index b146aa3..8ac46c2 100644
--- a/src/python/pybind11/stats.cc
+++ b/src/python/pybind11/stats.cc
@@ -44,6 +44,7 @@
 #include "pybind11/stl.h"

 #include "base/statistics.hh"
+#include "base/stats/json.hh"
 #include "base/stats/text.hh"
 #if USE_HDF5
 #include "base/stats/hdf5.hh"
@@ -99,6 +100,7 @@
     m
         .def("initSimStats", &Stats::initSimStats)
.def("initText", &Stats::initText, py::return_value_policy::reference) + .def("initJson", &Stats::initJson, py::return_value_policy::reference)
 #if USE_HDF5
         .def("initHDF5", &Stats::initHDF5)
 #endif

--
To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/35575
To unsubscribe, or for help writing mail filters, visit https://gem5-review.googlesource.com/settings

Gerrit-Project: public/gem5
Gerrit-Branch: develop
Gerrit-Change-Id: If6f98fbad7f61dd6f87ac9c409e54e2724807de6
Gerrit-Change-Number: 35575
Gerrit-PatchSet: 1
Gerrit-Owner: Jason Lowe-Power <power...@gmail.com>
Gerrit-MessageType: newchange
_______________________________________________
gem5-dev mailing list -- gem5-dev@gem5.org
To unsubscribe send an email to gem5-dev-le...@gem5.org
%(web_page_url)slistinfo%(cgiext)s/%(_internal_name)s

Reply via email to