text.cc revision 4078
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;
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) {
266695SN/A        for (int 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);
298695SN/A            for (int 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 {
318695SN/A            for (int 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    Result min_val;
355695SN/A    Result max_val;
356695SN/A    Result underflow;
357695SN/A    Result overflow;
358695SN/A    VResult vec;
359695SN/A    Result sum;
360695SN/A    Result squares;
361695SN/A    Result samples;
362695SN/A
363695SN/A    Counter min;
364695SN/A    Counter max;
365695SN/A    Counter bucket_size;
366695SN/A    int size;
367695SN/A    bool fancy;
368695SN/A
369695SN/A    void operator()(ostream &stream) const;
370695SN/A};
371695SN/A
372695SN/Avoid
373695SN/ADistPrint::operator()(ostream &stream) const
374695SN/A{
375695SN/A    if (fancy) {
376695SN/A        ScalarPrint print;
377695SN/A        string base = name + (compat ? "_" : "::");
378695SN/A
379695SN/A        print.precision = precision;
380695SN/A        print.flags = flags;
381695SN/A        print.compat = compat;
382695SN/A        print.descriptions = descriptions;
383695SN/A        print.desc = desc;
384695SN/A        print.pdf = NAN;
385695SN/A        print.cdf = NAN;
386695SN/A
387695SN/A        print.name = base + "mean";
388695SN/A        print.value = samples ? sum / samples : NAN;
389695SN/A        print(stream);
390695SN/A
391695SN/A        print.name = base + "stdev";
392695SN/A        print.value = samples ? sqrt((samples * squares - sum * sum) /
393695SN/A                                     (samples * (samples - 1.0))) : NAN;
394695SN/A        print(stream);
395695SN/A
396695SN/A        print.name = "**Ignore: " + base + "TOT";
397695SN/A        print.value = samples;
398695SN/A        print(stream);
399695SN/A        return;
400695SN/A    }
401695SN/A
402695SN/A    assert(size == vec.size());
403695SN/A
404695SN/A    Result total = 0.0;
405695SN/A
406695SN/A    total += underflow;
407695SN/A    for (int i = 0; i < size; ++i)
408695SN/A        total += vec[i];
409695SN/A    total += overflow;
410695SN/A
411695SN/A    string base = name + (compat ? "." : "::");
412695SN/A
413695SN/A    ScalarPrint print;
414695SN/A    print.desc = compat ? "" : desc;
415695SN/A    print.flags = flags;
416695SN/A    print.compat = compat;
417695SN/A    print.descriptions = descriptions;
418695SN/A    print.precision = precision;
419695SN/A    print.pdf = NAN;
420695SN/A    print.cdf = NAN;
421695SN/A
422695SN/A    if (compat) {
423695SN/A        ccprintf(stream, "%-42s", base + "start_dist");
424695SN/A        if (descriptions && !desc.empty())
425695SN/A            ccprintf(stream, "                     # %s", desc);
426695SN/A        stream << endl;
427695SN/A    }
428695SN/A
429695SN/A    print.name = base + "samples";
430695SN/A    print.value = samples;
431695SN/A    print(stream);
432695SN/A
433695SN/A    print.name = base + "min_value";
434695SN/A    print.value = min_val;
435695SN/A    print(stream);
436695SN/A
437695SN/A    if (!compat || underflow > 0.0) {
438695SN/A        print.name = base + "underflows";
439695SN/A        print.value = underflow;
440695SN/A        if (!compat && total) {
441695SN/A            print.pdf = underflow / total;
442695SN/A            print.cdf += print.pdf;
443695SN/A        }
444695SN/A        print(stream);
445695SN/A    }
446695SN/A
447695SN/A
448695SN/A    if (!compat) {
449695SN/A        for (int i = 0; i < size; ++i) {
450695SN/A            stringstream namestr;
451695SN/A            namestr << name;
452695SN/A
453695SN/A            Counter low = i * bucket_size + min;
454695SN/A            Counter high = ::min(low + bucket_size, max);
455695SN/A            namestr << low;
456695SN/A            if (low < high)
457695SN/A                namestr << "-" << high;
458695SN/A
459695SN/A            print.name = namestr.str();
460695SN/A            print.value = vec[i];
461695SN/A            if (total) {
462695SN/A                print.pdf = vec[i] / total;
463695SN/A                print.cdf += print.pdf;
464695SN/A            }
465695SN/A            print(stream);
466695SN/A        }
467695SN/A
468695SN/A    } else {
469695SN/A        Counter _min;
470695SN/A        Result _pdf;
471695SN/A        Result _cdf = 0.0;
472695SN/A
473695SN/A        print.flags = flags | __substat;
474695SN/A
475695SN/A        for (int i = 0; i < size; ++i) {
476695SN/A            if (flags & nozero && vec[i] == 0.0 ||
477695SN/A                flags & nonan && isnan(vec[i]))
478695SN/A                continue;
479695SN/A
480695SN/A            _min = i * bucket_size + min;
481695SN/A            _pdf = vec[i] / total * 100.0;
482695SN/A            _cdf += _pdf;
483695SN/A
484695SN/A
485695SN/A            print.name = ValueToString(_min, 0, compat);
486695SN/A            print.value = vec[i];
487695SN/A            print.pdf = (flags & pdf) ? _pdf : NAN;
488695SN/A            print.cdf = (flags & cdf) ? _cdf : NAN;
489695SN/A            print(stream);
490695SN/A        }
491695SN/A
492695SN/A        print.flags = flags;
493695SN/A    }
494695SN/A
495695SN/A    if (!compat || overflow > 0.0) {
496695SN/A        print.name = base + "overflows";
497695SN/A        print.value = overflow;
498695SN/A        if (!compat && total) {
499695SN/A            print.pdf = overflow / total;
500695SN/A            print.cdf += print.pdf;
501695SN/A        } else {
502695SN/A            print.pdf = NAN;
503695SN/A            print.cdf = NAN;
504695SN/A        }
505695SN/A        print(stream);
506695SN/A    }
507695SN/A
508695SN/A    print.pdf = NAN;
509695SN/A    print.cdf = NAN;
510695SN/A
511695SN/A    if (!compat) {
512695SN/A        print.name = base + "total";
513695SN/A        print.value = total;
514695SN/A        print(stream);
515695SN/A    }
516695SN/A
517695SN/A    print.name = base + "max_value";
518695SN/A    print.value = max_val;
519695SN/A    print(stream);
520695SN/A
521695SN/A    if (!compat && samples != 0) {
522695SN/A        print.name = base + "mean";
523695SN/A        print.value = sum / samples;
524695SN/A        print(stream);
525695SN/A
526695SN/A        print.name = base + "stdev";
527695SN/A        print.value = sqrt((samples * squares - sum * sum) /
528695SN/A                           (samples * (samples - 1.0)));
529695SN/A        print(stream);
530695SN/A    }
531695SN/A
532695SN/A    if (compat)
533695SN/A        ccprintf(stream, "%send_dist\n\n", base);
534695SN/A}
535695SN/A
536695SN/Avoid
537695SN/AText::visit(const ScalarData &data)
538695SN/A{
539695SN/A    if (noOutput(data))
540695SN/A        return;
541695SN/A
542695SN/A    ScalarPrint print;
543695SN/A    print.value = data.result();
544695SN/A    print.name = data.name;
545695SN/A    print.desc = data.desc;
546695SN/A    print.flags = data.flags;
547695SN/A    print.compat = compat;
548695SN/A    print.descriptions = descriptions;
549695SN/A    print.precision = data.precision;
550695SN/A    print.pdf = NAN;
551695SN/A    print.cdf = NAN;
552695SN/A
553695SN/A    print(*stream);
554695SN/A}
555695SN/A
556695SN/Avoid
557695SN/AText::visit(const VectorData &data)
558695SN/A{
559695SN/A    if (noOutput(data))
560695SN/A        return;
561695SN/A
562695SN/A    int size = data.size();
563695SN/A    VectorPrint print;
564695SN/A
565695SN/A    print.name = data.name;
566695SN/A    print.desc = data.desc;
567695SN/A    print.flags = data.flags;
568695SN/A    print.compat = compat;
569695SN/A    print.descriptions = descriptions;
570695SN/A    print.precision = data.precision;
571695SN/A    print.vec = data.result();
572695SN/A    print.total = data.total();
573695SN/A
574695SN/A    if (!data.subnames.empty()) {
575695SN/A        for (int i = 0; i < size; ++i) {
576695SN/A            if (!data.subnames[i].empty()) {
577695SN/A                print.subnames = data.subnames;
578695SN/A                print.subnames.resize(size);
579695SN/A                for (int i = 0; i < size; ++i) {
580695SN/A                    if (!data.subnames[i].empty() &&
581695SN/A                        !data.subdescs[i].empty()) {
582695SN/A                        print.subdescs = data.subdescs;
583695SN/A                        print.subdescs.resize(size);
584695SN/A                        break;
585695SN/A                    }
586695SN/A                }
587695SN/A                break;
588695SN/A            }
589695SN/A        }
590695SN/A    }
591695SN/A
592695SN/A    print(*stream);
593695SN/A}
594695SN/A
595695SN/Avoid
596695SN/AText::visit(const Vector2dData &data)
597695SN/A{
598695SN/A    if (noOutput(data))
599695SN/A        return;
600695SN/A
601695SN/A    bool havesub = false;
602695SN/A    VectorPrint print;
603695SN/A
604695SN/A    print.subnames = data.y_subnames;
605695SN/A    print.flags = data.flags;
606695SN/A    print.compat = compat;
607695SN/A    print.descriptions = descriptions;
608695SN/A    print.precision = data.precision;
609695SN/A
610695SN/A    if (!data.subnames.empty()) {
611695SN/A        for (int i = 0; i < data.x; ++i)
612695SN/A            if (!data.subnames[i].empty())
613695SN/A                havesub = true;
614695SN/A    }
615695SN/A
616695SN/A    VResult tot_vec(data.y);
617695SN/A    Result super_total = 0.0;
618695SN/A    for (int i = 0; i < data.x; ++i) {
619695SN/A        if (havesub && (i >= data.subnames.size() || data.subnames[i].empty()))
620695SN/A            continue;
621695SN/A
622695SN/A        int iy = i * data.y;
623695SN/A        VResult yvec(data.y);
624695SN/A
625695SN/A        Result total = 0.0;
626695SN/A        for (int j = 0; j < data.y; ++j) {
627695SN/A            yvec[j] = data.cvec[iy + j];
628695SN/A            tot_vec[j] += yvec[j];
629695SN/A            total += yvec[j];
630695SN/A            super_total += yvec[j];
631695SN/A        }
632695SN/A
633695SN/A        print.name = data.name + "_" + (havesub ? data.subnames[i] : to_string(i));
634695SN/A        print.desc = data.desc;
635695SN/A        print.vec = yvec;
636695SN/A        print.total = total;
637695SN/A        print(*stream);
638695SN/A    }
639695SN/A
640729SN/A    if ((data.flags & ::Stats::total) && (data.x > 1)) {
641695SN/A        print.name = data.name;
642695SN/A        print.desc = data.desc;
643695SN/A        print.vec = tot_vec;
644695SN/A        print.total = super_total;
645695SN/A        print(*stream);
646695SN/A    }
647695SN/A}
648695SN/A
649695SN/Avoid
650695SN/AText::visit(const DistData &data)
651695SN/A{
652695SN/A    if (noOutput(data))
653695SN/A        return;
654695SN/A
655695SN/A    DistPrint print;
656695SN/A
657695SN/A    print.name = data.name;
658695SN/A    print.desc = data.desc;
659695SN/A    print.flags = data.flags;
660695SN/A    print.compat = compat;
661695SN/A    print.descriptions = descriptions;
662695SN/A    print.precision = data.precision;
663695SN/A
664695SN/A    print.min_val = data.data.min_val;
665695SN/A    print.max_val = data.data.max_val;
666695SN/A    print.underflow = data.data.underflow;
667695SN/A    print.overflow = data.data.overflow;
668695SN/A    print.vec.resize(data.data.cvec.size());
669695SN/A    for (int i = 0; i < print.vec.size(); ++i)
670695SN/A        print.vec[i] = (Result)data.data.cvec[i];
671695SN/A    print.sum = data.data.sum;
672695SN/A    print.squares = data.data.squares;
673695SN/A    print.samples = data.data.samples;
674695SN/A
675695SN/A    print.min = data.data.min;
676695SN/A    print.max = data.data.max;
677695SN/A    print.bucket_size = data.data.bucket_size;
678695SN/A    print.size = data.data.size;
679695SN/A    print.fancy = data.data.fancy;
680695SN/A
681695SN/A    print(*stream);
682695SN/A}
683695SN/A
684695SN/Avoid
685695SN/AText::visit(const VectorDistData &data)
686695SN/A{
687695SN/A    if (noOutput(data))
688695SN/A        return;
689695SN/A
690695SN/A    for (int i = 0; i < data.size(); ++i) {
691695SN/A        DistPrint print;
692695SN/A
693695SN/A        print.name = data.name +
694695SN/A            (data.subnames[i].empty() ? ("_" + to_string(i)) : data.subnames[i]);
695695SN/A        print.desc = data.subdescs[i].empty() ? data.desc : data.subdescs[i];
696695SN/A        print.flags = data.flags;
697695SN/A        print.compat = compat;
698695SN/A        print.descriptions = descriptions;
699695SN/A        print.precision = data.precision;
700695SN/A
701695SN/A        print.min_val = data.data[i].min_val;
702695SN/A        print.max_val = data.data[i].max_val;
703695SN/A        print.underflow = data.data[i].underflow;
704695SN/A        print.overflow = data.data[i].overflow;
705695SN/A        print.vec.resize(data.data[i].cvec.size());
706695SN/A        for (int j = 0; j < print.vec.size(); ++j)
707695SN/A            print.vec[j] = (Result)data.data[i].cvec[j];
708695SN/A        print.sum = data.data[i].sum;
709695SN/A        print.squares = data.data[i].squares;
710695SN/A        print.samples = data.data[i].samples;
711695SN/A
712695SN/A        print.min = data.data[i].min;
713695SN/A        print.max = data.data[i].max;
714695SN/A        print.bucket_size = data.data[i].bucket_size;
715695SN/A        print.size = data.data[i].size;
716695SN/A        print.fancy = data.data[i].fancy;
717695SN/A
718695SN/A        print(*stream);
719695SN/A    }
720695SN/A}
721695SN/A
722695SN/Avoid
723695SN/AText::visit(const FormulaData &data)
724695SN/A{
725695SN/A    visit((const VectorData &)data);
726695SN/A}
727695SN/A
7284078Sbinkertn@umich.edubool
7294078Sbinkertn@umich.eduinitText(const string &filename, bool desc, bool compat)
7304078Sbinkertn@umich.edu{
7314078Sbinkertn@umich.edu    static Text text;
7324078Sbinkertn@umich.edu    static bool connected = false;
7334078Sbinkertn@umich.edu
7344078Sbinkertn@umich.edu    if (connected)
7354078Sbinkertn@umich.edu        return false;
7364078Sbinkertn@umich.edu
7374078Sbinkertn@umich.edu    extern list<Output *> OutputList;
7384078Sbinkertn@umich.edu
7394078Sbinkertn@umich.edu    text.open(*simout.find(filename));
7404078Sbinkertn@umich.edu    text.descriptions = desc;
7414078Sbinkertn@umich.edu    text.compat = compat;
7424078Sbinkertn@umich.edu    OutputList.push_back(&text);
7434078Sbinkertn@umich.edu    connected = true;
7444078Sbinkertn@umich.edu
7454078Sbinkertn@umich.edu    return true;
7464078Sbinkertn@umich.edu}
7474078Sbinkertn@umich.edu
7484078Sbinkertn@umich.edu
749729SN/A/* namespace Stats */ }
750