text.cc revision 8634
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 3706211Snate@binkert.org Result stdev = NAN; 3716211Snate@binkert.org if (data.samples) 3726211Snate@binkert.org stdev = sqrt((data.samples * data.squares - data.sum * data.sum) / 3736211Snate@binkert.org (data.samples * (data.samples - 1.0))); 3746211Snate@binkert.org print.name = base + "stdev"; 3756211Snate@binkert.org print.value = stdev; 3766211Snate@binkert.org print(stream); 3776211Snate@binkert.org 3787505Snate@binkert.org if (data.type == Deviation) 3796211Snate@binkert.org return; 3806211Snate@binkert.org 3817505Snate@binkert.org size_t size = data.cvec.size(); 3826211Snate@binkert.org 3836211Snate@binkert.org Result total = 0.0; 3847831Snate@binkert.org if (data.type == Dist && data.underflow != NAN) 3856211Snate@binkert.org total += data.underflow; 3866211Snate@binkert.org for (off_type i = 0; i < size; ++i) 3876211Snate@binkert.org total += data.cvec[i]; 3887831Snate@binkert.org if (data.type == Dist && data.overflow != NAN) 3896211Snate@binkert.org total += data.overflow; 3906211Snate@binkert.org 3916126Snate@binkert.org if (total) { 3926211Snate@binkert.org print.pdf = 0.0; 3936211Snate@binkert.org print.cdf = 0.0; 3946126Snate@binkert.org } 3956211Snate@binkert.org 3967831Snate@binkert.org if (data.type == Dist && data.underflow != NAN) { 3976211Snate@binkert.org print.name = base + "underflows"; 3986211Snate@binkert.org print.update(data.underflow, total); 3996211Snate@binkert.org print(stream); 4006211Snate@binkert.org } 4016126Snate@binkert.org 4026126Snate@binkert.org for (off_type i = 0; i < size; ++i) { 4036126Snate@binkert.org stringstream namestr; 4046126Snate@binkert.org namestr << base; 4056126Snate@binkert.org 4067505Snate@binkert.org Counter low = i * data.bucket_size + data.min; 4077505Snate@binkert.org Counter high = ::min(low + data.bucket_size - 1.0, data.max); 4086126Snate@binkert.org namestr << low; 4096126Snate@binkert.org if (low < high) 4106126Snate@binkert.org namestr << "-" << high; 4116126Snate@binkert.org 4126126Snate@binkert.org print.name = namestr.str(); 4136211Snate@binkert.org print.update(data.cvec[i], total); 414695SN/A print(stream); 415695SN/A } 416695SN/A 4177831Snate@binkert.org if (data.type == Dist && data.overflow != NAN) { 4186211Snate@binkert.org print.name = base + "overflows"; 4196211Snate@binkert.org print.update(data.overflow, total); 4206211Snate@binkert.org print(stream); 421695SN/A } 422695SN/A 423695SN/A print.pdf = NAN; 424695SN/A print.cdf = NAN; 425695SN/A 4267831Snate@binkert.org if (data.type == Dist && data.min_val != NAN) { 4276211Snate@binkert.org print.name = base + "min_value"; 4286211Snate@binkert.org print.value = data.min_val; 4296211Snate@binkert.org print(stream); 4306211Snate@binkert.org } 4316211Snate@binkert.org 4327831Snate@binkert.org if (data.type == Dist && data.max_val != NAN) { 4336211Snate@binkert.org print.name = base + "max_value"; 4346211Snate@binkert.org print.value = data.max_val; 4356211Snate@binkert.org print(stream); 4366211Snate@binkert.org } 4376211Snate@binkert.org 4386126Snate@binkert.org print.name = base + "total"; 4396126Snate@binkert.org print.value = total; 4406126Snate@binkert.org print(stream); 441695SN/A} 442695SN/A 443695SN/Avoid 4446128Snate@binkert.orgText::visit(const ScalarInfo &info) 445695SN/A{ 4465886Snate@binkert.org if (noOutput(info)) 447695SN/A return; 448695SN/A 449695SN/A ScalarPrint print; 4505886Snate@binkert.org print.value = info.result(); 4515886Snate@binkert.org print.name = info.name; 4525886Snate@binkert.org print.desc = info.desc; 4535886Snate@binkert.org print.flags = info.flags; 454695SN/A print.descriptions = descriptions; 4555886Snate@binkert.org print.precision = info.precision; 456695SN/A print.pdf = NAN; 457695SN/A print.cdf = NAN; 458695SN/A 459695SN/A print(*stream); 460695SN/A} 461695SN/A 462695SN/Avoid 4636128Snate@binkert.orgText::visit(const VectorInfo &info) 464695SN/A{ 4655886Snate@binkert.org if (noOutput(info)) 466695SN/A return; 467695SN/A 4685886Snate@binkert.org size_type size = info.size(); 469695SN/A VectorPrint print; 470695SN/A 4715886Snate@binkert.org print.name = info.name; 4728243Sbradley.danofsky@amd.com print.separatorString = info.separatorString; 4735886Snate@binkert.org print.desc = info.desc; 4745886Snate@binkert.org print.flags = info.flags; 475695SN/A print.descriptions = descriptions; 4765886Snate@binkert.org print.precision = info.precision; 4775886Snate@binkert.org print.vec = info.result(); 4785886Snate@binkert.org print.total = info.total(); 479695SN/A 4805886Snate@binkert.org if (!info.subnames.empty()) { 4815599Snate@binkert.org for (off_type i = 0; i < size; ++i) { 4825886Snate@binkert.org if (!info.subnames[i].empty()) { 4835886Snate@binkert.org print.subnames = info.subnames; 484695SN/A print.subnames.resize(size); 4855599Snate@binkert.org for (off_type i = 0; i < size; ++i) { 4865886Snate@binkert.org if (!info.subnames[i].empty() && 4875886Snate@binkert.org !info.subdescs[i].empty()) { 4885886Snate@binkert.org print.subdescs = info.subdescs; 489695SN/A print.subdescs.resize(size); 490695SN/A break; 491695SN/A } 492695SN/A } 493695SN/A break; 494695SN/A } 495695SN/A } 496695SN/A } 497695SN/A 498695SN/A print(*stream); 499695SN/A} 500695SN/A 501695SN/Avoid 5026128Snate@binkert.orgText::visit(const Vector2dInfo &info) 503695SN/A{ 5045886Snate@binkert.org if (noOutput(info)) 505695SN/A return; 506695SN/A 507695SN/A bool havesub = false; 508695SN/A VectorPrint print; 509695SN/A 5105886Snate@binkert.org print.subnames = info.y_subnames; 5115886Snate@binkert.org print.flags = info.flags; 5128243Sbradley.danofsky@amd.com print.separatorString = info.separatorString; 513695SN/A print.descriptions = descriptions; 5145886Snate@binkert.org print.precision = info.precision; 515695SN/A 5165886Snate@binkert.org if (!info.subnames.empty()) { 5175886Snate@binkert.org for (off_type i = 0; i < info.x; ++i) 5185886Snate@binkert.org if (!info.subnames[i].empty()) 519695SN/A havesub = true; 520695SN/A } 521695SN/A 5225886Snate@binkert.org VResult tot_vec(info.y); 523695SN/A Result super_total = 0.0; 5245886Snate@binkert.org for (off_type i = 0; i < info.x; ++i) { 5255886Snate@binkert.org if (havesub && (i >= info.subnames.size() || info.subnames[i].empty())) 526695SN/A continue; 527695SN/A 5285886Snate@binkert.org off_type iy = i * info.y; 5295886Snate@binkert.org VResult yvec(info.y); 530695SN/A 531695SN/A Result total = 0.0; 5325886Snate@binkert.org for (off_type j = 0; j < info.y; ++j) { 5335886Snate@binkert.org yvec[j] = info.cvec[iy + j]; 534695SN/A tot_vec[j] += yvec[j]; 535695SN/A total += yvec[j]; 536695SN/A super_total += yvec[j]; 537695SN/A } 538695SN/A 5395886Snate@binkert.org print.name = info.name + "_" + 5405886Snate@binkert.org (havesub ? info.subnames[i] : to_string(i)); 5415886Snate@binkert.org print.desc = info.desc; 542695SN/A print.vec = yvec; 543695SN/A print.total = total; 544695SN/A print(*stream); 545695SN/A } 546695SN/A 5476130Snate@binkert.org if (info.flags.isSet(::Stats::total) && (info.x > 1)) { 5485886Snate@binkert.org print.name = info.name; 5495886Snate@binkert.org print.desc = info.desc; 550695SN/A print.vec = tot_vec; 551695SN/A print.total = super_total; 552695SN/A print(*stream); 553695SN/A } 554695SN/A} 555695SN/A 556695SN/Avoid 5576128Snate@binkert.orgText::visit(const DistInfo &info) 558695SN/A{ 5595886Snate@binkert.org if (noOutput(info)) 560695SN/A return; 561695SN/A 5626125Snate@binkert.org DistPrint print(this, info); 563695SN/A print(*stream); 564695SN/A} 565695SN/A 566695SN/Avoid 5676128Snate@binkert.orgText::visit(const VectorDistInfo &info) 568695SN/A{ 5695886Snate@binkert.org if (noOutput(info)) 570695SN/A return; 571695SN/A 5725886Snate@binkert.org for (off_type i = 0; i < info.size(); ++i) { 5736125Snate@binkert.org DistPrint print(this, info, i); 574695SN/A print(*stream); 575695SN/A } 576695SN/A} 577695SN/A 578695SN/Avoid 5796128Snate@binkert.orgText::visit(const FormulaInfo &info) 580695SN/A{ 5816128Snate@binkert.org visit((const VectorInfo &)info); 582695SN/A} 583695SN/A 5848514SThomas.Grass@ARM.com/* 5858514SThomas.Grass@ARM.com This struct implements the output methods for the sparse 5868514SThomas.Grass@ARM.com histogram stat 5878514SThomas.Grass@ARM.com*/ 5888514SThomas.Grass@ARM.comstruct SparseHistPrint 5898514SThomas.Grass@ARM.com{ 5908514SThomas.Grass@ARM.com string name; 5918514SThomas.Grass@ARM.com string separatorString; 5928514SThomas.Grass@ARM.com string desc; 5938514SThomas.Grass@ARM.com Flags flags; 5948514SThomas.Grass@ARM.com bool descriptions; 5958514SThomas.Grass@ARM.com int precision; 5968514SThomas.Grass@ARM.com 5978514SThomas.Grass@ARM.com const SparseHistData &data; 5988514SThomas.Grass@ARM.com 5998514SThomas.Grass@ARM.com SparseHistPrint(const Text *text, const SparseHistInfo &info); 6008514SThomas.Grass@ARM.com void init(const Text *text, const Info &info); 6018514SThomas.Grass@ARM.com void operator()(ostream &stream) const; 6028514SThomas.Grass@ARM.com}; 6038514SThomas.Grass@ARM.com 6048514SThomas.Grass@ARM.com/* Call initialization function */ 6058514SThomas.Grass@ARM.comSparseHistPrint::SparseHistPrint(const Text *text, const SparseHistInfo &info) 6068514SThomas.Grass@ARM.com : data(info.data) 6078514SThomas.Grass@ARM.com{ 6088514SThomas.Grass@ARM.com init(text, info); 6098514SThomas.Grass@ARM.com} 6108514SThomas.Grass@ARM.com 6118514SThomas.Grass@ARM.com/* Initialization function */ 6128514SThomas.Grass@ARM.comvoid 6138514SThomas.Grass@ARM.comSparseHistPrint::init(const Text *text, const Info &info) 6148514SThomas.Grass@ARM.com{ 6158514SThomas.Grass@ARM.com name = info.name; 6168514SThomas.Grass@ARM.com separatorString = info.separatorString; 6178514SThomas.Grass@ARM.com desc = info.desc; 6188514SThomas.Grass@ARM.com flags = info.flags; 6198514SThomas.Grass@ARM.com precision = info.precision; 6208514SThomas.Grass@ARM.com descriptions = text->descriptions; 6218514SThomas.Grass@ARM.com} 6228514SThomas.Grass@ARM.com 6238514SThomas.Grass@ARM.com/* Grab data from map and write to output stream */ 6248514SThomas.Grass@ARM.comvoid 6258514SThomas.Grass@ARM.comSparseHistPrint::operator()(ostream &stream) const 6268514SThomas.Grass@ARM.com{ 6278514SThomas.Grass@ARM.com string base = name + separatorString; 6288514SThomas.Grass@ARM.com 6298514SThomas.Grass@ARM.com ScalarPrint print; 6308514SThomas.Grass@ARM.com print.precision = precision; 6318514SThomas.Grass@ARM.com print.flags = flags; 6328514SThomas.Grass@ARM.com print.descriptions = descriptions; 6338514SThomas.Grass@ARM.com print.desc = desc; 6348514SThomas.Grass@ARM.com print.pdf = NAN; 6358514SThomas.Grass@ARM.com print.cdf = NAN; 6368514SThomas.Grass@ARM.com 6378514SThomas.Grass@ARM.com print.name = base + "samples"; 6388514SThomas.Grass@ARM.com print.value = data.samples; 6398514SThomas.Grass@ARM.com print(stream); 6408514SThomas.Grass@ARM.com 6418514SThomas.Grass@ARM.com MCounter::const_iterator it; 6428514SThomas.Grass@ARM.com for (it = data.cmap.begin(); it != data.cmap.end(); it++) { 6438514SThomas.Grass@ARM.com stringstream namestr; 6448514SThomas.Grass@ARM.com namestr << base; 6458514SThomas.Grass@ARM.com 6468514SThomas.Grass@ARM.com namestr <<(*it).first; 6478514SThomas.Grass@ARM.com print.name = namestr.str(); 6488514SThomas.Grass@ARM.com print.value = (*it).second; 6498514SThomas.Grass@ARM.com print(stream); 6508514SThomas.Grass@ARM.com } 6518514SThomas.Grass@ARM.com 6528514SThomas.Grass@ARM.com print.pdf = NAN; 6538514SThomas.Grass@ARM.com print.cdf = NAN; 6548514SThomas.Grass@ARM.com 6558514SThomas.Grass@ARM.com print.name = base + "total"; 6568514SThomas.Grass@ARM.com print.value = total; 6578514SThomas.Grass@ARM.com print(stream); 6588514SThomas.Grass@ARM.com} 6598514SThomas.Grass@ARM.com 6608514SThomas.Grass@ARM.comvoid 6618514SThomas.Grass@ARM.comText::visit(const SparseHistInfo &info) 6628514SThomas.Grass@ARM.com{ 6638514SThomas.Grass@ARM.com if (noOutput(info)) 6648514SThomas.Grass@ARM.com return; 6658514SThomas.Grass@ARM.com 6668514SThomas.Grass@ARM.com SparseHistPrint print(this, info); 6678514SThomas.Grass@ARM.com print(*stream); 6688514SThomas.Grass@ARM.com} 6698514SThomas.Grass@ARM.com 6708296Snate@binkert.orgOutput * 6716126Snate@binkert.orginitText(const string &filename, bool desc) 6724078Sbinkertn@umich.edu{ 6734078Sbinkertn@umich.edu static Text text; 6744078Sbinkertn@umich.edu static bool connected = false; 6754078Sbinkertn@umich.edu 6768296Snate@binkert.org if (!connected) { 6778634Schris.emmons@arm.com ostream *os = simout.find(filename); 6788634Schris.emmons@arm.com if (!os) 6798634Schris.emmons@arm.com os = simout.create(filename); 6808634Schris.emmons@arm.com 6818634Schris.emmons@arm.com text.open(*os); 6828296Snate@binkert.org text.descriptions = desc; 6838296Snate@binkert.org connected = true; 6848296Snate@binkert.org } 6854078Sbinkertn@umich.edu 6868296Snate@binkert.org return &text; 6874078Sbinkertn@umich.edu} 6884078Sbinkertn@umich.edu 6897811Ssteve.reinhardt@amd.com} // namespace Stats 690