text.cc revision 5599
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/statdb.hh"
47695SN/A#include "base/stats/text.hh"
48695SN/A#include "base/stats/visit.hh"
49695SN/A
50695SN/Ausing namespace std;
51695SN/A
52695SN/A#ifndef NAN
53695SN/Afloat __nan();
54695SN/A/** Define Not a number. */
55695SN/A#define NAN (__nan())
56695SN/A/** Need to define __nan() */
57695SN/A#define __M5_NAN
58695SN/A#endif
59695SN/A
60695SN/A#ifdef __M5_NAN
61695SN/Afloat
62695SN/A__nan()
63695SN/A{
64695SN/A    union {
65695SN/A        uint32_t ui;
66695SN/A        float f;
67695SN/A    } nan;
68695SN/A
69695SN/A    nan.ui = 0x7fc00000;
70695SN/A    return nan.f;
71695SN/A}
72695SN/A#endif
73695SN/A
74729SN/Anamespace Stats {
75695SN/A
76695SN/AText::Text()
77695SN/A    : mystream(false), stream(NULL), compat(false), descriptions(false)
78695SN/A{
79695SN/A}
80695SN/A
81695SN/AText::Text(std::ostream &stream)
82695SN/A    : mystream(false), stream(NULL), compat(false), descriptions(false)
83695SN/A{
84695SN/A    open(stream);
85695SN/A}
86695SN/A
87695SN/AText::Text(const std::string &file)
88695SN/A    : mystream(false), stream(NULL), compat(false), descriptions(false)
89695SN/A{
90695SN/A    open(file);
91695SN/A}
92695SN/A
93695SN/A
94695SN/AText::~Text()
95695SN/A{
96695SN/A    if (mystream) {
97695SN/A        assert(stream);
98695SN/A        delete stream;
99695SN/A    }
100695SN/A}
101695SN/A
102695SN/Avoid
103695SN/AText::open(std::ostream &_stream)
104695SN/A{
105695SN/A    if (stream)
106695SN/A        panic("stream already set!");
107695SN/A
108695SN/A    mystream = false;
109695SN/A    stream = &_stream;
1105581Ssaidi@eecs.umich.edu    if (!valid())
1115581Ssaidi@eecs.umich.edu        fatal("Unable to open output stream for writing\n");
112695SN/A}
113695SN/A
114695SN/Avoid
115695SN/AText::open(const std::string &file)
116695SN/A{
117695SN/A    if (stream)
118695SN/A        panic("stream already set!");
119695SN/A
120695SN/A    mystream = true;
121695SN/A    stream = new ofstream(file.c_str(), ios::trunc);
1225581Ssaidi@eecs.umich.edu    if (!valid())
1235581Ssaidi@eecs.umich.edu        fatal("Unable to open statistics file for writing\n");
124695SN/A}
125695SN/A
126695SN/Abool
127695SN/AText::valid() const
128695SN/A{
1295581Ssaidi@eecs.umich.edu    return stream != NULL && stream->good();
130695SN/A}
131695SN/A
132695SN/Avoid
133695SN/AText::output()
134695SN/A{
135695SN/A    using namespace Database;
136695SN/A
137695SN/A    ccprintf(*stream, "\n---------- Begin Simulation Statistics ----------\n");
1382343SN/A    stat_list_t::const_iterator i, end = stats().end();
1392343SN/A    for (i = stats().begin(); i != end; ++i)
1402343SN/A        (*i)->visit(*this);
141695SN/A    ccprintf(*stream, "\n---------- End Simulation Statistics   ----------\n");
142695SN/A    stream->flush();
143695SN/A}
144695SN/A
145695SN/Abool
146695SN/AText::noOutput(const StatData &data)
147695SN/A{
148695SN/A    if (!(data.flags & print))
149695SN/A        return true;
150695SN/A
151695SN/A    if (data.prereq && data.prereq->zero())
152695SN/A        return true;
153695SN/A
154695SN/A    return false;
155695SN/A}
156695SN/A
157695SN/Astring
158695SN/AValueToString(Result value, int precision, bool compat)
159695SN/A{
160695SN/A    stringstream val;
161695SN/A
162695SN/A    if (!isnan(value)) {
163695SN/A        if (precision != -1)
164695SN/A            val.precision(precision);
165695SN/A        else if (value == rint(value))
166695SN/A            val.precision(0);
167695SN/A
168695SN/A        val.unsetf(ios::showpoint);
169695SN/A        val.setf(ios::fixed);
170695SN/A        val << value;
171695SN/A    } else {
172695SN/A        val << (compat ? "<err: div-0>" : "no value");
173695SN/A    }
174695SN/A
175695SN/A    return val.str();
176695SN/A}
177695SN/A
178695SN/Astruct ScalarPrint
179695SN/A{
180695SN/A    Result value;
181695SN/A    string name;
182695SN/A    string desc;
183695SN/A    StatFlags flags;
184695SN/A    bool compat;
185695SN/A    bool descriptions;
186695SN/A    int precision;
187695SN/A    Result pdf;
188695SN/A    Result cdf;
189695SN/A
190695SN/A    void operator()(ostream &stream) const;
191695SN/A};
192695SN/A
193695SN/Avoid
194695SN/AScalarPrint::operator()(ostream &stream) const
195695SN/A{
1965570Snate@binkert.org    if ((flags & nozero && value == 0.0) ||
1975570Snate@binkert.org        (flags & nonan && isnan(value)))
198695SN/A        return;
199695SN/A
200695SN/A    stringstream pdfstr, cdfstr;
201695SN/A
202695SN/A    if (!isnan(pdf))
203695SN/A        ccprintf(pdfstr, "%.2f%%", pdf * 100.0);
204695SN/A
205695SN/A    if (!isnan(cdf))
206695SN/A        ccprintf(cdfstr, "%.2f%%", cdf * 100.0);
207695SN/A
208695SN/A    if (compat && flags & __substat) {
209695SN/A        ccprintf(stream, "%32s %12s %10s %10s", name,
210695SN/A                 ValueToString(value, precision, compat), pdfstr, cdfstr);
211695SN/A    } else {
212695SN/A        ccprintf(stream, "%-40s %12s %10s %10s", name,
213695SN/A                 ValueToString(value, precision, compat), pdfstr, cdfstr);
214695SN/A    }
215695SN/A
216695SN/A    if (descriptions) {
217695SN/A        if (!desc.empty())
218695SN/A            ccprintf(stream, " # %s", desc);
219695SN/A    }
220695SN/A    stream << endl;
221695SN/A}
222695SN/A
223695SN/Astruct VectorPrint
224695SN/A{
225695SN/A    string name;
226695SN/A    string desc;
227695SN/A    vector<string> subnames;
228695SN/A    vector<string> subdescs;
229695SN/A    StatFlags flags;
230695SN/A    bool compat;
231695SN/A    bool descriptions;
232695SN/A    int precision;
233695SN/A    VResult vec;
234695SN/A    Result total;
235695SN/A
236695SN/A    void operator()(ostream &stream) const;
237695SN/A};
238695SN/A
239695SN/Avoid
240695SN/AVectorPrint::operator()(std::ostream &stream) const
241695SN/A{
2425599Snate@binkert.org    size_type _size = vec.size();
243695SN/A    Result _total = 0.0;
244695SN/A
245695SN/A    if (flags & (pdf | cdf)) {
2465599Snate@binkert.org        for (off_type i = 0; i < _size; ++i) {
247695SN/A            _total += vec[i];
248695SN/A        }
249695SN/A    }
250695SN/A
251695SN/A    string base = name + (compat ? "_" : "::");
252695SN/A
253695SN/A    ScalarPrint print;
254695SN/A    print.name = name;
255695SN/A    print.desc = desc;
2564209Ssaidi@eecs.umich.edu    print.compat = compat;
257695SN/A    print.precision = precision;
258695SN/A    print.descriptions = descriptions;
259695SN/A    print.flags = flags;
260695SN/A    print.pdf = NAN;
261695SN/A    print.cdf = NAN;
262695SN/A
263695SN/A    bool havesub = !subnames.empty();
264695SN/A
265695SN/A    if (_size == 1) {
266695SN/A        print.value = vec[0];
267695SN/A        print(stream);
268695SN/A    } else if (!compat) {
2695599Snate@binkert.org        for (off_type i = 0; i < _size; ++i) {
270695SN/A            if (havesub && (i >= subnames.size() || subnames[i].empty()))
271695SN/A                continue;
272695SN/A
273695SN/A            print.name = base + (havesub ? subnames[i] : to_string(i));
274695SN/A            print.desc = subdescs.empty() ? desc : subdescs[i];
275695SN/A            print.value = vec[i];
276695SN/A
277695SN/A            if (_total && (flags & pdf)) {
278695SN/A                print.pdf = vec[i] / _total;
279695SN/A                print.cdf += print.pdf;
280695SN/A            }
281695SN/A
282695SN/A            print(stream);
283695SN/A        }
284695SN/A
285729SN/A        if (flags & ::Stats::total) {
286695SN/A            print.name = base + "total";
287695SN/A            print.desc = desc;
288695SN/A            print.value = total;
289695SN/A            print(stream);
290695SN/A        }
291695SN/A    } else {
292729SN/A        if (flags & ::Stats::total) {
293695SN/A            print.value = total;
294695SN/A            print(stream);
295695SN/A        }
296695SN/A
297695SN/A        Result _pdf = 0.0;
298695SN/A        Result _cdf = 0.0;
299695SN/A        if (flags & dist) {
300695SN/A            ccprintf(stream, "%s.start_dist\n", name);
3015599Snate@binkert.org            for (off_type i = 0; i < _size; ++i) {
302695SN/A                print.name = havesub ? subnames[i] : to_string(i);
303695SN/A                print.desc = subdescs.empty() ? desc : subdescs[i];
304695SN/A                print.flags |= __substat;
305695SN/A                print.value = vec[i];
306695SN/A
307695SN/A                if (_total) {
308695SN/A                    _pdf = vec[i] / _total;
309695SN/A                    _cdf += _pdf;
310695SN/A                }
311695SN/A
312695SN/A                if (flags & pdf)
313695SN/A                    print.pdf = _pdf;
314695SN/A                if (flags & cdf)
315695SN/A                    print.cdf = _cdf;
316695SN/A
317695SN/A                print(stream);
318695SN/A            }
319695SN/A            ccprintf(stream, "%s.end_dist\n", name);
320695SN/A        } else {
3215599Snate@binkert.org            for (off_type i = 0; i < _size; ++i) {
322695SN/A                if (havesub && subnames[i].empty())
323695SN/A                    continue;
324695SN/A
325695SN/A                print.name = base;
326695SN/A                print.name += havesub ? subnames[i] : to_string(i);
327695SN/A                print.desc = subdescs.empty() ? desc : subdescs[i];
328695SN/A                print.value = vec[i];
329695SN/A
330695SN/A                if (_total) {
331695SN/A                    _pdf = vec[i] / _total;
332695SN/A                    _cdf += _pdf;
333695SN/A                } else {
334695SN/A                    _pdf = _cdf = NAN;
335695SN/A                }
336695SN/A
337695SN/A                if (flags & pdf) {
338695SN/A                    print.pdf = _pdf;
339695SN/A                    print.cdf = _cdf;
340695SN/A                }
341695SN/A
342695SN/A                print(stream);
343695SN/A            }
344695SN/A        }
345695SN/A    }
346695SN/A}
347695SN/A
348695SN/Astruct DistPrint
349695SN/A{
350695SN/A    string name;
351695SN/A    string desc;
352695SN/A    StatFlags flags;
353695SN/A    bool compat;
354695SN/A    bool descriptions;
355695SN/A    int precision;
356695SN/A
357695SN/A    Result min_val;
358695SN/A    Result max_val;
359695SN/A    Result underflow;
360695SN/A    Result overflow;
361695SN/A    VResult vec;
362695SN/A    Result sum;
363695SN/A    Result squares;
364695SN/A    Result samples;
365695SN/A
366695SN/A    Counter min;
367695SN/A    Counter max;
368695SN/A    Counter bucket_size;
3695599Snate@binkert.org    size_type size;
370695SN/A    bool fancy;
371695SN/A
372695SN/A    void operator()(ostream &stream) const;
373695SN/A};
374695SN/A
375695SN/Avoid
376695SN/ADistPrint::operator()(ostream &stream) const
377695SN/A{
378695SN/A    if (fancy) {
379695SN/A        ScalarPrint print;
380695SN/A        string base = name + (compat ? "_" : "::");
381695SN/A
382695SN/A        print.precision = precision;
383695SN/A        print.flags = flags;
384695SN/A        print.compat = compat;
385695SN/A        print.descriptions = descriptions;
386695SN/A        print.desc = desc;
387695SN/A        print.pdf = NAN;
388695SN/A        print.cdf = NAN;
389695SN/A
390695SN/A        print.name = base + "mean";
391695SN/A        print.value = samples ? sum / samples : NAN;
392695SN/A        print(stream);
393695SN/A
394695SN/A        print.name = base + "stdev";
395695SN/A        print.value = samples ? sqrt((samples * squares - sum * sum) /
396695SN/A                                     (samples * (samples - 1.0))) : NAN;
397695SN/A        print(stream);
398695SN/A
399695SN/A        print.name = "**Ignore: " + base + "TOT";
400695SN/A        print.value = samples;
401695SN/A        print(stream);
402695SN/A        return;
403695SN/A    }
404695SN/A
405695SN/A    assert(size == vec.size());
406695SN/A
407695SN/A    Result total = 0.0;
408695SN/A
409695SN/A    total += underflow;
4105599Snate@binkert.org    for (off_type i = 0; i < size; ++i)
411695SN/A        total += vec[i];
412695SN/A    total += overflow;
413695SN/A
414695SN/A    string base = name + (compat ? "." : "::");
415695SN/A
416695SN/A    ScalarPrint print;
417695SN/A    print.desc = compat ? "" : desc;
418695SN/A    print.flags = flags;
419695SN/A    print.compat = compat;
420695SN/A    print.descriptions = descriptions;
421695SN/A    print.precision = precision;
422695SN/A    print.pdf = NAN;
423695SN/A    print.cdf = NAN;
424695SN/A
425695SN/A    if (compat) {
426695SN/A        ccprintf(stream, "%-42s", base + "start_dist");
427695SN/A        if (descriptions && !desc.empty())
428695SN/A            ccprintf(stream, "                     # %s", desc);
429695SN/A        stream << endl;
430695SN/A    }
431695SN/A
432695SN/A    print.name = base + "samples";
433695SN/A    print.value = samples;
434695SN/A    print(stream);
435695SN/A
436695SN/A    print.name = base + "min_value";
437695SN/A    print.value = min_val;
438695SN/A    print(stream);
439695SN/A
440695SN/A    if (!compat || underflow > 0.0) {
441695SN/A        print.name = base + "underflows";
442695SN/A        print.value = underflow;
443695SN/A        if (!compat && total) {
444695SN/A            print.pdf = underflow / total;
445695SN/A            print.cdf += print.pdf;
446695SN/A        }
447695SN/A        print(stream);
448695SN/A    }
449695SN/A
450695SN/A    if (!compat) {
4515599Snate@binkert.org        for (off_type i = 0; i < size; ++i) {
452695SN/A            stringstream namestr;
453695SN/A            namestr << name;
454695SN/A
455695SN/A            Counter low = i * bucket_size + min;
456695SN/A            Counter high = ::min(low + bucket_size, max);
457695SN/A            namestr << low;
458695SN/A            if (low < high)
459695SN/A                namestr << "-" << high;
460695SN/A
461695SN/A            print.name = namestr.str();
462695SN/A            print.value = vec[i];
463695SN/A            if (total) {
464695SN/A                print.pdf = vec[i] / total;
465695SN/A                print.cdf += print.pdf;
466695SN/A            }
467695SN/A            print(stream);
468695SN/A        }
469695SN/A    } else {
470695SN/A        Counter _min;
471695SN/A        Result _pdf;
472695SN/A        Result _cdf = 0.0;
473695SN/A
474695SN/A        print.flags = flags | __substat;
475695SN/A
4765599Snate@binkert.org        for (off_type i = 0; i < size; ++i) {
4775570Snate@binkert.org            if ((flags & nozero && vec[i] == 0.0) ||
4785570Snate@binkert.org                (flags & nonan && isnan(vec[i])))
479695SN/A                continue;
480695SN/A
481695SN/A            _min = i * bucket_size + min;
482695SN/A            _pdf = vec[i] / total * 100.0;
483695SN/A            _cdf += _pdf;
484695SN/A
485695SN/A
486695SN/A            print.name = ValueToString(_min, 0, compat);
487695SN/A            print.value = vec[i];
488695SN/A            print.pdf = (flags & pdf) ? _pdf : NAN;
489695SN/A            print.cdf = (flags & cdf) ? _cdf : NAN;
490695SN/A            print(stream);
491695SN/A        }
492695SN/A
493695SN/A        print.flags = flags;
494695SN/A    }
495695SN/A
496695SN/A    if (!compat || overflow > 0.0) {
497695SN/A        print.name = base + "overflows";
498695SN/A        print.value = overflow;
499695SN/A        if (!compat && total) {
500695SN/A            print.pdf = overflow / total;
501695SN/A            print.cdf += print.pdf;
502695SN/A        } else {
503695SN/A            print.pdf = NAN;
504695SN/A            print.cdf = NAN;
505695SN/A        }
506695SN/A        print(stream);
507695SN/A    }
508695SN/A
509695SN/A    print.pdf = NAN;
510695SN/A    print.cdf = NAN;
511695SN/A
512695SN/A    if (!compat) {
513695SN/A        print.name = base + "total";
514695SN/A        print.value = total;
515695SN/A        print(stream);
516695SN/A    }
517695SN/A
518695SN/A    print.name = base + "max_value";
519695SN/A    print.value = max_val;
520695SN/A    print(stream);
521695SN/A
522695SN/A    if (!compat && samples != 0) {
523695SN/A        print.name = base + "mean";
524695SN/A        print.value = sum / samples;
525695SN/A        print(stream);
526695SN/A
527695SN/A        print.name = base + "stdev";
528695SN/A        print.value = sqrt((samples * squares - sum * sum) /
529695SN/A                           (samples * (samples - 1.0)));
530695SN/A        print(stream);
531695SN/A    }
532695SN/A
533695SN/A    if (compat)
534695SN/A        ccprintf(stream, "%send_dist\n\n", base);
535695SN/A}
536695SN/A
537695SN/Avoid
538695SN/AText::visit(const ScalarData &data)
539695SN/A{
540695SN/A    if (noOutput(data))
541695SN/A        return;
542695SN/A
543695SN/A    ScalarPrint print;
544695SN/A    print.value = data.result();
545695SN/A    print.name = data.name;
546695SN/A    print.desc = data.desc;
547695SN/A    print.flags = data.flags;
548695SN/A    print.compat = compat;
549695SN/A    print.descriptions = descriptions;
550695SN/A    print.precision = data.precision;
551695SN/A    print.pdf = NAN;
552695SN/A    print.cdf = NAN;
553695SN/A
554695SN/A    print(*stream);
555695SN/A}
556695SN/A
557695SN/Avoid
558695SN/AText::visit(const VectorData &data)
559695SN/A{
560695SN/A    if (noOutput(data))
561695SN/A        return;
562695SN/A
5635599Snate@binkert.org    size_type size = data.size();
564695SN/A    VectorPrint print;
565695SN/A
566695SN/A    print.name = data.name;
567695SN/A    print.desc = data.desc;
568695SN/A    print.flags = data.flags;
569695SN/A    print.compat = compat;
570695SN/A    print.descriptions = descriptions;
571695SN/A    print.precision = data.precision;
572695SN/A    print.vec = data.result();
573695SN/A    print.total = data.total();
574695SN/A
575695SN/A    if (!data.subnames.empty()) {
5765599Snate@binkert.org        for (off_type i = 0; i < size; ++i) {
577695SN/A            if (!data.subnames[i].empty()) {
578695SN/A                print.subnames = data.subnames;
579695SN/A                print.subnames.resize(size);
5805599Snate@binkert.org                for (off_type i = 0; i < size; ++i) {
581695SN/A                    if (!data.subnames[i].empty() &&
582695SN/A                        !data.subdescs[i].empty()) {
583695SN/A                        print.subdescs = data.subdescs;
584695SN/A                        print.subdescs.resize(size);
585695SN/A                        break;
586695SN/A                    }
587695SN/A                }
588695SN/A                break;
589695SN/A            }
590695SN/A        }
591695SN/A    }
592695SN/A
593695SN/A    print(*stream);
594695SN/A}
595695SN/A
596695SN/Avoid
597695SN/AText::visit(const Vector2dData &data)
598695SN/A{
599695SN/A    if (noOutput(data))
600695SN/A        return;
601695SN/A
602695SN/A    bool havesub = false;
603695SN/A    VectorPrint print;
604695SN/A
605695SN/A    print.subnames = data.y_subnames;
606695SN/A    print.flags = data.flags;
607695SN/A    print.compat = compat;
608695SN/A    print.descriptions = descriptions;
609695SN/A    print.precision = data.precision;
610695SN/A
611695SN/A    if (!data.subnames.empty()) {
6125599Snate@binkert.org        for (off_type i = 0; i < data.x; ++i)
613695SN/A            if (!data.subnames[i].empty())
614695SN/A                havesub = true;
615695SN/A    }
616695SN/A
617695SN/A    VResult tot_vec(data.y);
618695SN/A    Result super_total = 0.0;
6195599Snate@binkert.org    for (off_type i = 0; i < data.x; ++i) {
620695SN/A        if (havesub && (i >= data.subnames.size() || data.subnames[i].empty()))
621695SN/A            continue;
622695SN/A
6235599Snate@binkert.org        off_type iy = i * data.y;
624695SN/A        VResult yvec(data.y);
625695SN/A
626695SN/A        Result total = 0.0;
6275599Snate@binkert.org        for (off_type j = 0; j < data.y; ++j) {
628695SN/A            yvec[j] = data.cvec[iy + j];
629695SN/A            tot_vec[j] += yvec[j];
630695SN/A            total += yvec[j];
631695SN/A            super_total += yvec[j];
632695SN/A        }
633695SN/A
6345598Snate@binkert.org        print.name = data.name + "_" +
6355598Snate@binkert.org            (havesub ? data.subnames[i] : to_string(i));
636695SN/A        print.desc = data.desc;
637695SN/A        print.vec = yvec;
638695SN/A        print.total = total;
639695SN/A        print(*stream);
640695SN/A    }
641695SN/A
642729SN/A    if ((data.flags & ::Stats::total) && (data.x > 1)) {
643695SN/A        print.name = data.name;
644695SN/A        print.desc = data.desc;
645695SN/A        print.vec = tot_vec;
646695SN/A        print.total = super_total;
647695SN/A        print(*stream);
648695SN/A    }
649695SN/A}
650695SN/A
651695SN/Avoid
652695SN/AText::visit(const DistData &data)
653695SN/A{
654695SN/A    if (noOutput(data))
655695SN/A        return;
656695SN/A
657695SN/A    DistPrint print;
658695SN/A
659695SN/A    print.name = data.name;
660695SN/A    print.desc = data.desc;
661695SN/A    print.flags = data.flags;
662695SN/A    print.compat = compat;
663695SN/A    print.descriptions = descriptions;
664695SN/A    print.precision = data.precision;
665695SN/A
666695SN/A    print.min_val = data.data.min_val;
667695SN/A    print.max_val = data.data.max_val;
668695SN/A    print.underflow = data.data.underflow;
669695SN/A    print.overflow = data.data.overflow;
670695SN/A    print.vec.resize(data.data.cvec.size());
6715599Snate@binkert.org    for (off_type i = 0; i < print.vec.size(); ++i)
672695SN/A        print.vec[i] = (Result)data.data.cvec[i];
673695SN/A    print.sum = data.data.sum;
674695SN/A    print.squares = data.data.squares;
675695SN/A    print.samples = data.data.samples;
676695SN/A
677695SN/A    print.min = data.data.min;
678695SN/A    print.max = data.data.max;
679695SN/A    print.bucket_size = data.data.bucket_size;
680695SN/A    print.size = data.data.size;
681695SN/A    print.fancy = data.data.fancy;
682695SN/A
683695SN/A    print(*stream);
684695SN/A}
685695SN/A
686695SN/Avoid
687695SN/AText::visit(const VectorDistData &data)
688695SN/A{
689695SN/A    if (noOutput(data))
690695SN/A        return;
691695SN/A
6925599Snate@binkert.org    for (off_type i = 0; i < data.size(); ++i) {
693695SN/A        DistPrint print;
694695SN/A
6955598Snate@binkert.org        print.name = data.name + "_" +
6965598Snate@binkert.org            (data.subnames[i].empty() ? (to_string(i)) : data.subnames[i]);
697695SN/A        print.desc = data.subdescs[i].empty() ? data.desc : data.subdescs[i];
698695SN/A        print.flags = data.flags;
699695SN/A        print.compat = compat;
700695SN/A        print.descriptions = descriptions;
701695SN/A        print.precision = data.precision;
702695SN/A
703695SN/A        print.min_val = data.data[i].min_val;
704695SN/A        print.max_val = data.data[i].max_val;
705695SN/A        print.underflow = data.data[i].underflow;
706695SN/A        print.overflow = data.data[i].overflow;
707695SN/A        print.vec.resize(data.data[i].cvec.size());
7085599Snate@binkert.org        for (off_type j = 0; j < print.vec.size(); ++j)
709695SN/A            print.vec[j] = (Result)data.data[i].cvec[j];
710695SN/A        print.sum = data.data[i].sum;
711695SN/A        print.squares = data.data[i].squares;
712695SN/A        print.samples = data.data[i].samples;
713695SN/A
714695SN/A        print.min = data.data[i].min;
715695SN/A        print.max = data.data[i].max;
716695SN/A        print.bucket_size = data.data[i].bucket_size;
717695SN/A        print.size = data.data[i].size;
718695SN/A        print.fancy = data.data[i].fancy;
719695SN/A
720695SN/A        print(*stream);
721695SN/A    }
722695SN/A}
723695SN/A
724695SN/Avoid
725695SN/AText::visit(const FormulaData &data)
726695SN/A{
727695SN/A    visit((const VectorData &)data);
728695SN/A}
729695SN/A
7304078Sbinkertn@umich.edubool
7314078Sbinkertn@umich.eduinitText(const string &filename, bool desc, bool compat)
7324078Sbinkertn@umich.edu{
7334078Sbinkertn@umich.edu    static Text text;
7344078Sbinkertn@umich.edu    static bool connected = false;
7354078Sbinkertn@umich.edu
7364078Sbinkertn@umich.edu    if (connected)
7374078Sbinkertn@umich.edu        return false;
7384078Sbinkertn@umich.edu
7394078Sbinkertn@umich.edu    extern list<Output *> OutputList;
7404078Sbinkertn@umich.edu
7414078Sbinkertn@umich.edu    text.open(*simout.find(filename));
7424078Sbinkertn@umich.edu    text.descriptions = desc;
7434078Sbinkertn@umich.edu    text.compat = compat;
7444078Sbinkertn@umich.edu    OutputList.push_back(&text);
7454078Sbinkertn@umich.edu    connected = true;
7464078Sbinkertn@umich.edu
7474078Sbinkertn@umich.edu    return true;
7484078Sbinkertn@umich.edu}
7494078Sbinkertn@umich.edu
750729SN/A/* namespace Stats */ }
751