text.cc revision 8667:62372a8d4ef2
111986Sandreas.sandberg@arm.com/* 211986Sandreas.sandberg@arm.com * Copyright (c) 2004-2005 The Regents of The University of Michigan 311986Sandreas.sandberg@arm.com * All rights reserved. 411986Sandreas.sandberg@arm.com * 511986Sandreas.sandberg@arm.com * Redistribution and use in source and binary forms, with or without 611986Sandreas.sandberg@arm.com * modification, are permitted provided that the following conditions are 711986Sandreas.sandberg@arm.com * met: redistributions of source code must retain the above copyright 811986Sandreas.sandberg@arm.com * notice, this list of conditions and the following disclaimer; 911986Sandreas.sandberg@arm.com * redistributions in binary form must reproduce the above copyright 1011986Sandreas.sandberg@arm.com * notice, this list of conditions and the following disclaimer in the 1111986Sandreas.sandberg@arm.com * documentation and/or other materials provided with the distribution; 1211986Sandreas.sandberg@arm.com * neither the name of the copyright holders nor the names of its 1311986Sandreas.sandberg@arm.com * contributors may be used to endorse or promote products derived from 1411986Sandreas.sandberg@arm.com * this software without specific prior written permission. 1511986Sandreas.sandberg@arm.com * 1611986Sandreas.sandberg@arm.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1711986Sandreas.sandberg@arm.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1811986Sandreas.sandberg@arm.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 1911986Sandreas.sandberg@arm.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2011986Sandreas.sandberg@arm.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2111986Sandreas.sandberg@arm.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 2211986Sandreas.sandberg@arm.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2311986Sandreas.sandberg@arm.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2411986Sandreas.sandberg@arm.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2511986Sandreas.sandberg@arm.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 2611986Sandreas.sandberg@arm.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2711986Sandreas.sandberg@arm.com * 2811986Sandreas.sandberg@arm.com * Authors: Nathan Binkert 2911986Sandreas.sandberg@arm.com */ 3011986Sandreas.sandberg@arm.com 3111986Sandreas.sandberg@arm.com#if defined(__APPLE__) 3211986Sandreas.sandberg@arm.com#define _GLIBCPP_USE_C99 1 3311986Sandreas.sandberg@arm.com#endif 3411986Sandreas.sandberg@arm.com 3511986Sandreas.sandberg@arm.com#if defined(__sun) 3612037Sandreas.sandberg@arm.com#include <math.h> 3711986Sandreas.sandberg@arm.com#endif 3811986Sandreas.sandberg@arm.com 3911986Sandreas.sandberg@arm.com#include <cassert> 4011986Sandreas.sandberg@arm.com#ifdef __SUNPRO_CC 4111986Sandreas.sandberg@arm.com#include <math.h> 4211986Sandreas.sandberg@arm.com#endif 4311986Sandreas.sandberg@arm.com#include <cmath> 4411986Sandreas.sandberg@arm.com#include <fstream> 4511986Sandreas.sandberg@arm.com#include <iostream> 4611986Sandreas.sandberg@arm.com#include <sstream> 4711986Sandreas.sandberg@arm.com#include <string> 4811986Sandreas.sandberg@arm.com 4912037Sandreas.sandberg@arm.com#include "base/stats/info.hh" 5012037Sandreas.sandberg@arm.com#include "base/stats/text.hh" 5112037Sandreas.sandberg@arm.com#include "base/cast.hh" 5212037Sandreas.sandberg@arm.com#include "base/misc.hh" 5312037Sandreas.sandberg@arm.com#include "base/str.hh" 5412037Sandreas.sandberg@arm.com 5511986Sandreas.sandberg@arm.comusing namespace std; 5611986Sandreas.sandberg@arm.com 5711986Sandreas.sandberg@arm.com#ifndef NAN 5811986Sandreas.sandberg@arm.comfloat __nan(); 5911986Sandreas.sandberg@arm.com/** Define Not a number. */ 6011986Sandreas.sandberg@arm.com#define NAN (__nan()) 6111986Sandreas.sandberg@arm.com/** Need to define __nan() */ 6211986Sandreas.sandberg@arm.com#define __M5_NAN 6311986Sandreas.sandberg@arm.com#endif 6411986Sandreas.sandberg@arm.com 6511986Sandreas.sandberg@arm.com#ifdef __M5_NAN 6611986Sandreas.sandberg@arm.comfloat 6711986Sandreas.sandberg@arm.com__nan() 6811986Sandreas.sandberg@arm.com{ 6911986Sandreas.sandberg@arm.com union { 7011986Sandreas.sandberg@arm.com uint32_t ui; 7111986Sandreas.sandberg@arm.com float f; 7211986Sandreas.sandberg@arm.com } nan; 7311986Sandreas.sandberg@arm.com 7411986Sandreas.sandberg@arm.com nan.ui = 0x7fc00000; 7511986Sandreas.sandberg@arm.com return nan.f; 7611986Sandreas.sandberg@arm.com} 7711986Sandreas.sandberg@arm.com#endif 7811986Sandreas.sandberg@arm.com 7911986Sandreas.sandberg@arm.comnamespace Stats { 8011986Sandreas.sandberg@arm.com 8111986Sandreas.sandberg@arm.comstd::list<Info *> &statsList(); 8211986Sandreas.sandberg@arm.com 8312037Sandreas.sandberg@arm.comText::Text() 8411986Sandreas.sandberg@arm.com : mystream(false), stream(NULL), descriptions(false) 8511986Sandreas.sandberg@arm.com{ 8611986Sandreas.sandberg@arm.com} 8711986Sandreas.sandberg@arm.com 8811986Sandreas.sandberg@arm.comText::Text(std::ostream &stream) 8911986Sandreas.sandberg@arm.com : mystream(false), stream(NULL), descriptions(false) 9011986Sandreas.sandberg@arm.com{ 9111986Sandreas.sandberg@arm.com open(stream); 9211986Sandreas.sandberg@arm.com} 9311986Sandreas.sandberg@arm.com 9411986Sandreas.sandberg@arm.comText::Text(const std::string &file) 9511986Sandreas.sandberg@arm.com : mystream(false), stream(NULL), descriptions(false) 9611986Sandreas.sandberg@arm.com{ 9711986Sandreas.sandberg@arm.com open(file); 9811986Sandreas.sandberg@arm.com} 9911986Sandreas.sandberg@arm.com 10011986Sandreas.sandberg@arm.com 10111986Sandreas.sandberg@arm.comText::~Text() 10211986Sandreas.sandberg@arm.com{ 10311986Sandreas.sandberg@arm.com if (mystream) { 10411986Sandreas.sandberg@arm.com assert(stream); 10511986Sandreas.sandberg@arm.com delete stream; 10611986Sandreas.sandberg@arm.com } 10711986Sandreas.sandberg@arm.com} 10811986Sandreas.sandberg@arm.com 10911986Sandreas.sandberg@arm.comvoid 11011986Sandreas.sandberg@arm.comText::open(std::ostream &_stream) 11111986Sandreas.sandberg@arm.com{ 11211986Sandreas.sandberg@arm.com if (stream) 11311986Sandreas.sandberg@arm.com panic("stream already set!"); 11411986Sandreas.sandberg@arm.com 11511986Sandreas.sandberg@arm.com mystream = false; 11611986Sandreas.sandberg@arm.com stream = &_stream; 11711986Sandreas.sandberg@arm.com if (!valid()) 11811986Sandreas.sandberg@arm.com fatal("Unable to open output stream for writing\n"); 11911986Sandreas.sandberg@arm.com} 12011986Sandreas.sandberg@arm.com 12111986Sandreas.sandberg@arm.comvoid 12211986Sandreas.sandberg@arm.comText::open(const std::string &file) 12311986Sandreas.sandberg@arm.com{ 12411986Sandreas.sandberg@arm.com if (stream) 12511986Sandreas.sandberg@arm.com panic("stream already set!"); 12611986Sandreas.sandberg@arm.com 12711986Sandreas.sandberg@arm.com mystream = true; 12811986Sandreas.sandberg@arm.com stream = new ofstream(file.c_str(), ios::trunc); 12911986Sandreas.sandberg@arm.com if (!valid()) 13011986Sandreas.sandberg@arm.com fatal("Unable to open statistics file for writing\n"); 13111986Sandreas.sandberg@arm.com} 13211986Sandreas.sandberg@arm.com 13311986Sandreas.sandberg@arm.combool 13411986Sandreas.sandberg@arm.comText::valid() const 13511986Sandreas.sandberg@arm.com{ 13611986Sandreas.sandberg@arm.com return stream != NULL && stream->good(); 13711986Sandreas.sandberg@arm.com} 13811986Sandreas.sandberg@arm.com 13911986Sandreas.sandberg@arm.comvoid 14011986Sandreas.sandberg@arm.comText::begin() 14111986Sandreas.sandberg@arm.com{ 14211986Sandreas.sandberg@arm.com ccprintf(*stream, "\n---------- Begin Simulation Statistics ----------\n"); 14311986Sandreas.sandberg@arm.com} 14411986Sandreas.sandberg@arm.com 14511986Sandreas.sandberg@arm.comvoid 14611986Sandreas.sandberg@arm.comText::end() 14711986Sandreas.sandberg@arm.com{ 14811986Sandreas.sandberg@arm.com ccprintf(*stream, "\n---------- End Simulation Statistics ----------\n"); 14911986Sandreas.sandberg@arm.com stream->flush(); 15011986Sandreas.sandberg@arm.com} 15111986Sandreas.sandberg@arm.com 15211986Sandreas.sandberg@arm.combool 15311986Sandreas.sandberg@arm.comText::noOutput(const Info &info) 15411986Sandreas.sandberg@arm.com{ 15511986Sandreas.sandberg@arm.com if (!info.flags.isSet(display)) 15611986Sandreas.sandberg@arm.com return true; 15711986Sandreas.sandberg@arm.com 15812037Sandreas.sandberg@arm.com if (info.prereq && info.prereq->zero()) 15911986Sandreas.sandberg@arm.com return true; 16011986Sandreas.sandberg@arm.com 16111986Sandreas.sandberg@arm.com return false; 16211986Sandreas.sandberg@arm.com} 16311986Sandreas.sandberg@arm.com 16411986Sandreas.sandberg@arm.comstring 16511986Sandreas.sandberg@arm.comValueToString(Result value, int precision) 16611986Sandreas.sandberg@arm.com{ 16711986Sandreas.sandberg@arm.com stringstream val; 16811986Sandreas.sandberg@arm.com 16911986Sandreas.sandberg@arm.com if (!isnan(value)) { 17011986Sandreas.sandberg@arm.com if (precision != -1) 17111986Sandreas.sandberg@arm.com val.precision(precision); 17211986Sandreas.sandberg@arm.com else if (value == rint(value)) 17311986Sandreas.sandberg@arm.com val.precision(0); 17411986Sandreas.sandberg@arm.com 17511986Sandreas.sandberg@arm.com val.unsetf(ios::showpoint); 17611986Sandreas.sandberg@arm.com val.setf(ios::fixed); 17711986Sandreas.sandberg@arm.com val << value; 17811986Sandreas.sandberg@arm.com } else { 17912037Sandreas.sandberg@arm.com val << "no_value"; 18012037Sandreas.sandberg@arm.com } 18112037Sandreas.sandberg@arm.com 18212037Sandreas.sandberg@arm.com return val.str(); 18311986Sandreas.sandberg@arm.com} 18411986Sandreas.sandberg@arm.com 18511986Sandreas.sandberg@arm.comstruct ScalarPrint 18611986Sandreas.sandberg@arm.com{ 18711986Sandreas.sandberg@arm.com Result value; 18811986Sandreas.sandberg@arm.com string name; 18911986Sandreas.sandberg@arm.com string desc; 19011986Sandreas.sandberg@arm.com Flags flags; 19111986Sandreas.sandberg@arm.com bool descriptions; 19211986Sandreas.sandberg@arm.com int precision; 19311986Sandreas.sandberg@arm.com Result pdf; 19411986Sandreas.sandberg@arm.com Result cdf; 19511986Sandreas.sandberg@arm.com 19612037Sandreas.sandberg@arm.com void update(Result val, Result total); 19712037Sandreas.sandberg@arm.com void operator()(ostream &stream) const; 19812037Sandreas.sandberg@arm.com}; 19911986Sandreas.sandberg@arm.com 20012037Sandreas.sandberg@arm.comvoid 20112037Sandreas.sandberg@arm.comScalarPrint::update(Result val, Result total) 20212037Sandreas.sandberg@arm.com{ 20312037Sandreas.sandberg@arm.com value = val; 20411986Sandreas.sandberg@arm.com if (total) { 20511986Sandreas.sandberg@arm.com pdf = val / total; 20611986Sandreas.sandberg@arm.com cdf += pdf; 20711986Sandreas.sandberg@arm.com } 20811986Sandreas.sandberg@arm.com} 20911986Sandreas.sandberg@arm.com 21011986Sandreas.sandberg@arm.comvoid 21111986Sandreas.sandberg@arm.comScalarPrint::operator()(ostream &stream) const 21211986Sandreas.sandberg@arm.com{ 21311986Sandreas.sandberg@arm.com if ((flags.isSet(nozero) && value == 0.0) || 21411986Sandreas.sandberg@arm.com (flags.isSet(nonan) && isnan(value))) 21511986Sandreas.sandberg@arm.com return; 21611986Sandreas.sandberg@arm.com 21711986Sandreas.sandberg@arm.com stringstream pdfstr, cdfstr; 21811986Sandreas.sandberg@arm.com 21911986Sandreas.sandberg@arm.com if (!isnan(pdf)) 22011986Sandreas.sandberg@arm.com ccprintf(pdfstr, "%.2f%%", pdf * 100.0); 22111986Sandreas.sandberg@arm.com 22211986Sandreas.sandberg@arm.com if (!isnan(cdf)) 22311986Sandreas.sandberg@arm.com ccprintf(cdfstr, "%.2f%%", cdf * 100.0); 22411986Sandreas.sandberg@arm.com 22511986Sandreas.sandberg@arm.com ccprintf(stream, "%-40s %12s %10s %10s", name, 22611986Sandreas.sandberg@arm.com ValueToString(value, precision), pdfstr, cdfstr); 22711986Sandreas.sandberg@arm.com 22811986Sandreas.sandberg@arm.com if (descriptions) { 22911986Sandreas.sandberg@arm.com if (!desc.empty()) 23011986Sandreas.sandberg@arm.com ccprintf(stream, " # %s", desc); 23111986Sandreas.sandberg@arm.com } 23211986Sandreas.sandberg@arm.com stream << endl; 23311986Sandreas.sandberg@arm.com} 23411986Sandreas.sandberg@arm.com 23511986Sandreas.sandberg@arm.comstruct VectorPrint 23611986Sandreas.sandberg@arm.com{ 23711986Sandreas.sandberg@arm.com string name; 23811986Sandreas.sandberg@arm.com string separatorString; 23911986Sandreas.sandberg@arm.com string desc; 24011986Sandreas.sandberg@arm.com vector<string> subnames; 24111986Sandreas.sandberg@arm.com vector<string> subdescs; 24211986Sandreas.sandberg@arm.com Flags flags; 24311986Sandreas.sandberg@arm.com bool descriptions; 24411986Sandreas.sandberg@arm.com int precision; 24511986Sandreas.sandberg@arm.com VResult vec; 24611986Sandreas.sandberg@arm.com Result total; 24711986Sandreas.sandberg@arm.com 24811986Sandreas.sandberg@arm.com void operator()(ostream &stream) const; 24911986Sandreas.sandberg@arm.com}; 25011986Sandreas.sandberg@arm.com 25111986Sandreas.sandberg@arm.comvoid 25211986Sandreas.sandberg@arm.comVectorPrint::operator()(std::ostream &stream) const 25311986Sandreas.sandberg@arm.com{ 25411986Sandreas.sandberg@arm.com size_type _size = vec.size(); 25511986Sandreas.sandberg@arm.com Result _total = 0.0; 25611986Sandreas.sandberg@arm.com 25711986Sandreas.sandberg@arm.com if (flags.isSet(pdf | cdf)) { 25811986Sandreas.sandberg@arm.com for (off_type i = 0; i < _size; ++i) { 25911986Sandreas.sandberg@arm.com _total += vec[i]; 26011986Sandreas.sandberg@arm.com } 26111986Sandreas.sandberg@arm.com } 26211986Sandreas.sandberg@arm.com 26311986Sandreas.sandberg@arm.com string base = name + separatorString; 26411986Sandreas.sandberg@arm.com 26511986Sandreas.sandberg@arm.com ScalarPrint print; 26611986Sandreas.sandberg@arm.com print.name = name; 26711986Sandreas.sandberg@arm.com print.desc = desc; 26811986Sandreas.sandberg@arm.com print.precision = precision; 26911986Sandreas.sandberg@arm.com print.descriptions = descriptions; 27011986Sandreas.sandberg@arm.com print.flags = flags; 27111986Sandreas.sandberg@arm.com print.pdf = _total ? 0.0 : NAN; 27211986Sandreas.sandberg@arm.com print.cdf = _total ? 0.0 : NAN; 27311986Sandreas.sandberg@arm.com 27411986Sandreas.sandberg@arm.com bool havesub = !subnames.empty(); 27511986Sandreas.sandberg@arm.com 27611986Sandreas.sandberg@arm.com if (_size == 1) { 27711986Sandreas.sandberg@arm.com print.value = vec[0]; 27811986Sandreas.sandberg@arm.com print(stream); 27911986Sandreas.sandberg@arm.com return; 28011986Sandreas.sandberg@arm.com } 28111986Sandreas.sandberg@arm.com 28211986Sandreas.sandberg@arm.com for (off_type i = 0; i < _size; ++i) { 28311986Sandreas.sandberg@arm.com if (havesub && (i >= subnames.size() || subnames[i].empty())) 28411986Sandreas.sandberg@arm.com continue; 28511986Sandreas.sandberg@arm.com 28611986Sandreas.sandberg@arm.com print.name = base + (havesub ? subnames[i] : to_string(i)); 28711986Sandreas.sandberg@arm.com print.desc = subdescs.empty() ? desc : subdescs[i]; 28811986Sandreas.sandberg@arm.com 28911986Sandreas.sandberg@arm.com print.update(vec[i], _total); 29011986Sandreas.sandberg@arm.com print(stream); 29111986Sandreas.sandberg@arm.com } 29211986Sandreas.sandberg@arm.com 29311986Sandreas.sandberg@arm.com if (flags.isSet(::Stats::total)) { 29411986Sandreas.sandberg@arm.com print.pdf = NAN; 29511986Sandreas.sandberg@arm.com print.cdf = NAN; 29611986Sandreas.sandberg@arm.com print.name = base + "total"; 29711986Sandreas.sandberg@arm.com print.desc = desc; 29811986Sandreas.sandberg@arm.com print.value = total; 29911986Sandreas.sandberg@arm.com print(stream); 30011986Sandreas.sandberg@arm.com } 30111986Sandreas.sandberg@arm.com} 30211986Sandreas.sandberg@arm.com 30311986Sandreas.sandberg@arm.comstruct DistPrint 30411986Sandreas.sandberg@arm.com{ 30511986Sandreas.sandberg@arm.com string name; 30611986Sandreas.sandberg@arm.com string separatorString; 30711986Sandreas.sandberg@arm.com string desc; 30812037Sandreas.sandberg@arm.com Flags flags; 30912037Sandreas.sandberg@arm.com bool descriptions; 31012037Sandreas.sandberg@arm.com int precision; 31112037Sandreas.sandberg@arm.com 31212037Sandreas.sandberg@arm.com const DistData &data; 31312037Sandreas.sandberg@arm.com 31412037Sandreas.sandberg@arm.com DistPrint(const Text *text, const DistInfo &info); 31512037Sandreas.sandberg@arm.com DistPrint(const Text *text, const VectorDistInfo &info, int i); 31612037Sandreas.sandberg@arm.com void init(const Text *text, const Info &info); 31712037Sandreas.sandberg@arm.com void operator()(ostream &stream) const; 31812037Sandreas.sandberg@arm.com}; 31912037Sandreas.sandberg@arm.com 32012037Sandreas.sandberg@arm.comDistPrint::DistPrint(const Text *text, const DistInfo &info) 32112037Sandreas.sandberg@arm.com : data(info.data) 32212037Sandreas.sandberg@arm.com{ 32312037Sandreas.sandberg@arm.com init(text, info); 32412037Sandreas.sandberg@arm.com} 32512037Sandreas.sandberg@arm.com 32612037Sandreas.sandberg@arm.comDistPrint::DistPrint(const Text *text, const VectorDistInfo &info, int i) 32712037Sandreas.sandberg@arm.com : data(info.data[i]) 32812037Sandreas.sandberg@arm.com{ 32912037Sandreas.sandberg@arm.com init(text, info); 33012037Sandreas.sandberg@arm.com 33112037Sandreas.sandberg@arm.com name = info.name + "_" + 33212037Sandreas.sandberg@arm.com (info.subnames[i].empty() ? (to_string(i)) : info.subnames[i]); 33312037Sandreas.sandberg@arm.com 33412037Sandreas.sandberg@arm.com if (!info.subdescs[i].empty()) 33512037Sandreas.sandberg@arm.com desc = info.subdescs[i]; 33612037Sandreas.sandberg@arm.com} 33712037Sandreas.sandberg@arm.com 33812037Sandreas.sandberg@arm.comvoid 33912037Sandreas.sandberg@arm.comDistPrint::init(const Text *text, const Info &info) 34012037Sandreas.sandberg@arm.com{ 34112037Sandreas.sandberg@arm.com name = info.name; 34212037Sandreas.sandberg@arm.com separatorString = info.separatorString; 34312037Sandreas.sandberg@arm.com desc = info.desc; 34412037Sandreas.sandberg@arm.com flags = info.flags; 34512037Sandreas.sandberg@arm.com precision = info.precision; 34612037Sandreas.sandberg@arm.com descriptions = text->descriptions; 34712037Sandreas.sandberg@arm.com} 34812037Sandreas.sandberg@arm.com 34912037Sandreas.sandberg@arm.comvoid 35012037Sandreas.sandberg@arm.comDistPrint::operator()(ostream &stream) const 35112037Sandreas.sandberg@arm.com{ 35212037Sandreas.sandberg@arm.com string base = name + separatorString; 35312037Sandreas.sandberg@arm.com 35412037Sandreas.sandberg@arm.com ScalarPrint print; 35512037Sandreas.sandberg@arm.com print.precision = precision; 35612037Sandreas.sandberg@arm.com print.flags = flags; 35712037Sandreas.sandberg@arm.com print.descriptions = descriptions; 35812037Sandreas.sandberg@arm.com print.desc = desc; 35912037Sandreas.sandberg@arm.com print.pdf = NAN; 36012037Sandreas.sandberg@arm.com print.cdf = NAN; 36112037Sandreas.sandberg@arm.com 36212037Sandreas.sandberg@arm.com print.name = base + "samples"; 36312037Sandreas.sandberg@arm.com print.value = data.samples; 36412037Sandreas.sandberg@arm.com print(stream); 36512037Sandreas.sandberg@arm.com 36612037Sandreas.sandberg@arm.com print.name = base + "mean"; 36712037Sandreas.sandberg@arm.com print.value = data.samples ? data.sum / data.samples : NAN; 36812037Sandreas.sandberg@arm.com print(stream); 36912037Sandreas.sandberg@arm.com 37012037Sandreas.sandberg@arm.com if (data.type == Hist) { 37112037Sandreas.sandberg@arm.com print.name = base + "gmean"; 37212037Sandreas.sandberg@arm.com print.value = data.samples ? exp(data.logs / data.samples) : NAN; 37312037Sandreas.sandberg@arm.com print(stream); 37412037Sandreas.sandberg@arm.com } 37512037Sandreas.sandberg@arm.com 37612037Sandreas.sandberg@arm.com Result stdev = NAN; 37712037Sandreas.sandberg@arm.com if (data.samples) 37812037Sandreas.sandberg@arm.com stdev = sqrt((data.samples * data.squares - data.sum * data.sum) / 37912037Sandreas.sandberg@arm.com (data.samples * (data.samples - 1.0))); 380 print.name = base + "stdev"; 381 print.value = stdev; 382 print(stream); 383 384 if (data.type == Deviation) 385 return; 386 387 size_t size = data.cvec.size(); 388 389 Result total = 0.0; 390 if (data.type == Dist && data.underflow != NAN) 391 total += data.underflow; 392 for (off_type i = 0; i < size; ++i) 393 total += data.cvec[i]; 394 if (data.type == Dist && data.overflow != NAN) 395 total += data.overflow; 396 397 if (total) { 398 print.pdf = 0.0; 399 print.cdf = 0.0; 400 } 401 402 if (data.type == Dist && data.underflow != NAN) { 403 print.name = base + "underflows"; 404 print.update(data.underflow, total); 405 print(stream); 406 } 407 408 for (off_type i = 0; i < size; ++i) { 409 stringstream namestr; 410 namestr << base; 411 412 Counter low = i * data.bucket_size + data.min; 413 Counter high = ::min(low + data.bucket_size - 1.0, data.max); 414 namestr << low; 415 if (low < high) 416 namestr << "-" << high; 417 418 print.name = namestr.str(); 419 print.update(data.cvec[i], total); 420 print(stream); 421 } 422 423 if (data.type == Dist && data.overflow != NAN) { 424 print.name = base + "overflows"; 425 print.update(data.overflow, total); 426 print(stream); 427 } 428 429 print.pdf = NAN; 430 print.cdf = NAN; 431 432 if (data.type == Dist && data.min_val != NAN) { 433 print.name = base + "min_value"; 434 print.value = data.min_val; 435 print(stream); 436 } 437 438 if (data.type == Dist && data.max_val != NAN) { 439 print.name = base + "max_value"; 440 print.value = data.max_val; 441 print(stream); 442 } 443 444 print.name = base + "total"; 445 print.value = total; 446 print(stream); 447} 448 449void 450Text::visit(const ScalarInfo &info) 451{ 452 if (noOutput(info)) 453 return; 454 455 ScalarPrint print; 456 print.value = info.result(); 457 print.name = info.name; 458 print.desc = info.desc; 459 print.flags = info.flags; 460 print.descriptions = descriptions; 461 print.precision = info.precision; 462 print.pdf = NAN; 463 print.cdf = NAN; 464 465 print(*stream); 466} 467 468void 469Text::visit(const VectorInfo &info) 470{ 471 if (noOutput(info)) 472 return; 473 474 size_type size = info.size(); 475 VectorPrint print; 476 477 print.name = info.name; 478 print.separatorString = info.separatorString; 479 print.desc = info.desc; 480 print.flags = info.flags; 481 print.descriptions = descriptions; 482 print.precision = info.precision; 483 print.vec = info.result(); 484 print.total = info.total(); 485 486 if (!info.subnames.empty()) { 487 for (off_type i = 0; i < size; ++i) { 488 if (!info.subnames[i].empty()) { 489 print.subnames = info.subnames; 490 print.subnames.resize(size); 491 for (off_type i = 0; i < size; ++i) { 492 if (!info.subnames[i].empty() && 493 !info.subdescs[i].empty()) { 494 print.subdescs = info.subdescs; 495 print.subdescs.resize(size); 496 break; 497 } 498 } 499 break; 500 } 501 } 502 } 503 504 print(*stream); 505} 506 507void 508Text::visit(const Vector2dInfo &info) 509{ 510 if (noOutput(info)) 511 return; 512 513 bool havesub = false; 514 VectorPrint print; 515 516 if (!info.y_subnames.empty()) { 517 for (off_type i = 0; i < info.y; ++i) { 518 if (!info.y_subnames[i].empty()) { 519 print.subnames = info.y_subnames; 520 } 521 break; 522 } 523 } 524 print.flags = info.flags; 525 print.separatorString = info.separatorString; 526 print.descriptions = descriptions; 527 print.precision = info.precision; 528 529 if (!info.subnames.empty()) { 530 for (off_type i = 0; i < info.x; ++i) 531 if (!info.subnames[i].empty()) 532 havesub = true; 533 } 534 535 VResult tot_vec(info.y); 536 Result super_total = 0.0; 537 for (off_type i = 0; i < info.x; ++i) { 538 if (havesub && (i >= info.subnames.size() || info.subnames[i].empty())) 539 continue; 540 541 off_type iy = i * info.y; 542 VResult yvec(info.y); 543 544 Result total = 0.0; 545 for (off_type j = 0; j < info.y; ++j) { 546 yvec[j] = info.cvec[iy + j]; 547 tot_vec[j] += yvec[j]; 548 total += yvec[j]; 549 super_total += yvec[j]; 550 } 551 552 print.name = info.name + "_" + 553 (havesub ? info.subnames[i] : to_string(i)); 554 print.desc = info.desc; 555 print.vec = yvec; 556 print.total = total; 557 print(*stream); 558 } 559 560 if (info.flags.isSet(::Stats::total) && (info.x > 1)) { 561 print.name = info.name; 562 print.desc = info.desc; 563 print.vec = tot_vec; 564 print.total = super_total; 565 print(*stream); 566 } 567} 568 569void 570Text::visit(const DistInfo &info) 571{ 572 if (noOutput(info)) 573 return; 574 575 DistPrint print(this, info); 576 print(*stream); 577} 578 579void 580Text::visit(const VectorDistInfo &info) 581{ 582 if (noOutput(info)) 583 return; 584 585 for (off_type i = 0; i < info.size(); ++i) { 586 DistPrint print(this, info, i); 587 print(*stream); 588 } 589} 590 591void 592Text::visit(const FormulaInfo &info) 593{ 594 visit((const VectorInfo &)info); 595} 596 597/* 598 This struct implements the output methods for the sparse 599 histogram stat 600*/ 601struct SparseHistPrint 602{ 603 string name; 604 string separatorString; 605 string desc; 606 Flags flags; 607 bool descriptions; 608 int precision; 609 610 const SparseHistData &data; 611 612 SparseHistPrint(const Text *text, const SparseHistInfo &info); 613 void init(const Text *text, const Info &info); 614 void operator()(ostream &stream) const; 615}; 616 617/* Call initialization function */ 618SparseHistPrint::SparseHistPrint(const Text *text, const SparseHistInfo &info) 619 : data(info.data) 620{ 621 init(text, info); 622} 623 624/* Initialization function */ 625void 626SparseHistPrint::init(const Text *text, const Info &info) 627{ 628 name = info.name; 629 separatorString = info.separatorString; 630 desc = info.desc; 631 flags = info.flags; 632 precision = info.precision; 633 descriptions = text->descriptions; 634} 635 636/* Grab data from map and write to output stream */ 637void 638SparseHistPrint::operator()(ostream &stream) const 639{ 640 string base = name + separatorString; 641 642 ScalarPrint print; 643 print.precision = precision; 644 print.flags = flags; 645 print.descriptions = descriptions; 646 print.desc = desc; 647 print.pdf = NAN; 648 print.cdf = NAN; 649 650 print.name = base + "samples"; 651 print.value = data.samples; 652 print(stream); 653 654 MCounter::const_iterator it; 655 for (it = data.cmap.begin(); it != data.cmap.end(); it++) { 656 stringstream namestr; 657 namestr << base; 658 659 namestr <<(*it).first; 660 print.name = namestr.str(); 661 print.value = (*it).second; 662 print(stream); 663 } 664 665 print.pdf = NAN; 666 print.cdf = NAN; 667 668 print.name = base + "total"; 669 print.value = total; 670 print(stream); 671} 672 673void 674Text::visit(const SparseHistInfo &info) 675{ 676 if (noOutput(info)) 677 return; 678 679 SparseHistPrint print(this, info); 680 print(*stream); 681} 682 683Output * 684initText(const string &filename, bool desc) 685{ 686 static Text text; 687 static bool connected = false; 688 689 if (!connected) { 690 ostream *os = simout.find(filename); 691 if (!os) 692 os = simout.create(filename); 693 694 text.open(*os); 695 text.descriptions = desc; 696 connected = true; 697 } 698 699 return &text; 700} 701 702} // namespace Stats 703