text.cc revision 11359
1695SN/A/*
21762SN/A * Copyright (c) 2004-2005 The Regents of The University of Michigan
3695SN/A * All rights reserved.
4695SN/A *
5695SN/A * Redistribution and use in source and binary forms, with or without
6695SN/A * modification, are permitted provided that the following conditions are
7695SN/A * met: redistributions of source code must retain the above copyright
8695SN/A * notice, this list of conditions and the following disclaimer;
9695SN/A * redistributions in binary form must reproduce the above copyright
10695SN/A * notice, this list of conditions and the following disclaimer in the
11695SN/A * documentation and/or other materials provided with the distribution;
12695SN/A * neither the name of the copyright holders nor the names of its
13695SN/A * contributors may be used to endorse or promote products derived from
14695SN/A * this software without specific prior written permission.
15695SN/A *
16695SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17695SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18695SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19695SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20695SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21695SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22695SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23695SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24695SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25695SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26695SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
272665Ssaidi@eecs.umich.edu *
282665Ssaidi@eecs.umich.edu * Authors: Nathan Binkert
29695SN/A */
30695SN/A
31873SN/A#if defined(__APPLE__)
32873SN/A#define _GLIBCPP_USE_C99 1
33873SN/A#endif
34873SN/A
353918Ssaidi@eecs.umich.edu#if defined(__sun)
368230Snate@binkert.org#include <math.h>
373918Ssaidi@eecs.umich.edu#endif
383918Ssaidi@eecs.umich.edu
396129Snate@binkert.org#include <cassert>
406129Snate@binkert.org#ifdef __SUNPRO_CC
418230Snate@binkert.org#include <math.h>
426129Snate@binkert.org#endif
436129Snate@binkert.org#include <cmath>
448229Snate@binkert.org#include <fstream>
45695SN/A#include <iostream>
462621SN/A#include <sstream>
47695SN/A#include <string>
48695SN/A
498229Snate@binkert.org#include "base/stats/info.hh"
508229Snate@binkert.org#include "base/stats/text.hh"
516129Snate@binkert.org#include "base/cast.hh"
52695SN/A#include "base/misc.hh"
536129Snate@binkert.org#include "base/str.hh"
54695SN/A
55695SN/Ausing namespace std;
56695SN/A
57695SN/A#ifndef NAN
58695SN/Afloat __nan();
59695SN/A/** Define Not a number. */
60695SN/A#define NAN (__nan())
61695SN/A/** Need to define __nan() */
62695SN/A#define __M5_NAN
63695SN/A#endif
64695SN/A
65695SN/A#ifdef __M5_NAN
66695SN/Afloat
67695SN/A__nan()
68695SN/A{
69695SN/A    union {
70695SN/A        uint32_t ui;
71695SN/A        float f;
72695SN/A    } nan;
73695SN/A
74695SN/A    nan.ui = 0x7fc00000;
75695SN/A    return nan.f;
76695SN/A}
77695SN/A#endif
78695SN/A
79729SN/Anamespace Stats {
80695SN/A
816129Snate@binkert.orgstd::list<Info *> &statsList();
826129Snate@binkert.org
83695SN/AText::Text()
846126Snate@binkert.org    : mystream(false), stream(NULL), descriptions(false)
85695SN/A{
86695SN/A}
87695SN/A
88695SN/AText::Text(std::ostream &stream)
896126Snate@binkert.org    : mystream(false), stream(NULL), descriptions(false)
90695SN/A{
91695SN/A    open(stream);
92695SN/A}
93695SN/A
94695SN/AText::Text(const std::string &file)
956126Snate@binkert.org    : mystream(false), stream(NULL), descriptions(false)
96695SN/A{
97695SN/A    open(file);
98695SN/A}
99695SN/A
100695SN/A
101695SN/AText::~Text()
102695SN/A{
103695SN/A    if (mystream) {
104695SN/A        assert(stream);
105695SN/A        delete stream;
106695SN/A    }
107695SN/A}
108695SN/A
109695SN/Avoid
110695SN/AText::open(std::ostream &_stream)
111695SN/A{
112695SN/A    if (stream)
113695SN/A        panic("stream already set!");
114695SN/A
115695SN/A    mystream = false;
116695SN/A    stream = &_stream;
1175581Ssaidi@eecs.umich.edu    if (!valid())
1185581Ssaidi@eecs.umich.edu        fatal("Unable to open output stream for writing\n");
119695SN/A}
120695SN/A
121695SN/Avoid
122695SN/AText::open(const std::string &file)
123695SN/A{
124695SN/A    if (stream)
125695SN/A        panic("stream already set!");
126695SN/A
127695SN/A    mystream = true;
128695SN/A    stream = new ofstream(file.c_str(), ios::trunc);
1295581Ssaidi@eecs.umich.edu    if (!valid())
1305581Ssaidi@eecs.umich.edu        fatal("Unable to open statistics file for writing\n");
131695SN/A}
132695SN/A
133695SN/Abool
134695SN/AText::valid() const
135695SN/A{
1365581Ssaidi@eecs.umich.edu    return stream != NULL && stream->good();
137695SN/A}
138695SN/A
139695SN/Avoid
1408296Snate@binkert.orgText::begin()
141695SN/A{
142695SN/A    ccprintf(*stream, "\n---------- Begin Simulation Statistics ----------\n");
1438296Snate@binkert.org}
1448296Snate@binkert.org
1458296Snate@binkert.orgvoid
1468296Snate@binkert.orgText::end()
1478296Snate@binkert.org{
148695SN/A    ccprintf(*stream, "\n---------- End Simulation Statistics   ----------\n");
149695SN/A    stream->flush();
150695SN/A}
151695SN/A
152695SN/Abool
1535886Snate@binkert.orgText::noOutput(const Info &info)
154695SN/A{
1557462Snate@binkert.org    if (!info.flags.isSet(display))
156695SN/A        return true;
157695SN/A
1585886Snate@binkert.org    if (info.prereq && info.prereq->zero())
159695SN/A        return true;
160695SN/A
161695SN/A    return false;
162695SN/A}
163695SN/A
164695SN/Astring
1656126Snate@binkert.orgValueToString(Result value, int precision)
166695SN/A{
167695SN/A    stringstream val;
168695SN/A
1698946Sandreas.hansson@arm.com    if (!std::isnan(value)) {
170695SN/A        if (precision != -1)
171695SN/A            val.precision(precision);
172695SN/A        else if (value == rint(value))
173695SN/A            val.precision(0);
174695SN/A
175695SN/A        val.unsetf(ios::showpoint);
176695SN/A        val.setf(ios::fixed);
177695SN/A        val << value;
178695SN/A    } else {
1798982Snate@binkert.org        val << "nan";
180695SN/A    }
181695SN/A
182695SN/A    return val.str();
183695SN/A}
184695SN/A
185695SN/Astruct ScalarPrint
186695SN/A{
187695SN/A    Result value;
188695SN/A    string name;
189695SN/A    string desc;
1906130Snate@binkert.org    Flags flags;
191695SN/A    bool descriptions;
192695SN/A    int precision;
193695SN/A    Result pdf;
194695SN/A    Result cdf;
195695SN/A
1966211Snate@binkert.org    void update(Result val, Result total);
1979743Snilay@cs.wisc.edu    void operator()(ostream &stream, bool oneLine = false) const;
198695SN/A};
199695SN/A
200695SN/Avoid
2016211Snate@binkert.orgScalarPrint::update(Result val, Result total)
2026211Snate@binkert.org{
2036211Snate@binkert.org    value = val;
2046211Snate@binkert.org    if (total) {
2056211Snate@binkert.org        pdf = val / total;
2066211Snate@binkert.org        cdf += pdf;
2076211Snate@binkert.org    }
2086211Snate@binkert.org}
2096211Snate@binkert.org
2106211Snate@binkert.orgvoid
2119743Snilay@cs.wisc.eduScalarPrint::operator()(ostream &stream, bool oneLine) const
212695SN/A{
21310011Snilay@cs.wisc.edu    if ((flags.isSet(nozero) && (!oneLine) && value == 0.0) ||
2148946Sandreas.hansson@arm.com        (flags.isSet(nonan) && std::isnan(value)))
215695SN/A        return;
216695SN/A
217695SN/A    stringstream pdfstr, cdfstr;
218695SN/A
2198946Sandreas.hansson@arm.com    if (!std::isnan(pdf))
220695SN/A        ccprintf(pdfstr, "%.2f%%", pdf * 100.0);
221695SN/A
2228946Sandreas.hansson@arm.com    if (!std::isnan(cdf))
223695SN/A        ccprintf(cdfstr, "%.2f%%", cdf * 100.0);
224695SN/A
2259743Snilay@cs.wisc.edu    if (oneLine) {
2269743Snilay@cs.wisc.edu        ccprintf(stream, " |%12s %10s %10s",
2279743Snilay@cs.wisc.edu                 ValueToString(value, precision), pdfstr.str(), cdfstr.str());
2289743Snilay@cs.wisc.edu    } else {
2299743Snilay@cs.wisc.edu        ccprintf(stream, "%-40s %12s %10s %10s", name,
2309743Snilay@cs.wisc.edu                 ValueToString(value, precision), pdfstr.str(), cdfstr.str());
231695SN/A
2329743Snilay@cs.wisc.edu        if (descriptions) {
2339743Snilay@cs.wisc.edu            if (!desc.empty())
2349743Snilay@cs.wisc.edu                ccprintf(stream, " # %s", desc);
2359743Snilay@cs.wisc.edu        }
2369743Snilay@cs.wisc.edu        stream << endl;
237695SN/A    }
238695SN/A}
239695SN/A
240695SN/Astruct VectorPrint
241695SN/A{
242695SN/A    string name;
2438243Sbradley.danofsky@amd.com    string separatorString;
244695SN/A    string desc;
245695SN/A    vector<string> subnames;
246695SN/A    vector<string> subdescs;
2476130Snate@binkert.org    Flags flags;
248695SN/A    bool descriptions;
249695SN/A    int precision;
250695SN/A    VResult vec;
251695SN/A    Result total;
2529839Sandreas.hansson@arm.com    bool forceSubnames;
253695SN/A
254695SN/A    void operator()(ostream &stream) const;
255695SN/A};
256695SN/A
257695SN/Avoid
258695SN/AVectorPrint::operator()(std::ostream &stream) const
259695SN/A{
2605599Snate@binkert.org    size_type _size = vec.size();
261695SN/A    Result _total = 0.0;
262695SN/A
2636130Snate@binkert.org    if (flags.isSet(pdf | cdf)) {
2645599Snate@binkert.org        for (off_type i = 0; i < _size; ++i) {
265695SN/A            _total += vec[i];
266695SN/A        }
267695SN/A    }
268695SN/A
2698243Sbradley.danofsky@amd.com    string base = name + separatorString;
270695SN/A
271695SN/A    ScalarPrint print;
272695SN/A    print.name = name;
273695SN/A    print.desc = desc;
274695SN/A    print.precision = precision;
275695SN/A    print.descriptions = descriptions;
276695SN/A    print.flags = flags;
2776211Snate@binkert.org    print.pdf = _total ? 0.0 : NAN;
2786211Snate@binkert.org    print.cdf = _total ? 0.0 : NAN;
279695SN/A
280695SN/A    bool havesub = !subnames.empty();
281695SN/A
282695SN/A    if (_size == 1) {
2839828Ssascha.bischoff@arm.com        // If forceSubnames is set, get the first subname (or index in
2849828Ssascha.bischoff@arm.com        // the case where there are no subnames) and append it to the
2859828Ssascha.bischoff@arm.com        // base name.
2869828Ssascha.bischoff@arm.com        if (forceSubnames)
28710386Sandreas.hansson@arm.com            print.name = base + (havesub ? subnames[0] : std::to_string(0));
288695SN/A        print.value = vec[0];
289695SN/A        print(stream);
2906126Snate@binkert.org        return;
2916126Snate@binkert.org    }
292695SN/A
2939743Snilay@cs.wisc.edu    if ((!flags.isSet(nozero)) || (total != 0)) {
2949743Snilay@cs.wisc.edu        if (flags.isSet(oneline)) {
2959743Snilay@cs.wisc.edu            ccprintf(stream, "%-40s", name);
2969743Snilay@cs.wisc.edu            print.flags = print.flags & (~nozero);
2979743Snilay@cs.wisc.edu        }
298695SN/A
2999743Snilay@cs.wisc.edu        for (off_type i = 0; i < _size; ++i) {
3009743Snilay@cs.wisc.edu            if (havesub && (i >= subnames.size() || subnames[i].empty()))
3019743Snilay@cs.wisc.edu                continue;
302695SN/A
30310386Sandreas.hansson@arm.com            print.name = base + (havesub ? subnames[i] : std::to_string(i));
3049743Snilay@cs.wisc.edu            print.desc = subdescs.empty() ? desc : subdescs[i];
3059743Snilay@cs.wisc.edu
3069743Snilay@cs.wisc.edu            print.update(vec[i], _total);
3079743Snilay@cs.wisc.edu            print(stream, flags.isSet(oneline));
3089743Snilay@cs.wisc.edu        }
3099743Snilay@cs.wisc.edu
3109743Snilay@cs.wisc.edu        if (flags.isSet(oneline)) {
3119743Snilay@cs.wisc.edu            if (descriptions) {
3129743Snilay@cs.wisc.edu                if (!desc.empty())
3139743Snilay@cs.wisc.edu                    ccprintf(stream, " # %s", desc);
3149743Snilay@cs.wisc.edu            }
3159743Snilay@cs.wisc.edu            stream << endl;
3169743Snilay@cs.wisc.edu        }
3176126Snate@binkert.org    }
318695SN/A
3196130Snate@binkert.org    if (flags.isSet(::Stats::total)) {
3206126Snate@binkert.org        print.pdf = NAN;
3216126Snate@binkert.org        print.cdf = NAN;
3226126Snate@binkert.org        print.name = base + "total";
3236126Snate@binkert.org        print.desc = desc;
3246126Snate@binkert.org        print.value = total;
3256126Snate@binkert.org        print(stream);
326695SN/A    }
327695SN/A}
328695SN/A
329695SN/Astruct DistPrint
330695SN/A{
331695SN/A    string name;
3328243Sbradley.danofsky@amd.com    string separatorString;
333695SN/A    string desc;
3346130Snate@binkert.org    Flags flags;
335695SN/A    bool descriptions;
336695SN/A    int precision;
337695SN/A
3386004Snate@binkert.org    const DistData &data;
3396004Snate@binkert.org
3406128Snate@binkert.org    DistPrint(const Text *text, const DistInfo &info);
3416128Snate@binkert.org    DistPrint(const Text *text, const VectorDistInfo &info, int i);
3427505Snate@binkert.org    void init(const Text *text, const Info &info);
343695SN/A    void operator()(ostream &stream) const;
344695SN/A};
345695SN/A
3466128Snate@binkert.orgDistPrint::DistPrint(const Text *text, const DistInfo &info)
3476004Snate@binkert.org    : data(info.data)
3486004Snate@binkert.org{
3497505Snate@binkert.org    init(text, info);
3506004Snate@binkert.org}
3516004Snate@binkert.org
3526128Snate@binkert.orgDistPrint::DistPrint(const Text *text, const VectorDistInfo &info, int i)
3536004Snate@binkert.org    : data(info.data[i])
3546004Snate@binkert.org{
3557505Snate@binkert.org    init(text, info);
3566004Snate@binkert.org
3576004Snate@binkert.org    name = info.name + "_" +
35810386Sandreas.hansson@arm.com        (info.subnames[i].empty() ? (std::to_string(i)) : info.subnames[i]);
3596004Snate@binkert.org
3606004Snate@binkert.org    if (!info.subdescs[i].empty())
3616004Snate@binkert.org        desc = info.subdescs[i];
3626004Snate@binkert.org}
3636004Snate@binkert.org
3646004Snate@binkert.orgvoid
3657505Snate@binkert.orgDistPrint::init(const Text *text, const Info &info)
3666004Snate@binkert.org{
3676004Snate@binkert.org    name = info.name;
3688243Sbradley.danofsky@amd.com    separatorString = info.separatorString;
3696004Snate@binkert.org    desc = info.desc;
3706004Snate@binkert.org    flags = info.flags;
3716004Snate@binkert.org    precision = info.precision;
3726125Snate@binkert.org    descriptions = text->descriptions;
3736004Snate@binkert.org}
3746004Snate@binkert.org
375695SN/Avoid
376695SN/ADistPrint::operator()(ostream &stream) const
377695SN/A{
37810011Snilay@cs.wisc.edu    if (flags.isSet(nozero) && data.samples == 0) return;
3798243Sbradley.danofsky@amd.com    string base = name + separatorString;
380695SN/A
381695SN/A    ScalarPrint print;
3826211Snate@binkert.org    print.precision = precision;
383695SN/A    print.flags = flags;
384695SN/A    print.descriptions = descriptions;
3856211Snate@binkert.org    print.desc = desc;
386695SN/A    print.pdf = NAN;
387695SN/A    print.cdf = NAN;
388695SN/A
38910011Snilay@cs.wisc.edu    if (flags.isSet(oneline)) {
39010011Snilay@cs.wisc.edu        print.name = base + "bucket_size";
39110011Snilay@cs.wisc.edu        print.value = data.bucket_size;
39210011Snilay@cs.wisc.edu        print(stream);
39310011Snilay@cs.wisc.edu
39410011Snilay@cs.wisc.edu        print.name = base + "min_bucket";
39510011Snilay@cs.wisc.edu        print.value = data.min;
39610011Snilay@cs.wisc.edu        print(stream);
39710011Snilay@cs.wisc.edu
39810011Snilay@cs.wisc.edu        print.name = base + "max_bucket";
39910011Snilay@cs.wisc.edu        print.value = data.max;
40010011Snilay@cs.wisc.edu        print(stream);
40110011Snilay@cs.wisc.edu    }
40210011Snilay@cs.wisc.edu
403695SN/A    print.name = base + "samples";
4046004Snate@binkert.org    print.value = data.samples;
405695SN/A    print(stream);
406695SN/A
4076211Snate@binkert.org    print.name = base + "mean";
4086211Snate@binkert.org    print.value = data.samples ? data.sum / data.samples : NAN;
409695SN/A    print(stream);
410695SN/A
4118666SPrakash.Ramrakhyani@arm.com    if (data.type == Hist) {
4128666SPrakash.Ramrakhyani@arm.com        print.name = base + "gmean";
4138666SPrakash.Ramrakhyani@arm.com        print.value = data.samples ? exp(data.logs / data.samples) : NAN;
4148666SPrakash.Ramrakhyani@arm.com        print(stream);
4158666SPrakash.Ramrakhyani@arm.com    }
4168666SPrakash.Ramrakhyani@arm.com
4176211Snate@binkert.org    Result stdev = NAN;
4186211Snate@binkert.org    if (data.samples)
4196211Snate@binkert.org        stdev = sqrt((data.samples * data.squares - data.sum * data.sum) /
4206211Snate@binkert.org                     (data.samples * (data.samples - 1.0)));
4216211Snate@binkert.org    print.name = base + "stdev";
4226211Snate@binkert.org    print.value = stdev;
4236211Snate@binkert.org    print(stream);
4246211Snate@binkert.org
4257505Snate@binkert.org    if (data.type == Deviation)
4266211Snate@binkert.org        return;
4276211Snate@binkert.org
4287505Snate@binkert.org    size_t size = data.cvec.size();
4296211Snate@binkert.org
4306211Snate@binkert.org    Result total = 0.0;
4317831Snate@binkert.org    if (data.type == Dist && data.underflow != NAN)
4326211Snate@binkert.org        total += data.underflow;
4336211Snate@binkert.org    for (off_type i = 0; i < size; ++i)
4346211Snate@binkert.org        total += data.cvec[i];
4357831Snate@binkert.org    if (data.type == Dist && data.overflow != NAN)
4366211Snate@binkert.org        total += data.overflow;
4376211Snate@binkert.org
4386126Snate@binkert.org    if (total) {
4396211Snate@binkert.org        print.pdf = 0.0;
4406211Snate@binkert.org        print.cdf = 0.0;
4416126Snate@binkert.org    }
4426211Snate@binkert.org
4437831Snate@binkert.org    if (data.type == Dist && data.underflow != NAN) {
4446211Snate@binkert.org        print.name = base + "underflows";
4456211Snate@binkert.org        print.update(data.underflow, total);
4466211Snate@binkert.org        print(stream);
4476211Snate@binkert.org    }
4486126Snate@binkert.org
44910011Snilay@cs.wisc.edu    if (flags.isSet(oneline)) {
45010011Snilay@cs.wisc.edu        ccprintf(stream, "%-40s", name);
45110011Snilay@cs.wisc.edu    }
45210011Snilay@cs.wisc.edu
4536126Snate@binkert.org    for (off_type i = 0; i < size; ++i) {
4546126Snate@binkert.org        stringstream namestr;
4556126Snate@binkert.org        namestr << base;
4566126Snate@binkert.org
4577505Snate@binkert.org        Counter low = i * data.bucket_size + data.min;
4587505Snate@binkert.org        Counter high = ::min(low + data.bucket_size - 1.0, data.max);
4596126Snate@binkert.org        namestr << low;
4606126Snate@binkert.org        if (low < high)
4616126Snate@binkert.org            namestr << "-" << high;
4626126Snate@binkert.org
4636126Snate@binkert.org        print.name = namestr.str();
4646211Snate@binkert.org        print.update(data.cvec[i], total);
46510011Snilay@cs.wisc.edu        print(stream, flags.isSet(oneline));
46610011Snilay@cs.wisc.edu    }
46710011Snilay@cs.wisc.edu
46810011Snilay@cs.wisc.edu    if (flags.isSet(oneline)) {
46910011Snilay@cs.wisc.edu        if (descriptions) {
47010011Snilay@cs.wisc.edu            if (!desc.empty())
47110011Snilay@cs.wisc.edu                ccprintf(stream, " # %s", desc);
47210011Snilay@cs.wisc.edu        }
47310011Snilay@cs.wisc.edu        stream << endl;
474695SN/A    }
475695SN/A
4767831Snate@binkert.org    if (data.type == Dist && data.overflow != NAN) {
4776211Snate@binkert.org        print.name = base + "overflows";
4786211Snate@binkert.org        print.update(data.overflow, total);
4796211Snate@binkert.org        print(stream);
480695SN/A    }
481695SN/A
482695SN/A    print.pdf = NAN;
483695SN/A    print.cdf = NAN;
484695SN/A
4857831Snate@binkert.org    if (data.type == Dist && data.min_val != NAN) {
4866211Snate@binkert.org        print.name = base + "min_value";
4876211Snate@binkert.org        print.value = data.min_val;
4886211Snate@binkert.org        print(stream);
4896211Snate@binkert.org    }
4906211Snate@binkert.org
4917831Snate@binkert.org    if (data.type == Dist && data.max_val != NAN) {
4926211Snate@binkert.org        print.name = base + "max_value";
4936211Snate@binkert.org        print.value = data.max_val;
4946211Snate@binkert.org        print(stream);
4956211Snate@binkert.org    }
4966211Snate@binkert.org
4976126Snate@binkert.org    print.name = base + "total";
4986126Snate@binkert.org    print.value = total;
4996126Snate@binkert.org    print(stream);
500695SN/A}
501695SN/A
502695SN/Avoid
5036128Snate@binkert.orgText::visit(const ScalarInfo &info)
504695SN/A{
5055886Snate@binkert.org    if (noOutput(info))
506695SN/A        return;
507695SN/A
508695SN/A    ScalarPrint print;
5095886Snate@binkert.org    print.value = info.result();
5105886Snate@binkert.org    print.name = info.name;
5115886Snate@binkert.org    print.desc = info.desc;
5125886Snate@binkert.org    print.flags = info.flags;
513695SN/A    print.descriptions = descriptions;
5145886Snate@binkert.org    print.precision = info.precision;
515695SN/A    print.pdf = NAN;
516695SN/A    print.cdf = NAN;
517695SN/A
518695SN/A    print(*stream);
519695SN/A}
520695SN/A
521695SN/Avoid
5226128Snate@binkert.orgText::visit(const VectorInfo &info)
523695SN/A{
5245886Snate@binkert.org    if (noOutput(info))
525695SN/A        return;
526695SN/A
5275886Snate@binkert.org    size_type size = info.size();
528695SN/A    VectorPrint print;
529695SN/A
5305886Snate@binkert.org    print.name = info.name;
5318243Sbradley.danofsky@amd.com    print.separatorString = info.separatorString;
5325886Snate@binkert.org    print.desc = info.desc;
5335886Snate@binkert.org    print.flags = info.flags;
534695SN/A    print.descriptions = descriptions;
5355886Snate@binkert.org    print.precision = info.precision;
5365886Snate@binkert.org    print.vec = info.result();
5375886Snate@binkert.org    print.total = info.total();
5389839Sandreas.hansson@arm.com    print.forceSubnames = false;
539695SN/A
5405886Snate@binkert.org    if (!info.subnames.empty()) {
5415599Snate@binkert.org        for (off_type i = 0; i < size; ++i) {
5425886Snate@binkert.org            if (!info.subnames[i].empty()) {
5435886Snate@binkert.org                print.subnames = info.subnames;
544695SN/A                print.subnames.resize(size);
5455599Snate@binkert.org                for (off_type i = 0; i < size; ++i) {
5465886Snate@binkert.org                    if (!info.subnames[i].empty() &&
5475886Snate@binkert.org                        !info.subdescs[i].empty()) {
5485886Snate@binkert.org                        print.subdescs = info.subdescs;
549695SN/A                        print.subdescs.resize(size);
550695SN/A                        break;
551695SN/A                    }
552695SN/A                }
553695SN/A                break;
554695SN/A            }
555695SN/A        }
556695SN/A    }
557695SN/A
558695SN/A    print(*stream);
559695SN/A}
560695SN/A
561695SN/Avoid
5626128Snate@binkert.orgText::visit(const Vector2dInfo &info)
563695SN/A{
5645886Snate@binkert.org    if (noOutput(info))
565695SN/A        return;
566695SN/A
567695SN/A    bool havesub = false;
568695SN/A    VectorPrint print;
569695SN/A
5708667Sdam.sunwoo@arm.com    if (!info.y_subnames.empty()) {
5718667Sdam.sunwoo@arm.com        for (off_type i = 0; i < info.y; ++i) {
5728667Sdam.sunwoo@arm.com            if (!info.y_subnames[i].empty()) {
5738667Sdam.sunwoo@arm.com                print.subnames = info.y_subnames;
57410374Sandreas.hansson@arm.com                break;
5758667Sdam.sunwoo@arm.com            }
5768667Sdam.sunwoo@arm.com        }
5778667Sdam.sunwoo@arm.com    }
5785886Snate@binkert.org    print.flags = info.flags;
5798243Sbradley.danofsky@amd.com    print.separatorString = info.separatorString;
580695SN/A    print.descriptions = descriptions;
5815886Snate@binkert.org    print.precision = info.precision;
5829828Ssascha.bischoff@arm.com    print.forceSubnames = true;
583695SN/A
5845886Snate@binkert.org    if (!info.subnames.empty()) {
5855886Snate@binkert.org        for (off_type i = 0; i < info.x; ++i)
5865886Snate@binkert.org            if (!info.subnames[i].empty())
587695SN/A                havesub = true;
588695SN/A    }
589695SN/A
5905886Snate@binkert.org    VResult tot_vec(info.y);
5919828Ssascha.bischoff@arm.com    VResult super_total(1, 0.0);
5925886Snate@binkert.org    for (off_type i = 0; i < info.x; ++i) {
5935886Snate@binkert.org        if (havesub && (i >= info.subnames.size() || info.subnames[i].empty()))
594695SN/A            continue;
595695SN/A
5965886Snate@binkert.org        off_type iy = i * info.y;
5975886Snate@binkert.org        VResult yvec(info.y);
598695SN/A
599695SN/A        Result total = 0.0;
6005886Snate@binkert.org        for (off_type j = 0; j < info.y; ++j) {
6015886Snate@binkert.org            yvec[j] = info.cvec[iy + j];
602695SN/A            tot_vec[j] += yvec[j];
603695SN/A            total += yvec[j];
6049828Ssascha.bischoff@arm.com            super_total[0] += yvec[j];
605695SN/A        }
606695SN/A
6075886Snate@binkert.org        print.name = info.name + "_" +
60810386Sandreas.hansson@arm.com            (havesub ? info.subnames[i] : std::to_string(i));
6095886Snate@binkert.org        print.desc = info.desc;
610695SN/A        print.vec = yvec;
611695SN/A        print.total = total;
612695SN/A        print(*stream);
613695SN/A    }
614695SN/A
6159828Ssascha.bischoff@arm.com    // Create a subname for printing the total
6169828Ssascha.bischoff@arm.com    vector<string> total_subname;
6179828Ssascha.bischoff@arm.com    total_subname.push_back("total");
6189828Ssascha.bischoff@arm.com
6196130Snate@binkert.org    if (info.flags.isSet(::Stats::total) && (info.x > 1)) {
6205886Snate@binkert.org        print.name = info.name;
6219828Ssascha.bischoff@arm.com        print.subnames = total_subname;
6225886Snate@binkert.org        print.desc = info.desc;
6239828Ssascha.bischoff@arm.com        print.vec = super_total;
6249828Ssascha.bischoff@arm.com        print.flags = print.flags & ~total;
625695SN/A        print(*stream);
626695SN/A    }
627695SN/A}
628695SN/A
629695SN/Avoid
6306128Snate@binkert.orgText::visit(const DistInfo &info)
631695SN/A{
6325886Snate@binkert.org    if (noOutput(info))
633695SN/A        return;
634695SN/A
6356125Snate@binkert.org    DistPrint print(this, info);
636695SN/A    print(*stream);
637695SN/A}
638695SN/A
639695SN/Avoid
6406128Snate@binkert.orgText::visit(const VectorDistInfo &info)
641695SN/A{
6425886Snate@binkert.org    if (noOutput(info))
643695SN/A        return;
644695SN/A
6455886Snate@binkert.org    for (off_type i = 0; i < info.size(); ++i) {
6466125Snate@binkert.org        DistPrint print(this, info, i);
647695SN/A        print(*stream);
648695SN/A    }
649695SN/A}
650695SN/A
651695SN/Avoid
6526128Snate@binkert.orgText::visit(const FormulaInfo &info)
653695SN/A{
6546128Snate@binkert.org    visit((const VectorInfo &)info);
655695SN/A}
656695SN/A
6578514SThomas.Grass@ARM.com/*
6588514SThomas.Grass@ARM.com  This struct implements the output methods for the sparse
6598514SThomas.Grass@ARM.com  histogram stat
6608514SThomas.Grass@ARM.com*/
6618514SThomas.Grass@ARM.comstruct SparseHistPrint
6628514SThomas.Grass@ARM.com{
6638514SThomas.Grass@ARM.com    string name;
6648514SThomas.Grass@ARM.com    string separatorString;
6658514SThomas.Grass@ARM.com    string desc;
6668514SThomas.Grass@ARM.com    Flags flags;
6678514SThomas.Grass@ARM.com    bool descriptions;
6688514SThomas.Grass@ARM.com    int precision;
6698514SThomas.Grass@ARM.com
6708514SThomas.Grass@ARM.com    const SparseHistData &data;
6718514SThomas.Grass@ARM.com
6728514SThomas.Grass@ARM.com    SparseHistPrint(const Text *text, const SparseHistInfo &info);
6738514SThomas.Grass@ARM.com    void init(const Text *text, const Info &info);
6748514SThomas.Grass@ARM.com    void operator()(ostream &stream) const;
6758514SThomas.Grass@ARM.com};
6768514SThomas.Grass@ARM.com
6778514SThomas.Grass@ARM.com/* Call initialization function */
6788514SThomas.Grass@ARM.comSparseHistPrint::SparseHistPrint(const Text *text, const SparseHistInfo &info)
6798514SThomas.Grass@ARM.com    : data(info.data)
6808514SThomas.Grass@ARM.com{
6818514SThomas.Grass@ARM.com    init(text, info);
6828514SThomas.Grass@ARM.com}
6838514SThomas.Grass@ARM.com
6848514SThomas.Grass@ARM.com/* Initialization function */
6858514SThomas.Grass@ARM.comvoid
6868514SThomas.Grass@ARM.comSparseHistPrint::init(const Text *text, const Info &info)
6878514SThomas.Grass@ARM.com{
6888514SThomas.Grass@ARM.com    name = info.name;
6898514SThomas.Grass@ARM.com    separatorString = info.separatorString;
6908514SThomas.Grass@ARM.com    desc = info.desc;
6918514SThomas.Grass@ARM.com    flags = info.flags;
6928514SThomas.Grass@ARM.com    precision = info.precision;
6938514SThomas.Grass@ARM.com    descriptions = text->descriptions;
6948514SThomas.Grass@ARM.com}
6958514SThomas.Grass@ARM.com
6968514SThomas.Grass@ARM.com/* Grab data from map and write to output stream */
6978514SThomas.Grass@ARM.comvoid
6988514SThomas.Grass@ARM.comSparseHistPrint::operator()(ostream &stream) const
6998514SThomas.Grass@ARM.com{
7008514SThomas.Grass@ARM.com    string base = name + separatorString;
7018514SThomas.Grass@ARM.com
7028514SThomas.Grass@ARM.com    ScalarPrint print;
7038514SThomas.Grass@ARM.com    print.precision = precision;
7048514SThomas.Grass@ARM.com    print.flags = flags;
7058514SThomas.Grass@ARM.com    print.descriptions = descriptions;
7068514SThomas.Grass@ARM.com    print.desc = desc;
7078514SThomas.Grass@ARM.com    print.pdf = NAN;
7088514SThomas.Grass@ARM.com    print.cdf = NAN;
7098514SThomas.Grass@ARM.com
7108514SThomas.Grass@ARM.com    print.name = base + "samples";
7118514SThomas.Grass@ARM.com    print.value = data.samples;
7128514SThomas.Grass@ARM.com    print(stream);
7138514SThomas.Grass@ARM.com
7148514SThomas.Grass@ARM.com    MCounter::const_iterator it;
7158514SThomas.Grass@ARM.com    for (it = data.cmap.begin(); it != data.cmap.end(); it++) {
7168514SThomas.Grass@ARM.com        stringstream namestr;
7178514SThomas.Grass@ARM.com        namestr << base;
7188514SThomas.Grass@ARM.com
7198514SThomas.Grass@ARM.com        namestr <<(*it).first;
7208514SThomas.Grass@ARM.com        print.name = namestr.str();
7218514SThomas.Grass@ARM.com        print.value = (*it).second;
7228514SThomas.Grass@ARM.com        print(stream);
7238514SThomas.Grass@ARM.com    }
7248514SThomas.Grass@ARM.com}
7258514SThomas.Grass@ARM.com
7268514SThomas.Grass@ARM.comvoid
7278514SThomas.Grass@ARM.comText::visit(const SparseHistInfo &info)
7288514SThomas.Grass@ARM.com{
7298514SThomas.Grass@ARM.com    if (noOutput(info))
7308514SThomas.Grass@ARM.com        return;
7318514SThomas.Grass@ARM.com
7328514SThomas.Grass@ARM.com    SparseHistPrint print(this, info);
7338514SThomas.Grass@ARM.com    print(*stream);
7348514SThomas.Grass@ARM.com}
7358514SThomas.Grass@ARM.com
7368296Snate@binkert.orgOutput *
7376126Snate@binkert.orginitText(const string &filename, bool desc)
7384078Sbinkertn@umich.edu{
7394078Sbinkertn@umich.edu    static Text text;
7404078Sbinkertn@umich.edu    static bool connected = false;
7414078Sbinkertn@umich.edu
7428296Snate@binkert.org    if (!connected) {
74311359Sandreas@sandberg.pp.se        text.open(*simout.findOrCreate(filename)->stream());
7448296Snate@binkert.org        text.descriptions = desc;
7458296Snate@binkert.org        connected = true;
7468296Snate@binkert.org    }
7474078Sbinkertn@umich.edu
7488296Snate@binkert.org    return &text;
7494078Sbinkertn@umich.edu}
7504078Sbinkertn@umich.edu
7517811Ssteve.reinhardt@amd.com} // namespace Stats
752