text.cc (6125:3bbbdd324a60) text.cc (6126:5f32f9e3c65a)
1/*
2 * Copyright (c) 2004-2005 The Regents of The University of Michigan
3 * All rights reserved.
4 *
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.
15 *
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.
27 *
28 * Authors: Nathan Binkert
29 */
30
31#if defined(__APPLE__)
32#define _GLIBCPP_USE_C99 1
33#endif
34
35#if defined(__sun)
36#include <math.h>
37#endif
38
39#include <iostream>
40#include <sstream>
41#include <fstream>
42#include <string>
43
44#include "base/misc.hh"
45#include "base/statistics.hh"
46#include "base/stats/text.hh"
47#include "base/stats/visit.hh"
48
49using namespace std;
50
51#ifndef NAN
52float __nan();
53/** Define Not a number. */
54#define NAN (__nan())
55/** Need to define __nan() */
56#define __M5_NAN
57#endif
58
59#ifdef __M5_NAN
60float
61__nan()
62{
63 union {
64 uint32_t ui;
65 float f;
66 } nan;
67
68 nan.ui = 0x7fc00000;
69 return nan.f;
70}
71#endif
72
73namespace Stats {
74
75Text::Text()
1/*
2 * Copyright (c) 2004-2005 The Regents of The University of Michigan
3 * All rights reserved.
4 *
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.
15 *
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.
27 *
28 * Authors: Nathan Binkert
29 */
30
31#if defined(__APPLE__)
32#define _GLIBCPP_USE_C99 1
33#endif
34
35#if defined(__sun)
36#include <math.h>
37#endif
38
39#include <iostream>
40#include <sstream>
41#include <fstream>
42#include <string>
43
44#include "base/misc.hh"
45#include "base/statistics.hh"
46#include "base/stats/text.hh"
47#include "base/stats/visit.hh"
48
49using namespace std;
50
51#ifndef NAN
52float __nan();
53/** Define Not a number. */
54#define NAN (__nan())
55/** Need to define __nan() */
56#define __M5_NAN
57#endif
58
59#ifdef __M5_NAN
60float
61__nan()
62{
63 union {
64 uint32_t ui;
65 float f;
66 } nan;
67
68 nan.ui = 0x7fc00000;
69 return nan.f;
70}
71#endif
72
73namespace Stats {
74
75Text::Text()
76 : mystream(false), stream(NULL), compat(false), descriptions(false)
76 : mystream(false), stream(NULL), descriptions(false)
77{
78}
79
80Text::Text(std::ostream &stream)
77{
78}
79
80Text::Text(std::ostream &stream)
81 : mystream(false), stream(NULL), compat(false), descriptions(false)
81 : mystream(false), stream(NULL), descriptions(false)
82{
83 open(stream);
84}
85
86Text::Text(const std::string &file)
82{
83 open(stream);
84}
85
86Text::Text(const std::string &file)
87 : mystream(false), stream(NULL), compat(false), descriptions(false)
87 : mystream(false), stream(NULL), descriptions(false)
88{
89 open(file);
90}
91
92
93Text::~Text()
94{
95 if (mystream) {
96 assert(stream);
97 delete stream;
98 }
99}
100
101void
102Text::open(std::ostream &_stream)
103{
104 if (stream)
105 panic("stream already set!");
106
107 mystream = false;
108 stream = &_stream;
109 if (!valid())
110 fatal("Unable to open output stream for writing\n");
111}
112
113void
114Text::open(const std::string &file)
115{
116 if (stream)
117 panic("stream already set!");
118
119 mystream = true;
120 stream = new ofstream(file.c_str(), ios::trunc);
121 if (!valid())
122 fatal("Unable to open statistics file for writing\n");
123}
124
125bool
126Text::valid() const
127{
128 return stream != NULL && stream->good();
129}
130
131void
132Text::output()
133{
134 ccprintf(*stream, "\n---------- Begin Simulation Statistics ----------\n");
135 list<Info *>::const_iterator i, end = statsList().end();
136 for (i = statsList().begin(); i != end; ++i)
137 (*i)->visit(*this);
138 ccprintf(*stream, "\n---------- End Simulation Statistics ----------\n");
139 stream->flush();
140}
141
142bool
143Text::noOutput(const Info &info)
144{
145 if (!(info.flags & print))
146 return true;
147
148 if (info.prereq && info.prereq->zero())
149 return true;
150
151 return false;
152}
153
154string
88{
89 open(file);
90}
91
92
93Text::~Text()
94{
95 if (mystream) {
96 assert(stream);
97 delete stream;
98 }
99}
100
101void
102Text::open(std::ostream &_stream)
103{
104 if (stream)
105 panic("stream already set!");
106
107 mystream = false;
108 stream = &_stream;
109 if (!valid())
110 fatal("Unable to open output stream for writing\n");
111}
112
113void
114Text::open(const std::string &file)
115{
116 if (stream)
117 panic("stream already set!");
118
119 mystream = true;
120 stream = new ofstream(file.c_str(), ios::trunc);
121 if (!valid())
122 fatal("Unable to open statistics file for writing\n");
123}
124
125bool
126Text::valid() const
127{
128 return stream != NULL && stream->good();
129}
130
131void
132Text::output()
133{
134 ccprintf(*stream, "\n---------- Begin Simulation Statistics ----------\n");
135 list<Info *>::const_iterator i, end = statsList().end();
136 for (i = statsList().begin(); i != end; ++i)
137 (*i)->visit(*this);
138 ccprintf(*stream, "\n---------- End Simulation Statistics ----------\n");
139 stream->flush();
140}
141
142bool
143Text::noOutput(const Info &info)
144{
145 if (!(info.flags & print))
146 return true;
147
148 if (info.prereq && info.prereq->zero())
149 return true;
150
151 return false;
152}
153
154string
155ValueToString(Result value, int precision, bool compat)
155ValueToString(Result value, int precision)
156{
157 stringstream val;
158
159 if (!isnan(value)) {
160 if (precision != -1)
161 val.precision(precision);
162 else if (value == rint(value))
163 val.precision(0);
164
165 val.unsetf(ios::showpoint);
166 val.setf(ios::fixed);
167 val << value;
168 } else {
156{
157 stringstream val;
158
159 if (!isnan(value)) {
160 if (precision != -1)
161 val.precision(precision);
162 else if (value == rint(value))
163 val.precision(0);
164
165 val.unsetf(ios::showpoint);
166 val.setf(ios::fixed);
167 val << value;
168 } else {
169 val << (compat ? "<err: div-0>" : "no value");
169 val << "no_value";
170 }
171
172 return val.str();
173}
174
175struct ScalarPrint
176{
177 Result value;
178 string name;
179 string desc;
180 StatFlags flags;
170 }
171
172 return val.str();
173}
174
175struct ScalarPrint
176{
177 Result value;
178 string name;
179 string desc;
180 StatFlags flags;
181 bool compat;
182 bool descriptions;
183 int precision;
184 Result pdf;
185 Result cdf;
186
187 void operator()(ostream &stream) const;
188};
189
190void
191ScalarPrint::operator()(ostream &stream) const
192{
193 if ((flags & nozero && value == 0.0) ||
194 (flags & nonan && isnan(value)))
195 return;
196
197 stringstream pdfstr, cdfstr;
198
199 if (!isnan(pdf))
200 ccprintf(pdfstr, "%.2f%%", pdf * 100.0);
201
202 if (!isnan(cdf))
203 ccprintf(cdfstr, "%.2f%%", cdf * 100.0);
204
181 bool descriptions;
182 int precision;
183 Result pdf;
184 Result cdf;
185
186 void operator()(ostream &stream) const;
187};
188
189void
190ScalarPrint::operator()(ostream &stream) const
191{
192 if ((flags & nozero && value == 0.0) ||
193 (flags & nonan && isnan(value)))
194 return;
195
196 stringstream pdfstr, cdfstr;
197
198 if (!isnan(pdf))
199 ccprintf(pdfstr, "%.2f%%", pdf * 100.0);
200
201 if (!isnan(cdf))
202 ccprintf(cdfstr, "%.2f%%", cdf * 100.0);
203
205 if (compat && flags & __substat) {
206 ccprintf(stream, "%32s %12s %10s %10s", name,
207 ValueToString(value, precision, compat), pdfstr, cdfstr);
208 } else {
209 ccprintf(stream, "%-40s %12s %10s %10s", name,
210 ValueToString(value, precision, compat), pdfstr, cdfstr);
211 }
204 ccprintf(stream, "%-40s %12s %10s %10s", name,
205 ValueToString(value, precision), pdfstr, cdfstr);
212
213 if (descriptions) {
214 if (!desc.empty())
215 ccprintf(stream, " # %s", desc);
216 }
217 stream << endl;
218}
219
220struct VectorPrint
221{
222 string name;
223 string desc;
224 vector<string> subnames;
225 vector<string> subdescs;
226 StatFlags flags;
206
207 if (descriptions) {
208 if (!desc.empty())
209 ccprintf(stream, " # %s", desc);
210 }
211 stream << endl;
212}
213
214struct VectorPrint
215{
216 string name;
217 string desc;
218 vector<string> subnames;
219 vector<string> subdescs;
220 StatFlags flags;
227 bool compat;
228 bool descriptions;
229 int precision;
230 VResult vec;
231 Result total;
232
233 void operator()(ostream &stream) const;
234};
235
236void
237VectorPrint::operator()(std::ostream &stream) const
238{
239 size_type _size = vec.size();
240 Result _total = 0.0;
241
242 if (flags & (pdf | cdf)) {
243 for (off_type i = 0; i < _size; ++i) {
244 _total += vec[i];
245 }
246 }
247
221 bool descriptions;
222 int precision;
223 VResult vec;
224 Result total;
225
226 void operator()(ostream &stream) const;
227};
228
229void
230VectorPrint::operator()(std::ostream &stream) const
231{
232 size_type _size = vec.size();
233 Result _total = 0.0;
234
235 if (flags & (pdf | cdf)) {
236 for (off_type i = 0; i < _size; ++i) {
237 _total += vec[i];
238 }
239 }
240
248 string base = name + (compat ? "_" : "::");
241 string base = name + "::";
249
250 ScalarPrint print;
251 print.name = name;
252 print.desc = desc;
242
243 ScalarPrint print;
244 print.name = name;
245 print.desc = desc;
253 print.compat = compat;
254 print.precision = precision;
255 print.descriptions = descriptions;
256 print.flags = flags;
257 print.pdf = NAN;
258 print.cdf = NAN;
259
260 bool havesub = !subnames.empty();
261
262 if (_size == 1) {
263 print.value = vec[0];
264 print(stream);
246 print.precision = precision;
247 print.descriptions = descriptions;
248 print.flags = flags;
249 print.pdf = NAN;
250 print.cdf = NAN;
251
252 bool havesub = !subnames.empty();
253
254 if (_size == 1) {
255 print.value = vec[0];
256 print(stream);
265 } else if (!compat) {
266 for (off_type i = 0; i < _size; ++i) {
267 if (havesub && (i >= subnames.size() || subnames[i].empty()))
268 continue;
257 return;
258 }
269
259
270 print.name = base + (havesub ? subnames[i] : to_string(i));
271 print.desc = subdescs.empty() ? desc : subdescs[i];
272 print.value = vec[i];
260 for (off_type i = 0; i < _size; ++i) {
261 if (havesub && (i >= subnames.size() || subnames[i].empty()))
262 continue;
273
263
274 if (_total && (flags & pdf)) {
275 print.pdf = vec[i] / _total;
276 print.cdf += print.pdf;
277 }
264 print.name = base + (havesub ? subnames[i] : to_string(i));
265 print.desc = subdescs.empty() ? desc : subdescs[i];
266 print.value = vec[i];
278
267
279 print(stream);
268 if (_total && flags & pdf) {
269 print.pdf = vec[i] / _total;
270 print.cdf += print.pdf;
280 }
281
271 }
272
282 if (flags & ::Stats::total) {
283 print.name = base + "total";
284 print.desc = desc;
285 print.value = total;
286 print(stream);
287 }
288 } else {
289 if (flags & ::Stats::total) {
290 print.value = total;
291 print(stream);
292 }
273 print(stream);
274 }
293
275
294 Result _pdf = 0.0;
295 Result _cdf = 0.0;
296 if (flags & dist) {
297 ccprintf(stream, "%s.start_dist\n", name);
298 for (off_type i = 0; i < _size; ++i) {
299 print.name = havesub ? subnames[i] : to_string(i);
300 print.desc = subdescs.empty() ? desc : subdescs[i];
301 print.flags |= __substat;
302 print.value = vec[i];
303
304 if (_total) {
305 _pdf = vec[i] / _total;
306 _cdf += _pdf;
307 }
308
309 if (flags & pdf)
310 print.pdf = _pdf;
311 if (flags & cdf)
312 print.cdf = _cdf;
313
314 print(stream);
315 }
316 ccprintf(stream, "%s.end_dist\n", name);
317 } else {
318 for (off_type i = 0; i < _size; ++i) {
319 if (havesub && subnames[i].empty())
320 continue;
321
322 print.name = base;
323 print.name += havesub ? subnames[i] : to_string(i);
324 print.desc = subdescs.empty() ? desc : subdescs[i];
325 print.value = vec[i];
326
327 if (_total) {
328 _pdf = vec[i] / _total;
329 _cdf += _pdf;
330 } else {
331 _pdf = _cdf = NAN;
332 }
333
334 if (flags & pdf) {
335 print.pdf = _pdf;
336 print.cdf = _cdf;
337 }
338
339 print(stream);
340 }
341 }
276 if (flags & ::Stats::total) {
277 print.pdf = NAN;
278 print.cdf = NAN;
279 print.name = base + "total";
280 print.desc = desc;
281 print.value = total;
282 print(stream);
342 }
343}
344
345struct DistPrint
346{
347 string name;
348 string desc;
349 StatFlags flags;
283 }
284}
285
286struct DistPrint
287{
288 string name;
289 string desc;
290 StatFlags flags;
350 bool compat;
351 bool descriptions;
352 int precision;
353
354 Counter min;
355 Counter max;
356 Counter bucket_size;
357 size_type size;
358 bool fancy;
359
360 const DistData &data;
361
362 DistPrint(const Text *text, const DistInfoBase &info);
363 DistPrint(const Text *text, const VectorDistInfoBase &info, int i);
364 void init(const Text *text, const Info &info, const DistParams *params);
365 void operator()(ostream &stream) const;
366};
367
368DistPrint::DistPrint(const Text *text, const DistInfoBase &info)
369 : data(info.data)
370{
371 init(text, info, safe_cast<const DistParams *>(info.storageParams));
372}
373
374DistPrint::DistPrint(const Text *text, const VectorDistInfoBase &info, int i)
375 : data(info.data[i])
376{
377 init(text, info, safe_cast<const DistParams *>(info.storageParams));
378
379 name = info.name + "_" +
380 (info.subnames[i].empty() ? (to_string(i)) : info.subnames[i]);
381
382 if (!info.subdescs[i].empty())
383 desc = info.subdescs[i];
384}
385
386void
387DistPrint::init(const Text *text, const Info &info, const DistParams *params)
388{
389 name = info.name;
390 desc = info.desc;
391 flags = info.flags;
392 precision = info.precision;
291 bool descriptions;
292 int precision;
293
294 Counter min;
295 Counter max;
296 Counter bucket_size;
297 size_type size;
298 bool fancy;
299
300 const DistData &data;
301
302 DistPrint(const Text *text, const DistInfoBase &info);
303 DistPrint(const Text *text, const VectorDistInfoBase &info, int i);
304 void init(const Text *text, const Info &info, const DistParams *params);
305 void operator()(ostream &stream) const;
306};
307
308DistPrint::DistPrint(const Text *text, const DistInfoBase &info)
309 : data(info.data)
310{
311 init(text, info, safe_cast<const DistParams *>(info.storageParams));
312}
313
314DistPrint::DistPrint(const Text *text, const VectorDistInfoBase &info, int i)
315 : data(info.data[i])
316{
317 init(text, info, safe_cast<const DistParams *>(info.storageParams));
318
319 name = info.name + "_" +
320 (info.subnames[i].empty() ? (to_string(i)) : info.subnames[i]);
321
322 if (!info.subdescs[i].empty())
323 desc = info.subdescs[i];
324}
325
326void
327DistPrint::init(const Text *text, const Info &info, const DistParams *params)
328{
329 name = info.name;
330 desc = info.desc;
331 flags = info.flags;
332 precision = info.precision;
393 compat = text->compat;
394 descriptions = text->descriptions;
395
396 fancy = params->fancy;
397 min = params->min;
398 max = params->max;
399 bucket_size = params->bucket_size;
400 size = params->buckets;
401}
402
403void
404DistPrint::operator()(ostream &stream) const
405{
406 Result stdev = NAN;
407 if (data.samples)
408 stdev = sqrt((data.samples * data.squares - data.sum * data.sum) /
409 (data.samples * (data.samples - 1.0)));
410
411 if (fancy) {
412 ScalarPrint print;
333 descriptions = text->descriptions;
334
335 fancy = params->fancy;
336 min = params->min;
337 max = params->max;
338 bucket_size = params->bucket_size;
339 size = params->buckets;
340}
341
342void
343DistPrint::operator()(ostream &stream) const
344{
345 Result stdev = NAN;
346 if (data.samples)
347 stdev = sqrt((data.samples * data.squares - data.sum * data.sum) /
348 (data.samples * (data.samples - 1.0)));
349
350 if (fancy) {
351 ScalarPrint print;
413 string base = name + (compat ? "_" : "::");
352 string base = name + "::";
414
415 print.precision = precision;
416 print.flags = flags;
353
354 print.precision = precision;
355 print.flags = flags;
417 print.compat = compat;
418 print.descriptions = descriptions;
419 print.desc = desc;
420 print.pdf = NAN;
421 print.cdf = NAN;
422
423 print.name = base + "mean";
424 print.value = data.samples ? data.sum / data.samples : NAN;
425 print(stream);
426
427 print.name = base + "stdev";
428 print.value = stdev;
429 print(stream);
430
431 print.name = "**Ignore: " + base + "TOT";
432 print.value = data.samples;
433 print(stream);
434 return;
435 }
436
437 assert(size == data.cvec.size());
438
439 Result total = 0.0;
440
441 total += data.underflow;
442 for (off_type i = 0; i < size; ++i)
443 total += data.cvec[i];
444 total += data.overflow;
445
356 print.descriptions = descriptions;
357 print.desc = desc;
358 print.pdf = NAN;
359 print.cdf = NAN;
360
361 print.name = base + "mean";
362 print.value = data.samples ? data.sum / data.samples : NAN;
363 print(stream);
364
365 print.name = base + "stdev";
366 print.value = stdev;
367 print(stream);
368
369 print.name = "**Ignore: " + base + "TOT";
370 print.value = data.samples;
371 print(stream);
372 return;
373 }
374
375 assert(size == data.cvec.size());
376
377 Result total = 0.0;
378
379 total += data.underflow;
380 for (off_type i = 0; i < size; ++i)
381 total += data.cvec[i];
382 total += data.overflow;
383
446 string base = name + (compat ? "." : "::");
384 string base = name + "::";
447
448 ScalarPrint print;
385
386 ScalarPrint print;
449 print.desc = compat ? "" : desc;
387 print.desc = desc;
450 print.flags = flags;
388 print.flags = flags;
451 print.compat = compat;
452 print.descriptions = descriptions;
453 print.precision = precision;
454 print.pdf = NAN;
455 print.cdf = NAN;
456
389 print.descriptions = descriptions;
390 print.precision = precision;
391 print.pdf = NAN;
392 print.cdf = NAN;
393
457 if (compat) {
458 ccprintf(stream, "%-42s", base + "start_dist");
459 if (descriptions && !desc.empty())
460 ccprintf(stream, " # %s", desc);
461 stream << endl;
462 }
463
464 print.name = base + "samples";
465 print.value = data.samples;
466 print(stream);
467
468 print.name = base + "min_value";
469 print.value = data.min_val;
470 print(stream);
471
394 print.name = base + "samples";
395 print.value = data.samples;
396 print(stream);
397
398 print.name = base + "min_value";
399 print.value = data.min_val;
400 print(stream);
401
472 if (!compat || data.underflow > 0.0) {
473 print.name = base + "underflows";
474 print.value = data.underflow;
475 if (!compat && total) {
476 print.pdf = data.underflow / total;
477 print.cdf += print.pdf;
478 }
479 print(stream);
402 print.name = base + "underflows";
403 print.value = data.underflow;
404 if (total) {
405 print.pdf = data.underflow / total;
406 print.cdf += print.pdf;
480 }
407 }
408 print(stream);
481
409
482 if (!compat) {
483 for (off_type i = 0; i < size; ++i) {
484 stringstream namestr;
485 namestr << base;
410 for (off_type i = 0; i < size; ++i) {
411 stringstream namestr;
412 namestr << base;
486
413
487 Counter low = i * bucket_size + min;
488 Counter high = ::min(low + bucket_size, max);
489 namestr << low;
490 if (low < high)
491 namestr << "-" << high;
414 Counter low = i * bucket_size + min;
415 Counter high = ::min(low + bucket_size, max);
416 namestr << low;
417 if (low < high)
418 namestr << "-" << high;
492
419
493 print.name = namestr.str();
494 print.value = data.cvec[i];
495 if (total) {
496 print.pdf = data.cvec[i] / total;
497 print.cdf += print.pdf;
498 }
499 print(stream);
500 }
501 } else {
502 Counter _min;
503 Result _pdf;
504 Result _cdf = 0.0;
505
506 print.flags = flags | __substat;
507
508 for (off_type i = 0; i < size; ++i) {
509 if ((flags & nozero && data.cvec[i] == 0.0) ||
510 (flags & nonan && isnan(data.cvec[i])))
511 continue;
512
513 _min = i * bucket_size + min;
514 _pdf = data.cvec[i] / total * 100.0;
515 _cdf += _pdf;
516
517
518 print.name = ValueToString(_min, 0, compat);
519 print.value = data.cvec[i];
520 print.pdf = (flags & pdf) ? _pdf : NAN;
521 print.cdf = (flags & cdf) ? _cdf : NAN;
522 print(stream);
523 }
524
525 print.flags = flags;
526 }
527
528 if (!compat || data.overflow > 0.0) {
529 print.name = base + "overflows";
530 print.value = data.overflow;
531 if (!compat && total) {
532 print.pdf = data.overflow / total;
420 print.name = namestr.str();
421 print.value = data.cvec[i];
422 if (total) {
423 print.pdf = data.cvec[i] / total;
533 print.cdf += print.pdf;
424 print.cdf += print.pdf;
534 } else {
535 print.pdf = NAN;
536 print.cdf = NAN;
537 }
538 print(stream);
539 }
540
425 }
426 print(stream);
427 }
428
429 print.name = base + "overflows";
430 print.value = data.overflow;
431 if (total) {
432 print.pdf = data.overflow / total;
433 print.cdf += print.pdf;
434 } else {
435 print.pdf = NAN;
436 print.cdf = NAN;
437 }
438 print(stream);
439
541 print.pdf = NAN;
542 print.cdf = NAN;
543
440 print.pdf = NAN;
441 print.cdf = NAN;
442
544 if (!compat) {
545 print.name = base + "total";
546 print.value = total;
547 print(stream);
548 }
443 print.name = base + "total";
444 print.value = total;
445 print(stream);
549
550 print.name = base + "max_value";
551 print.value = data.max_val;
552 print(stream);
553
446
447 print.name = base + "max_value";
448 print.value = data.max_val;
449 print(stream);
450
554 if (!compat && data.samples != 0) {
555 print.name = base + "mean";
556 print.value = data.sum / data.samples;
557 print(stream);
451 print.name = base + "mean";
452 print.value = data.sum / data.samples;
453 print(stream);
558
454
559 print.name = base + "stdev";
560 print.value = stdev;
561 print(stream);
562 }
563
564 if (compat)
565 ccprintf(stream, "%send_dist\n\n", base);
455 print.name = base + "stdev";
456 print.value = stdev;
457 print(stream);
566}
567
568void
569Text::visit(const ScalarInfoBase &info)
570{
571 if (noOutput(info))
572 return;
573
574 ScalarPrint print;
575 print.value = info.result();
576 print.name = info.name;
577 print.desc = info.desc;
578 print.flags = info.flags;
458}
459
460void
461Text::visit(const ScalarInfoBase &info)
462{
463 if (noOutput(info))
464 return;
465
466 ScalarPrint print;
467 print.value = info.result();
468 print.name = info.name;
469 print.desc = info.desc;
470 print.flags = info.flags;
579 print.compat = compat;
580 print.descriptions = descriptions;
581 print.precision = info.precision;
582 print.pdf = NAN;
583 print.cdf = NAN;
584
585 print(*stream);
586}
587
588void
589Text::visit(const VectorInfoBase &info)
590{
591 if (noOutput(info))
592 return;
593
594 size_type size = info.size();
595 VectorPrint print;
596
597 print.name = info.name;
598 print.desc = info.desc;
599 print.flags = info.flags;
471 print.descriptions = descriptions;
472 print.precision = info.precision;
473 print.pdf = NAN;
474 print.cdf = NAN;
475
476 print(*stream);
477}
478
479void
480Text::visit(const VectorInfoBase &info)
481{
482 if (noOutput(info))
483 return;
484
485 size_type size = info.size();
486 VectorPrint print;
487
488 print.name = info.name;
489 print.desc = info.desc;
490 print.flags = info.flags;
600 print.compat = compat;
601 print.descriptions = descriptions;
602 print.precision = info.precision;
603 print.vec = info.result();
604 print.total = info.total();
605
606 if (!info.subnames.empty()) {
607 for (off_type i = 0; i < size; ++i) {
608 if (!info.subnames[i].empty()) {
609 print.subnames = info.subnames;
610 print.subnames.resize(size);
611 for (off_type i = 0; i < size; ++i) {
612 if (!info.subnames[i].empty() &&
613 !info.subdescs[i].empty()) {
614 print.subdescs = info.subdescs;
615 print.subdescs.resize(size);
616 break;
617 }
618 }
619 break;
620 }
621 }
622 }
623
624 print(*stream);
625}
626
627void
628Text::visit(const Vector2dInfoBase &info)
629{
630 if (noOutput(info))
631 return;
632
633 bool havesub = false;
634 VectorPrint print;
635
636 print.subnames = info.y_subnames;
637 print.flags = info.flags;
491 print.descriptions = descriptions;
492 print.precision = info.precision;
493 print.vec = info.result();
494 print.total = info.total();
495
496 if (!info.subnames.empty()) {
497 for (off_type i = 0; i < size; ++i) {
498 if (!info.subnames[i].empty()) {
499 print.subnames = info.subnames;
500 print.subnames.resize(size);
501 for (off_type i = 0; i < size; ++i) {
502 if (!info.subnames[i].empty() &&
503 !info.subdescs[i].empty()) {
504 print.subdescs = info.subdescs;
505 print.subdescs.resize(size);
506 break;
507 }
508 }
509 break;
510 }
511 }
512 }
513
514 print(*stream);
515}
516
517void
518Text::visit(const Vector2dInfoBase &info)
519{
520 if (noOutput(info))
521 return;
522
523 bool havesub = false;
524 VectorPrint print;
525
526 print.subnames = info.y_subnames;
527 print.flags = info.flags;
638 print.compat = compat;
639 print.descriptions = descriptions;
640 print.precision = info.precision;
641
642 if (!info.subnames.empty()) {
643 for (off_type i = 0; i < info.x; ++i)
644 if (!info.subnames[i].empty())
645 havesub = true;
646 }
647
648 VResult tot_vec(info.y);
649 Result super_total = 0.0;
650 for (off_type i = 0; i < info.x; ++i) {
651 if (havesub && (i >= info.subnames.size() || info.subnames[i].empty()))
652 continue;
653
654 off_type iy = i * info.y;
655 VResult yvec(info.y);
656
657 Result total = 0.0;
658 for (off_type j = 0; j < info.y; ++j) {
659 yvec[j] = info.cvec[iy + j];
660 tot_vec[j] += yvec[j];
661 total += yvec[j];
662 super_total += yvec[j];
663 }
664
665 print.name = info.name + "_" +
666 (havesub ? info.subnames[i] : to_string(i));
667 print.desc = info.desc;
668 print.vec = yvec;
669 print.total = total;
670 print(*stream);
671 }
672
673 if ((info.flags & ::Stats::total) && (info.x > 1)) {
674 print.name = info.name;
675 print.desc = info.desc;
676 print.vec = tot_vec;
677 print.total = super_total;
678 print(*stream);
679 }
680}
681
682void
683Text::visit(const DistInfoBase &info)
684{
685 if (noOutput(info))
686 return;
687
688 DistPrint print(this, info);
689 print(*stream);
690}
691
692void
693Text::visit(const VectorDistInfoBase &info)
694{
695 if (noOutput(info))
696 return;
697
698 for (off_type i = 0; i < info.size(); ++i) {
699 DistPrint print(this, info, i);
700 print(*stream);
701 }
702}
703
704void
705Text::visit(const FormulaInfoBase &info)
706{
707 visit((const VectorInfoBase &)info);
708}
709
710bool
528 print.descriptions = descriptions;
529 print.precision = info.precision;
530
531 if (!info.subnames.empty()) {
532 for (off_type i = 0; i < info.x; ++i)
533 if (!info.subnames[i].empty())
534 havesub = true;
535 }
536
537 VResult tot_vec(info.y);
538 Result super_total = 0.0;
539 for (off_type i = 0; i < info.x; ++i) {
540 if (havesub && (i >= info.subnames.size() || info.subnames[i].empty()))
541 continue;
542
543 off_type iy = i * info.y;
544 VResult yvec(info.y);
545
546 Result total = 0.0;
547 for (off_type j = 0; j < info.y; ++j) {
548 yvec[j] = info.cvec[iy + j];
549 tot_vec[j] += yvec[j];
550 total += yvec[j];
551 super_total += yvec[j];
552 }
553
554 print.name = info.name + "_" +
555 (havesub ? info.subnames[i] : to_string(i));
556 print.desc = info.desc;
557 print.vec = yvec;
558 print.total = total;
559 print(*stream);
560 }
561
562 if ((info.flags & ::Stats::total) && (info.x > 1)) {
563 print.name = info.name;
564 print.desc = info.desc;
565 print.vec = tot_vec;
566 print.total = super_total;
567 print(*stream);
568 }
569}
570
571void
572Text::visit(const DistInfoBase &info)
573{
574 if (noOutput(info))
575 return;
576
577 DistPrint print(this, info);
578 print(*stream);
579}
580
581void
582Text::visit(const VectorDistInfoBase &info)
583{
584 if (noOutput(info))
585 return;
586
587 for (off_type i = 0; i < info.size(); ++i) {
588 DistPrint print(this, info, i);
589 print(*stream);
590 }
591}
592
593void
594Text::visit(const FormulaInfoBase &info)
595{
596 visit((const VectorInfoBase &)info);
597}
598
599bool
711initText(const string &filename, bool desc, bool compat)
600initText(const string &filename, bool desc)
712{
713 static Text text;
714 static bool connected = false;
715
716 if (connected)
717 return false;
718
719 extern list<Output *> OutputList;
720
721 text.open(*simout.find(filename));
722 text.descriptions = desc;
601{
602 static Text text;
603 static bool connected = false;
604
605 if (connected)
606 return false;
607
608 extern list<Output *> OutputList;
609
610 text.open(*simout.find(filename));
611 text.descriptions = desc;
723 text.compat = compat;
724 OutputList.push_back(&text);
725 connected = true;
726
727 return true;
728}
729
730/* namespace Stats */ }
612 OutputList.push_back(&text);
613 connected = true;
614
615 return true;
616}
617
618/* namespace Stats */ }