2 * Copyright (c) 2004-2005 The Regents of The University of Michigan
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met: redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer;
9 * redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution;
12 * neither the name of the copyright holders nor the names of its
13 * contributors may be used to endorse or promote products derived from
14 * this software without specific prior written permission.
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 * Authors: Nathan Binkert
31 #if defined(__APPLE__)
32 #define _GLIBCPP_USE_C99 1
44 #include "base/misc.hh"
45 #include "base/statistics.hh"
46 #include "base/stats/statdb.hh"
47 #include "base/stats/text.hh"
48 #include "base/stats/visit.hh"
54 /** Define Not a number. */
56 /** Need to define __nan() */
77 : mystream(false), stream(NULL
), compat(false), descriptions(false)
81 Text::Text(std::ostream
&stream
)
82 : mystream(false), stream(NULL
), compat(false), descriptions(false)
87 Text::Text(const std::string
&file
)
88 : mystream(false), stream(NULL
), compat(false), descriptions(false)
103 Text::open(std::ostream
&_stream
)
106 panic("stream already set!");
114 Text::open(const std::string
&file
)
117 panic("stream already set!");
120 stream
= new ofstream(file
.c_str(), ios::trunc
);
127 return stream
!= NULL
;
133 using namespace Database
;
135 ccprintf(*stream
, "\n---------- Begin Simulation Statistics ----------\n");
136 stat_list_t::const_iterator i
, end
= stats().end();
137 for (i
= stats().begin(); i
!= end
; ++i
)
139 ccprintf(*stream
, "\n---------- End Simulation Statistics ----------\n");
144 Text::noOutput(const StatData
&data
)
146 if (!(data
.flags
& print
))
149 if (data
.prereq
&& data
.prereq
->zero())
156 ValueToString(Result value
, int precision
, bool compat
)
162 val
.precision(precision
);
163 else if (value
== rint(value
))
166 val
.unsetf(ios::showpoint
);
167 val
.setf(ios::fixed
);
170 val
<< (compat
? "<err: div-0>" : "no value");
188 void operator()(ostream
&stream
) const;
192 ScalarPrint::operator()(ostream
&stream
) const
194 if (flags
& nozero
&& value
== 0.0 ||
195 flags
& nonan
&& isnan(value
))
198 stringstream pdfstr
, cdfstr
;
201 ccprintf(pdfstr
, "%.2f%%", pdf
* 100.0);
204 ccprintf(cdfstr
, "%.2f%%", cdf
* 100.0);
206 if (compat
&& flags
& __substat
) {
207 ccprintf(stream
, "%32s %12s %10s %10s", name
,
208 ValueToString(value
, precision
, compat
), pdfstr
, cdfstr
);
210 ccprintf(stream
, "%-40s %12s %10s %10s", name
,
211 ValueToString(value
, precision
, compat
), pdfstr
, cdfstr
);
216 ccprintf(stream
, " # %s", desc
);
225 vector
<string
> subnames
;
226 vector
<string
> subdescs
;
234 void operator()(ostream
&stream
) const;
238 VectorPrint::operator()(std::ostream
&stream
) const
240 int _size
= vec
.size();
243 if (flags
& (pdf
| cdf
)) {
244 for (int i
= 0; i
< _size
; ++i
) {
249 string base
= name
+ (compat
? "_" : "::");
254 print
.compat
= compat
;
255 print
.precision
= precision
;
256 print
.descriptions
= descriptions
;
261 bool havesub
= !subnames
.empty();
264 print
.value
= vec
[0];
266 } else if (!compat
) {
267 for (int i
= 0; i
< _size
; ++i
) {
268 if (havesub
&& (i
>= subnames
.size() || subnames
[i
].empty()))
271 print
.name
= base
+ (havesub
? subnames
[i
] : to_string(i
));
272 print
.desc
= subdescs
.empty() ? desc
: subdescs
[i
];
273 print
.value
= vec
[i
];
275 if (_total
&& (flags
& pdf
)) {
276 print
.pdf
= vec
[i
] / _total
;
277 print
.cdf
+= print
.pdf
;
283 if (flags
& ::Stats::total
) {
284 print
.name
= base
+ "total";
290 if (flags
& ::Stats::total
) {
298 ccprintf(stream
, "%s.start_dist\n", name
);
299 for (int i
= 0; i
< _size
; ++i
) {
300 print
.name
= havesub
? subnames
[i
] : to_string(i
);
301 print
.desc
= subdescs
.empty() ? desc
: subdescs
[i
];
302 print
.flags
|= __substat
;
303 print
.value
= vec
[i
];
306 _pdf
= vec
[i
] / _total
;
317 ccprintf(stream
, "%s.end_dist\n", name
);
319 for (int i
= 0; i
< _size
; ++i
) {
320 if (havesub
&& subnames
[i
].empty())
324 print
.name
+= havesub
? subnames
[i
] : to_string(i
);
325 print
.desc
= subdescs
.empty() ? desc
: subdescs
[i
];
326 print
.value
= vec
[i
];
329 _pdf
= vec
[i
] / _total
;
370 void operator()(ostream
&stream
) const;
374 DistPrint::operator()(ostream
&stream
) const
378 string base
= name
+ (compat
? "_" : "::");
380 print
.precision
= precision
;
382 print
.compat
= compat
;
383 print
.descriptions
= descriptions
;
388 print
.name
= base
+ "mean";
389 print
.value
= samples
? sum
/ samples
: NAN
;
392 print
.name
= base
+ "stdev";
393 print
.value
= samples
? sqrt((samples
* squares
- sum
* sum
) /
394 (samples
* (samples
- 1.0))) : NAN
;
397 print
.name
= "**Ignore: " + base
+ "TOT";
398 print
.value
= samples
;
403 assert(size
== vec
.size());
408 for (int i
= 0; i
< size
; ++i
)
412 string base
= name
+ (compat
? "." : "::");
415 print
.desc
= compat
? "" : desc
;
417 print
.compat
= compat
;
418 print
.descriptions
= descriptions
;
419 print
.precision
= precision
;
424 ccprintf(stream
, "%-42s", base
+ "start_dist");
425 if (descriptions
&& !desc
.empty())
426 ccprintf(stream
, " # %s", desc
);
430 print
.name
= base
+ "samples";
431 print
.value
= samples
;
434 print
.name
= base
+ "min_value";
435 print
.value
= min_val
;
438 if (!compat
|| underflow
> 0.0) {
439 print
.name
= base
+ "underflows";
440 print
.value
= underflow
;
441 if (!compat
&& total
) {
442 print
.pdf
= underflow
/ total
;
443 print
.cdf
+= print
.pdf
;
450 for (int i
= 0; i
< size
; ++i
) {
451 stringstream namestr
;
454 Counter low
= i
* bucket_size
+ min
;
455 Counter high
= ::min(low
+ bucket_size
, max
);
458 namestr
<< "-" << high
;
460 print
.name
= namestr
.str();
461 print
.value
= vec
[i
];
463 print
.pdf
= vec
[i
] / total
;
464 print
.cdf
+= print
.pdf
;
474 print
.flags
= flags
| __substat
;
476 for (int i
= 0; i
< size
; ++i
) {
477 if (flags
& nozero
&& vec
[i
] == 0.0 ||
478 flags
& nonan
&& isnan(vec
[i
]))
481 _min
= i
* bucket_size
+ min
;
482 _pdf
= vec
[i
] / total
* 100.0;
486 print
.name
= ValueToString(_min
, 0, compat
);
487 print
.value
= vec
[i
];
488 print
.pdf
= (flags
& pdf
) ? _pdf
: NAN
;
489 print
.cdf
= (flags
& cdf
) ? _cdf
: NAN
;
496 if (!compat
|| overflow
> 0.0) {
497 print
.name
= base
+ "overflows";
498 print
.value
= overflow
;
499 if (!compat
&& total
) {
500 print
.pdf
= overflow
/ total
;
501 print
.cdf
+= print
.pdf
;
513 print
.name
= base
+ "total";
518 print
.name
= base
+ "max_value";
519 print
.value
= max_val
;
522 if (!compat
&& samples
!= 0) {
523 print
.name
= base
+ "mean";
524 print
.value
= sum
/ samples
;
527 print
.name
= base
+ "stdev";
528 print
.value
= sqrt((samples
* squares
- sum
* sum
) /
529 (samples
* (samples
- 1.0)));
534 ccprintf(stream
, "%send_dist\n\n", base
);
538 Text::visit(const ScalarData
&data
)
544 print
.value
= data
.result();
545 print
.name
= data
.name
;
546 print
.desc
= data
.desc
;
547 print
.flags
= data
.flags
;
548 print
.compat
= compat
;
549 print
.descriptions
= descriptions
;
550 print
.precision
= data
.precision
;
558 Text::visit(const VectorData
&data
)
563 int size
= data
.size();
566 print
.name
= data
.name
;
567 print
.desc
= data
.desc
;
568 print
.flags
= data
.flags
;
569 print
.compat
= compat
;
570 print
.descriptions
= descriptions
;
571 print
.precision
= data
.precision
;
572 print
.vec
= data
.result();
573 print
.total
= data
.total();
575 if (!data
.subnames
.empty()) {
576 for (int i
= 0; i
< size
; ++i
) {
577 if (!data
.subnames
[i
].empty()) {
578 print
.subnames
= data
.subnames
;
579 print
.subnames
.resize(size
);
580 for (int i
= 0; i
< size
; ++i
) {
581 if (!data
.subnames
[i
].empty() &&
582 !data
.subdescs
[i
].empty()) {
583 print
.subdescs
= data
.subdescs
;
584 print
.subdescs
.resize(size
);
597 Text::visit(const Vector2dData
&data
)
602 bool havesub
= false;
605 print
.subnames
= data
.y_subnames
;
606 print
.flags
= data
.flags
;
607 print
.compat
= compat
;
608 print
.descriptions
= descriptions
;
609 print
.precision
= data
.precision
;
611 if (!data
.subnames
.empty()) {
612 for (int i
= 0; i
< data
.x
; ++i
)
613 if (!data
.subnames
[i
].empty())
617 VResult
tot_vec(data
.y
);
618 Result super_total
= 0.0;
619 for (int i
= 0; i
< data
.x
; ++i
) {
620 if (havesub
&& (i
>= data
.subnames
.size() || data
.subnames
[i
].empty()))
624 VResult
yvec(data
.y
);
627 for (int j
= 0; j
< data
.y
; ++j
) {
628 yvec
[j
] = data
.cvec
[iy
+ j
];
629 tot_vec
[j
] += yvec
[j
];
631 super_total
+= yvec
[j
];
634 print
.name
= data
.name
+ "_" + (havesub
? data
.subnames
[i
] : to_string(i
));
635 print
.desc
= data
.desc
;
641 if ((data
.flags
& ::Stats::total
) && (data
.x
> 1)) {
642 print
.name
= data
.name
;
643 print
.desc
= data
.desc
;
645 print
.total
= super_total
;
651 Text::visit(const DistData
&data
)
658 print
.name
= data
.name
;
659 print
.desc
= data
.desc
;
660 print
.flags
= data
.flags
;
661 print
.compat
= compat
;
662 print
.descriptions
= descriptions
;
663 print
.precision
= data
.precision
;
665 print
.min_val
= data
.data
.min_val
;
666 print
.max_val
= data
.data
.max_val
;
667 print
.underflow
= data
.data
.underflow
;
668 print
.overflow
= data
.data
.overflow
;
669 print
.vec
.resize(data
.data
.cvec
.size());
670 for (int i
= 0; i
< print
.vec
.size(); ++i
)
671 print
.vec
[i
] = (Result
)data
.data
.cvec
[i
];
672 print
.sum
= data
.data
.sum
;
673 print
.squares
= data
.data
.squares
;
674 print
.samples
= data
.data
.samples
;
676 print
.min
= data
.data
.min
;
677 print
.max
= data
.data
.max
;
678 print
.bucket_size
= data
.data
.bucket_size
;
679 print
.size
= data
.data
.size
;
680 print
.fancy
= data
.data
.fancy
;
686 Text::visit(const VectorDistData
&data
)
691 for (int i
= 0; i
< data
.size(); ++i
) {
694 print
.name
= data
.name
+
695 (data
.subnames
[i
].empty() ? ("_" + to_string(i
)) : data
.subnames
[i
]);
696 print
.desc
= data
.subdescs
[i
].empty() ? data
.desc
: data
.subdescs
[i
];
697 print
.flags
= data
.flags
;
698 print
.compat
= compat
;
699 print
.descriptions
= descriptions
;
700 print
.precision
= data
.precision
;
702 print
.min_val
= data
.data
[i
].min_val
;
703 print
.max_val
= data
.data
[i
].max_val
;
704 print
.underflow
= data
.data
[i
].underflow
;
705 print
.overflow
= data
.data
[i
].overflow
;
706 print
.vec
.resize(data
.data
[i
].cvec
.size());
707 for (int j
= 0; j
< print
.vec
.size(); ++j
)
708 print
.vec
[j
] = (Result
)data
.data
[i
].cvec
[j
];
709 print
.sum
= data
.data
[i
].sum
;
710 print
.squares
= data
.data
[i
].squares
;
711 print
.samples
= data
.data
[i
].samples
;
713 print
.min
= data
.data
[i
].min
;
714 print
.max
= data
.data
[i
].max
;
715 print
.bucket_size
= data
.data
[i
].bucket_size
;
716 print
.size
= data
.data
[i
].size
;
717 print
.fancy
= data
.data
[i
].fancy
;
724 Text::visit(const FormulaData
&data
)
726 visit((const VectorData
&)data
);
730 initText(const string
&filename
, bool desc
, bool compat
)
733 static bool connected
= false;
738 extern list
<Output
*> OutputList
;
740 text
.open(*simout
.find(filename
));
741 text
.descriptions
= desc
;
742 text
.compat
= compat
;
743 OutputList
.push_back(&text
);
750 /* namespace Stats */ }