text.cc revision 8667:62372a8d4ef2
111986Sandreas.sandberg@arm.com/*
211986Sandreas.sandberg@arm.com * Copyright (c) 2004-2005 The Regents of The University of Michigan
311986Sandreas.sandberg@arm.com * All rights reserved.
411986Sandreas.sandberg@arm.com *
511986Sandreas.sandberg@arm.com * Redistribution and use in source and binary forms, with or without
611986Sandreas.sandberg@arm.com * modification, are permitted provided that the following conditions are
711986Sandreas.sandberg@arm.com * met: redistributions of source code must retain the above copyright
811986Sandreas.sandberg@arm.com * notice, this list of conditions and the following disclaimer;
911986Sandreas.sandberg@arm.com * redistributions in binary form must reproduce the above copyright
1011986Sandreas.sandberg@arm.com * notice, this list of conditions and the following disclaimer in the
1111986Sandreas.sandberg@arm.com * documentation and/or other materials provided with the distribution;
1211986Sandreas.sandberg@arm.com * neither the name of the copyright holders nor the names of its
1311986Sandreas.sandberg@arm.com * contributors may be used to endorse or promote products derived from
1411986Sandreas.sandberg@arm.com * this software without specific prior written permission.
1511986Sandreas.sandberg@arm.com *
1611986Sandreas.sandberg@arm.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1711986Sandreas.sandberg@arm.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
1811986Sandreas.sandberg@arm.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
1911986Sandreas.sandberg@arm.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2011986Sandreas.sandberg@arm.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2111986Sandreas.sandberg@arm.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2211986Sandreas.sandberg@arm.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2311986Sandreas.sandberg@arm.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2411986Sandreas.sandberg@arm.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2511986Sandreas.sandberg@arm.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2611986Sandreas.sandberg@arm.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2711986Sandreas.sandberg@arm.com *
2811986Sandreas.sandberg@arm.com * Authors: Nathan Binkert
2911986Sandreas.sandberg@arm.com */
3011986Sandreas.sandberg@arm.com
3111986Sandreas.sandberg@arm.com#if defined(__APPLE__)
3211986Sandreas.sandberg@arm.com#define _GLIBCPP_USE_C99 1
3311986Sandreas.sandberg@arm.com#endif
3411986Sandreas.sandberg@arm.com
3511986Sandreas.sandberg@arm.com#if defined(__sun)
3612037Sandreas.sandberg@arm.com#include <math.h>
3711986Sandreas.sandberg@arm.com#endif
3811986Sandreas.sandberg@arm.com
3911986Sandreas.sandberg@arm.com#include <cassert>
4011986Sandreas.sandberg@arm.com#ifdef __SUNPRO_CC
4111986Sandreas.sandberg@arm.com#include <math.h>
4211986Sandreas.sandberg@arm.com#endif
4311986Sandreas.sandberg@arm.com#include <cmath>
4411986Sandreas.sandberg@arm.com#include <fstream>
4511986Sandreas.sandberg@arm.com#include <iostream>
4611986Sandreas.sandberg@arm.com#include <sstream>
4711986Sandreas.sandberg@arm.com#include <string>
4811986Sandreas.sandberg@arm.com
4912037Sandreas.sandberg@arm.com#include "base/stats/info.hh"
5012037Sandreas.sandberg@arm.com#include "base/stats/text.hh"
5112037Sandreas.sandberg@arm.com#include "base/cast.hh"
5212037Sandreas.sandberg@arm.com#include "base/misc.hh"
5312037Sandreas.sandberg@arm.com#include "base/str.hh"
5412037Sandreas.sandberg@arm.com
5511986Sandreas.sandberg@arm.comusing namespace std;
5611986Sandreas.sandberg@arm.com
5711986Sandreas.sandberg@arm.com#ifndef NAN
5811986Sandreas.sandberg@arm.comfloat __nan();
5911986Sandreas.sandberg@arm.com/** Define Not a number. */
6011986Sandreas.sandberg@arm.com#define NAN (__nan())
6111986Sandreas.sandberg@arm.com/** Need to define __nan() */
6211986Sandreas.sandberg@arm.com#define __M5_NAN
6311986Sandreas.sandberg@arm.com#endif
6411986Sandreas.sandberg@arm.com
6511986Sandreas.sandberg@arm.com#ifdef __M5_NAN
6611986Sandreas.sandberg@arm.comfloat
6711986Sandreas.sandberg@arm.com__nan()
6811986Sandreas.sandberg@arm.com{
6911986Sandreas.sandberg@arm.com    union {
7011986Sandreas.sandberg@arm.com        uint32_t ui;
7111986Sandreas.sandberg@arm.com        float f;
7211986Sandreas.sandberg@arm.com    } nan;
7311986Sandreas.sandberg@arm.com
7411986Sandreas.sandberg@arm.com    nan.ui = 0x7fc00000;
7511986Sandreas.sandberg@arm.com    return nan.f;
7611986Sandreas.sandberg@arm.com}
7711986Sandreas.sandberg@arm.com#endif
7811986Sandreas.sandberg@arm.com
7911986Sandreas.sandberg@arm.comnamespace Stats {
8011986Sandreas.sandberg@arm.com
8111986Sandreas.sandberg@arm.comstd::list<Info *> &statsList();
8211986Sandreas.sandberg@arm.com
8312037Sandreas.sandberg@arm.comText::Text()
8411986Sandreas.sandberg@arm.com    : mystream(false), stream(NULL), descriptions(false)
8511986Sandreas.sandberg@arm.com{
8611986Sandreas.sandberg@arm.com}
8711986Sandreas.sandberg@arm.com
8811986Sandreas.sandberg@arm.comText::Text(std::ostream &stream)
8911986Sandreas.sandberg@arm.com    : mystream(false), stream(NULL), descriptions(false)
9011986Sandreas.sandberg@arm.com{
9111986Sandreas.sandberg@arm.com    open(stream);
9211986Sandreas.sandberg@arm.com}
9311986Sandreas.sandberg@arm.com
9411986Sandreas.sandberg@arm.comText::Text(const std::string &file)
9511986Sandreas.sandberg@arm.com    : mystream(false), stream(NULL), descriptions(false)
9611986Sandreas.sandberg@arm.com{
9711986Sandreas.sandberg@arm.com    open(file);
9811986Sandreas.sandberg@arm.com}
9911986Sandreas.sandberg@arm.com
10011986Sandreas.sandberg@arm.com
10111986Sandreas.sandberg@arm.comText::~Text()
10211986Sandreas.sandberg@arm.com{
10311986Sandreas.sandberg@arm.com    if (mystream) {
10411986Sandreas.sandberg@arm.com        assert(stream);
10511986Sandreas.sandberg@arm.com        delete stream;
10611986Sandreas.sandberg@arm.com    }
10711986Sandreas.sandberg@arm.com}
10811986Sandreas.sandberg@arm.com
10911986Sandreas.sandberg@arm.comvoid
11011986Sandreas.sandberg@arm.comText::open(std::ostream &_stream)
11111986Sandreas.sandberg@arm.com{
11211986Sandreas.sandberg@arm.com    if (stream)
11311986Sandreas.sandberg@arm.com        panic("stream already set!");
11411986Sandreas.sandberg@arm.com
11511986Sandreas.sandberg@arm.com    mystream = false;
11611986Sandreas.sandberg@arm.com    stream = &_stream;
11711986Sandreas.sandberg@arm.com    if (!valid())
11811986Sandreas.sandberg@arm.com        fatal("Unable to open output stream for writing\n");
11911986Sandreas.sandberg@arm.com}
12011986Sandreas.sandberg@arm.com
12111986Sandreas.sandberg@arm.comvoid
12211986Sandreas.sandberg@arm.comText::open(const std::string &file)
12311986Sandreas.sandberg@arm.com{
12411986Sandreas.sandberg@arm.com    if (stream)
12511986Sandreas.sandberg@arm.com        panic("stream already set!");
12611986Sandreas.sandberg@arm.com
12711986Sandreas.sandberg@arm.com    mystream = true;
12811986Sandreas.sandberg@arm.com    stream = new ofstream(file.c_str(), ios::trunc);
12911986Sandreas.sandberg@arm.com    if (!valid())
13011986Sandreas.sandberg@arm.com        fatal("Unable to open statistics file for writing\n");
13111986Sandreas.sandberg@arm.com}
13211986Sandreas.sandberg@arm.com
13311986Sandreas.sandberg@arm.combool
13411986Sandreas.sandberg@arm.comText::valid() const
13511986Sandreas.sandberg@arm.com{
13611986Sandreas.sandberg@arm.com    return stream != NULL && stream->good();
13711986Sandreas.sandberg@arm.com}
13811986Sandreas.sandberg@arm.com
13911986Sandreas.sandberg@arm.comvoid
14011986Sandreas.sandberg@arm.comText::begin()
14111986Sandreas.sandberg@arm.com{
14211986Sandreas.sandberg@arm.com    ccprintf(*stream, "\n---------- Begin Simulation Statistics ----------\n");
14311986Sandreas.sandberg@arm.com}
14411986Sandreas.sandberg@arm.com
14511986Sandreas.sandberg@arm.comvoid
14611986Sandreas.sandberg@arm.comText::end()
14711986Sandreas.sandberg@arm.com{
14811986Sandreas.sandberg@arm.com    ccprintf(*stream, "\n---------- End Simulation Statistics   ----------\n");
14911986Sandreas.sandberg@arm.com    stream->flush();
15011986Sandreas.sandberg@arm.com}
15111986Sandreas.sandberg@arm.com
15211986Sandreas.sandberg@arm.combool
15311986Sandreas.sandberg@arm.comText::noOutput(const Info &info)
15411986Sandreas.sandberg@arm.com{
15511986Sandreas.sandberg@arm.com    if (!info.flags.isSet(display))
15611986Sandreas.sandberg@arm.com        return true;
15711986Sandreas.sandberg@arm.com
15812037Sandreas.sandberg@arm.com    if (info.prereq && info.prereq->zero())
15911986Sandreas.sandberg@arm.com        return true;
16011986Sandreas.sandberg@arm.com
16111986Sandreas.sandberg@arm.com    return false;
16211986Sandreas.sandberg@arm.com}
16311986Sandreas.sandberg@arm.com
16411986Sandreas.sandberg@arm.comstring
16511986Sandreas.sandberg@arm.comValueToString(Result value, int precision)
16611986Sandreas.sandberg@arm.com{
16711986Sandreas.sandberg@arm.com    stringstream val;
16811986Sandreas.sandberg@arm.com
16911986Sandreas.sandberg@arm.com    if (!isnan(value)) {
17011986Sandreas.sandberg@arm.com        if (precision != -1)
17111986Sandreas.sandberg@arm.com            val.precision(precision);
17211986Sandreas.sandberg@arm.com        else if (value == rint(value))
17311986Sandreas.sandberg@arm.com            val.precision(0);
17411986Sandreas.sandberg@arm.com
17511986Sandreas.sandberg@arm.com        val.unsetf(ios::showpoint);
17611986Sandreas.sandberg@arm.com        val.setf(ios::fixed);
17711986Sandreas.sandberg@arm.com        val << value;
17811986Sandreas.sandberg@arm.com    } else {
17912037Sandreas.sandberg@arm.com        val << "no_value";
18012037Sandreas.sandberg@arm.com    }
18112037Sandreas.sandberg@arm.com
18212037Sandreas.sandberg@arm.com    return val.str();
18311986Sandreas.sandberg@arm.com}
18411986Sandreas.sandberg@arm.com
18511986Sandreas.sandberg@arm.comstruct ScalarPrint
18611986Sandreas.sandberg@arm.com{
18711986Sandreas.sandberg@arm.com    Result value;
18811986Sandreas.sandberg@arm.com    string name;
18911986Sandreas.sandberg@arm.com    string desc;
19011986Sandreas.sandberg@arm.com    Flags flags;
19111986Sandreas.sandberg@arm.com    bool descriptions;
19211986Sandreas.sandberg@arm.com    int precision;
19311986Sandreas.sandberg@arm.com    Result pdf;
19411986Sandreas.sandberg@arm.com    Result cdf;
19511986Sandreas.sandberg@arm.com
19612037Sandreas.sandberg@arm.com    void update(Result val, Result total);
19712037Sandreas.sandberg@arm.com    void operator()(ostream &stream) const;
19812037Sandreas.sandberg@arm.com};
19911986Sandreas.sandberg@arm.com
20012037Sandreas.sandberg@arm.comvoid
20112037Sandreas.sandberg@arm.comScalarPrint::update(Result val, Result total)
20212037Sandreas.sandberg@arm.com{
20312037Sandreas.sandberg@arm.com    value = val;
20411986Sandreas.sandberg@arm.com    if (total) {
20511986Sandreas.sandberg@arm.com        pdf = val / total;
20611986Sandreas.sandberg@arm.com        cdf += pdf;
20711986Sandreas.sandberg@arm.com    }
20811986Sandreas.sandberg@arm.com}
20911986Sandreas.sandberg@arm.com
21011986Sandreas.sandberg@arm.comvoid
21111986Sandreas.sandberg@arm.comScalarPrint::operator()(ostream &stream) const
21211986Sandreas.sandberg@arm.com{
21311986Sandreas.sandberg@arm.com    if ((flags.isSet(nozero) && value == 0.0) ||
21411986Sandreas.sandberg@arm.com        (flags.isSet(nonan) && isnan(value)))
21511986Sandreas.sandberg@arm.com        return;
21611986Sandreas.sandberg@arm.com
21711986Sandreas.sandberg@arm.com    stringstream pdfstr, cdfstr;
21811986Sandreas.sandberg@arm.com
21911986Sandreas.sandberg@arm.com    if (!isnan(pdf))
22011986Sandreas.sandberg@arm.com        ccprintf(pdfstr, "%.2f%%", pdf * 100.0);
22111986Sandreas.sandberg@arm.com
22211986Sandreas.sandberg@arm.com    if (!isnan(cdf))
22311986Sandreas.sandberg@arm.com        ccprintf(cdfstr, "%.2f%%", cdf * 100.0);
22411986Sandreas.sandberg@arm.com
22511986Sandreas.sandberg@arm.com    ccprintf(stream, "%-40s %12s %10s %10s", name,
22611986Sandreas.sandberg@arm.com             ValueToString(value, precision), pdfstr, cdfstr);
22711986Sandreas.sandberg@arm.com
22811986Sandreas.sandberg@arm.com    if (descriptions) {
22911986Sandreas.sandberg@arm.com        if (!desc.empty())
23011986Sandreas.sandberg@arm.com            ccprintf(stream, " # %s", desc);
23111986Sandreas.sandberg@arm.com    }
23211986Sandreas.sandberg@arm.com    stream << endl;
23311986Sandreas.sandberg@arm.com}
23411986Sandreas.sandberg@arm.com
23511986Sandreas.sandberg@arm.comstruct VectorPrint
23611986Sandreas.sandberg@arm.com{
23711986Sandreas.sandberg@arm.com    string name;
23811986Sandreas.sandberg@arm.com    string separatorString;
23911986Sandreas.sandberg@arm.com    string desc;
24011986Sandreas.sandberg@arm.com    vector<string> subnames;
24111986Sandreas.sandberg@arm.com    vector<string> subdescs;
24211986Sandreas.sandberg@arm.com    Flags flags;
24311986Sandreas.sandberg@arm.com    bool descriptions;
24411986Sandreas.sandberg@arm.com    int precision;
24511986Sandreas.sandberg@arm.com    VResult vec;
24611986Sandreas.sandberg@arm.com    Result total;
24711986Sandreas.sandberg@arm.com
24811986Sandreas.sandberg@arm.com    void operator()(ostream &stream) const;
24911986Sandreas.sandberg@arm.com};
25011986Sandreas.sandberg@arm.com
25111986Sandreas.sandberg@arm.comvoid
25211986Sandreas.sandberg@arm.comVectorPrint::operator()(std::ostream &stream) const
25311986Sandreas.sandberg@arm.com{
25411986Sandreas.sandberg@arm.com    size_type _size = vec.size();
25511986Sandreas.sandberg@arm.com    Result _total = 0.0;
25611986Sandreas.sandberg@arm.com
25711986Sandreas.sandberg@arm.com    if (flags.isSet(pdf | cdf)) {
25811986Sandreas.sandberg@arm.com        for (off_type i = 0; i < _size; ++i) {
25911986Sandreas.sandberg@arm.com            _total += vec[i];
26011986Sandreas.sandberg@arm.com        }
26111986Sandreas.sandberg@arm.com    }
26211986Sandreas.sandberg@arm.com
26311986Sandreas.sandberg@arm.com    string base = name + separatorString;
26411986Sandreas.sandberg@arm.com
26511986Sandreas.sandberg@arm.com    ScalarPrint print;
26611986Sandreas.sandberg@arm.com    print.name = name;
26711986Sandreas.sandberg@arm.com    print.desc = desc;
26811986Sandreas.sandberg@arm.com    print.precision = precision;
26911986Sandreas.sandberg@arm.com    print.descriptions = descriptions;
27011986Sandreas.sandberg@arm.com    print.flags = flags;
27111986Sandreas.sandberg@arm.com    print.pdf = _total ? 0.0 : NAN;
27211986Sandreas.sandberg@arm.com    print.cdf = _total ? 0.0 : NAN;
27311986Sandreas.sandberg@arm.com
27411986Sandreas.sandberg@arm.com    bool havesub = !subnames.empty();
27511986Sandreas.sandberg@arm.com
27611986Sandreas.sandberg@arm.com    if (_size == 1) {
27711986Sandreas.sandberg@arm.com        print.value = vec[0];
27811986Sandreas.sandberg@arm.com        print(stream);
27911986Sandreas.sandberg@arm.com        return;
28011986Sandreas.sandberg@arm.com    }
28111986Sandreas.sandberg@arm.com
28211986Sandreas.sandberg@arm.com    for (off_type i = 0; i < _size; ++i) {
28311986Sandreas.sandberg@arm.com        if (havesub && (i >= subnames.size() || subnames[i].empty()))
28411986Sandreas.sandberg@arm.com            continue;
28511986Sandreas.sandberg@arm.com
28611986Sandreas.sandberg@arm.com        print.name = base + (havesub ? subnames[i] : to_string(i));
28711986Sandreas.sandberg@arm.com        print.desc = subdescs.empty() ? desc : subdescs[i];
28811986Sandreas.sandberg@arm.com
28911986Sandreas.sandberg@arm.com        print.update(vec[i], _total);
29011986Sandreas.sandberg@arm.com        print(stream);
29111986Sandreas.sandberg@arm.com    }
29211986Sandreas.sandberg@arm.com
29311986Sandreas.sandberg@arm.com    if (flags.isSet(::Stats::total)) {
29411986Sandreas.sandberg@arm.com        print.pdf = NAN;
29511986Sandreas.sandberg@arm.com        print.cdf = NAN;
29611986Sandreas.sandberg@arm.com        print.name = base + "total";
29711986Sandreas.sandberg@arm.com        print.desc = desc;
29811986Sandreas.sandberg@arm.com        print.value = total;
29911986Sandreas.sandberg@arm.com        print(stream);
30011986Sandreas.sandberg@arm.com    }
30111986Sandreas.sandberg@arm.com}
30211986Sandreas.sandberg@arm.com
30311986Sandreas.sandberg@arm.comstruct DistPrint
30411986Sandreas.sandberg@arm.com{
30511986Sandreas.sandberg@arm.com    string name;
30611986Sandreas.sandberg@arm.com    string separatorString;
30711986Sandreas.sandberg@arm.com    string desc;
30812037Sandreas.sandberg@arm.com    Flags flags;
30912037Sandreas.sandberg@arm.com    bool descriptions;
31012037Sandreas.sandberg@arm.com    int precision;
31112037Sandreas.sandberg@arm.com
31212037Sandreas.sandberg@arm.com    const DistData &data;
31312037Sandreas.sandberg@arm.com
31412037Sandreas.sandberg@arm.com    DistPrint(const Text *text, const DistInfo &info);
31512037Sandreas.sandberg@arm.com    DistPrint(const Text *text, const VectorDistInfo &info, int i);
31612037Sandreas.sandberg@arm.com    void init(const Text *text, const Info &info);
31712037Sandreas.sandberg@arm.com    void operator()(ostream &stream) const;
31812037Sandreas.sandberg@arm.com};
31912037Sandreas.sandberg@arm.com
32012037Sandreas.sandberg@arm.comDistPrint::DistPrint(const Text *text, const DistInfo &info)
32112037Sandreas.sandberg@arm.com    : data(info.data)
32212037Sandreas.sandberg@arm.com{
32312037Sandreas.sandberg@arm.com    init(text, info);
32412037Sandreas.sandberg@arm.com}
32512037Sandreas.sandberg@arm.com
32612037Sandreas.sandberg@arm.comDistPrint::DistPrint(const Text *text, const VectorDistInfo &info, int i)
32712037Sandreas.sandberg@arm.com    : data(info.data[i])
32812037Sandreas.sandberg@arm.com{
32912037Sandreas.sandberg@arm.com    init(text, info);
33012037Sandreas.sandberg@arm.com
33112037Sandreas.sandberg@arm.com    name = info.name + "_" +
33212037Sandreas.sandberg@arm.com        (info.subnames[i].empty() ? (to_string(i)) : info.subnames[i]);
33312037Sandreas.sandberg@arm.com
33412037Sandreas.sandberg@arm.com    if (!info.subdescs[i].empty())
33512037Sandreas.sandberg@arm.com        desc = info.subdescs[i];
33612037Sandreas.sandberg@arm.com}
33712037Sandreas.sandberg@arm.com
33812037Sandreas.sandberg@arm.comvoid
33912037Sandreas.sandberg@arm.comDistPrint::init(const Text *text, const Info &info)
34012037Sandreas.sandberg@arm.com{
34112037Sandreas.sandberg@arm.com    name = info.name;
34212037Sandreas.sandberg@arm.com    separatorString = info.separatorString;
34312037Sandreas.sandberg@arm.com    desc = info.desc;
34412037Sandreas.sandberg@arm.com    flags = info.flags;
34512037Sandreas.sandberg@arm.com    precision = info.precision;
34612037Sandreas.sandberg@arm.com    descriptions = text->descriptions;
34712037Sandreas.sandberg@arm.com}
34812037Sandreas.sandberg@arm.com
34912037Sandreas.sandberg@arm.comvoid
35012037Sandreas.sandberg@arm.comDistPrint::operator()(ostream &stream) const
35112037Sandreas.sandberg@arm.com{
35212037Sandreas.sandberg@arm.com    string base = name + separatorString;
35312037Sandreas.sandberg@arm.com
35412037Sandreas.sandberg@arm.com    ScalarPrint print;
35512037Sandreas.sandberg@arm.com    print.precision = precision;
35612037Sandreas.sandberg@arm.com    print.flags = flags;
35712037Sandreas.sandberg@arm.com    print.descriptions = descriptions;
35812037Sandreas.sandberg@arm.com    print.desc = desc;
35912037Sandreas.sandberg@arm.com    print.pdf = NAN;
36012037Sandreas.sandberg@arm.com    print.cdf = NAN;
36112037Sandreas.sandberg@arm.com
36212037Sandreas.sandberg@arm.com    print.name = base + "samples";
36312037Sandreas.sandberg@arm.com    print.value = data.samples;
36412037Sandreas.sandberg@arm.com    print(stream);
36512037Sandreas.sandberg@arm.com
36612037Sandreas.sandberg@arm.com    print.name = base + "mean";
36712037Sandreas.sandberg@arm.com    print.value = data.samples ? data.sum / data.samples : NAN;
36812037Sandreas.sandberg@arm.com    print(stream);
36912037Sandreas.sandberg@arm.com
37012037Sandreas.sandberg@arm.com    if (data.type == Hist) {
37112037Sandreas.sandberg@arm.com        print.name = base + "gmean";
37212037Sandreas.sandberg@arm.com        print.value = data.samples ? exp(data.logs / data.samples) : NAN;
37312037Sandreas.sandberg@arm.com        print(stream);
37412037Sandreas.sandberg@arm.com    }
37512037Sandreas.sandberg@arm.com
37612037Sandreas.sandberg@arm.com    Result stdev = NAN;
37712037Sandreas.sandberg@arm.com    if (data.samples)
37812037Sandreas.sandberg@arm.com        stdev = sqrt((data.samples * data.squares - data.sum * data.sum) /
37912037Sandreas.sandberg@arm.com                     (data.samples * (data.samples - 1.0)));
380    print.name = base + "stdev";
381    print.value = stdev;
382    print(stream);
383
384    if (data.type == Deviation)
385        return;
386
387    size_t size = data.cvec.size();
388
389    Result total = 0.0;
390    if (data.type == Dist && data.underflow != NAN)
391        total += data.underflow;
392    for (off_type i = 0; i < size; ++i)
393        total += data.cvec[i];
394    if (data.type == Dist && data.overflow != NAN)
395        total += data.overflow;
396
397    if (total) {
398        print.pdf = 0.0;
399        print.cdf = 0.0;
400    }
401
402    if (data.type == Dist && data.underflow != NAN) {
403        print.name = base + "underflows";
404        print.update(data.underflow, total);
405        print(stream);
406    }
407
408    for (off_type i = 0; i < size; ++i) {
409        stringstream namestr;
410        namestr << base;
411
412        Counter low = i * data.bucket_size + data.min;
413        Counter high = ::min(low + data.bucket_size - 1.0, data.max);
414        namestr << low;
415        if (low < high)
416            namestr << "-" << high;
417
418        print.name = namestr.str();
419        print.update(data.cvec[i], total);
420        print(stream);
421    }
422
423    if (data.type == Dist && data.overflow != NAN) {
424        print.name = base + "overflows";
425        print.update(data.overflow, total);
426        print(stream);
427    }
428
429    print.pdf = NAN;
430    print.cdf = NAN;
431
432    if (data.type == Dist && data.min_val != NAN) {
433        print.name = base + "min_value";
434        print.value = data.min_val;
435        print(stream);
436    }
437
438    if (data.type == Dist && data.max_val != NAN) {
439        print.name = base + "max_value";
440        print.value = data.max_val;
441        print(stream);
442    }
443
444    print.name = base + "total";
445    print.value = total;
446    print(stream);
447}
448
449void
450Text::visit(const ScalarInfo &info)
451{
452    if (noOutput(info))
453        return;
454
455    ScalarPrint print;
456    print.value = info.result();
457    print.name = info.name;
458    print.desc = info.desc;
459    print.flags = info.flags;
460    print.descriptions = descriptions;
461    print.precision = info.precision;
462    print.pdf = NAN;
463    print.cdf = NAN;
464
465    print(*stream);
466}
467
468void
469Text::visit(const VectorInfo &info)
470{
471    if (noOutput(info))
472        return;
473
474    size_type size = info.size();
475    VectorPrint print;
476
477    print.name = info.name;
478    print.separatorString = info.separatorString;
479    print.desc = info.desc;
480    print.flags = info.flags;
481    print.descriptions = descriptions;
482    print.precision = info.precision;
483    print.vec = info.result();
484    print.total = info.total();
485
486    if (!info.subnames.empty()) {
487        for (off_type i = 0; i < size; ++i) {
488            if (!info.subnames[i].empty()) {
489                print.subnames = info.subnames;
490                print.subnames.resize(size);
491                for (off_type i = 0; i < size; ++i) {
492                    if (!info.subnames[i].empty() &&
493                        !info.subdescs[i].empty()) {
494                        print.subdescs = info.subdescs;
495                        print.subdescs.resize(size);
496                        break;
497                    }
498                }
499                break;
500            }
501        }
502    }
503
504    print(*stream);
505}
506
507void
508Text::visit(const Vector2dInfo &info)
509{
510    if (noOutput(info))
511        return;
512
513    bool havesub = false;
514    VectorPrint print;
515
516    if (!info.y_subnames.empty()) {
517        for (off_type i = 0; i < info.y; ++i) {
518            if (!info.y_subnames[i].empty()) {
519                print.subnames = info.y_subnames;
520            }
521            break;
522        }
523    }
524    print.flags = info.flags;
525    print.separatorString = info.separatorString;
526    print.descriptions = descriptions;
527    print.precision = info.precision;
528
529    if (!info.subnames.empty()) {
530        for (off_type i = 0; i < info.x; ++i)
531            if (!info.subnames[i].empty())
532                havesub = true;
533    }
534
535    VResult tot_vec(info.y);
536    Result super_total = 0.0;
537    for (off_type i = 0; i < info.x; ++i) {
538        if (havesub && (i >= info.subnames.size() || info.subnames[i].empty()))
539            continue;
540
541        off_type iy = i * info.y;
542        VResult yvec(info.y);
543
544        Result total = 0.0;
545        for (off_type j = 0; j < info.y; ++j) {
546            yvec[j] = info.cvec[iy + j];
547            tot_vec[j] += yvec[j];
548            total += yvec[j];
549            super_total += yvec[j];
550        }
551
552        print.name = info.name + "_" +
553            (havesub ? info.subnames[i] : to_string(i));
554        print.desc = info.desc;
555        print.vec = yvec;
556        print.total = total;
557        print(*stream);
558    }
559
560    if (info.flags.isSet(::Stats::total) && (info.x > 1)) {
561        print.name = info.name;
562        print.desc = info.desc;
563        print.vec = tot_vec;
564        print.total = super_total;
565        print(*stream);
566    }
567}
568
569void
570Text::visit(const DistInfo &info)
571{
572    if (noOutput(info))
573        return;
574
575    DistPrint print(this, info);
576    print(*stream);
577}
578
579void
580Text::visit(const VectorDistInfo &info)
581{
582    if (noOutput(info))
583        return;
584
585    for (off_type i = 0; i < info.size(); ++i) {
586        DistPrint print(this, info, i);
587        print(*stream);
588    }
589}
590
591void
592Text::visit(const FormulaInfo &info)
593{
594    visit((const VectorInfo &)info);
595}
596
597/*
598  This struct implements the output methods for the sparse
599  histogram stat
600*/
601struct SparseHistPrint
602{
603    string name;
604    string separatorString;
605    string desc;
606    Flags flags;
607    bool descriptions;
608    int precision;
609
610    const SparseHistData &data;
611
612    SparseHistPrint(const Text *text, const SparseHistInfo &info);
613    void init(const Text *text, const Info &info);
614    void operator()(ostream &stream) const;
615};
616
617/* Call initialization function */
618SparseHistPrint::SparseHistPrint(const Text *text, const SparseHistInfo &info)
619    : data(info.data)
620{
621    init(text, info);
622}
623
624/* Initialization function */
625void
626SparseHistPrint::init(const Text *text, const Info &info)
627{
628    name = info.name;
629    separatorString = info.separatorString;
630    desc = info.desc;
631    flags = info.flags;
632    precision = info.precision;
633    descriptions = text->descriptions;
634}
635
636/* Grab data from map and write to output stream */
637void
638SparseHistPrint::operator()(ostream &stream) const
639{
640    string base = name + separatorString;
641
642    ScalarPrint print;
643    print.precision = precision;
644    print.flags = flags;
645    print.descriptions = descriptions;
646    print.desc = desc;
647    print.pdf = NAN;
648    print.cdf = NAN;
649
650    print.name = base + "samples";
651    print.value = data.samples;
652    print(stream);
653
654    MCounter::const_iterator it;
655    for (it = data.cmap.begin(); it != data.cmap.end(); it++) {
656        stringstream namestr;
657        namestr << base;
658
659        namestr <<(*it).first;
660        print.name = namestr.str();
661        print.value = (*it).second;
662        print(stream);
663    }
664
665    print.pdf = NAN;
666    print.cdf = NAN;
667
668    print.name = base + "total";
669    print.value = total;
670    print(stream);
671}
672
673void
674Text::visit(const SparseHistInfo &info)
675{
676    if (noOutput(info))
677        return;
678
679    SparseHistPrint print(this, info);
680    print(*stream);
681}
682
683Output *
684initText(const string &filename, bool desc)
685{
686    static Text text;
687    static bool connected = false;
688
689    if (!connected) {
690        ostream *os = simout.find(filename);
691        if (!os)
692            os = simout.create(filename);
693
694        text.open(*os);
695        text.descriptions = desc;
696        connected = true;
697    }
698
699    return &text;
700}
701
702} // namespace Stats
703