text.cc revision 12334
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)
3611793Sbrandon.potter@amd.com#include <cmath>
3711793Sbrandon.potter@amd.com
383918Ssaidi@eecs.umich.edu#endif
393918Ssaidi@eecs.umich.edu
406129Snate@binkert.org#include <cassert>
4111793Sbrandon.potter@amd.com
426129Snate@binkert.org#ifdef __SUNPRO_CC
4311793Sbrandon.potter@amd.com#include <cmath>
4411793Sbrandon.potter@amd.com
456129Snate@binkert.org#endif
4611793Sbrandon.potter@amd.com#include "base/stats/text.hh"
4711793Sbrandon.potter@amd.com
486129Snate@binkert.org#include <cmath>
498229Snate@binkert.org#include <fstream>
50695SN/A#include <iostream>
512621SN/A#include <sstream>
52695SN/A#include <string>
53695SN/A
546129Snate@binkert.org#include "base/cast.hh"
5512334Sgabeblack@google.com#include "base/logging.hh"
5611793Sbrandon.potter@amd.com#include "base/stats/info.hh"
576129Snate@binkert.org#include "base/str.hh"
58695SN/A
59695SN/Ausing namespace std;
60695SN/A
61695SN/A#ifndef NAN
62695SN/Afloat __nan();
63695SN/A/** Define Not a number. */
64695SN/A#define NAN (__nan())
65695SN/A/** Need to define __nan() */
66695SN/A#define __M5_NAN
67695SN/A#endif
68695SN/A
69695SN/A#ifdef __M5_NAN
70695SN/Afloat
71695SN/A__nan()
72695SN/A{
73695SN/A    union {
74695SN/A        uint32_t ui;
75695SN/A        float f;
76695SN/A    } nan;
77695SN/A
78695SN/A    nan.ui = 0x7fc00000;
79695SN/A    return nan.f;
80695SN/A}
81695SN/A#endif
82695SN/A
83729SN/Anamespace Stats {
84695SN/A
856129Snate@binkert.orgstd::list<Info *> &statsList();
866129Snate@binkert.org
87695SN/AText::Text()
886126Snate@binkert.org    : mystream(false), stream(NULL), descriptions(false)
89695SN/A{
90695SN/A}
91695SN/A
92695SN/AText::Text(std::ostream &stream)
936126Snate@binkert.org    : mystream(false), stream(NULL), descriptions(false)
94695SN/A{
95695SN/A    open(stream);
96695SN/A}
97695SN/A
98695SN/AText::Text(const std::string &file)
996126Snate@binkert.org    : mystream(false), stream(NULL), descriptions(false)
100695SN/A{
101695SN/A    open(file);
102695SN/A}
103695SN/A
104695SN/A
105695SN/AText::~Text()
106695SN/A{
107695SN/A    if (mystream) {
108695SN/A        assert(stream);
109695SN/A        delete stream;
110695SN/A    }
111695SN/A}
112695SN/A
113695SN/Avoid
114695SN/AText::open(std::ostream &_stream)
115695SN/A{
116695SN/A    if (stream)
117695SN/A        panic("stream already set!");
118695SN/A
119695SN/A    mystream = false;
120695SN/A    stream = &_stream;
1215581Ssaidi@eecs.umich.edu    if (!valid())
1225581Ssaidi@eecs.umich.edu        fatal("Unable to open output stream for writing\n");
123695SN/A}
124695SN/A
125695SN/Avoid
126695SN/AText::open(const std::string &file)
127695SN/A{
128695SN/A    if (stream)
129695SN/A        panic("stream already set!");
130695SN/A
131695SN/A    mystream = true;
132695SN/A    stream = new ofstream(file.c_str(), ios::trunc);
1335581Ssaidi@eecs.umich.edu    if (!valid())
1345581Ssaidi@eecs.umich.edu        fatal("Unable to open statistics file for writing\n");
135695SN/A}
136695SN/A
137695SN/Abool
138695SN/AText::valid() const
139695SN/A{
1405581Ssaidi@eecs.umich.edu    return stream != NULL && stream->good();
141695SN/A}
142695SN/A
143695SN/Avoid
1448296Snate@binkert.orgText::begin()
145695SN/A{
146695SN/A    ccprintf(*stream, "\n---------- Begin Simulation Statistics ----------\n");
1478296Snate@binkert.org}
1488296Snate@binkert.org
1498296Snate@binkert.orgvoid
1508296Snate@binkert.orgText::end()
1518296Snate@binkert.org{
152695SN/A    ccprintf(*stream, "\n---------- End Simulation Statistics   ----------\n");
153695SN/A    stream->flush();
154695SN/A}
155695SN/A
156695SN/Abool
1575886Snate@binkert.orgText::noOutput(const Info &info)
158695SN/A{
1597462Snate@binkert.org    if (!info.flags.isSet(display))
160695SN/A        return true;
161695SN/A
1625886Snate@binkert.org    if (info.prereq && info.prereq->zero())
163695SN/A        return true;
164695SN/A
165695SN/A    return false;
166695SN/A}
167695SN/A
168695SN/Astring
1696126Snate@binkert.orgValueToString(Result value, int precision)
170695SN/A{
171695SN/A    stringstream val;
172695SN/A
1738946Sandreas.hansson@arm.com    if (!std::isnan(value)) {
174695SN/A        if (precision != -1)
175695SN/A            val.precision(precision);
176695SN/A        else if (value == rint(value))
177695SN/A            val.precision(0);
178695SN/A
179695SN/A        val.unsetf(ios::showpoint);
180695SN/A        val.setf(ios::fixed);
181695SN/A        val << value;
182695SN/A    } else {
1838982Snate@binkert.org        val << "nan";
184695SN/A    }
185695SN/A
186695SN/A    return val.str();
187695SN/A}
188695SN/A
189695SN/Astruct ScalarPrint
190695SN/A{
191695SN/A    Result value;
192695SN/A    string name;
193695SN/A    string desc;
1946130Snate@binkert.org    Flags flags;
195695SN/A    bool descriptions;
196695SN/A    int precision;
197695SN/A    Result pdf;
198695SN/A    Result cdf;
199695SN/A
2006211Snate@binkert.org    void update(Result val, Result total);
2019743Snilay@cs.wisc.edu    void operator()(ostream &stream, bool oneLine = false) const;
202695SN/A};
203695SN/A
204695SN/Avoid
2056211Snate@binkert.orgScalarPrint::update(Result val, Result total)
2066211Snate@binkert.org{
2076211Snate@binkert.org    value = val;
2086211Snate@binkert.org    if (total) {
2096211Snate@binkert.org        pdf = val / total;
2106211Snate@binkert.org        cdf += pdf;
2116211Snate@binkert.org    }
2126211Snate@binkert.org}
2136211Snate@binkert.org
2146211Snate@binkert.orgvoid
2159743Snilay@cs.wisc.eduScalarPrint::operator()(ostream &stream, bool oneLine) const
216695SN/A{
21710011Snilay@cs.wisc.edu    if ((flags.isSet(nozero) && (!oneLine) && value == 0.0) ||
2188946Sandreas.hansson@arm.com        (flags.isSet(nonan) && std::isnan(value)))
219695SN/A        return;
220695SN/A
221695SN/A    stringstream pdfstr, cdfstr;
222695SN/A
2238946Sandreas.hansson@arm.com    if (!std::isnan(pdf))
224695SN/A        ccprintf(pdfstr, "%.2f%%", pdf * 100.0);
225695SN/A
2268946Sandreas.hansson@arm.com    if (!std::isnan(cdf))
227695SN/A        ccprintf(cdfstr, "%.2f%%", cdf * 100.0);
228695SN/A
2299743Snilay@cs.wisc.edu    if (oneLine) {
2309743Snilay@cs.wisc.edu        ccprintf(stream, " |%12s %10s %10s",
2319743Snilay@cs.wisc.edu                 ValueToString(value, precision), pdfstr.str(), cdfstr.str());
2329743Snilay@cs.wisc.edu    } else {
2339743Snilay@cs.wisc.edu        ccprintf(stream, "%-40s %12s %10s %10s", name,
2349743Snilay@cs.wisc.edu                 ValueToString(value, precision), pdfstr.str(), cdfstr.str());
235695SN/A
2369743Snilay@cs.wisc.edu        if (descriptions) {
2379743Snilay@cs.wisc.edu            if (!desc.empty())
2389743Snilay@cs.wisc.edu                ccprintf(stream, " # %s", desc);
2399743Snilay@cs.wisc.edu        }
2409743Snilay@cs.wisc.edu        stream << endl;
241695SN/A    }
242695SN/A}
243695SN/A
244695SN/Astruct VectorPrint
245695SN/A{
246695SN/A    string name;
2478243Sbradley.danofsky@amd.com    string separatorString;
248695SN/A    string desc;
249695SN/A    vector<string> subnames;
250695SN/A    vector<string> subdescs;
2516130Snate@binkert.org    Flags flags;
252695SN/A    bool descriptions;
253695SN/A    int precision;
254695SN/A    VResult vec;
255695SN/A    Result total;
2569839Sandreas.hansson@arm.com    bool forceSubnames;
257695SN/A
258695SN/A    void operator()(ostream &stream) const;
259695SN/A};
260695SN/A
261695SN/Avoid
262695SN/AVectorPrint::operator()(std::ostream &stream) const
263695SN/A{
2645599Snate@binkert.org    size_type _size = vec.size();
265695SN/A    Result _total = 0.0;
266695SN/A
2676130Snate@binkert.org    if (flags.isSet(pdf | cdf)) {
2685599Snate@binkert.org        for (off_type i = 0; i < _size; ++i) {
269695SN/A            _total += vec[i];
270695SN/A        }
271695SN/A    }
272695SN/A
2738243Sbradley.danofsky@amd.com    string base = name + separatorString;
274695SN/A
275695SN/A    ScalarPrint print;
276695SN/A    print.name = name;
277695SN/A    print.desc = desc;
278695SN/A    print.precision = precision;
279695SN/A    print.descriptions = descriptions;
280695SN/A    print.flags = flags;
2816211Snate@binkert.org    print.pdf = _total ? 0.0 : NAN;
2826211Snate@binkert.org    print.cdf = _total ? 0.0 : NAN;
283695SN/A
284695SN/A    bool havesub = !subnames.empty();
285695SN/A
286695SN/A    if (_size == 1) {
2879828Ssascha.bischoff@arm.com        // If forceSubnames is set, get the first subname (or index in
2889828Ssascha.bischoff@arm.com        // the case where there are no subnames) and append it to the
2899828Ssascha.bischoff@arm.com        // base name.
2909828Ssascha.bischoff@arm.com        if (forceSubnames)
29110386Sandreas.hansson@arm.com            print.name = base + (havesub ? subnames[0] : std::to_string(0));
292695SN/A        print.value = vec[0];
293695SN/A        print(stream);
2946126Snate@binkert.org        return;
2956126Snate@binkert.org    }
296695SN/A
2979743Snilay@cs.wisc.edu    if ((!flags.isSet(nozero)) || (total != 0)) {
2989743Snilay@cs.wisc.edu        if (flags.isSet(oneline)) {
2999743Snilay@cs.wisc.edu            ccprintf(stream, "%-40s", name);
3009743Snilay@cs.wisc.edu            print.flags = print.flags & (~nozero);
3019743Snilay@cs.wisc.edu        }
302695SN/A
3039743Snilay@cs.wisc.edu        for (off_type i = 0; i < _size; ++i) {
3049743Snilay@cs.wisc.edu            if (havesub && (i >= subnames.size() || subnames[i].empty()))
3059743Snilay@cs.wisc.edu                continue;
306695SN/A
30710386Sandreas.hansson@arm.com            print.name = base + (havesub ? subnames[i] : std::to_string(i));
3089743Snilay@cs.wisc.edu            print.desc = subdescs.empty() ? desc : subdescs[i];
3099743Snilay@cs.wisc.edu
3109743Snilay@cs.wisc.edu            print.update(vec[i], _total);
3119743Snilay@cs.wisc.edu            print(stream, flags.isSet(oneline));
3129743Snilay@cs.wisc.edu        }
3139743Snilay@cs.wisc.edu
3149743Snilay@cs.wisc.edu        if (flags.isSet(oneline)) {
3159743Snilay@cs.wisc.edu            if (descriptions) {
3169743Snilay@cs.wisc.edu                if (!desc.empty())
3179743Snilay@cs.wisc.edu                    ccprintf(stream, " # %s", desc);
3189743Snilay@cs.wisc.edu            }
3199743Snilay@cs.wisc.edu            stream << endl;
3209743Snilay@cs.wisc.edu        }
3216126Snate@binkert.org    }
322695SN/A
3236130Snate@binkert.org    if (flags.isSet(::Stats::total)) {
3246126Snate@binkert.org        print.pdf = NAN;
3256126Snate@binkert.org        print.cdf = NAN;
3266126Snate@binkert.org        print.name = base + "total";
3276126Snate@binkert.org        print.desc = desc;
3286126Snate@binkert.org        print.value = total;
3296126Snate@binkert.org        print(stream);
330695SN/A    }
331695SN/A}
332695SN/A
333695SN/Astruct DistPrint
334695SN/A{
335695SN/A    string name;
3368243Sbradley.danofsky@amd.com    string separatorString;
337695SN/A    string desc;
3386130Snate@binkert.org    Flags flags;
339695SN/A    bool descriptions;
340695SN/A    int precision;
341695SN/A
3426004Snate@binkert.org    const DistData &data;
3436004Snate@binkert.org
3446128Snate@binkert.org    DistPrint(const Text *text, const DistInfo &info);
3456128Snate@binkert.org    DistPrint(const Text *text, const VectorDistInfo &info, int i);
3467505Snate@binkert.org    void init(const Text *text, const Info &info);
347695SN/A    void operator()(ostream &stream) const;
348695SN/A};
349695SN/A
3506128Snate@binkert.orgDistPrint::DistPrint(const Text *text, const DistInfo &info)
3516004Snate@binkert.org    : data(info.data)
3526004Snate@binkert.org{
3537505Snate@binkert.org    init(text, info);
3546004Snate@binkert.org}
3556004Snate@binkert.org
3566128Snate@binkert.orgDistPrint::DistPrint(const Text *text, const VectorDistInfo &info, int i)
3576004Snate@binkert.org    : data(info.data[i])
3586004Snate@binkert.org{
3597505Snate@binkert.org    init(text, info);
3606004Snate@binkert.org
3616004Snate@binkert.org    name = info.name + "_" +
36210386Sandreas.hansson@arm.com        (info.subnames[i].empty() ? (std::to_string(i)) : info.subnames[i]);
3636004Snate@binkert.org
3646004Snate@binkert.org    if (!info.subdescs[i].empty())
3656004Snate@binkert.org        desc = info.subdescs[i];
3666004Snate@binkert.org}
3676004Snate@binkert.org
3686004Snate@binkert.orgvoid
3697505Snate@binkert.orgDistPrint::init(const Text *text, const Info &info)
3706004Snate@binkert.org{
3716004Snate@binkert.org    name = info.name;
3728243Sbradley.danofsky@amd.com    separatorString = info.separatorString;
3736004Snate@binkert.org    desc = info.desc;
3746004Snate@binkert.org    flags = info.flags;
3756004Snate@binkert.org    precision = info.precision;
3766125Snate@binkert.org    descriptions = text->descriptions;
3776004Snate@binkert.org}
3786004Snate@binkert.org
379695SN/Avoid
380695SN/ADistPrint::operator()(ostream &stream) const
381695SN/A{
38210011Snilay@cs.wisc.edu    if (flags.isSet(nozero) && data.samples == 0) return;
3838243Sbradley.danofsky@amd.com    string base = name + separatorString;
384695SN/A
385695SN/A    ScalarPrint print;
3866211Snate@binkert.org    print.precision = precision;
387695SN/A    print.flags = flags;
388695SN/A    print.descriptions = descriptions;
3896211Snate@binkert.org    print.desc = desc;
390695SN/A    print.pdf = NAN;
391695SN/A    print.cdf = NAN;
392695SN/A
39310011Snilay@cs.wisc.edu    if (flags.isSet(oneline)) {
39410011Snilay@cs.wisc.edu        print.name = base + "bucket_size";
39510011Snilay@cs.wisc.edu        print.value = data.bucket_size;
39610011Snilay@cs.wisc.edu        print(stream);
39710011Snilay@cs.wisc.edu
39810011Snilay@cs.wisc.edu        print.name = base + "min_bucket";
39910011Snilay@cs.wisc.edu        print.value = data.min;
40010011Snilay@cs.wisc.edu        print(stream);
40110011Snilay@cs.wisc.edu
40210011Snilay@cs.wisc.edu        print.name = base + "max_bucket";
40310011Snilay@cs.wisc.edu        print.value = data.max;
40410011Snilay@cs.wisc.edu        print(stream);
40510011Snilay@cs.wisc.edu    }
40610011Snilay@cs.wisc.edu
407695SN/A    print.name = base + "samples";
4086004Snate@binkert.org    print.value = data.samples;
409695SN/A    print(stream);
410695SN/A
4116211Snate@binkert.org    print.name = base + "mean";
4126211Snate@binkert.org    print.value = data.samples ? data.sum / data.samples : NAN;
413695SN/A    print(stream);
414695SN/A
4158666SPrakash.Ramrakhyani@arm.com    if (data.type == Hist) {
4168666SPrakash.Ramrakhyani@arm.com        print.name = base + "gmean";
4178666SPrakash.Ramrakhyani@arm.com        print.value = data.samples ? exp(data.logs / data.samples) : NAN;
4188666SPrakash.Ramrakhyani@arm.com        print(stream);
4198666SPrakash.Ramrakhyani@arm.com    }
4208666SPrakash.Ramrakhyani@arm.com
4216211Snate@binkert.org    Result stdev = NAN;
4226211Snate@binkert.org    if (data.samples)
4236211Snate@binkert.org        stdev = sqrt((data.samples * data.squares - data.sum * data.sum) /
4246211Snate@binkert.org                     (data.samples * (data.samples - 1.0)));
4256211Snate@binkert.org    print.name = base + "stdev";
4266211Snate@binkert.org    print.value = stdev;
4276211Snate@binkert.org    print(stream);
4286211Snate@binkert.org
4297505Snate@binkert.org    if (data.type == Deviation)
4306211Snate@binkert.org        return;
4316211Snate@binkert.org
4327505Snate@binkert.org    size_t size = data.cvec.size();
4336211Snate@binkert.org
4346211Snate@binkert.org    Result total = 0.0;
4357831Snate@binkert.org    if (data.type == Dist && data.underflow != NAN)
4366211Snate@binkert.org        total += data.underflow;
4376211Snate@binkert.org    for (off_type i = 0; i < size; ++i)
4386211Snate@binkert.org        total += data.cvec[i];
4397831Snate@binkert.org    if (data.type == Dist && data.overflow != NAN)
4406211Snate@binkert.org        total += data.overflow;
4416211Snate@binkert.org
4426126Snate@binkert.org    if (total) {
4436211Snate@binkert.org        print.pdf = 0.0;
4446211Snate@binkert.org        print.cdf = 0.0;
4456126Snate@binkert.org    }
4466211Snate@binkert.org
4477831Snate@binkert.org    if (data.type == Dist && data.underflow != NAN) {
4486211Snate@binkert.org        print.name = base + "underflows";
4496211Snate@binkert.org        print.update(data.underflow, total);
4506211Snate@binkert.org        print(stream);
4516211Snate@binkert.org    }
4526126Snate@binkert.org
45310011Snilay@cs.wisc.edu    if (flags.isSet(oneline)) {
45410011Snilay@cs.wisc.edu        ccprintf(stream, "%-40s", name);
45510011Snilay@cs.wisc.edu    }
45610011Snilay@cs.wisc.edu
4576126Snate@binkert.org    for (off_type i = 0; i < size; ++i) {
4586126Snate@binkert.org        stringstream namestr;
4596126Snate@binkert.org        namestr << base;
4606126Snate@binkert.org
4617505Snate@binkert.org        Counter low = i * data.bucket_size + data.min;
4627505Snate@binkert.org        Counter high = ::min(low + data.bucket_size - 1.0, data.max);
4636126Snate@binkert.org        namestr << low;
4646126Snate@binkert.org        if (low < high)
4656126Snate@binkert.org            namestr << "-" << high;
4666126Snate@binkert.org
4676126Snate@binkert.org        print.name = namestr.str();
4686211Snate@binkert.org        print.update(data.cvec[i], total);
46910011Snilay@cs.wisc.edu        print(stream, flags.isSet(oneline));
47010011Snilay@cs.wisc.edu    }
47110011Snilay@cs.wisc.edu
47210011Snilay@cs.wisc.edu    if (flags.isSet(oneline)) {
47310011Snilay@cs.wisc.edu        if (descriptions) {
47410011Snilay@cs.wisc.edu            if (!desc.empty())
47510011Snilay@cs.wisc.edu                ccprintf(stream, " # %s", desc);
47610011Snilay@cs.wisc.edu        }
47710011Snilay@cs.wisc.edu        stream << endl;
478695SN/A    }
479695SN/A
4807831Snate@binkert.org    if (data.type == Dist && data.overflow != NAN) {
4816211Snate@binkert.org        print.name = base + "overflows";
4826211Snate@binkert.org        print.update(data.overflow, total);
4836211Snate@binkert.org        print(stream);
484695SN/A    }
485695SN/A
486695SN/A    print.pdf = NAN;
487695SN/A    print.cdf = NAN;
488695SN/A
4897831Snate@binkert.org    if (data.type == Dist && data.min_val != NAN) {
4906211Snate@binkert.org        print.name = base + "min_value";
4916211Snate@binkert.org        print.value = data.min_val;
4926211Snate@binkert.org        print(stream);
4936211Snate@binkert.org    }
4946211Snate@binkert.org
4957831Snate@binkert.org    if (data.type == Dist && data.max_val != NAN) {
4966211Snate@binkert.org        print.name = base + "max_value";
4976211Snate@binkert.org        print.value = data.max_val;
4986211Snate@binkert.org        print(stream);
4996211Snate@binkert.org    }
5006211Snate@binkert.org
5016126Snate@binkert.org    print.name = base + "total";
5026126Snate@binkert.org    print.value = total;
5036126Snate@binkert.org    print(stream);
504695SN/A}
505695SN/A
506695SN/Avoid
5076128Snate@binkert.orgText::visit(const ScalarInfo &info)
508695SN/A{
5095886Snate@binkert.org    if (noOutput(info))
510695SN/A        return;
511695SN/A
512695SN/A    ScalarPrint print;
5135886Snate@binkert.org    print.value = info.result();
5145886Snate@binkert.org    print.name = info.name;
5155886Snate@binkert.org    print.desc = info.desc;
5165886Snate@binkert.org    print.flags = info.flags;
517695SN/A    print.descriptions = descriptions;
5185886Snate@binkert.org    print.precision = info.precision;
519695SN/A    print.pdf = NAN;
520695SN/A    print.cdf = NAN;
521695SN/A
522695SN/A    print(*stream);
523695SN/A}
524695SN/A
525695SN/Avoid
5266128Snate@binkert.orgText::visit(const VectorInfo &info)
527695SN/A{
5285886Snate@binkert.org    if (noOutput(info))
529695SN/A        return;
530695SN/A
5315886Snate@binkert.org    size_type size = info.size();
532695SN/A    VectorPrint print;
533695SN/A
5345886Snate@binkert.org    print.name = info.name;
5358243Sbradley.danofsky@amd.com    print.separatorString = info.separatorString;
5365886Snate@binkert.org    print.desc = info.desc;
5375886Snate@binkert.org    print.flags = info.flags;
538695SN/A    print.descriptions = descriptions;
5395886Snate@binkert.org    print.precision = info.precision;
5405886Snate@binkert.org    print.vec = info.result();
5415886Snate@binkert.org    print.total = info.total();
5429839Sandreas.hansson@arm.com    print.forceSubnames = false;
543695SN/A
5445886Snate@binkert.org    if (!info.subnames.empty()) {
5455599Snate@binkert.org        for (off_type i = 0; i < size; ++i) {
5465886Snate@binkert.org            if (!info.subnames[i].empty()) {
5475886Snate@binkert.org                print.subnames = info.subnames;
548695SN/A                print.subnames.resize(size);
5495599Snate@binkert.org                for (off_type i = 0; i < size; ++i) {
5505886Snate@binkert.org                    if (!info.subnames[i].empty() &&
5515886Snate@binkert.org                        !info.subdescs[i].empty()) {
5525886Snate@binkert.org                        print.subdescs = info.subdescs;
553695SN/A                        print.subdescs.resize(size);
554695SN/A                        break;
555695SN/A                    }
556695SN/A                }
557695SN/A                break;
558695SN/A            }
559695SN/A        }
560695SN/A    }
561695SN/A
562695SN/A    print(*stream);
563695SN/A}
564695SN/A
565695SN/Avoid
5666128Snate@binkert.orgText::visit(const Vector2dInfo &info)
567695SN/A{
5685886Snate@binkert.org    if (noOutput(info))
569695SN/A        return;
570695SN/A
571695SN/A    bool havesub = false;
572695SN/A    VectorPrint print;
573695SN/A
5748667Sdam.sunwoo@arm.com    if (!info.y_subnames.empty()) {
5758667Sdam.sunwoo@arm.com        for (off_type i = 0; i < info.y; ++i) {
5768667Sdam.sunwoo@arm.com            if (!info.y_subnames[i].empty()) {
5778667Sdam.sunwoo@arm.com                print.subnames = info.y_subnames;
57810374Sandreas.hansson@arm.com                break;
5798667Sdam.sunwoo@arm.com            }
5808667Sdam.sunwoo@arm.com        }
5818667Sdam.sunwoo@arm.com    }
5825886Snate@binkert.org    print.flags = info.flags;
5838243Sbradley.danofsky@amd.com    print.separatorString = info.separatorString;
584695SN/A    print.descriptions = descriptions;
5855886Snate@binkert.org    print.precision = info.precision;
5869828Ssascha.bischoff@arm.com    print.forceSubnames = true;
587695SN/A
5885886Snate@binkert.org    if (!info.subnames.empty()) {
5895886Snate@binkert.org        for (off_type i = 0; i < info.x; ++i)
5905886Snate@binkert.org            if (!info.subnames[i].empty())
591695SN/A                havesub = true;
592695SN/A    }
593695SN/A
5945886Snate@binkert.org    VResult tot_vec(info.y);
5955886Snate@binkert.org    for (off_type i = 0; i < info.x; ++i) {
5965886Snate@binkert.org        if (havesub && (i >= info.subnames.size() || info.subnames[i].empty()))
597695SN/A            continue;
598695SN/A
5995886Snate@binkert.org        off_type iy = i * info.y;
6005886Snate@binkert.org        VResult yvec(info.y);
601695SN/A
602695SN/A        Result total = 0.0;
6035886Snate@binkert.org        for (off_type j = 0; j < info.y; ++j) {
6045886Snate@binkert.org            yvec[j] = info.cvec[iy + j];
605695SN/A            tot_vec[j] += yvec[j];
606695SN/A            total += yvec[j];
607695SN/A        }
608695SN/A
6095886Snate@binkert.org        print.name = info.name + "_" +
61010386Sandreas.hansson@arm.com            (havesub ? info.subnames[i] : std::to_string(i));
6115886Snate@binkert.org        print.desc = info.desc;
612695SN/A        print.vec = yvec;
613695SN/A        print.total = total;
614695SN/A        print(*stream);
615695SN/A    }
616695SN/A
6179828Ssascha.bischoff@arm.com    // Create a subname for printing the total
6189828Ssascha.bischoff@arm.com    vector<string> total_subname;
6199828Ssascha.bischoff@arm.com    total_subname.push_back("total");
6209828Ssascha.bischoff@arm.com
6216130Snate@binkert.org    if (info.flags.isSet(::Stats::total) && (info.x > 1)) {
6225886Snate@binkert.org        print.name = info.name;
6239828Ssascha.bischoff@arm.com        print.subnames = total_subname;
6245886Snate@binkert.org        print.desc = info.desc;
62511565Sdavid.guillen@arm.com        print.vec = VResult(1, info.total());
6269828Ssascha.bischoff@arm.com        print.flags = print.flags & ~total;
627695SN/A        print(*stream);
628695SN/A    }
629695SN/A}
630695SN/A
631695SN/Avoid
6326128Snate@binkert.orgText::visit(const DistInfo &info)
633695SN/A{
6345886Snate@binkert.org    if (noOutput(info))
635695SN/A        return;
636695SN/A
6376125Snate@binkert.org    DistPrint print(this, info);
638695SN/A    print(*stream);
639695SN/A}
640695SN/A
641695SN/Avoid
6426128Snate@binkert.orgText::visit(const VectorDistInfo &info)
643695SN/A{
6445886Snate@binkert.org    if (noOutput(info))
645695SN/A        return;
646695SN/A
6475886Snate@binkert.org    for (off_type i = 0; i < info.size(); ++i) {
6486125Snate@binkert.org        DistPrint print(this, info, i);
649695SN/A        print(*stream);
650695SN/A    }
651695SN/A}
652695SN/A
653695SN/Avoid
6546128Snate@binkert.orgText::visit(const FormulaInfo &info)
655695SN/A{
6566128Snate@binkert.org    visit((const VectorInfo &)info);
657695SN/A}
658695SN/A
6598514SThomas.Grass@ARM.com/*
6608514SThomas.Grass@ARM.com  This struct implements the output methods for the sparse
6618514SThomas.Grass@ARM.com  histogram stat
6628514SThomas.Grass@ARM.com*/
6638514SThomas.Grass@ARM.comstruct SparseHistPrint
6648514SThomas.Grass@ARM.com{
6658514SThomas.Grass@ARM.com    string name;
6668514SThomas.Grass@ARM.com    string separatorString;
6678514SThomas.Grass@ARM.com    string desc;
6688514SThomas.Grass@ARM.com    Flags flags;
6698514SThomas.Grass@ARM.com    bool descriptions;
6708514SThomas.Grass@ARM.com    int precision;
6718514SThomas.Grass@ARM.com
6728514SThomas.Grass@ARM.com    const SparseHistData &data;
6738514SThomas.Grass@ARM.com
6748514SThomas.Grass@ARM.com    SparseHistPrint(const Text *text, const SparseHistInfo &info);
6758514SThomas.Grass@ARM.com    void init(const Text *text, const Info &info);
6768514SThomas.Grass@ARM.com    void operator()(ostream &stream) const;
6778514SThomas.Grass@ARM.com};
6788514SThomas.Grass@ARM.com
6798514SThomas.Grass@ARM.com/* Call initialization function */
6808514SThomas.Grass@ARM.comSparseHistPrint::SparseHistPrint(const Text *text, const SparseHistInfo &info)
6818514SThomas.Grass@ARM.com    : data(info.data)
6828514SThomas.Grass@ARM.com{
6838514SThomas.Grass@ARM.com    init(text, info);
6848514SThomas.Grass@ARM.com}
6858514SThomas.Grass@ARM.com
6868514SThomas.Grass@ARM.com/* Initialization function */
6878514SThomas.Grass@ARM.comvoid
6888514SThomas.Grass@ARM.comSparseHistPrint::init(const Text *text, const Info &info)
6898514SThomas.Grass@ARM.com{
6908514SThomas.Grass@ARM.com    name = info.name;
6918514SThomas.Grass@ARM.com    separatorString = info.separatorString;
6928514SThomas.Grass@ARM.com    desc = info.desc;
6938514SThomas.Grass@ARM.com    flags = info.flags;
6948514SThomas.Grass@ARM.com    precision = info.precision;
6958514SThomas.Grass@ARM.com    descriptions = text->descriptions;
6968514SThomas.Grass@ARM.com}
6978514SThomas.Grass@ARM.com
6988514SThomas.Grass@ARM.com/* Grab data from map and write to output stream */
6998514SThomas.Grass@ARM.comvoid
7008514SThomas.Grass@ARM.comSparseHistPrint::operator()(ostream &stream) const
7018514SThomas.Grass@ARM.com{
7028514SThomas.Grass@ARM.com    string base = name + separatorString;
7038514SThomas.Grass@ARM.com
7048514SThomas.Grass@ARM.com    ScalarPrint print;
7058514SThomas.Grass@ARM.com    print.precision = precision;
7068514SThomas.Grass@ARM.com    print.flags = flags;
7078514SThomas.Grass@ARM.com    print.descriptions = descriptions;
7088514SThomas.Grass@ARM.com    print.desc = desc;
7098514SThomas.Grass@ARM.com    print.pdf = NAN;
7108514SThomas.Grass@ARM.com    print.cdf = NAN;
7118514SThomas.Grass@ARM.com
7128514SThomas.Grass@ARM.com    print.name = base + "samples";
7138514SThomas.Grass@ARM.com    print.value = data.samples;
7148514SThomas.Grass@ARM.com    print(stream);
7158514SThomas.Grass@ARM.com
7168514SThomas.Grass@ARM.com    MCounter::const_iterator it;
7178514SThomas.Grass@ARM.com    for (it = data.cmap.begin(); it != data.cmap.end(); it++) {
7188514SThomas.Grass@ARM.com        stringstream namestr;
7198514SThomas.Grass@ARM.com        namestr << base;
7208514SThomas.Grass@ARM.com
7218514SThomas.Grass@ARM.com        namestr <<(*it).first;
7228514SThomas.Grass@ARM.com        print.name = namestr.str();
7238514SThomas.Grass@ARM.com        print.value = (*it).second;
7248514SThomas.Grass@ARM.com        print(stream);
7258514SThomas.Grass@ARM.com    }
7268514SThomas.Grass@ARM.com}
7278514SThomas.Grass@ARM.com
7288514SThomas.Grass@ARM.comvoid
7298514SThomas.Grass@ARM.comText::visit(const SparseHistInfo &info)
7308514SThomas.Grass@ARM.com{
7318514SThomas.Grass@ARM.com    if (noOutput(info))
7328514SThomas.Grass@ARM.com        return;
7338514SThomas.Grass@ARM.com
7348514SThomas.Grass@ARM.com    SparseHistPrint print(this, info);
7358514SThomas.Grass@ARM.com    print(*stream);
7368514SThomas.Grass@ARM.com}
7378514SThomas.Grass@ARM.com
7388296Snate@binkert.orgOutput *
7396126Snate@binkert.orginitText(const string &filename, bool desc)
7404078Sbinkertn@umich.edu{
7414078Sbinkertn@umich.edu    static Text text;
7424078Sbinkertn@umich.edu    static bool connected = false;
7434078Sbinkertn@umich.edu
7448296Snate@binkert.org    if (!connected) {
74511359Sandreas@sandberg.pp.se        text.open(*simout.findOrCreate(filename)->stream());
7468296Snate@binkert.org        text.descriptions = desc;
7478296Snate@binkert.org        connected = true;
7488296Snate@binkert.org    }
7494078Sbinkertn@umich.edu
7508296Snate@binkert.org    return &text;
7514078Sbinkertn@umich.edu}
7524078Sbinkertn@umich.edu
7537811Ssteve.reinhardt@amd.com} // namespace Stats
754