text.cc revision 4209
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;
110695SN/A    assert(valid());
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);
121695SN/A    assert(valid());
122695SN/A}
123695SN/A
124695SN/Abool
125695SN/AText::valid() const
126695SN/A{
127695SN/A    return stream != NULL;
128695SN/A}
129695SN/A
130695SN/Avoid
131695SN/AText::output()
132695SN/A{
133695SN/A    using namespace Database;
134695SN/A
135695SN/A    ccprintf(*stream, "\n---------- Begin Simulation Statistics ----------\n");
1362343SN/A    stat_list_t::const_iterator i, end = stats().end();
1372343SN/A    for (i = stats().begin(); i != end; ++i)
1382343SN/A        (*i)->visit(*this);
139695SN/A    ccprintf(*stream, "\n---------- End Simulation Statistics   ----------\n");
140695SN/A    stream->flush();
141695SN/A}
142695SN/A
143695SN/Abool
144695SN/AText::noOutput(const StatData &data)
145695SN/A{
146695SN/A    if (!(data.flags & print))
147695SN/A        return true;
148695SN/A
149695SN/A    if (data.prereq && data.prereq->zero())
150695SN/A        return true;
151695SN/A
152695SN/A    return false;
153695SN/A}
154695SN/A
155695SN/Astring
156695SN/AValueToString(Result value, int precision, bool compat)
157695SN/A{
158695SN/A    stringstream val;
159695SN/A
160695SN/A    if (!isnan(value)) {
161695SN/A        if (precision != -1)
162695SN/A            val.precision(precision);
163695SN/A        else if (value == rint(value))
164695SN/A            val.precision(0);
165695SN/A
166695SN/A        val.unsetf(ios::showpoint);
167695SN/A        val.setf(ios::fixed);
168695SN/A        val << value;
169695SN/A    } else {
170695SN/A        val << (compat ? "<err: div-0>" : "no value");
171695SN/A    }
172695SN/A
173695SN/A    return val.str();
174695SN/A}
175695SN/A
176695SN/Astruct ScalarPrint
177695SN/A{
178695SN/A    Result value;
179695SN/A    string name;
180695SN/A    string desc;
181695SN/A    StatFlags flags;
182695SN/A    bool compat;
183695SN/A    bool descriptions;
184695SN/A    int precision;
185695SN/A    Result pdf;
186695SN/A    Result cdf;
187695SN/A
188695SN/A    void operator()(ostream &stream) const;
189695SN/A};
190695SN/A
191695SN/Avoid
192695SN/AScalarPrint::operator()(ostream &stream) const
193695SN/A{
194695SN/A    if (flags & nozero && value == 0.0 ||
195695SN/A        flags & nonan && isnan(value))
196695SN/A        return;
197695SN/A
198695SN/A    stringstream pdfstr, cdfstr;
199695SN/A
200695SN/A    if (!isnan(pdf))
201695SN/A        ccprintf(pdfstr, "%.2f%%", pdf * 100.0);
202695SN/A
203695SN/A    if (!isnan(cdf))
204695SN/A        ccprintf(cdfstr, "%.2f%%", cdf * 100.0);
205695SN/A
206695SN/A    if (compat && flags & __substat) {
207695SN/A        ccprintf(stream, "%32s %12s %10s %10s", name,
208695SN/A                 ValueToString(value, precision, compat), pdfstr, cdfstr);
209695SN/A    } else {
210695SN/A        ccprintf(stream, "%-40s %12s %10s %10s", name,
211695SN/A                 ValueToString(value, precision, compat), pdfstr, cdfstr);
212695SN/A    }
213695SN/A
214695SN/A    if (descriptions) {
215695SN/A        if (!desc.empty())
216695SN/A            ccprintf(stream, " # %s", desc);
217695SN/A    }
218695SN/A    stream << endl;
219695SN/A}
220695SN/A
221695SN/Astruct VectorPrint
222695SN/A{
223695SN/A    string name;
224695SN/A    string desc;
225695SN/A    vector<string> subnames;
226695SN/A    vector<string> subdescs;
227695SN/A    StatFlags flags;
228695SN/A    bool compat;
229695SN/A    bool descriptions;
230695SN/A    int precision;
231695SN/A    VResult vec;
232695SN/A    Result total;
233695SN/A
234695SN/A    void operator()(ostream &stream) const;
235695SN/A};
236695SN/A
237695SN/Avoid
238695SN/AVectorPrint::operator()(std::ostream &stream) const
239695SN/A{
240695SN/A    int _size = vec.size();
241695SN/A    Result _total = 0.0;
242695SN/A
243695SN/A    if (flags & (pdf | cdf)) {
244695SN/A        for (int i = 0; i < _size; ++i) {
245695SN/A            _total += vec[i];
246695SN/A        }
247695SN/A    }
248695SN/A
249695SN/A    string base = name + (compat ? "_" : "::");
250695SN/A
251695SN/A    ScalarPrint print;
252695SN/A    print.name = name;
253695SN/A    print.desc = desc;
2544209Ssaidi@eecs.umich.edu    print.compat = compat;
255695SN/A    print.precision = precision;
256695SN/A    print.descriptions = descriptions;
257695SN/A    print.flags = flags;
258695SN/A    print.pdf = NAN;
259695SN/A    print.cdf = NAN;
260695SN/A
261695SN/A    bool havesub = !subnames.empty();
262695SN/A
263695SN/A    if (_size == 1) {
264695SN/A        print.value = vec[0];
265695SN/A        print(stream);
266695SN/A    } else if (!compat) {
267695SN/A        for (int i = 0; i < _size; ++i) {
268695SN/A            if (havesub && (i >= subnames.size() || subnames[i].empty()))
269695SN/A                continue;
270695SN/A
271695SN/A            print.name = base + (havesub ? subnames[i] : to_string(i));
272695SN/A            print.desc = subdescs.empty() ? desc : subdescs[i];
273695SN/A            print.value = vec[i];
274695SN/A
275695SN/A            if (_total && (flags & pdf)) {
276695SN/A                print.pdf = vec[i] / _total;
277695SN/A                print.cdf += print.pdf;
278695SN/A            }
279695SN/A
280695SN/A            print(stream);
281695SN/A        }
282695SN/A
283729SN/A        if (flags & ::Stats::total) {
284695SN/A            print.name = base + "total";
285695SN/A            print.desc = desc;
286695SN/A            print.value = total;
287695SN/A            print(stream);
288695SN/A        }
289695SN/A    } else {
290729SN/A        if (flags & ::Stats::total) {
291695SN/A            print.value = total;
292695SN/A            print(stream);
293695SN/A        }
294695SN/A
295695SN/A        Result _pdf = 0.0;
296695SN/A        Result _cdf = 0.0;
297695SN/A        if (flags & dist) {
298695SN/A            ccprintf(stream, "%s.start_dist\n", name);
299695SN/A            for (int i = 0; i < _size; ++i) {
300695SN/A                print.name = havesub ? subnames[i] : to_string(i);
301695SN/A                print.desc = subdescs.empty() ? desc : subdescs[i];
302695SN/A                print.flags |= __substat;
303695SN/A                print.value = vec[i];
304695SN/A
305695SN/A                if (_total) {
306695SN/A                    _pdf = vec[i] / _total;
307695SN/A                    _cdf += _pdf;
308695SN/A                }
309695SN/A
310695SN/A                if (flags & pdf)
311695SN/A                    print.pdf = _pdf;
312695SN/A                if (flags & cdf)
313695SN/A                    print.cdf = _cdf;
314695SN/A
315695SN/A                print(stream);
316695SN/A            }
317695SN/A            ccprintf(stream, "%s.end_dist\n", name);
318695SN/A        } else {
319695SN/A            for (int i = 0; i < _size; ++i) {
320695SN/A                if (havesub && subnames[i].empty())
321695SN/A                    continue;
322695SN/A
323695SN/A                print.name = base;
324695SN/A                print.name += havesub ? subnames[i] : to_string(i);
325695SN/A                print.desc = subdescs.empty() ? desc : subdescs[i];
326695SN/A                print.value = vec[i];
327695SN/A
328695SN/A                if (_total) {
329695SN/A                    _pdf = vec[i] / _total;
330695SN/A                    _cdf += _pdf;
331695SN/A                } else {
332695SN/A                    _pdf = _cdf = NAN;
333695SN/A                }
334695SN/A
335695SN/A                if (flags & pdf) {
336695SN/A                    print.pdf = _pdf;
337695SN/A                    print.cdf = _cdf;
338695SN/A                }
339695SN/A
340695SN/A                print(stream);
341695SN/A            }
342695SN/A        }
343695SN/A    }
344695SN/A}
345695SN/A
346695SN/Astruct DistPrint
347695SN/A{
348695SN/A    string name;
349695SN/A    string desc;
350695SN/A    StatFlags flags;
351695SN/A    bool compat;
352695SN/A    bool descriptions;
353695SN/A    int precision;
354695SN/A
355695SN/A    Result min_val;
356695SN/A    Result max_val;
357695SN/A    Result underflow;
358695SN/A    Result overflow;
359695SN/A    VResult vec;
360695SN/A    Result sum;
361695SN/A    Result squares;
362695SN/A    Result samples;
363695SN/A
364695SN/A    Counter min;
365695SN/A    Counter max;
366695SN/A    Counter bucket_size;
367695SN/A    int size;
368695SN/A    bool fancy;
369695SN/A
370695SN/A    void operator()(ostream &stream) const;
371695SN/A};
372695SN/A
373695SN/Avoid
374695SN/ADistPrint::operator()(ostream &stream) const
375695SN/A{
376695SN/A    if (fancy) {
377695SN/A        ScalarPrint print;
378695SN/A        string base = name + (compat ? "_" : "::");
379695SN/A
380695SN/A        print.precision = precision;
381695SN/A        print.flags = flags;
382695SN/A        print.compat = compat;
383695SN/A        print.descriptions = descriptions;
384695SN/A        print.desc = desc;
385695SN/A        print.pdf = NAN;
386695SN/A        print.cdf = NAN;
387695SN/A
388695SN/A        print.name = base + "mean";
389695SN/A        print.value = samples ? sum / samples : NAN;
390695SN/A        print(stream);
391695SN/A
392695SN/A        print.name = base + "stdev";
393695SN/A        print.value = samples ? sqrt((samples * squares - sum * sum) /
394695SN/A                                     (samples * (samples - 1.0))) : NAN;
395695SN/A        print(stream);
396695SN/A
397695SN/A        print.name = "**Ignore: " + base + "TOT";
398695SN/A        print.value = samples;
399695SN/A        print(stream);
400695SN/A        return;
401695SN/A    }
402695SN/A
403695SN/A    assert(size == vec.size());
404695SN/A
405695SN/A    Result total = 0.0;
406695SN/A
407695SN/A    total += underflow;
408695SN/A    for (int i = 0; i < size; ++i)
409695SN/A        total += vec[i];
410695SN/A    total += overflow;
411695SN/A
412695SN/A    string base = name + (compat ? "." : "::");
413695SN/A
414695SN/A    ScalarPrint print;
415695SN/A    print.desc = compat ? "" : desc;
416695SN/A    print.flags = flags;
417695SN/A    print.compat = compat;
418695SN/A    print.descriptions = descriptions;
419695SN/A    print.precision = precision;
420695SN/A    print.pdf = NAN;
421695SN/A    print.cdf = NAN;
422695SN/A
423695SN/A    if (compat) {
424695SN/A        ccprintf(stream, "%-42s", base + "start_dist");
425695SN/A        if (descriptions && !desc.empty())
426695SN/A            ccprintf(stream, "                     # %s", desc);
427695SN/A        stream << endl;
428695SN/A    }
429695SN/A
430695SN/A    print.name = base + "samples";
431695SN/A    print.value = samples;
432695SN/A    print(stream);
433695SN/A
434695SN/A    print.name = base + "min_value";
435695SN/A    print.value = min_val;
436695SN/A    print(stream);
437695SN/A
438695SN/A    if (!compat || underflow > 0.0) {
439695SN/A        print.name = base + "underflows";
440695SN/A        print.value = underflow;
441695SN/A        if (!compat && total) {
442695SN/A            print.pdf = underflow / total;
443695SN/A            print.cdf += print.pdf;
444695SN/A        }
445695SN/A        print(stream);
446695SN/A    }
447695SN/A
448695SN/A
449695SN/A    if (!compat) {
450695SN/A        for (int i = 0; i < size; ++i) {
451695SN/A            stringstream namestr;
452695SN/A            namestr << name;
453695SN/A
454695SN/A            Counter low = i * bucket_size + min;
455695SN/A            Counter high = ::min(low + bucket_size, max);
456695SN/A            namestr << low;
457695SN/A            if (low < high)
458695SN/A                namestr << "-" << high;
459695SN/A
460695SN/A            print.name = namestr.str();
461695SN/A            print.value = vec[i];
462695SN/A            if (total) {
463695SN/A                print.pdf = vec[i] / total;
464695SN/A                print.cdf += print.pdf;
465695SN/A            }
466695SN/A            print(stream);
467695SN/A        }
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
476695SN/A        for (int i = 0; i < size; ++i) {
477695SN/A            if (flags & nozero && vec[i] == 0.0 ||
478695SN/A                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
563695SN/A    int 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()) {
576695SN/A        for (int i = 0; i < size; ++i) {
577695SN/A            if (!data.subnames[i].empty()) {
578695SN/A                print.subnames = data.subnames;
579695SN/A                print.subnames.resize(size);
580695SN/A                for (int 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()) {
612695SN/A        for (int 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;
619695SN/A    for (int i = 0; i < data.x; ++i) {
620695SN/A        if (havesub && (i >= data.subnames.size() || data.subnames[i].empty()))
621695SN/A            continue;
622695SN/A
623695SN/A        int iy = i * data.y;
624695SN/A        VResult yvec(data.y);
625695SN/A
626695SN/A        Result total = 0.0;
627695SN/A        for (int 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
634695SN/A        print.name = data.name + "_" + (havesub ? data.subnames[i] : to_string(i));
635695SN/A        print.desc = data.desc;
636695SN/A        print.vec = yvec;
637695SN/A        print.total = total;
638695SN/A        print(*stream);
639695SN/A    }
640695SN/A
641729SN/A    if ((data.flags & ::Stats::total) && (data.x > 1)) {
642695SN/A        print.name = data.name;
643695SN/A        print.desc = data.desc;
644695SN/A        print.vec = tot_vec;
645695SN/A        print.total = super_total;
646695SN/A        print(*stream);
647695SN/A    }
648695SN/A}
649695SN/A
650695SN/Avoid
651695SN/AText::visit(const DistData &data)
652695SN/A{
653695SN/A    if (noOutput(data))
654695SN/A        return;
655695SN/A
656695SN/A    DistPrint print;
657695SN/A
658695SN/A    print.name = data.name;
659695SN/A    print.desc = data.desc;
660695SN/A    print.flags = data.flags;
661695SN/A    print.compat = compat;
662695SN/A    print.descriptions = descriptions;
663695SN/A    print.precision = data.precision;
664695SN/A
665695SN/A    print.min_val = data.data.min_val;
666695SN/A    print.max_val = data.data.max_val;
667695SN/A    print.underflow = data.data.underflow;
668695SN/A    print.overflow = data.data.overflow;
669695SN/A    print.vec.resize(data.data.cvec.size());
670695SN/A    for (int i = 0; i < print.vec.size(); ++i)
671695SN/A        print.vec[i] = (Result)data.data.cvec[i];
672695SN/A    print.sum = data.data.sum;
673695SN/A    print.squares = data.data.squares;
674695SN/A    print.samples = data.data.samples;
675695SN/A
676695SN/A    print.min = data.data.min;
677695SN/A    print.max = data.data.max;
678695SN/A    print.bucket_size = data.data.bucket_size;
679695SN/A    print.size = data.data.size;
680695SN/A    print.fancy = data.data.fancy;
681695SN/A
682695SN/A    print(*stream);
683695SN/A}
684695SN/A
685695SN/Avoid
686695SN/AText::visit(const VectorDistData &data)
687695SN/A{
688695SN/A    if (noOutput(data))
689695SN/A        return;
690695SN/A
691695SN/A    for (int i = 0; i < data.size(); ++i) {
692695SN/A        DistPrint print;
693695SN/A
694695SN/A        print.name = data.name +
695695SN/A            (data.subnames[i].empty() ? ("_" + to_string(i)) : data.subnames[i]);
696695SN/A        print.desc = data.subdescs[i].empty() ? data.desc : data.subdescs[i];
697695SN/A        print.flags = data.flags;
698695SN/A        print.compat = compat;
699695SN/A        print.descriptions = descriptions;
700695SN/A        print.precision = data.precision;
701695SN/A
702695SN/A        print.min_val = data.data[i].min_val;
703695SN/A        print.max_val = data.data[i].max_val;
704695SN/A        print.underflow = data.data[i].underflow;
705695SN/A        print.overflow = data.data[i].overflow;
706695SN/A        print.vec.resize(data.data[i].cvec.size());
707695SN/A        for (int j = 0; j < print.vec.size(); ++j)
708695SN/A            print.vec[j] = (Result)data.data[i].cvec[j];
709695SN/A        print.sum = data.data[i].sum;
710695SN/A        print.squares = data.data[i].squares;
711695SN/A        print.samples = data.data[i].samples;
712695SN/A
713695SN/A        print.min = data.data[i].min;
714695SN/A        print.max = data.data[i].max;
715695SN/A        print.bucket_size = data.data[i].bucket_size;
716695SN/A        print.size = data.data[i].size;
717695SN/A        print.fancy = data.data[i].fancy;
718695SN/A
719695SN/A        print(*stream);
720695SN/A    }
721695SN/A}
722695SN/A
723695SN/Avoid
724695SN/AText::visit(const FormulaData &data)
725695SN/A{
726695SN/A    visit((const VectorData &)data);
727695SN/A}
728695SN/A
7294078Sbinkertn@umich.edubool
7304078Sbinkertn@umich.eduinitText(const string &filename, bool desc, bool compat)
7314078Sbinkertn@umich.edu{
7324078Sbinkertn@umich.edu    static Text text;
7334078Sbinkertn@umich.edu    static bool connected = false;
7344078Sbinkertn@umich.edu
7354078Sbinkertn@umich.edu    if (connected)
7364078Sbinkertn@umich.edu        return false;
7374078Sbinkertn@umich.edu
7384078Sbinkertn@umich.edu    extern list<Output *> OutputList;
7394078Sbinkertn@umich.edu
7404078Sbinkertn@umich.edu    text.open(*simout.find(filename));
7414078Sbinkertn@umich.edu    text.descriptions = desc;
7424078Sbinkertn@umich.edu    text.compat = compat;
7434078Sbinkertn@umich.edu    OutputList.push_back(&text);
7444078Sbinkertn@umich.edu    connected = true;
7454078Sbinkertn@umich.edu
7464078Sbinkertn@umich.edu    return true;
7474078Sbinkertn@umich.edu}
7484078Sbinkertn@umich.edu
7494078Sbinkertn@umich.edu
750729SN/A/* namespace Stats */ }
751