text.cc revision 8667
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) 368230Snate@binkert.org#include <math.h> 373918Ssaidi@eecs.umich.edu#endif 383918Ssaidi@eecs.umich.edu 396129Snate@binkert.org#include <cassert> 406129Snate@binkert.org#ifdef __SUNPRO_CC 418230Snate@binkert.org#include <math.h> 426129Snate@binkert.org#endif 436129Snate@binkert.org#include <cmath> 448229Snate@binkert.org#include <fstream> 45695SN/A#include <iostream> 462621SN/A#include <sstream> 47695SN/A#include <string> 48695SN/A 498229Snate@binkert.org#include "base/stats/info.hh" 508229Snate@binkert.org#include "base/stats/text.hh" 516129Snate@binkert.org#include "base/cast.hh" 52695SN/A#include "base/misc.hh" 536129Snate@binkert.org#include "base/str.hh" 54695SN/A 55695SN/Ausing namespace std; 56695SN/A 57695SN/A#ifndef NAN 58695SN/Afloat __nan(); 59695SN/A/** Define Not a number. */ 60695SN/A#define NAN (__nan()) 61695SN/A/** Need to define __nan() */ 62695SN/A#define __M5_NAN 63695SN/A#endif 64695SN/A 65695SN/A#ifdef __M5_NAN 66695SN/Afloat 67695SN/A__nan() 68695SN/A{ 69695SN/A union { 70695SN/A uint32_t ui; 71695SN/A float f; 72695SN/A } nan; 73695SN/A 74695SN/A nan.ui = 0x7fc00000; 75695SN/A return nan.f; 76695SN/A} 77695SN/A#endif 78695SN/A 79729SN/Anamespace Stats { 80695SN/A 816129Snate@binkert.orgstd::list<Info *> &statsList(); 826129Snate@binkert.org 83695SN/AText::Text() 846126Snate@binkert.org : mystream(false), stream(NULL), descriptions(false) 85695SN/A{ 86695SN/A} 87695SN/A 88695SN/AText::Text(std::ostream &stream) 896126Snate@binkert.org : mystream(false), stream(NULL), descriptions(false) 90695SN/A{ 91695SN/A open(stream); 92695SN/A} 93695SN/A 94695SN/AText::Text(const std::string &file) 956126Snate@binkert.org : mystream(false), stream(NULL), descriptions(false) 96695SN/A{ 97695SN/A open(file); 98695SN/A} 99695SN/A 100695SN/A 101695SN/AText::~Text() 102695SN/A{ 103695SN/A if (mystream) { 104695SN/A assert(stream); 105695SN/A delete stream; 106695SN/A } 107695SN/A} 108695SN/A 109695SN/Avoid 110695SN/AText::open(std::ostream &_stream) 111695SN/A{ 112695SN/A if (stream) 113695SN/A panic("stream already set!"); 114695SN/A 115695SN/A mystream = false; 116695SN/A stream = &_stream; 1175581Ssaidi@eecs.umich.edu if (!valid()) 1185581Ssaidi@eecs.umich.edu fatal("Unable to open output stream for writing\n"); 119695SN/A} 120695SN/A 121695SN/Avoid 122695SN/AText::open(const std::string &file) 123695SN/A{ 124695SN/A if (stream) 125695SN/A panic("stream already set!"); 126695SN/A 127695SN/A mystream = true; 128695SN/A stream = new ofstream(file.c_str(), ios::trunc); 1295581Ssaidi@eecs.umich.edu if (!valid()) 1305581Ssaidi@eecs.umich.edu fatal("Unable to open statistics file for writing\n"); 131695SN/A} 132695SN/A 133695SN/Abool 134695SN/AText::valid() const 135695SN/A{ 1365581Ssaidi@eecs.umich.edu return stream != NULL && stream->good(); 137695SN/A} 138695SN/A 139695SN/Avoid 1408296Snate@binkert.orgText::begin() 141695SN/A{ 142695SN/A ccprintf(*stream, "\n---------- Begin Simulation Statistics ----------\n"); 1438296Snate@binkert.org} 1448296Snate@binkert.org 1458296Snate@binkert.orgvoid 1468296Snate@binkert.orgText::end() 1478296Snate@binkert.org{ 148695SN/A ccprintf(*stream, "\n---------- End Simulation Statistics ----------\n"); 149695SN/A stream->flush(); 150695SN/A} 151695SN/A 152695SN/Abool 1535886Snate@binkert.orgText::noOutput(const Info &info) 154695SN/A{ 1557462Snate@binkert.org if (!info.flags.isSet(display)) 156695SN/A return true; 157695SN/A 1585886Snate@binkert.org if (info.prereq && info.prereq->zero()) 159695SN/A return true; 160695SN/A 161695SN/A return false; 162695SN/A} 163695SN/A 164695SN/Astring 1656126Snate@binkert.orgValueToString(Result value, int precision) 166695SN/A{ 167695SN/A stringstream val; 168695SN/A 169695SN/A if (!isnan(value)) { 170695SN/A if (precision != -1) 171695SN/A val.precision(precision); 172695SN/A else if (value == rint(value)) 173695SN/A val.precision(0); 174695SN/A 175695SN/A val.unsetf(ios::showpoint); 176695SN/A val.setf(ios::fixed); 177695SN/A val << value; 178695SN/A } else { 1796126Snate@binkert.org val << "no_value"; 180695SN/A } 181695SN/A 182695SN/A return val.str(); 183695SN/A} 184695SN/A 185695SN/Astruct ScalarPrint 186695SN/A{ 187695SN/A Result value; 188695SN/A string name; 189695SN/A string desc; 1906130Snate@binkert.org Flags flags; 191695SN/A bool descriptions; 192695SN/A int precision; 193695SN/A Result pdf; 194695SN/A Result cdf; 195695SN/A 1966211Snate@binkert.org void update(Result val, Result total); 197695SN/A void operator()(ostream &stream) const; 198695SN/A}; 199695SN/A 200695SN/Avoid 2016211Snate@binkert.orgScalarPrint::update(Result val, Result total) 2026211Snate@binkert.org{ 2036211Snate@binkert.org value = val; 2046211Snate@binkert.org if (total) { 2056211Snate@binkert.org pdf = val / total; 2066211Snate@binkert.org cdf += pdf; 2076211Snate@binkert.org } 2086211Snate@binkert.org} 2096211Snate@binkert.org 2106211Snate@binkert.orgvoid 211695SN/AScalarPrint::operator()(ostream &stream) const 212695SN/A{ 2136130Snate@binkert.org if ((flags.isSet(nozero) && value == 0.0) || 2146130Snate@binkert.org (flags.isSet(nonan) && isnan(value))) 215695SN/A return; 216695SN/A 217695SN/A stringstream pdfstr, cdfstr; 218695SN/A 219695SN/A if (!isnan(pdf)) 220695SN/A ccprintf(pdfstr, "%.2f%%", pdf * 100.0); 221695SN/A 222695SN/A if (!isnan(cdf)) 223695SN/A ccprintf(cdfstr, "%.2f%%", cdf * 100.0); 224695SN/A 2256126Snate@binkert.org ccprintf(stream, "%-40s %12s %10s %10s", name, 2266126Snate@binkert.org ValueToString(value, precision), pdfstr, cdfstr); 227695SN/A 228695SN/A if (descriptions) { 229695SN/A if (!desc.empty()) 230695SN/A ccprintf(stream, " # %s", desc); 231695SN/A } 232695SN/A stream << endl; 233695SN/A} 234695SN/A 235695SN/Astruct VectorPrint 236695SN/A{ 237695SN/A string name; 2388243Sbradley.danofsky@amd.com string separatorString; 239695SN/A string desc; 240695SN/A vector<string> subnames; 241695SN/A vector<string> subdescs; 2426130Snate@binkert.org Flags flags; 243695SN/A bool descriptions; 244695SN/A int precision; 245695SN/A VResult vec; 246695SN/A Result total; 247695SN/A 248695SN/A void operator()(ostream &stream) const; 249695SN/A}; 250695SN/A 251695SN/Avoid 252695SN/AVectorPrint::operator()(std::ostream &stream) const 253695SN/A{ 2545599Snate@binkert.org size_type _size = vec.size(); 255695SN/A Result _total = 0.0; 256695SN/A 2576130Snate@binkert.org if (flags.isSet(pdf | cdf)) { 2585599Snate@binkert.org for (off_type i = 0; i < _size; ++i) { 259695SN/A _total += vec[i]; 260695SN/A } 261695SN/A } 262695SN/A 2638243Sbradley.danofsky@amd.com string base = name + separatorString; 264695SN/A 265695SN/A ScalarPrint print; 266695SN/A print.name = name; 267695SN/A print.desc = desc; 268695SN/A print.precision = precision; 269695SN/A print.descriptions = descriptions; 270695SN/A print.flags = flags; 2716211Snate@binkert.org print.pdf = _total ? 0.0 : NAN; 2726211Snate@binkert.org print.cdf = _total ? 0.0 : NAN; 273695SN/A 274695SN/A bool havesub = !subnames.empty(); 275695SN/A 276695SN/A if (_size == 1) { 277695SN/A print.value = vec[0]; 278695SN/A print(stream); 2796126Snate@binkert.org return; 2806126Snate@binkert.org } 281695SN/A 2826126Snate@binkert.org for (off_type i = 0; i < _size; ++i) { 2836126Snate@binkert.org if (havesub && (i >= subnames.size() || subnames[i].empty())) 2846126Snate@binkert.org continue; 285695SN/A 2866126Snate@binkert.org print.name = base + (havesub ? subnames[i] : to_string(i)); 2876126Snate@binkert.org print.desc = subdescs.empty() ? desc : subdescs[i]; 288695SN/A 2896211Snate@binkert.org print.update(vec[i], _total); 2906126Snate@binkert.org print(stream); 2916126Snate@binkert.org } 292695SN/A 2936130Snate@binkert.org if (flags.isSet(::Stats::total)) { 2946126Snate@binkert.org print.pdf = NAN; 2956126Snate@binkert.org print.cdf = NAN; 2966126Snate@binkert.org print.name = base + "total"; 2976126Snate@binkert.org print.desc = desc; 2986126Snate@binkert.org print.value = total; 2996126Snate@binkert.org print(stream); 300695SN/A } 301695SN/A} 302695SN/A 303695SN/Astruct DistPrint 304695SN/A{ 305695SN/A string name; 3068243Sbradley.danofsky@amd.com string separatorString; 307695SN/A string desc; 3086130Snate@binkert.org Flags flags; 309695SN/A bool descriptions; 310695SN/A int precision; 311695SN/A 3126004Snate@binkert.org const DistData &data; 3136004Snate@binkert.org 3146128Snate@binkert.org DistPrint(const Text *text, const DistInfo &info); 3156128Snate@binkert.org DistPrint(const Text *text, const VectorDistInfo &info, int i); 3167505Snate@binkert.org void init(const Text *text, const Info &info); 317695SN/A void operator()(ostream &stream) const; 318695SN/A}; 319695SN/A 3206128Snate@binkert.orgDistPrint::DistPrint(const Text *text, const DistInfo &info) 3216004Snate@binkert.org : data(info.data) 3226004Snate@binkert.org{ 3237505Snate@binkert.org init(text, info); 3246004Snate@binkert.org} 3256004Snate@binkert.org 3266128Snate@binkert.orgDistPrint::DistPrint(const Text *text, const VectorDistInfo &info, int i) 3276004Snate@binkert.org : data(info.data[i]) 3286004Snate@binkert.org{ 3297505Snate@binkert.org init(text, info); 3306004Snate@binkert.org 3316004Snate@binkert.org name = info.name + "_" + 3326004Snate@binkert.org (info.subnames[i].empty() ? (to_string(i)) : info.subnames[i]); 3336004Snate@binkert.org 3346004Snate@binkert.org if (!info.subdescs[i].empty()) 3356004Snate@binkert.org desc = info.subdescs[i]; 3366004Snate@binkert.org} 3376004Snate@binkert.org 3386004Snate@binkert.orgvoid 3397505Snate@binkert.orgDistPrint::init(const Text *text, const Info &info) 3406004Snate@binkert.org{ 3416004Snate@binkert.org name = info.name; 3428243Sbradley.danofsky@amd.com separatorString = info.separatorString; 3436004Snate@binkert.org desc = info.desc; 3446004Snate@binkert.org flags = info.flags; 3456004Snate@binkert.org precision = info.precision; 3466125Snate@binkert.org descriptions = text->descriptions; 3476004Snate@binkert.org} 3486004Snate@binkert.org 349695SN/Avoid 350695SN/ADistPrint::operator()(ostream &stream) const 351695SN/A{ 3528243Sbradley.danofsky@amd.com string base = name + separatorString; 353695SN/A 354695SN/A ScalarPrint print; 3556211Snate@binkert.org print.precision = precision; 356695SN/A print.flags = flags; 357695SN/A print.descriptions = descriptions; 3586211Snate@binkert.org print.desc = desc; 359695SN/A print.pdf = NAN; 360695SN/A print.cdf = NAN; 361695SN/A 362695SN/A print.name = base + "samples"; 3636004Snate@binkert.org print.value = data.samples; 364695SN/A print(stream); 365695SN/A 3666211Snate@binkert.org print.name = base + "mean"; 3676211Snate@binkert.org print.value = data.samples ? data.sum / data.samples : NAN; 368695SN/A print(stream); 369695SN/A 3708666SPrakash.Ramrakhyani@arm.com if (data.type == Hist) { 3718666SPrakash.Ramrakhyani@arm.com print.name = base + "gmean"; 3728666SPrakash.Ramrakhyani@arm.com print.value = data.samples ? exp(data.logs / data.samples) : NAN; 3738666SPrakash.Ramrakhyani@arm.com print(stream); 3748666SPrakash.Ramrakhyani@arm.com } 3758666SPrakash.Ramrakhyani@arm.com 3766211Snate@binkert.org Result stdev = NAN; 3776211Snate@binkert.org if (data.samples) 3786211Snate@binkert.org stdev = sqrt((data.samples * data.squares - data.sum * data.sum) / 3796211Snate@binkert.org (data.samples * (data.samples - 1.0))); 3806211Snate@binkert.org print.name = base + "stdev"; 3816211Snate@binkert.org print.value = stdev; 3826211Snate@binkert.org print(stream); 3836211Snate@binkert.org 3847505Snate@binkert.org if (data.type == Deviation) 3856211Snate@binkert.org return; 3866211Snate@binkert.org 3877505Snate@binkert.org size_t size = data.cvec.size(); 3886211Snate@binkert.org 3896211Snate@binkert.org Result total = 0.0; 3907831Snate@binkert.org if (data.type == Dist && data.underflow != NAN) 3916211Snate@binkert.org total += data.underflow; 3926211Snate@binkert.org for (off_type i = 0; i < size; ++i) 3936211Snate@binkert.org total += data.cvec[i]; 3947831Snate@binkert.org if (data.type == Dist && data.overflow != NAN) 3956211Snate@binkert.org total += data.overflow; 3966211Snate@binkert.org 3976126Snate@binkert.org if (total) { 3986211Snate@binkert.org print.pdf = 0.0; 3996211Snate@binkert.org print.cdf = 0.0; 4006126Snate@binkert.org } 4016211Snate@binkert.org 4027831Snate@binkert.org if (data.type == Dist && data.underflow != NAN) { 4036211Snate@binkert.org print.name = base + "underflows"; 4046211Snate@binkert.org print.update(data.underflow, total); 4056211Snate@binkert.org print(stream); 4066211Snate@binkert.org } 4076126Snate@binkert.org 4086126Snate@binkert.org for (off_type i = 0; i < size; ++i) { 4096126Snate@binkert.org stringstream namestr; 4106126Snate@binkert.org namestr << base; 4116126Snate@binkert.org 4127505Snate@binkert.org Counter low = i * data.bucket_size + data.min; 4137505Snate@binkert.org Counter high = ::min(low + data.bucket_size - 1.0, data.max); 4146126Snate@binkert.org namestr << low; 4156126Snate@binkert.org if (low < high) 4166126Snate@binkert.org namestr << "-" << high; 4176126Snate@binkert.org 4186126Snate@binkert.org print.name = namestr.str(); 4196211Snate@binkert.org print.update(data.cvec[i], total); 420695SN/A print(stream); 421695SN/A } 422695SN/A 4237831Snate@binkert.org if (data.type == Dist && data.overflow != NAN) { 4246211Snate@binkert.org print.name = base + "overflows"; 4256211Snate@binkert.org print.update(data.overflow, total); 4266211Snate@binkert.org print(stream); 427695SN/A } 428695SN/A 429695SN/A print.pdf = NAN; 430695SN/A print.cdf = NAN; 431695SN/A 4327831Snate@binkert.org if (data.type == Dist && data.min_val != NAN) { 4336211Snate@binkert.org print.name = base + "min_value"; 4346211Snate@binkert.org print.value = data.min_val; 4356211Snate@binkert.org print(stream); 4366211Snate@binkert.org } 4376211Snate@binkert.org 4387831Snate@binkert.org if (data.type == Dist && data.max_val != NAN) { 4396211Snate@binkert.org print.name = base + "max_value"; 4406211Snate@binkert.org print.value = data.max_val; 4416211Snate@binkert.org print(stream); 4426211Snate@binkert.org } 4436211Snate@binkert.org 4446126Snate@binkert.org print.name = base + "total"; 4456126Snate@binkert.org print.value = total; 4466126Snate@binkert.org print(stream); 447695SN/A} 448695SN/A 449695SN/Avoid 4506128Snate@binkert.orgText::visit(const ScalarInfo &info) 451695SN/A{ 4525886Snate@binkert.org if (noOutput(info)) 453695SN/A return; 454695SN/A 455695SN/A ScalarPrint print; 4565886Snate@binkert.org print.value = info.result(); 4575886Snate@binkert.org print.name = info.name; 4585886Snate@binkert.org print.desc = info.desc; 4595886Snate@binkert.org print.flags = info.flags; 460695SN/A print.descriptions = descriptions; 4615886Snate@binkert.org print.precision = info.precision; 462695SN/A print.pdf = NAN; 463695SN/A print.cdf = NAN; 464695SN/A 465695SN/A print(*stream); 466695SN/A} 467695SN/A 468695SN/Avoid 4696128Snate@binkert.orgText::visit(const VectorInfo &info) 470695SN/A{ 4715886Snate@binkert.org if (noOutput(info)) 472695SN/A return; 473695SN/A 4745886Snate@binkert.org size_type size = info.size(); 475695SN/A VectorPrint print; 476695SN/A 4775886Snate@binkert.org print.name = info.name; 4788243Sbradley.danofsky@amd.com print.separatorString = info.separatorString; 4795886Snate@binkert.org print.desc = info.desc; 4805886Snate@binkert.org print.flags = info.flags; 481695SN/A print.descriptions = descriptions; 4825886Snate@binkert.org print.precision = info.precision; 4835886Snate@binkert.org print.vec = info.result(); 4845886Snate@binkert.org print.total = info.total(); 485695SN/A 4865886Snate@binkert.org if (!info.subnames.empty()) { 4875599Snate@binkert.org for (off_type i = 0; i < size; ++i) { 4885886Snate@binkert.org if (!info.subnames[i].empty()) { 4895886Snate@binkert.org print.subnames = info.subnames; 490695SN/A print.subnames.resize(size); 4915599Snate@binkert.org for (off_type i = 0; i < size; ++i) { 4925886Snate@binkert.org if (!info.subnames[i].empty() && 4935886Snate@binkert.org !info.subdescs[i].empty()) { 4945886Snate@binkert.org print.subdescs = info.subdescs; 495695SN/A print.subdescs.resize(size); 496695SN/A break; 497695SN/A } 498695SN/A } 499695SN/A break; 500695SN/A } 501695SN/A } 502695SN/A } 503695SN/A 504695SN/A print(*stream); 505695SN/A} 506695SN/A 507695SN/Avoid 5086128Snate@binkert.orgText::visit(const Vector2dInfo &info) 509695SN/A{ 5105886Snate@binkert.org if (noOutput(info)) 511695SN/A return; 512695SN/A 513695SN/A bool havesub = false; 514695SN/A VectorPrint print; 515695SN/A 5168667Sdam.sunwoo@arm.com if (!info.y_subnames.empty()) { 5178667Sdam.sunwoo@arm.com for (off_type i = 0; i < info.y; ++i) { 5188667Sdam.sunwoo@arm.com if (!info.y_subnames[i].empty()) { 5198667Sdam.sunwoo@arm.com print.subnames = info.y_subnames; 5208667Sdam.sunwoo@arm.com } 5218667Sdam.sunwoo@arm.com break; 5228667Sdam.sunwoo@arm.com } 5238667Sdam.sunwoo@arm.com } 5245886Snate@binkert.org print.flags = info.flags; 5258243Sbradley.danofsky@amd.com print.separatorString = info.separatorString; 526695SN/A print.descriptions = descriptions; 5275886Snate@binkert.org print.precision = info.precision; 528695SN/A 5295886Snate@binkert.org if (!info.subnames.empty()) { 5305886Snate@binkert.org for (off_type i = 0; i < info.x; ++i) 5315886Snate@binkert.org if (!info.subnames[i].empty()) 532695SN/A havesub = true; 533695SN/A } 534695SN/A 5355886Snate@binkert.org VResult tot_vec(info.y); 536695SN/A Result super_total = 0.0; 5375886Snate@binkert.org for (off_type i = 0; i < info.x; ++i) { 5385886Snate@binkert.org if (havesub && (i >= info.subnames.size() || info.subnames[i].empty())) 539695SN/A continue; 540695SN/A 5415886Snate@binkert.org off_type iy = i * info.y; 5425886Snate@binkert.org VResult yvec(info.y); 543695SN/A 544695SN/A Result total = 0.0; 5455886Snate@binkert.org for (off_type j = 0; j < info.y; ++j) { 5465886Snate@binkert.org yvec[j] = info.cvec[iy + j]; 547695SN/A tot_vec[j] += yvec[j]; 548695SN/A total += yvec[j]; 549695SN/A super_total += yvec[j]; 550695SN/A } 551695SN/A 5525886Snate@binkert.org print.name = info.name + "_" + 5535886Snate@binkert.org (havesub ? info.subnames[i] : to_string(i)); 5545886Snate@binkert.org print.desc = info.desc; 555695SN/A print.vec = yvec; 556695SN/A print.total = total; 557695SN/A print(*stream); 558695SN/A } 559695SN/A 5606130Snate@binkert.org if (info.flags.isSet(::Stats::total) && (info.x > 1)) { 5615886Snate@binkert.org print.name = info.name; 5625886Snate@binkert.org print.desc = info.desc; 563695SN/A print.vec = tot_vec; 564695SN/A print.total = super_total; 565695SN/A print(*stream); 566695SN/A } 567695SN/A} 568695SN/A 569695SN/Avoid 5706128Snate@binkert.orgText::visit(const DistInfo &info) 571695SN/A{ 5725886Snate@binkert.org if (noOutput(info)) 573695SN/A return; 574695SN/A 5756125Snate@binkert.org DistPrint print(this, info); 576695SN/A print(*stream); 577695SN/A} 578695SN/A 579695SN/Avoid 5806128Snate@binkert.orgText::visit(const VectorDistInfo &info) 581695SN/A{ 5825886Snate@binkert.org if (noOutput(info)) 583695SN/A return; 584695SN/A 5855886Snate@binkert.org for (off_type i = 0; i < info.size(); ++i) { 5866125Snate@binkert.org DistPrint print(this, info, i); 587695SN/A print(*stream); 588695SN/A } 589695SN/A} 590695SN/A 591695SN/Avoid 5926128Snate@binkert.orgText::visit(const FormulaInfo &info) 593695SN/A{ 5946128Snate@binkert.org visit((const VectorInfo &)info); 595695SN/A} 596695SN/A 5978514SThomas.Grass@ARM.com/* 5988514SThomas.Grass@ARM.com This struct implements the output methods for the sparse 5998514SThomas.Grass@ARM.com histogram stat 6008514SThomas.Grass@ARM.com*/ 6018514SThomas.Grass@ARM.comstruct SparseHistPrint 6028514SThomas.Grass@ARM.com{ 6038514SThomas.Grass@ARM.com string name; 6048514SThomas.Grass@ARM.com string separatorString; 6058514SThomas.Grass@ARM.com string desc; 6068514SThomas.Grass@ARM.com Flags flags; 6078514SThomas.Grass@ARM.com bool descriptions; 6088514SThomas.Grass@ARM.com int precision; 6098514SThomas.Grass@ARM.com 6108514SThomas.Grass@ARM.com const SparseHistData &data; 6118514SThomas.Grass@ARM.com 6128514SThomas.Grass@ARM.com SparseHistPrint(const Text *text, const SparseHistInfo &info); 6138514SThomas.Grass@ARM.com void init(const Text *text, const Info &info); 6148514SThomas.Grass@ARM.com void operator()(ostream &stream) const; 6158514SThomas.Grass@ARM.com}; 6168514SThomas.Grass@ARM.com 6178514SThomas.Grass@ARM.com/* Call initialization function */ 6188514SThomas.Grass@ARM.comSparseHistPrint::SparseHistPrint(const Text *text, const SparseHistInfo &info) 6198514SThomas.Grass@ARM.com : data(info.data) 6208514SThomas.Grass@ARM.com{ 6218514SThomas.Grass@ARM.com init(text, info); 6228514SThomas.Grass@ARM.com} 6238514SThomas.Grass@ARM.com 6248514SThomas.Grass@ARM.com/* Initialization function */ 6258514SThomas.Grass@ARM.comvoid 6268514SThomas.Grass@ARM.comSparseHistPrint::init(const Text *text, const Info &info) 6278514SThomas.Grass@ARM.com{ 6288514SThomas.Grass@ARM.com name = info.name; 6298514SThomas.Grass@ARM.com separatorString = info.separatorString; 6308514SThomas.Grass@ARM.com desc = info.desc; 6318514SThomas.Grass@ARM.com flags = info.flags; 6328514SThomas.Grass@ARM.com precision = info.precision; 6338514SThomas.Grass@ARM.com descriptions = text->descriptions; 6348514SThomas.Grass@ARM.com} 6358514SThomas.Grass@ARM.com 6368514SThomas.Grass@ARM.com/* Grab data from map and write to output stream */ 6378514SThomas.Grass@ARM.comvoid 6388514SThomas.Grass@ARM.comSparseHistPrint::operator()(ostream &stream) const 6398514SThomas.Grass@ARM.com{ 6408514SThomas.Grass@ARM.com string base = name + separatorString; 6418514SThomas.Grass@ARM.com 6428514SThomas.Grass@ARM.com ScalarPrint print; 6438514SThomas.Grass@ARM.com print.precision = precision; 6448514SThomas.Grass@ARM.com print.flags = flags; 6458514SThomas.Grass@ARM.com print.descriptions = descriptions; 6468514SThomas.Grass@ARM.com print.desc = desc; 6478514SThomas.Grass@ARM.com print.pdf = NAN; 6488514SThomas.Grass@ARM.com print.cdf = NAN; 6498514SThomas.Grass@ARM.com 6508514SThomas.Grass@ARM.com print.name = base + "samples"; 6518514SThomas.Grass@ARM.com print.value = data.samples; 6528514SThomas.Grass@ARM.com print(stream); 6538514SThomas.Grass@ARM.com 6548514SThomas.Grass@ARM.com MCounter::const_iterator it; 6558514SThomas.Grass@ARM.com for (it = data.cmap.begin(); it != data.cmap.end(); it++) { 6568514SThomas.Grass@ARM.com stringstream namestr; 6578514SThomas.Grass@ARM.com namestr << base; 6588514SThomas.Grass@ARM.com 6598514SThomas.Grass@ARM.com namestr <<(*it).first; 6608514SThomas.Grass@ARM.com print.name = namestr.str(); 6618514SThomas.Grass@ARM.com print.value = (*it).second; 6628514SThomas.Grass@ARM.com print(stream); 6638514SThomas.Grass@ARM.com } 6648514SThomas.Grass@ARM.com 6658514SThomas.Grass@ARM.com print.pdf = NAN; 6668514SThomas.Grass@ARM.com print.cdf = NAN; 6678514SThomas.Grass@ARM.com 6688514SThomas.Grass@ARM.com print.name = base + "total"; 6698514SThomas.Grass@ARM.com print.value = total; 6708514SThomas.Grass@ARM.com print(stream); 6718514SThomas.Grass@ARM.com} 6728514SThomas.Grass@ARM.com 6738514SThomas.Grass@ARM.comvoid 6748514SThomas.Grass@ARM.comText::visit(const SparseHistInfo &info) 6758514SThomas.Grass@ARM.com{ 6768514SThomas.Grass@ARM.com if (noOutput(info)) 6778514SThomas.Grass@ARM.com return; 6788514SThomas.Grass@ARM.com 6798514SThomas.Grass@ARM.com SparseHistPrint print(this, info); 6808514SThomas.Grass@ARM.com print(*stream); 6818514SThomas.Grass@ARM.com} 6828514SThomas.Grass@ARM.com 6838296Snate@binkert.orgOutput * 6846126Snate@binkert.orginitText(const string &filename, bool desc) 6854078Sbinkertn@umich.edu{ 6864078Sbinkertn@umich.edu static Text text; 6874078Sbinkertn@umich.edu static bool connected = false; 6884078Sbinkertn@umich.edu 6898296Snate@binkert.org if (!connected) { 6908634Schris.emmons@arm.com ostream *os = simout.find(filename); 6918634Schris.emmons@arm.com if (!os) 6928634Schris.emmons@arm.com os = simout.create(filename); 6938634Schris.emmons@arm.com 6948634Schris.emmons@arm.com text.open(*os); 6958296Snate@binkert.org text.descriptions = desc; 6968296Snate@binkert.org connected = true; 6978296Snate@binkert.org } 6984078Sbinkertn@umich.edu 6998296Snate@binkert.org return &text; 7004078Sbinkertn@umich.edu} 7014078Sbinkertn@umich.edu 7027811Ssteve.reinhardt@amd.com} // namespace Stats 703