diff --git a/src/base/SConscript b/src/base/SConscript --- a/src/base/SConscript +++ b/src/base/SConscript @@ -71,8 +71,6 @@ Source('loader/raw_object.cc') Source('loader/symtab.cc') -Source('stats/text.cc') - DebugFlag('Annotate', "State machine annotation debugging") DebugFlag('AnnotateQ', "State machine annotation queue debugging") DebugFlag('AnnotateVerbose', "Dump all state machine annotation details") diff --git a/src/base/statistics.hh b/src/base/statistics.hh --- a/src/base/statistics.hh +++ b/src/base/statistics.hh @@ -61,7 +61,6 @@ #include #include "base/stats/info.hh" -#include "base/stats/output.hh" #include "base/stats/types.hh" #include "base/cast.hh" #include "base/cprintf.hh" @@ -90,11 +89,6 @@ bool check() const { return s.check(); } void prepare() { s.prepare(); } void reset() { s.reset(); } - void - visit(Output &visitor) - { - visitor.visit(*static_cast(this)); - } bool zero() const { return s.zero(); } }; @@ -738,8 +732,6 @@ void prepare() { } void reset() { } bool zero() const { return value() == 0; } - - void visit(Output &visitor) { visitor.visit(*this); } }; template diff --git a/src/base/stats/info.hh b/src/base/stats/info.hh --- a/src/base/stats/info.hh +++ b/src/base/stats/info.hh @@ -62,7 +62,6 @@ const FlagsType __reserved = init | display; struct StorageParams; -struct Output; class Info { @@ -127,11 +126,6 @@ virtual bool zero() const = 0; /** - * Visitor entry for outputing statistics data - */ - virtual void visit(Output &visitor) = 0; - - /** * Checks if the first stat's name is alphabetically less than the second. * This function breaks names up at periods and considers each subname * separately. diff --git a/src/base/stats/output.hh b/src/base/stats/output.hh --- a/src/base/stats/output.hh +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (c) 2004-2005 The Regents of The University of Michigan - * 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. - * - * Authors: Nathan Binkert - */ - -#ifndef __BASE_STATS_OUTPUT_HH__ -#define __BASE_STATS_OUTPUT_HH__ - -#include -#include - -namespace Stats { - -class Info; -class ScalarInfo; -class VectorInfo; -class DistInfo; -class VectorDistInfo; -class Vector2dInfo; -class FormulaInfo; -class SparseHistInfo; // Sparse histogram - -struct Output -{ - virtual ~Output() {} - virtual void begin() = 0; - virtual void end() = 0; - virtual bool valid() const = 0; - - virtual void visit(const ScalarInfo &info) = 0; - virtual void visit(const VectorInfo &info) = 0; - virtual void visit(const DistInfo &info) = 0; - virtual void visit(const VectorDistInfo &info) = 0; - virtual void visit(const Vector2dInfo &info) = 0; - virtual void visit(const FormulaInfo &info) = 0; - virtual void visit(const SparseHistInfo &info) = 0; // Sparse histogram -}; - -} // namespace Stats - -#endif // __BASE_STATS_OUTPUT_HH__ diff --git a/src/base/stats/text.hh b/src/base/stats/text.hh --- a/src/base/stats/text.hh +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright (c) 2004-2005 The Regents of The University of Michigan - * 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. - * - * Authors: Nathan Binkert - */ - -#ifndef __BASE_STATS_TEXT_HH__ -#define __BASE_STATS_TEXT_HH__ - -#include -#include - -#include "base/stats/output.hh" -#include "base/output.hh" - -namespace Stats { - -class Text : public Output -{ - protected: - bool mystream; - std::ostream *stream; - - protected: - bool noOutput(const Info &info); - - public: - bool descriptions; - - public: - Text(); - Text(std::ostream &stream); - Text(const std::string &file); - ~Text(); - - void open(std::ostream &stream); - void open(const std::string &file); - - // 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); - - // Implement Output - virtual bool valid() const; - virtual void begin(); - virtual void end(); -}; - -Output *initText(const std::string &filename, bool desc); - -} // namespace Stats - -#endif // __BASE_STATS_TEXT_HH__ diff --git a/src/base/stats/text.cc b/src/base/stats/text.cc --- a/src/base/stats/text.cc +++ /dev/null @@ -1,702 +0,0 @@ -/* - * Copyright (c) 2004-2005 The Regents of The University of Michigan - * 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. - * - * Authors: Nathan Binkert - */ - -#if defined(__APPLE__) -#define _GLIBCPP_USE_C99 1 -#endif - -#if defined(__sun) -#include -#endif - -#include -#ifdef __SUNPRO_CC -#include -#endif -#include -#include -#include -#include -#include - -#include "base/stats/info.hh" -#include "base/stats/text.hh" -#include "base/cast.hh" -#include "base/misc.hh" -#include "base/str.hh" - -using namespace std; - -#ifndef NAN -float __nan(); -/** Define Not a number. */ -#define NAN (__nan()) -/** Need to define __nan() */ -#define __M5_NAN -#endif - -#ifdef __M5_NAN -float -__nan() -{ - union { - uint32_t ui; - float f; - } nan; - - nan.ui = 0x7fc00000; - return nan.f; -} -#endif - -namespace Stats { - -std::list &statsList(); - -Text::Text() - : mystream(false), stream(NULL), descriptions(false) -{ -} - -Text::Text(std::ostream &stream) - : mystream(false), stream(NULL), descriptions(false) -{ - open(stream); -} - -Text::Text(const std::string &file) - : mystream(false), stream(NULL), descriptions(false) -{ - open(file); -} - - -Text::~Text() -{ - if (mystream) { - assert(stream); - delete stream; - } -} - -void -Text::open(std::ostream &_stream) -{ - if (stream) - panic("stream already set!"); - - mystream = false; - stream = &_stream; - if (!valid()) - fatal("Unable to open output stream for writing\n"); -} - -void -Text::open(const std::string &file) -{ - if (stream) - panic("stream already set!"); - - mystream = true; - stream = new ofstream(file.c_str(), ios::trunc); - if (!valid()) - fatal("Unable to open statistics file for writing\n"); -} - -bool -Text::valid() const -{ - return stream != NULL && stream->good(); -} - -void -Text::begin() -{ - ccprintf(*stream, "\n---------- Begin Simulation Statistics ----------\n"); -} - -void -Text::end() -{ - ccprintf(*stream, "\n---------- End Simulation Statistics ----------\n"); - stream->flush(); -} - -bool -Text::noOutput(const Info &info) -{ - if (!info.flags.isSet(display)) - return true; - - if (info.prereq && info.prereq->zero()) - return true; - - return false; -} - -string -ValueToString(Result value, int precision) -{ - stringstream val; - - if (!std::isnan(value)) { - if (precision != -1) - val.precision(precision); - else if (value == rint(value)) - val.precision(0); - - val.unsetf(ios::showpoint); - val.setf(ios::fixed); - val << value; - } else { - val << "nan"; - } - - return val.str(); -} - -struct ScalarPrint -{ - Result value; - string name; - string desc; - Flags flags; - bool descriptions; - int precision; - Result pdf; - Result cdf; - - void update(Result val, Result total); - void operator()(ostream &stream) const; -}; - -void -ScalarPrint::update(Result val, Result total) -{ - value = val; - if (total) { - pdf = val / total; - cdf += pdf; - } -} - -void -ScalarPrint::operator()(ostream &stream) const -{ - if ((flags.isSet(nozero) && value == 0.0) || - (flags.isSet(nonan) && std::isnan(value))) - return; - - stringstream pdfstr, cdfstr; - - if (!std::isnan(pdf)) - ccprintf(pdfstr, "%.2f%%", pdf * 100.0); - - if (!std::isnan(cdf)) - ccprintf(cdfstr, "%.2f%%", cdf * 100.0); - - ccprintf(stream, "%-40s %12s %10s %10s", name, - ValueToString(value, precision), pdfstr, cdfstr); - - if (descriptions) { - if (!desc.empty()) - ccprintf(stream, " # %s", desc); - } - stream << endl; -} - -struct VectorPrint -{ - string name; - string separatorString; - string desc; - vector subnames; - vector subdescs; - Flags flags; - bool descriptions; - int precision; - VResult vec; - Result total; - - void operator()(ostream &stream) const; -}; - -void -VectorPrint::operator()(std::ostream &stream) const -{ - size_type _size = vec.size(); - Result _total = 0.0; - - if (flags.isSet(pdf | cdf)) { - for (off_type i = 0; i < _size; ++i) { - _total += vec[i]; - } - } - - string base = name + separatorString; - - ScalarPrint print; - print.name = name; - print.desc = desc; - print.precision = precision; - print.descriptions = descriptions; - print.flags = flags; - print.pdf = _total ? 0.0 : NAN; - print.cdf = _total ? 0.0 : NAN; - - bool havesub = !subnames.empty(); - - if (_size == 1) { - print.value = vec[0]; - print(stream); - return; - } - - for (off_type i = 0; i < _size; ++i) { - if (havesub && (i >= subnames.size() || subnames[i].empty())) - continue; - - print.name = base + (havesub ? subnames[i] : to_string(i)); - print.desc = subdescs.empty() ? desc : subdescs[i]; - - print.update(vec[i], _total); - print(stream); - } - - if (flags.isSet(::Stats::total)) { - print.pdf = NAN; - print.cdf = NAN; - print.name = base + "total"; - print.desc = desc; - print.value = total; - print(stream); - } -} - -struct DistPrint -{ - string name; - string separatorString; - string desc; - Flags flags; - bool descriptions; - int precision; - - const DistData &data; - - DistPrint(const Text *text, const DistInfo &info); - DistPrint(const Text *text, const VectorDistInfo &info, int i); - void init(const Text *text, const Info &info); - void operator()(ostream &stream) const; -}; - -DistPrint::DistPrint(const Text *text, const DistInfo &info) - : data(info.data) -{ - init(text, info); -} - -DistPrint::DistPrint(const Text *text, const VectorDistInfo &info, int i) - : data(info.data[i]) -{ - init(text, info); - - name = info.name + "_" + - (info.subnames[i].empty() ? (to_string(i)) : info.subnames[i]); - - if (!info.subdescs[i].empty()) - desc = info.subdescs[i]; -} - -void -DistPrint::init(const Text *text, const Info &info) -{ - name = info.name; - separatorString = info.separatorString; - desc = info.desc; - flags = info.flags; - precision = info.precision; - descriptions = text->descriptions; -} - -void -DistPrint::operator()(ostream &stream) const -{ - string base = name + separatorString; - - ScalarPrint print; - print.precision = precision; - print.flags = flags; - print.descriptions = descriptions; - print.desc = desc; - print.pdf = NAN; - print.cdf = NAN; - - print.name = base + "samples"; - print.value = data.samples; - print(stream); - - print.name = base + "mean"; - print.value = data.samples ? data.sum / data.samples : NAN; - print(stream); - - if (data.type == Hist) { - print.name = base + "gmean"; - print.value = data.samples ? exp(data.logs / data.samples) : NAN; - print(stream); - } - - Result stdev = NAN; - if (data.samples) - stdev = sqrt((data.samples * data.squares - data.sum * data.sum) / - (data.samples * (data.samples - 1.0))); - print.name = base + "stdev"; - print.value = stdev; - print(stream); - - if (data.type == Deviation) - return; - - size_t size = data.cvec.size(); - - Result total = 0.0; - if (data.type == Dist && data.underflow != NAN) - total += data.underflow; - for (off_type i = 0; i < size; ++i) - total += data.cvec[i]; - if (data.type == Dist && data.overflow != NAN) - total += data.overflow; - - if (total) { - print.pdf = 0.0; - print.cdf = 0.0; - } - - if (data.type == Dist && data.underflow != NAN) { - print.name = base + "underflows"; - print.update(data.underflow, total); - print(stream); - } - - for (off_type i = 0; i < size; ++i) { - stringstream namestr; - namestr << base; - - Counter low = i * data.bucket_size + data.min; - Counter high = ::min(low + data.bucket_size - 1.0, data.max); - namestr << low; - if (low < high) - namestr << "-" << high; - - print.name = namestr.str(); - print.update(data.cvec[i], total); - print(stream); - } - - if (data.type == Dist && data.overflow != NAN) { - print.name = base + "overflows"; - print.update(data.overflow, total); - print(stream); - } - - print.pdf = NAN; - print.cdf = NAN; - - if (data.type == Dist && data.min_val != NAN) { - print.name = base + "min_value"; - print.value = data.min_val; - print(stream); - } - - if (data.type == Dist && data.max_val != NAN) { - print.name = base + "max_value"; - print.value = data.max_val; - print(stream); - } - - print.name = base + "total"; - print.value = total; - print(stream); -} - -void -Text::visit(const ScalarInfo &info) -{ - if (noOutput(info)) - return; - - ScalarPrint print; - print.value = info.result(); - print.name = info.name; - print.desc = info.desc; - print.flags = info.flags; - print.descriptions = descriptions; - print.precision = info.precision; - print.pdf = NAN; - print.cdf = NAN; - - print(*stream); -} - -void -Text::visit(const VectorInfo &info) -{ - if (noOutput(info)) - return; - - size_type size = info.size(); - VectorPrint print; - - print.name = info.name; - print.separatorString = info.separatorString; - print.desc = info.desc; - print.flags = info.flags; - print.descriptions = descriptions; - print.precision = info.precision; - print.vec = info.result(); - print.total = info.total(); - - if (!info.subnames.empty()) { - for (off_type i = 0; i < size; ++i) { - if (!info.subnames[i].empty()) { - print.subnames = info.subnames; - print.subnames.resize(size); - for (off_type i = 0; i < size; ++i) { - if (!info.subnames[i].empty() && - !info.subdescs[i].empty()) { - print.subdescs = info.subdescs; - print.subdescs.resize(size); - break; - } - } - break; - } - } - } - - print(*stream); -} - -void -Text::visit(const Vector2dInfo &info) -{ - if (noOutput(info)) - return; - - bool havesub = false; - VectorPrint print; - - if (!info.y_subnames.empty()) { - for (off_type i = 0; i < info.y; ++i) { - if (!info.y_subnames[i].empty()) { - print.subnames = info.y_subnames; - } - break; - } - } - print.flags = info.flags; - print.separatorString = info.separatorString; - print.descriptions = descriptions; - print.precision = info.precision; - - if (!info.subnames.empty()) { - for (off_type i = 0; i < info.x; ++i) - if (!info.subnames[i].empty()) - havesub = true; - } - - VResult tot_vec(info.y); - Result super_total = 0.0; - for (off_type i = 0; i < info.x; ++i) { - if (havesub && (i >= info.subnames.size() || info.subnames[i].empty())) - continue; - - off_type iy = i * info.y; - VResult yvec(info.y); - - Result total = 0.0; - for (off_type j = 0; j < info.y; ++j) { - yvec[j] = info.cvec[iy + j]; - tot_vec[j] += yvec[j]; - total += yvec[j]; - super_total += yvec[j]; - } - - print.name = info.name + "_" + - (havesub ? info.subnames[i] : to_string(i)); - print.desc = info.desc; - print.vec = yvec; - print.total = total; - print(*stream); - } - - if (info.flags.isSet(::Stats::total) && (info.x > 1)) { - print.name = info.name; - print.desc = info.desc; - print.vec = tot_vec; - print.total = super_total; - print(*stream); - } -} - -void -Text::visit(const DistInfo &info) -{ - if (noOutput(info)) - return; - - DistPrint print(this, info); - print(*stream); -} - -void -Text::visit(const VectorDistInfo &info) -{ - if (noOutput(info)) - return; - - for (off_type i = 0; i < info.size(); ++i) { - DistPrint print(this, info, i); - print(*stream); - } -} - -void -Text::visit(const FormulaInfo &info) -{ - visit((const VectorInfo &)info); -} - -/* - This struct implements the output methods for the sparse - histogram stat -*/ -struct SparseHistPrint -{ - string name; - string separatorString; - string desc; - Flags flags; - bool descriptions; - int precision; - - const SparseHistData &data; - - SparseHistPrint(const Text *text, const SparseHistInfo &info); - void init(const Text *text, const Info &info); - void operator()(ostream &stream) const; -}; - -/* Call initialization function */ -SparseHistPrint::SparseHistPrint(const Text *text, const SparseHistInfo &info) - : data(info.data) -{ - init(text, info); -} - -/* Initialization function */ -void -SparseHistPrint::init(const Text *text, const Info &info) -{ - name = info.name; - separatorString = info.separatorString; - desc = info.desc; - flags = info.flags; - precision = info.precision; - descriptions = text->descriptions; -} - -/* Grab data from map and write to output stream */ -void -SparseHistPrint::operator()(ostream &stream) const -{ - string base = name + separatorString; - - ScalarPrint print; - print.precision = precision; - print.flags = flags; - print.descriptions = descriptions; - print.desc = desc; - print.pdf = NAN; - print.cdf = NAN; - - print.name = base + "samples"; - print.value = data.samples; - print(stream); - - MCounter::const_iterator it; - for (it = data.cmap.begin(); it != data.cmap.end(); it++) { - stringstream namestr; - namestr << base; - - namestr <<(*it).first; - print.name = namestr.str(); - print.value = (*it).second; - print(stream); - } - - print.pdf = NAN; - print.cdf = NAN; - - print.name = base + "total"; - print.value = total; - print(stream); -} - -void -Text::visit(const SparseHistInfo &info) -{ - if (noOutput(info)) - return; - - SparseHistPrint print(this, info); - print(*stream); -} - -Output * -initText(const string &filename, bool desc) -{ - static Text text; - static bool connected = false; - - if (!connected) { - ostream *os = simout.find(filename); - if (!os) - os = simout.create(filename); - - text.open(*os); - text.descriptions = desc; - connected = true; - } - - return &text; -} - -} // namespace Stats diff --git a/src/python/m5/core.py b/src/python/m5/core.py --- a/src/python/m5/core.py +++ b/src/python/m5/core.py @@ -28,5 +28,29 @@ import internal -def setOutputDir(dir): - internal.core.setOutputDir(dir) +outputDirectory = None +def setOutputDir(outdir): + global outputDirectory + outputDirectory = outdir + internal.core.setOutputDir(outdir) + +def openOutputFile(filename, mode): + import os + import sys + + if filename in ("cerr", "stderr"): + return sys.stderr + + if filename in ("cout", "stdout"): + return sys.stdout + + path = os.path.join(outputDirectory, filename) + if filename.endswith('.gz'): + import gzip + return gzip.GzipFile(path, mode) + + if filename.endswith('.bz2'): + import bz2 + return bz2.BZ2File(path, mode) + + return file(path, mode) diff --git a/src/python/m5/stats/__init__.py b/src/python/m5/stats/__init__.py --- a/src/python/m5/stats/__init__.py +++ b/src/python/m5/stats/__init__.py @@ -35,11 +35,6 @@ from m5.stats.context import stat_context from m5.util import attrdict, fatal, panic, SortedDict -outputList = [] -def initText(filename, desc=True): - output = internal.stats.initText(filename, desc) - outputList.append(output) - def initSimStats(): internal.stats.initSimStats() @@ -236,15 +231,35 @@ shelf['info%d' % stat.id] = stat._info shelf['value%d' % stat.id] = stat.value -def display_text(context): - from m5.stats.display import display +class display_text(object): + def __init__(self, filename, desc): + self.filename = filename + self.desc = desc - print - print "---------- Begin Simulation Statistics ----------" - for name,stat in context.iterate(): - display(stat) - print - print "---------- End Simulation Statistics ----------" + def __call__(self, context): + from m5.stats import display + + save_desc = display.descriptions + display.descriptions = self.desc + + f = m5.core.openOutputFile(self.filename, 'a') + + print >>f + print >>f, "---------- Begin Simulation Statistics ----------" + + for name,stat in context.iterate(): + display.display(stat, f) + + print >>f + print >>f, "---------- End Simulation Statistics ----------" + f.close() + + display.descriptions = save_desc + +outputList = [] +def initText(filename, desc=True): + output = display_text(filename, desc) + outputList.append(output) lastDump = 0 def dump(): @@ -260,7 +275,8 @@ stats = gather_stats() context = make_context(stats) - display_text(context) + for output in outputList: + output(context) def reset(): '''Reset all statistics to the base state''' diff --git a/src/python/swig/stats.i b/src/python/swig/stats.i --- a/src/python/swig/stats.i +++ b/src/python/swig/stats.i @@ -37,7 +37,6 @@ %include %{ -#include "base/stats/text.hh" #include "base/stats/types.hh" #include "base/callback.hh" #include "base/misc.hh" @@ -119,7 +118,6 @@ %import "base/stats/types.hh" %include "base/stats/info.hh" -%include "base/stats/output.hh" namespace std { %template(list_info) list; @@ -142,7 +140,6 @@ %template(dynamic_SparseHistInfo) cast_info; void initSimStats(); -Output *initText(const std::string &filename, bool desc); void schedStatEvent(bool dump, bool reset, Tick when = curTick(), Tick repeat = 0); diff --git a/src/unittest/stattest.cc b/src/unittest/stattest.cc --- a/src/unittest/stattest.cc +++ b/src/unittest/stattest.cc @@ -104,17 +104,23 @@ void init(); }; -StatTest __stattest; +StatTest & +__stattest() +{ + static StatTest st; + return st; +} + void stattest_init() { - __stattest.init(); + __stattest().init(); } void stattest_run() { - __stattest.run(); + __stattest().run(); } void diff --git a/src/unittest/stattestmain.py b/src/unittest/stattestmain.py --- a/src/unittest/stattestmain.py +++ b/src/unittest/stattestmain.py @@ -6,7 +6,6 @@ # Initialize the global statistics m5.stats.initSimStats() - m5.stats.initText("cout") # We're done registering statistics. Enable the stats package now. m5.stats.enable()