text.cc revision 6004
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)
363918Ssaidi@eecs.umich.edu#include <math.h>
373918Ssaidi@eecs.umich.edu#endif
383918Ssaidi@eecs.umich.edu
39695SN/A#include <iostream>
402621SN/A#include <sstream>
41695SN/A#include <fstream>
42695SN/A#include <string>
43695SN/A
44695SN/A#include "base/misc.hh"
45695SN/A#include "base/statistics.hh"
46695SN/A#include "base/stats/text.hh"
47695SN/A#include "base/stats/visit.hh"
48695SN/A
49695SN/Ausing namespace std;
50695SN/A
51695SN/A#ifndef NAN
52695SN/Afloat __nan();
53695SN/A/** Define Not a number. */
54695SN/A#define NAN (__nan())
55695SN/A/** Need to define __nan() */
56695SN/A#define __M5_NAN
57695SN/A#endif
58695SN/A
59695SN/A#ifdef __M5_NAN
60695SN/Afloat
61695SN/A__nan()
62695SN/A{
63695SN/A    union {
64695SN/A        uint32_t ui;
65695SN/A        float f;
66695SN/A    } nan;
67695SN/A
68695SN/A    nan.ui = 0x7fc00000;
69695SN/A    return nan.f;
70695SN/A}
71695SN/A#endif
72695SN/A
73729SN/Anamespace Stats {
74695SN/A
75695SN/AText::Text()
76695SN/A    : mystream(false), stream(NULL), compat(false), descriptions(false)
77695SN/A{
78695SN/A}
79695SN/A
80695SN/AText::Text(std::ostream &stream)
81695SN/A    : mystream(false), stream(NULL), compat(false), descriptions(false)
82695SN/A{
83695SN/A    open(stream);
84695SN/A}
85695SN/A
86695SN/AText::Text(const std::string &file)
87695SN/A    : mystream(false), stream(NULL), compat(false), descriptions(false)
88695SN/A{
89695SN/A    open(file);
90695SN/A}
91695SN/A
92695SN/A
93695SN/AText::~Text()
94695SN/A{
95695SN/A    if (mystream) {
96695SN/A        assert(stream);
97695SN/A        delete stream;
98695SN/A    }
99695SN/A}
100695SN/A
101695SN/Avoid
102695SN/AText::open(std::ostream &_stream)
103695SN/A{
104695SN/A    if (stream)
105695SN/A        panic("stream already set!");
106695SN/A
107695SN/A    mystream = false;
108695SN/A    stream = &_stream;
1095581Ssaidi@eecs.umich.edu    if (!valid())
1105581Ssaidi@eecs.umich.edu        fatal("Unable to open output stream for writing\n");
111695SN/A}
112695SN/A
113695SN/Avoid
114695SN/AText::open(const std::string &file)
115695SN/A{
116695SN/A    if (stream)
117695SN/A        panic("stream already set!");
118695SN/A
119695SN/A    mystream = true;
120695SN/A    stream = new ofstream(file.c_str(), ios::trunc);
1215581Ssaidi@eecs.umich.edu    if (!valid())
1225581Ssaidi@eecs.umich.edu        fatal("Unable to open statistics file for writing\n");
123695SN/A}
124695SN/A
125695SN/Abool
126695SN/AText::valid() const
127695SN/A{
1285581Ssaidi@eecs.umich.edu    return stream != NULL && stream->good();
129695SN/A}
130695SN/A
131695SN/Avoid
132695SN/AText::output()
133695SN/A{
134695SN/A    ccprintf(*stream, "\n---------- Begin Simulation Statistics ----------\n");
1355887Snate@binkert.org    list<Info *>::const_iterator i, end = statsList().end();
1365887Snate@binkert.org    for (i = statsList().begin(); i != end; ++i)
1372343SN/A        (*i)->visit(*this);
138695SN/A    ccprintf(*stream, "\n---------- End Simulation Statistics   ----------\n");
139695SN/A    stream->flush();
140695SN/A}
141695SN/A
142695SN/Abool
1435886Snate@binkert.orgText::noOutput(const Info &info)
144695SN/A{
1455886Snate@binkert.org    if (!(info.flags & print))
146695SN/A        return true;
147695SN/A
1485886Snate@binkert.org    if (info.prereq && info.prereq->zero())
149695SN/A        return true;
150695SN/A
151695SN/A    return false;
152695SN/A}
153695SN/A
154695SN/Astring
155695SN/AValueToString(Result value, int precision, bool compat)
156695SN/A{
157695SN/A    stringstream val;
158695SN/A
159695SN/A    if (!isnan(value)) {
160695SN/A        if (precision != -1)
161695SN/A            val.precision(precision);
162695SN/A        else if (value == rint(value))
163695SN/A            val.precision(0);
164695SN/A
165695SN/A        val.unsetf(ios::showpoint);
166695SN/A        val.setf(ios::fixed);
167695SN/A        val << value;
168695SN/A    } else {
169695SN/A        val << (compat ? "<err: div-0>" : "no value");
170695SN/A    }
171695SN/A
172695SN/A    return val.str();
173695SN/A}
174695SN/A
175695SN/Astruct ScalarPrint
176695SN/A{
177695SN/A    Result value;
178695SN/A    string name;
179695SN/A    string desc;
180695SN/A    StatFlags flags;
181695SN/A    bool compat;
182695SN/A    bool descriptions;
183695SN/A    int precision;
184695SN/A    Result pdf;
185695SN/A    Result cdf;
186695SN/A
187695SN/A    void operator()(ostream &stream) const;
188695SN/A};
189695SN/A
190695SN/Avoid
191695SN/AScalarPrint::operator()(ostream &stream) const
192695SN/A{
1935570Snate@binkert.org    if ((flags & nozero && value == 0.0) ||
1945570Snate@binkert.org        (flags & nonan && isnan(value)))
195695SN/A        return;
196695SN/A
197695SN/A    stringstream pdfstr, cdfstr;
198695SN/A
199695SN/A    if (!isnan(pdf))
200695SN/A        ccprintf(pdfstr, "%.2f%%", pdf * 100.0);
201695SN/A
202695SN/A    if (!isnan(cdf))
203695SN/A        ccprintf(cdfstr, "%.2f%%", cdf * 100.0);
204695SN/A
205695SN/A    if (compat && flags & __substat) {
206695SN/A        ccprintf(stream, "%32s %12s %10s %10s", name,
207695SN/A                 ValueToString(value, precision, compat), pdfstr, cdfstr);
208695SN/A    } else {
209695SN/A        ccprintf(stream, "%-40s %12s %10s %10s", name,
210695SN/A                 ValueToString(value, precision, compat), pdfstr, cdfstr);
211695SN/A    }
212695SN/A
213695SN/A    if (descriptions) {
214695SN/A        if (!desc.empty())
215695SN/A            ccprintf(stream, " # %s", desc);
216695SN/A    }
217695SN/A    stream << endl;
218695SN/A}
219695SN/A
220695SN/Astruct VectorPrint
221695SN/A{
222695SN/A    string name;
223695SN/A    string desc;
224695SN/A    vector<string> subnames;
225695SN/A    vector<string> subdescs;
226695SN/A    StatFlags flags;
227695SN/A    bool compat;
228695SN/A    bool descriptions;
229695SN/A    int precision;
230695SN/A    VResult vec;
231695SN/A    Result total;
232695SN/A
233695SN/A    void operator()(ostream &stream) const;
234695SN/A};
235695SN/A
236695SN/Avoid
237695SN/AVectorPrint::operator()(std::ostream &stream) const
238695SN/A{
2395599Snate@binkert.org    size_type _size = vec.size();
240695SN/A    Result _total = 0.0;
241695SN/A
242695SN/A    if (flags & (pdf | cdf)) {
2435599Snate@binkert.org        for (off_type i = 0; i < _size; ++i) {
244695SN/A            _total += vec[i];
245695SN/A        }
246695SN/A    }
247695SN/A
248695SN/A    string base = name + (compat ? "_" : "::");
249695SN/A
250695SN/A    ScalarPrint print;
251695SN/A    print.name = name;
252695SN/A    print.desc = desc;
2534209Ssaidi@eecs.umich.edu    print.compat = compat;
254695SN/A    print.precision = precision;
255695SN/A    print.descriptions = descriptions;
256695SN/A    print.flags = flags;
257695SN/A    print.pdf = NAN;
258695SN/A    print.cdf = NAN;
259695SN/A
260695SN/A    bool havesub = !subnames.empty();
261695SN/A
262695SN/A    if (_size == 1) {
263695SN/A        print.value = vec[0];
264695SN/A        print(stream);
265695SN/A    } else if (!compat) {
2665599Snate@binkert.org        for (off_type i = 0; i < _size; ++i) {
267695SN/A            if (havesub && (i >= subnames.size() || subnames[i].empty()))
268695SN/A                continue;
269695SN/A
270695SN/A            print.name = base + (havesub ? subnames[i] : to_string(i));
271695SN/A            print.desc = subdescs.empty() ? desc : subdescs[i];
272695SN/A            print.value = vec[i];
273695SN/A
274695SN/A            if (_total && (flags & pdf)) {
275695SN/A                print.pdf = vec[i] / _total;
276695SN/A                print.cdf += print.pdf;
277695SN/A            }
278695SN/A
279695SN/A            print(stream);
280695SN/A        }
281695SN/A
282729SN/A        if (flags & ::Stats::total) {
283695SN/A            print.name = base + "total";
284695SN/A            print.desc = desc;
285695SN/A            print.value = total;
286695SN/A            print(stream);
287695SN/A        }
288695SN/A    } else {
289729SN/A        if (flags & ::Stats::total) {
290695SN/A            print.value = total;
291695SN/A            print(stream);
292695SN/A        }
293695SN/A
294695SN/A        Result _pdf = 0.0;
295695SN/A        Result _cdf = 0.0;
296695SN/A        if (flags & dist) {
297695SN/A            ccprintf(stream, "%s.start_dist\n", name);
2985599Snate@binkert.org            for (off_type i = 0; i < _size; ++i) {
299695SN/A                print.name = havesub ? subnames[i] : to_string(i);
300695SN/A                print.desc = subdescs.empty() ? desc : subdescs[i];
301695SN/A                print.flags |= __substat;
302695SN/A                print.value = vec[i];
303695SN/A
304695SN/A                if (_total) {
305695SN/A                    _pdf = vec[i] / _total;
306695SN/A                    _cdf += _pdf;
307695SN/A                }
308695SN/A
309695SN/A                if (flags & pdf)
310695SN/A                    print.pdf = _pdf;
311695SN/A                if (flags & cdf)
312695SN/A                    print.cdf = _cdf;
313695SN/A
314695SN/A                print(stream);
315695SN/A            }
316695SN/A            ccprintf(stream, "%s.end_dist\n", name);
317695SN/A        } else {
3185599Snate@binkert.org            for (off_type i = 0; i < _size; ++i) {
319695SN/A                if (havesub && subnames[i].empty())
320695SN/A                    continue;
321695SN/A
322695SN/A                print.name = base;
323695SN/A                print.name += havesub ? subnames[i] : to_string(i);
324695SN/A                print.desc = subdescs.empty() ? desc : subdescs[i];
325695SN/A                print.value = vec[i];
326695SN/A
327695SN/A                if (_total) {
328695SN/A                    _pdf = vec[i] / _total;
329695SN/A                    _cdf += _pdf;
330695SN/A                } else {
331695SN/A                    _pdf = _cdf = NAN;
332695SN/A                }
333695SN/A
334695SN/A                if (flags & pdf) {
335695SN/A                    print.pdf = _pdf;
336695SN/A                    print.cdf = _cdf;
337695SN/A                }
338695SN/A
339695SN/A                print(stream);
340695SN/A            }
341695SN/A        }
342695SN/A    }
343695SN/A}
344695SN/A
345695SN/Astruct DistPrint
346695SN/A{
347695SN/A    string name;
348695SN/A    string desc;
349695SN/A    StatFlags flags;
350695SN/A    bool compat;
351695SN/A    bool descriptions;
352695SN/A    int precision;
353695SN/A
354695SN/A    Counter min;
355695SN/A    Counter max;
356695SN/A    Counter bucket_size;
3575599Snate@binkert.org    size_type size;
358695SN/A    bool fancy;
359695SN/A
3606004Snate@binkert.org    const DistData &data;
3616004Snate@binkert.org
3626004Snate@binkert.org    DistPrint(const DistInfoBase &info);
3636004Snate@binkert.org    DistPrint(const VectorDistInfoBase &info, int i);
3646004Snate@binkert.org    void init(const Info &info, const DistParams *params);
365695SN/A    void operator()(ostream &stream) const;
366695SN/A};
367695SN/A
3686004Snate@binkert.orgDistPrint::DistPrint(const DistInfoBase &info)
3696004Snate@binkert.org    : data(info.data)
3706004Snate@binkert.org{
3716004Snate@binkert.org    init(info, safe_cast<const DistParams *>(info.storageParams));
3726004Snate@binkert.org}
3736004Snate@binkert.org
3746004Snate@binkert.orgDistPrint::DistPrint(const VectorDistInfoBase &info, int i)
3756004Snate@binkert.org    : data(info.data[i])
3766004Snate@binkert.org{
3776004Snate@binkert.org    init(info, safe_cast<const DistParams *>(info.storageParams));
3786004Snate@binkert.org
3796004Snate@binkert.org    name = info.name + "_" +
3806004Snate@binkert.org        (info.subnames[i].empty() ? (to_string(i)) : info.subnames[i]);
3816004Snate@binkert.org
3826004Snate@binkert.org    if (!info.subdescs[i].empty())
3836004Snate@binkert.org        desc = info.subdescs[i];
3846004Snate@binkert.org}
3856004Snate@binkert.org
3866004Snate@binkert.orgvoid
3876004Snate@binkert.orgDistPrint::init(const Info &info, const DistParams *params)
3886004Snate@binkert.org{
3896004Snate@binkert.org    name = info.name;
3906004Snate@binkert.org    desc = info.desc;
3916004Snate@binkert.org    flags = info.flags;
3926004Snate@binkert.org    compat = compat;
3936004Snate@binkert.org    descriptions = descriptions;
3946004Snate@binkert.org    precision = info.precision;
3956004Snate@binkert.org
3966004Snate@binkert.org    fancy = params->fancy;
3976004Snate@binkert.org    min = params->min;
3986004Snate@binkert.org    max = params->max;
3996004Snate@binkert.org    bucket_size = params->bucket_size;
4006004Snate@binkert.org    size = params->buckets;
4016004Snate@binkert.org}
4026004Snate@binkert.org
403695SN/Avoid
404695SN/ADistPrint::operator()(ostream &stream) const
405695SN/A{
4066004Snate@binkert.org    Result stdev = NAN;
4076004Snate@binkert.org    if (data.samples)
4086004Snate@binkert.org        stdev = sqrt((data.samples * data.squares - data.sum * data.sum) /
4096004Snate@binkert.org                     (data.samples * (data.samples - 1.0)));
4106004Snate@binkert.org
411695SN/A    if (fancy) {
412695SN/A        ScalarPrint print;
413695SN/A        string base = name + (compat ? "_" : "::");
414695SN/A
415695SN/A        print.precision = precision;
416695SN/A        print.flags = flags;
417695SN/A        print.compat = compat;
418695SN/A        print.descriptions = descriptions;
419695SN/A        print.desc = desc;
420695SN/A        print.pdf = NAN;
421695SN/A        print.cdf = NAN;
422695SN/A
423695SN/A        print.name = base + "mean";
4246004Snate@binkert.org        print.value = data.samples ? data.sum / data.samples : NAN;
425695SN/A        print(stream);
426695SN/A
427695SN/A        print.name = base + "stdev";
4286004Snate@binkert.org        print.value = stdev;
429695SN/A        print(stream);
430695SN/A
431695SN/A        print.name = "**Ignore: " + base + "TOT";
4326004Snate@binkert.org        print.value = data.samples;
433695SN/A        print(stream);
434695SN/A        return;
435695SN/A    }
436695SN/A
4376004Snate@binkert.org    assert(size == data.cvec.size());
438695SN/A
439695SN/A    Result total = 0.0;
440695SN/A
4416004Snate@binkert.org    total += data.underflow;
4425599Snate@binkert.org    for (off_type i = 0; i < size; ++i)
4436004Snate@binkert.org        total += data.cvec[i];
4446004Snate@binkert.org    total += data.overflow;
445695SN/A
446695SN/A    string base = name + (compat ? "." : "::");
447695SN/A
448695SN/A    ScalarPrint print;
449695SN/A    print.desc = compat ? "" : desc;
450695SN/A    print.flags = flags;
451695SN/A    print.compat = compat;
452695SN/A    print.descriptions = descriptions;
453695SN/A    print.precision = precision;
454695SN/A    print.pdf = NAN;
455695SN/A    print.cdf = NAN;
456695SN/A
457695SN/A    if (compat) {
458695SN/A        ccprintf(stream, "%-42s", base + "start_dist");
459695SN/A        if (descriptions && !desc.empty())
460695SN/A            ccprintf(stream, "                     # %s", desc);
461695SN/A        stream << endl;
462695SN/A    }
463695SN/A
464695SN/A    print.name = base + "samples";
4656004Snate@binkert.org    print.value = data.samples;
466695SN/A    print(stream);
467695SN/A
468695SN/A    print.name = base + "min_value";
4696004Snate@binkert.org    print.value = data.min_val;
470695SN/A    print(stream);
471695SN/A
4726004Snate@binkert.org    if (!compat || data.underflow > 0.0) {
473695SN/A        print.name = base + "underflows";
4746004Snate@binkert.org        print.value = data.underflow;
475695SN/A        if (!compat && total) {
4766004Snate@binkert.org            print.pdf = data.underflow / total;
477695SN/A            print.cdf += print.pdf;
478695SN/A        }
479695SN/A        print(stream);
480695SN/A    }
481695SN/A
482695SN/A    if (!compat) {
4835599Snate@binkert.org        for (off_type i = 0; i < size; ++i) {
484695SN/A            stringstream namestr;
4855884Snate@binkert.org            namestr << base;
486695SN/A
487695SN/A            Counter low = i * bucket_size + min;
488695SN/A            Counter high = ::min(low + bucket_size, max);
489695SN/A            namestr << low;
490695SN/A            if (low < high)
491695SN/A                namestr << "-" << high;
492695SN/A
493695SN/A            print.name = namestr.str();
4946004Snate@binkert.org            print.value = data.cvec[i];
495695SN/A            if (total) {
4966004Snate@binkert.org                print.pdf = data.cvec[i] / total;
497695SN/A                print.cdf += print.pdf;
498695SN/A            }
499695SN/A            print(stream);
500695SN/A        }
501695SN/A    } else {
502695SN/A        Counter _min;
503695SN/A        Result _pdf;
504695SN/A        Result _cdf = 0.0;
505695SN/A
506695SN/A        print.flags = flags | __substat;
507695SN/A
5085599Snate@binkert.org        for (off_type i = 0; i < size; ++i) {
5096004Snate@binkert.org            if ((flags & nozero && data.cvec[i] == 0.0) ||
5106004Snate@binkert.org                (flags & nonan && isnan(data.cvec[i])))
511695SN/A                continue;
512695SN/A
513695SN/A            _min = i * bucket_size + min;
5146004Snate@binkert.org            _pdf = data.cvec[i] / total * 100.0;
515695SN/A            _cdf += _pdf;
516695SN/A
517695SN/A
518695SN/A            print.name = ValueToString(_min, 0, compat);
5196004Snate@binkert.org            print.value = data.cvec[i];
520695SN/A            print.pdf = (flags & pdf) ? _pdf : NAN;
521695SN/A            print.cdf = (flags & cdf) ? _cdf : NAN;
522695SN/A            print(stream);
523695SN/A        }
524695SN/A
525695SN/A        print.flags = flags;
526695SN/A    }
527695SN/A
5286004Snate@binkert.org    if (!compat || data.overflow > 0.0) {
529695SN/A        print.name = base + "overflows";
5306004Snate@binkert.org        print.value = data.overflow;
531695SN/A        if (!compat && total) {
5326004Snate@binkert.org            print.pdf = data.overflow / total;
533695SN/A            print.cdf += print.pdf;
534695SN/A        } else {
535695SN/A            print.pdf = NAN;
536695SN/A            print.cdf = NAN;
537695SN/A        }
538695SN/A        print(stream);
539695SN/A    }
540695SN/A
541695SN/A    print.pdf = NAN;
542695SN/A    print.cdf = NAN;
543695SN/A
544695SN/A    if (!compat) {
545695SN/A        print.name = base + "total";
546695SN/A        print.value = total;
547695SN/A        print(stream);
548695SN/A    }
549695SN/A
550695SN/A    print.name = base + "max_value";
5516004Snate@binkert.org    print.value = data.max_val;
552695SN/A    print(stream);
553695SN/A
5546004Snate@binkert.org    if (!compat && data.samples != 0) {
555695SN/A        print.name = base + "mean";
5566004Snate@binkert.org        print.value = data.sum / data.samples;
557695SN/A        print(stream);
558695SN/A
559695SN/A        print.name = base + "stdev";
5606004Snate@binkert.org        print.value = stdev;
561695SN/A        print(stream);
562695SN/A    }
563695SN/A
564695SN/A    if (compat)
565695SN/A        ccprintf(stream, "%send_dist\n\n", base);
566695SN/A}
567695SN/A
568695SN/Avoid
5695886Snate@binkert.orgText::visit(const ScalarInfoBase &info)
570695SN/A{
5715886Snate@binkert.org    if (noOutput(info))
572695SN/A        return;
573695SN/A
574695SN/A    ScalarPrint print;
5755886Snate@binkert.org    print.value = info.result();
5765886Snate@binkert.org    print.name = info.name;
5775886Snate@binkert.org    print.desc = info.desc;
5785886Snate@binkert.org    print.flags = info.flags;
579695SN/A    print.compat = compat;
580695SN/A    print.descriptions = descriptions;
5815886Snate@binkert.org    print.precision = info.precision;
582695SN/A    print.pdf = NAN;
583695SN/A    print.cdf = NAN;
584695SN/A
585695SN/A    print(*stream);
586695SN/A}
587695SN/A
588695SN/Avoid
5895886Snate@binkert.orgText::visit(const VectorInfoBase &info)
590695SN/A{
5915886Snate@binkert.org    if (noOutput(info))
592695SN/A        return;
593695SN/A
5945886Snate@binkert.org    size_type size = info.size();
595695SN/A    VectorPrint print;
596695SN/A
5975886Snate@binkert.org    print.name = info.name;
5985886Snate@binkert.org    print.desc = info.desc;
5995886Snate@binkert.org    print.flags = info.flags;
600695SN/A    print.compat = compat;
601695SN/A    print.descriptions = descriptions;
6025886Snate@binkert.org    print.precision = info.precision;
6035886Snate@binkert.org    print.vec = info.result();
6045886Snate@binkert.org    print.total = info.total();
605695SN/A
6065886Snate@binkert.org    if (!info.subnames.empty()) {
6075599Snate@binkert.org        for (off_type i = 0; i < size; ++i) {
6085886Snate@binkert.org            if (!info.subnames[i].empty()) {
6095886Snate@binkert.org                print.subnames = info.subnames;
610695SN/A                print.subnames.resize(size);
6115599Snate@binkert.org                for (off_type i = 0; i < size; ++i) {
6125886Snate@binkert.org                    if (!info.subnames[i].empty() &&
6135886Snate@binkert.org                        !info.subdescs[i].empty()) {
6145886Snate@binkert.org                        print.subdescs = info.subdescs;
615695SN/A                        print.subdescs.resize(size);
616695SN/A                        break;
617695SN/A                    }
618695SN/A                }
619695SN/A                break;
620695SN/A            }
621695SN/A        }
622695SN/A    }
623695SN/A
624695SN/A    print(*stream);
625695SN/A}
626695SN/A
627695SN/Avoid
6285886Snate@binkert.orgText::visit(const Vector2dInfoBase &info)
629695SN/A{
6305886Snate@binkert.org    if (noOutput(info))
631695SN/A        return;
632695SN/A
633695SN/A    bool havesub = false;
634695SN/A    VectorPrint print;
635695SN/A
6365886Snate@binkert.org    print.subnames = info.y_subnames;
6375886Snate@binkert.org    print.flags = info.flags;
638695SN/A    print.compat = compat;
639695SN/A    print.descriptions = descriptions;
6405886Snate@binkert.org    print.precision = info.precision;
641695SN/A
6425886Snate@binkert.org    if (!info.subnames.empty()) {
6435886Snate@binkert.org        for (off_type i = 0; i < info.x; ++i)
6445886Snate@binkert.org            if (!info.subnames[i].empty())
645695SN/A                havesub = true;
646695SN/A    }
647695SN/A
6485886Snate@binkert.org    VResult tot_vec(info.y);
649695SN/A    Result super_total = 0.0;
6505886Snate@binkert.org    for (off_type i = 0; i < info.x; ++i) {
6515886Snate@binkert.org        if (havesub && (i >= info.subnames.size() || info.subnames[i].empty()))
652695SN/A            continue;
653695SN/A
6545886Snate@binkert.org        off_type iy = i * info.y;
6555886Snate@binkert.org        VResult yvec(info.y);
656695SN/A
657695SN/A        Result total = 0.0;
6585886Snate@binkert.org        for (off_type j = 0; j < info.y; ++j) {
6595886Snate@binkert.org            yvec[j] = info.cvec[iy + j];
660695SN/A            tot_vec[j] += yvec[j];
661695SN/A            total += yvec[j];
662695SN/A            super_total += yvec[j];
663695SN/A        }
664695SN/A
6655886Snate@binkert.org        print.name = info.name + "_" +
6665886Snate@binkert.org            (havesub ? info.subnames[i] : to_string(i));
6675886Snate@binkert.org        print.desc = info.desc;
668695SN/A        print.vec = yvec;
669695SN/A        print.total = total;
670695SN/A        print(*stream);
671695SN/A    }
672695SN/A
6735886Snate@binkert.org    if ((info.flags & ::Stats::total) && (info.x > 1)) {
6745886Snate@binkert.org        print.name = info.name;
6755886Snate@binkert.org        print.desc = info.desc;
676695SN/A        print.vec = tot_vec;
677695SN/A        print.total = super_total;
678695SN/A        print(*stream);
679695SN/A    }
680695SN/A}
681695SN/A
682695SN/Avoid
6835886Snate@binkert.orgText::visit(const DistInfoBase &info)
684695SN/A{
6855886Snate@binkert.org    if (noOutput(info))
686695SN/A        return;
687695SN/A
6886004Snate@binkert.org    DistPrint print(info);
689695SN/A    print(*stream);
690695SN/A}
691695SN/A
692695SN/Avoid
6935886Snate@binkert.orgText::visit(const VectorDistInfoBase &info)
694695SN/A{
6955886Snate@binkert.org    if (noOutput(info))
696695SN/A        return;
697695SN/A
6985886Snate@binkert.org    for (off_type i = 0; i < info.size(); ++i) {
6996004Snate@binkert.org        DistPrint print(info, i);
700695SN/A        print(*stream);
701695SN/A    }
702695SN/A}
703695SN/A
704695SN/Avoid
7055886Snate@binkert.orgText::visit(const FormulaInfoBase &info)
706695SN/A{
7075886Snate@binkert.org    visit((const VectorInfoBase &)info);
708695SN/A}
709695SN/A
7104078Sbinkertn@umich.edubool
7114078Sbinkertn@umich.eduinitText(const string &filename, bool desc, bool compat)
7124078Sbinkertn@umich.edu{
7134078Sbinkertn@umich.edu    static Text text;
7144078Sbinkertn@umich.edu    static bool connected = false;
7154078Sbinkertn@umich.edu
7164078Sbinkertn@umich.edu    if (connected)
7174078Sbinkertn@umich.edu        return false;
7184078Sbinkertn@umich.edu
7194078Sbinkertn@umich.edu    extern list<Output *> OutputList;
7204078Sbinkertn@umich.edu
7214078Sbinkertn@umich.edu    text.open(*simout.find(filename));
7224078Sbinkertn@umich.edu    text.descriptions = desc;
7234078Sbinkertn@umich.edu    text.compat = compat;
7244078Sbinkertn@umich.edu    OutputList.push_back(&text);
7254078Sbinkertn@umich.edu    connected = true;
7264078Sbinkertn@umich.edu
7274078Sbinkertn@umich.edu    return true;
7284078Sbinkertn@umich.edu}
7294078Sbinkertn@umich.edu
730729SN/A/* namespace Stats */ }
731