text.cc revision 10011
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 1698946Sandreas.hansson@arm.com if (!std::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 { 1798982Snate@binkert.org val << "nan"; 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); 1979743Snilay@cs.wisc.edu void operator()(ostream &stream, bool oneLine = false) 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 2119743Snilay@cs.wisc.eduScalarPrint::operator()(ostream &stream, bool oneLine) const 212695SN/A{ 21310011Snilay@cs.wisc.edu if ((flags.isSet(nozero) && (!oneLine) && value == 0.0) || 2148946Sandreas.hansson@arm.com (flags.isSet(nonan) && std::isnan(value))) 215695SN/A return; 216695SN/A 217695SN/A stringstream pdfstr, cdfstr; 218695SN/A 2198946Sandreas.hansson@arm.com if (!std::isnan(pdf)) 220695SN/A ccprintf(pdfstr, "%.2f%%", pdf * 100.0); 221695SN/A 2228946Sandreas.hansson@arm.com if (!std::isnan(cdf)) 223695SN/A ccprintf(cdfstr, "%.2f%%", cdf * 100.0); 224695SN/A 2259743Snilay@cs.wisc.edu if (oneLine) { 2269743Snilay@cs.wisc.edu ccprintf(stream, " |%12s %10s %10s", 2279743Snilay@cs.wisc.edu ValueToString(value, precision), pdfstr.str(), cdfstr.str()); 2289743Snilay@cs.wisc.edu } else { 2299743Snilay@cs.wisc.edu ccprintf(stream, "%-40s %12s %10s %10s", name, 2309743Snilay@cs.wisc.edu ValueToString(value, precision), pdfstr.str(), cdfstr.str()); 231695SN/A 2329743Snilay@cs.wisc.edu if (descriptions) { 2339743Snilay@cs.wisc.edu if (!desc.empty()) 2349743Snilay@cs.wisc.edu ccprintf(stream, " # %s", desc); 2359743Snilay@cs.wisc.edu } 2369743Snilay@cs.wisc.edu stream << endl; 237695SN/A } 238695SN/A} 239695SN/A 240695SN/Astruct VectorPrint 241695SN/A{ 242695SN/A string name; 2438243Sbradley.danofsky@amd.com string separatorString; 244695SN/A string desc; 245695SN/A vector<string> subnames; 246695SN/A vector<string> subdescs; 2476130Snate@binkert.org Flags flags; 248695SN/A bool descriptions; 249695SN/A int precision; 250695SN/A VResult vec; 251695SN/A Result total; 2529839Sandreas.hansson@arm.com bool forceSubnames; 253695SN/A 254695SN/A void operator()(ostream &stream) const; 255695SN/A}; 256695SN/A 257695SN/Avoid 258695SN/AVectorPrint::operator()(std::ostream &stream) const 259695SN/A{ 2605599Snate@binkert.org size_type _size = vec.size(); 261695SN/A Result _total = 0.0; 262695SN/A 2636130Snate@binkert.org if (flags.isSet(pdf | cdf)) { 2645599Snate@binkert.org for (off_type i = 0; i < _size; ++i) { 265695SN/A _total += vec[i]; 266695SN/A } 267695SN/A } 268695SN/A 2698243Sbradley.danofsky@amd.com string base = name + separatorString; 270695SN/A 271695SN/A ScalarPrint print; 272695SN/A print.name = name; 273695SN/A print.desc = desc; 274695SN/A print.precision = precision; 275695SN/A print.descriptions = descriptions; 276695SN/A print.flags = flags; 2776211Snate@binkert.org print.pdf = _total ? 0.0 : NAN; 2786211Snate@binkert.org print.cdf = _total ? 0.0 : NAN; 279695SN/A 280695SN/A bool havesub = !subnames.empty(); 281695SN/A 282695SN/A if (_size == 1) { 2839828Ssascha.bischoff@arm.com // If forceSubnames is set, get the first subname (or index in 2849828Ssascha.bischoff@arm.com // the case where there are no subnames) and append it to the 2859828Ssascha.bischoff@arm.com // base name. 2869828Ssascha.bischoff@arm.com if (forceSubnames) 2879828Ssascha.bischoff@arm.com print.name = base + (havesub ? subnames[0] : to_string(0)); 288695SN/A print.value = vec[0]; 289695SN/A print(stream); 2906126Snate@binkert.org return; 2916126Snate@binkert.org } 292695SN/A 2939743Snilay@cs.wisc.edu if ((!flags.isSet(nozero)) || (total != 0)) { 2949743Snilay@cs.wisc.edu if (flags.isSet(oneline)) { 2959743Snilay@cs.wisc.edu ccprintf(stream, "%-40s", name); 2969743Snilay@cs.wisc.edu print.flags = print.flags & (~nozero); 2979743Snilay@cs.wisc.edu } 298695SN/A 2999743Snilay@cs.wisc.edu for (off_type i = 0; i < _size; ++i) { 3009743Snilay@cs.wisc.edu if (havesub && (i >= subnames.size() || subnames[i].empty())) 3019743Snilay@cs.wisc.edu continue; 302695SN/A 3039743Snilay@cs.wisc.edu print.name = base + (havesub ? subnames[i] : to_string(i)); 3049743Snilay@cs.wisc.edu print.desc = subdescs.empty() ? desc : subdescs[i]; 3059743Snilay@cs.wisc.edu 3069743Snilay@cs.wisc.edu print.update(vec[i], _total); 3079743Snilay@cs.wisc.edu print(stream, flags.isSet(oneline)); 3089743Snilay@cs.wisc.edu } 3099743Snilay@cs.wisc.edu 3109743Snilay@cs.wisc.edu if (flags.isSet(oneline)) { 3119743Snilay@cs.wisc.edu if (descriptions) { 3129743Snilay@cs.wisc.edu if (!desc.empty()) 3139743Snilay@cs.wisc.edu ccprintf(stream, " # %s", desc); 3149743Snilay@cs.wisc.edu } 3159743Snilay@cs.wisc.edu stream << endl; 3169743Snilay@cs.wisc.edu } 3176126Snate@binkert.org } 318695SN/A 3196130Snate@binkert.org if (flags.isSet(::Stats::total)) { 3206126Snate@binkert.org print.pdf = NAN; 3216126Snate@binkert.org print.cdf = NAN; 3226126Snate@binkert.org print.name = base + "total"; 3236126Snate@binkert.org print.desc = desc; 3246126Snate@binkert.org print.value = total; 3256126Snate@binkert.org print(stream); 326695SN/A } 327695SN/A} 328695SN/A 329695SN/Astruct DistPrint 330695SN/A{ 331695SN/A string name; 3328243Sbradley.danofsky@amd.com string separatorString; 333695SN/A string desc; 3346130Snate@binkert.org Flags flags; 335695SN/A bool descriptions; 336695SN/A int precision; 337695SN/A 3386004Snate@binkert.org const DistData &data; 3396004Snate@binkert.org 3406128Snate@binkert.org DistPrint(const Text *text, const DistInfo &info); 3416128Snate@binkert.org DistPrint(const Text *text, const VectorDistInfo &info, int i); 3427505Snate@binkert.org void init(const Text *text, const Info &info); 343695SN/A void operator()(ostream &stream) const; 344695SN/A}; 345695SN/A 3466128Snate@binkert.orgDistPrint::DistPrint(const Text *text, const DistInfo &info) 3476004Snate@binkert.org : data(info.data) 3486004Snate@binkert.org{ 3497505Snate@binkert.org init(text, info); 3506004Snate@binkert.org} 3516004Snate@binkert.org 3526128Snate@binkert.orgDistPrint::DistPrint(const Text *text, const VectorDistInfo &info, int i) 3536004Snate@binkert.org : data(info.data[i]) 3546004Snate@binkert.org{ 3557505Snate@binkert.org init(text, info); 3566004Snate@binkert.org 3576004Snate@binkert.org name = info.name + "_" + 3586004Snate@binkert.org (info.subnames[i].empty() ? (to_string(i)) : info.subnames[i]); 3596004Snate@binkert.org 3606004Snate@binkert.org if (!info.subdescs[i].empty()) 3616004Snate@binkert.org desc = info.subdescs[i]; 3626004Snate@binkert.org} 3636004Snate@binkert.org 3646004Snate@binkert.orgvoid 3657505Snate@binkert.orgDistPrint::init(const Text *text, const Info &info) 3666004Snate@binkert.org{ 3676004Snate@binkert.org name = info.name; 3688243Sbradley.danofsky@amd.com separatorString = info.separatorString; 3696004Snate@binkert.org desc = info.desc; 3706004Snate@binkert.org flags = info.flags; 3716004Snate@binkert.org precision = info.precision; 3726125Snate@binkert.org descriptions = text->descriptions; 3736004Snate@binkert.org} 3746004Snate@binkert.org 375695SN/Avoid 376695SN/ADistPrint::operator()(ostream &stream) const 377695SN/A{ 37810011Snilay@cs.wisc.edu if (flags.isSet(nozero) && data.samples == 0) return; 3798243Sbradley.danofsky@amd.com string base = name + separatorString; 380695SN/A 381695SN/A ScalarPrint print; 3826211Snate@binkert.org print.precision = precision; 383695SN/A print.flags = flags; 384695SN/A print.descriptions = descriptions; 3856211Snate@binkert.org print.desc = desc; 386695SN/A print.pdf = NAN; 387695SN/A print.cdf = NAN; 388695SN/A 38910011Snilay@cs.wisc.edu if (flags.isSet(oneline)) { 39010011Snilay@cs.wisc.edu print.name = base + "bucket_size"; 39110011Snilay@cs.wisc.edu print.value = data.bucket_size; 39210011Snilay@cs.wisc.edu print(stream); 39310011Snilay@cs.wisc.edu 39410011Snilay@cs.wisc.edu print.name = base + "min_bucket"; 39510011Snilay@cs.wisc.edu print.value = data.min; 39610011Snilay@cs.wisc.edu print(stream); 39710011Snilay@cs.wisc.edu 39810011Snilay@cs.wisc.edu print.name = base + "max_bucket"; 39910011Snilay@cs.wisc.edu print.value = data.max; 40010011Snilay@cs.wisc.edu print(stream); 40110011Snilay@cs.wisc.edu } 40210011Snilay@cs.wisc.edu 403695SN/A print.name = base + "samples"; 4046004Snate@binkert.org print.value = data.samples; 405695SN/A print(stream); 406695SN/A 4076211Snate@binkert.org print.name = base + "mean"; 4086211Snate@binkert.org print.value = data.samples ? data.sum / data.samples : NAN; 409695SN/A print(stream); 410695SN/A 4118666SPrakash.Ramrakhyani@arm.com if (data.type == Hist) { 4128666SPrakash.Ramrakhyani@arm.com print.name = base + "gmean"; 4138666SPrakash.Ramrakhyani@arm.com print.value = data.samples ? exp(data.logs / data.samples) : NAN; 4148666SPrakash.Ramrakhyani@arm.com print(stream); 4158666SPrakash.Ramrakhyani@arm.com } 4168666SPrakash.Ramrakhyani@arm.com 4176211Snate@binkert.org Result stdev = NAN; 4186211Snate@binkert.org if (data.samples) 4196211Snate@binkert.org stdev = sqrt((data.samples * data.squares - data.sum * data.sum) / 4206211Snate@binkert.org (data.samples * (data.samples - 1.0))); 4216211Snate@binkert.org print.name = base + "stdev"; 4226211Snate@binkert.org print.value = stdev; 4236211Snate@binkert.org print(stream); 4246211Snate@binkert.org 4257505Snate@binkert.org if (data.type == Deviation) 4266211Snate@binkert.org return; 4276211Snate@binkert.org 4287505Snate@binkert.org size_t size = data.cvec.size(); 4296211Snate@binkert.org 4306211Snate@binkert.org Result total = 0.0; 4317831Snate@binkert.org if (data.type == Dist && data.underflow != NAN) 4326211Snate@binkert.org total += data.underflow; 4336211Snate@binkert.org for (off_type i = 0; i < size; ++i) 4346211Snate@binkert.org total += data.cvec[i]; 4357831Snate@binkert.org if (data.type == Dist && data.overflow != NAN) 4366211Snate@binkert.org total += data.overflow; 4376211Snate@binkert.org 4386126Snate@binkert.org if (total) { 4396211Snate@binkert.org print.pdf = 0.0; 4406211Snate@binkert.org print.cdf = 0.0; 4416126Snate@binkert.org } 4426211Snate@binkert.org 4437831Snate@binkert.org if (data.type == Dist && data.underflow != NAN) { 4446211Snate@binkert.org print.name = base + "underflows"; 4456211Snate@binkert.org print.update(data.underflow, total); 4466211Snate@binkert.org print(stream); 4476211Snate@binkert.org } 4486126Snate@binkert.org 44910011Snilay@cs.wisc.edu if (flags.isSet(oneline)) { 45010011Snilay@cs.wisc.edu ccprintf(stream, "%-40s", name); 45110011Snilay@cs.wisc.edu } 45210011Snilay@cs.wisc.edu 4536126Snate@binkert.org for (off_type i = 0; i < size; ++i) { 4546126Snate@binkert.org stringstream namestr; 4556126Snate@binkert.org namestr << base; 4566126Snate@binkert.org 4577505Snate@binkert.org Counter low = i * data.bucket_size + data.min; 4587505Snate@binkert.org Counter high = ::min(low + data.bucket_size - 1.0, data.max); 4596126Snate@binkert.org namestr << low; 4606126Snate@binkert.org if (low < high) 4616126Snate@binkert.org namestr << "-" << high; 4626126Snate@binkert.org 4636126Snate@binkert.org print.name = namestr.str(); 4646211Snate@binkert.org print.update(data.cvec[i], total); 46510011Snilay@cs.wisc.edu print(stream, flags.isSet(oneline)); 46610011Snilay@cs.wisc.edu } 46710011Snilay@cs.wisc.edu 46810011Snilay@cs.wisc.edu if (flags.isSet(oneline)) { 46910011Snilay@cs.wisc.edu if (descriptions) { 47010011Snilay@cs.wisc.edu if (!desc.empty()) 47110011Snilay@cs.wisc.edu ccprintf(stream, " # %s", desc); 47210011Snilay@cs.wisc.edu } 47310011Snilay@cs.wisc.edu stream << endl; 474695SN/A } 475695SN/A 4767831Snate@binkert.org if (data.type == Dist && data.overflow != NAN) { 4776211Snate@binkert.org print.name = base + "overflows"; 4786211Snate@binkert.org print.update(data.overflow, total); 4796211Snate@binkert.org print(stream); 480695SN/A } 481695SN/A 482695SN/A print.pdf = NAN; 483695SN/A print.cdf = NAN; 484695SN/A 4857831Snate@binkert.org if (data.type == Dist && data.min_val != NAN) { 4866211Snate@binkert.org print.name = base + "min_value"; 4876211Snate@binkert.org print.value = data.min_val; 4886211Snate@binkert.org print(stream); 4896211Snate@binkert.org } 4906211Snate@binkert.org 4917831Snate@binkert.org if (data.type == Dist && data.max_val != NAN) { 4926211Snate@binkert.org print.name = base + "max_value"; 4936211Snate@binkert.org print.value = data.max_val; 4946211Snate@binkert.org print(stream); 4956211Snate@binkert.org } 4966211Snate@binkert.org 4976126Snate@binkert.org print.name = base + "total"; 4986126Snate@binkert.org print.value = total; 4996126Snate@binkert.org print(stream); 500695SN/A} 501695SN/A 502695SN/Avoid 5036128Snate@binkert.orgText::visit(const ScalarInfo &info) 504695SN/A{ 5055886Snate@binkert.org if (noOutput(info)) 506695SN/A return; 507695SN/A 508695SN/A ScalarPrint print; 5095886Snate@binkert.org print.value = info.result(); 5105886Snate@binkert.org print.name = info.name; 5115886Snate@binkert.org print.desc = info.desc; 5125886Snate@binkert.org print.flags = info.flags; 513695SN/A print.descriptions = descriptions; 5145886Snate@binkert.org print.precision = info.precision; 515695SN/A print.pdf = NAN; 516695SN/A print.cdf = NAN; 517695SN/A 518695SN/A print(*stream); 519695SN/A} 520695SN/A 521695SN/Avoid 5226128Snate@binkert.orgText::visit(const VectorInfo &info) 523695SN/A{ 5245886Snate@binkert.org if (noOutput(info)) 525695SN/A return; 526695SN/A 5275886Snate@binkert.org size_type size = info.size(); 528695SN/A VectorPrint print; 529695SN/A 5305886Snate@binkert.org print.name = info.name; 5318243Sbradley.danofsky@amd.com print.separatorString = info.separatorString; 5325886Snate@binkert.org print.desc = info.desc; 5335886Snate@binkert.org print.flags = info.flags; 534695SN/A print.descriptions = descriptions; 5355886Snate@binkert.org print.precision = info.precision; 5365886Snate@binkert.org print.vec = info.result(); 5375886Snate@binkert.org print.total = info.total(); 5389839Sandreas.hansson@arm.com print.forceSubnames = false; 539695SN/A 5405886Snate@binkert.org if (!info.subnames.empty()) { 5415599Snate@binkert.org for (off_type i = 0; i < size; ++i) { 5425886Snate@binkert.org if (!info.subnames[i].empty()) { 5435886Snate@binkert.org print.subnames = info.subnames; 544695SN/A print.subnames.resize(size); 5455599Snate@binkert.org for (off_type i = 0; i < size; ++i) { 5465886Snate@binkert.org if (!info.subnames[i].empty() && 5475886Snate@binkert.org !info.subdescs[i].empty()) { 5485886Snate@binkert.org print.subdescs = info.subdescs; 549695SN/A print.subdescs.resize(size); 550695SN/A break; 551695SN/A } 552695SN/A } 553695SN/A break; 554695SN/A } 555695SN/A } 556695SN/A } 557695SN/A 558695SN/A print(*stream); 559695SN/A} 560695SN/A 561695SN/Avoid 5626128Snate@binkert.orgText::visit(const Vector2dInfo &info) 563695SN/A{ 5645886Snate@binkert.org if (noOutput(info)) 565695SN/A return; 566695SN/A 567695SN/A bool havesub = false; 568695SN/A VectorPrint print; 569695SN/A 5708667Sdam.sunwoo@arm.com if (!info.y_subnames.empty()) { 5718667Sdam.sunwoo@arm.com for (off_type i = 0; i < info.y; ++i) { 5728667Sdam.sunwoo@arm.com if (!info.y_subnames[i].empty()) { 5738667Sdam.sunwoo@arm.com print.subnames = info.y_subnames; 5748667Sdam.sunwoo@arm.com } 5758667Sdam.sunwoo@arm.com break; 5768667Sdam.sunwoo@arm.com } 5778667Sdam.sunwoo@arm.com } 5785886Snate@binkert.org print.flags = info.flags; 5798243Sbradley.danofsky@amd.com print.separatorString = info.separatorString; 580695SN/A print.descriptions = descriptions; 5815886Snate@binkert.org print.precision = info.precision; 5829828Ssascha.bischoff@arm.com print.forceSubnames = true; 583695SN/A 5845886Snate@binkert.org if (!info.subnames.empty()) { 5855886Snate@binkert.org for (off_type i = 0; i < info.x; ++i) 5865886Snate@binkert.org if (!info.subnames[i].empty()) 587695SN/A havesub = true; 588695SN/A } 589695SN/A 5905886Snate@binkert.org VResult tot_vec(info.y); 5919828Ssascha.bischoff@arm.com VResult super_total(1, 0.0); 5925886Snate@binkert.org for (off_type i = 0; i < info.x; ++i) { 5935886Snate@binkert.org if (havesub && (i >= info.subnames.size() || info.subnames[i].empty())) 594695SN/A continue; 595695SN/A 5965886Snate@binkert.org off_type iy = i * info.y; 5975886Snate@binkert.org VResult yvec(info.y); 598695SN/A 599695SN/A Result total = 0.0; 6005886Snate@binkert.org for (off_type j = 0; j < info.y; ++j) { 6015886Snate@binkert.org yvec[j] = info.cvec[iy + j]; 602695SN/A tot_vec[j] += yvec[j]; 603695SN/A total += yvec[j]; 6049828Ssascha.bischoff@arm.com super_total[0] += yvec[j]; 605695SN/A } 606695SN/A 6075886Snate@binkert.org print.name = info.name + "_" + 6085886Snate@binkert.org (havesub ? info.subnames[i] : to_string(i)); 6095886Snate@binkert.org print.desc = info.desc; 610695SN/A print.vec = yvec; 611695SN/A print.total = total; 612695SN/A print(*stream); 613695SN/A } 614695SN/A 6159828Ssascha.bischoff@arm.com // Create a subname for printing the total 6169828Ssascha.bischoff@arm.com vector<string> total_subname; 6179828Ssascha.bischoff@arm.com total_subname.push_back("total"); 6189828Ssascha.bischoff@arm.com 6196130Snate@binkert.org if (info.flags.isSet(::Stats::total) && (info.x > 1)) { 6205886Snate@binkert.org print.name = info.name; 6219828Ssascha.bischoff@arm.com print.subnames = total_subname; 6225886Snate@binkert.org print.desc = info.desc; 6239828Ssascha.bischoff@arm.com print.vec = super_total; 6249828Ssascha.bischoff@arm.com print.flags = print.flags & ~total; 625695SN/A print(*stream); 626695SN/A } 627695SN/A} 628695SN/A 629695SN/Avoid 6306128Snate@binkert.orgText::visit(const DistInfo &info) 631695SN/A{ 6325886Snate@binkert.org if (noOutput(info)) 633695SN/A return; 634695SN/A 6356125Snate@binkert.org DistPrint print(this, info); 636695SN/A print(*stream); 637695SN/A} 638695SN/A 639695SN/Avoid 6406128Snate@binkert.orgText::visit(const VectorDistInfo &info) 641695SN/A{ 6425886Snate@binkert.org if (noOutput(info)) 643695SN/A return; 644695SN/A 6455886Snate@binkert.org for (off_type i = 0; i < info.size(); ++i) { 6466125Snate@binkert.org DistPrint print(this, info, i); 647695SN/A print(*stream); 648695SN/A } 649695SN/A} 650695SN/A 651695SN/Avoid 6526128Snate@binkert.orgText::visit(const FormulaInfo &info) 653695SN/A{ 6546128Snate@binkert.org visit((const VectorInfo &)info); 655695SN/A} 656695SN/A 6578514SThomas.Grass@ARM.com/* 6588514SThomas.Grass@ARM.com This struct implements the output methods for the sparse 6598514SThomas.Grass@ARM.com histogram stat 6608514SThomas.Grass@ARM.com*/ 6618514SThomas.Grass@ARM.comstruct SparseHistPrint 6628514SThomas.Grass@ARM.com{ 6638514SThomas.Grass@ARM.com string name; 6648514SThomas.Grass@ARM.com string separatorString; 6658514SThomas.Grass@ARM.com string desc; 6668514SThomas.Grass@ARM.com Flags flags; 6678514SThomas.Grass@ARM.com bool descriptions; 6688514SThomas.Grass@ARM.com int precision; 6698514SThomas.Grass@ARM.com 6708514SThomas.Grass@ARM.com const SparseHistData &data; 6718514SThomas.Grass@ARM.com 6728514SThomas.Grass@ARM.com SparseHistPrint(const Text *text, const SparseHistInfo &info); 6738514SThomas.Grass@ARM.com void init(const Text *text, const Info &info); 6748514SThomas.Grass@ARM.com void operator()(ostream &stream) const; 6758514SThomas.Grass@ARM.com}; 6768514SThomas.Grass@ARM.com 6778514SThomas.Grass@ARM.com/* Call initialization function */ 6788514SThomas.Grass@ARM.comSparseHistPrint::SparseHistPrint(const Text *text, const SparseHistInfo &info) 6798514SThomas.Grass@ARM.com : data(info.data) 6808514SThomas.Grass@ARM.com{ 6818514SThomas.Grass@ARM.com init(text, info); 6828514SThomas.Grass@ARM.com} 6838514SThomas.Grass@ARM.com 6848514SThomas.Grass@ARM.com/* Initialization function */ 6858514SThomas.Grass@ARM.comvoid 6868514SThomas.Grass@ARM.comSparseHistPrint::init(const Text *text, const Info &info) 6878514SThomas.Grass@ARM.com{ 6888514SThomas.Grass@ARM.com name = info.name; 6898514SThomas.Grass@ARM.com separatorString = info.separatorString; 6908514SThomas.Grass@ARM.com desc = info.desc; 6918514SThomas.Grass@ARM.com flags = info.flags; 6928514SThomas.Grass@ARM.com precision = info.precision; 6938514SThomas.Grass@ARM.com descriptions = text->descriptions; 6948514SThomas.Grass@ARM.com} 6958514SThomas.Grass@ARM.com 6968514SThomas.Grass@ARM.com/* Grab data from map and write to output stream */ 6978514SThomas.Grass@ARM.comvoid 6988514SThomas.Grass@ARM.comSparseHistPrint::operator()(ostream &stream) const 6998514SThomas.Grass@ARM.com{ 7008514SThomas.Grass@ARM.com string base = name + separatorString; 7018514SThomas.Grass@ARM.com 7028514SThomas.Grass@ARM.com ScalarPrint print; 7038514SThomas.Grass@ARM.com print.precision = precision; 7048514SThomas.Grass@ARM.com print.flags = flags; 7058514SThomas.Grass@ARM.com print.descriptions = descriptions; 7068514SThomas.Grass@ARM.com print.desc = desc; 7078514SThomas.Grass@ARM.com print.pdf = NAN; 7088514SThomas.Grass@ARM.com print.cdf = NAN; 7098514SThomas.Grass@ARM.com 7108514SThomas.Grass@ARM.com print.name = base + "samples"; 7118514SThomas.Grass@ARM.com print.value = data.samples; 7128514SThomas.Grass@ARM.com print(stream); 7138514SThomas.Grass@ARM.com 7148514SThomas.Grass@ARM.com MCounter::const_iterator it; 7158514SThomas.Grass@ARM.com for (it = data.cmap.begin(); it != data.cmap.end(); it++) { 7168514SThomas.Grass@ARM.com stringstream namestr; 7178514SThomas.Grass@ARM.com namestr << base; 7188514SThomas.Grass@ARM.com 7198514SThomas.Grass@ARM.com namestr <<(*it).first; 7208514SThomas.Grass@ARM.com print.name = namestr.str(); 7218514SThomas.Grass@ARM.com print.value = (*it).second; 7228514SThomas.Grass@ARM.com print(stream); 7238514SThomas.Grass@ARM.com } 7248514SThomas.Grass@ARM.com} 7258514SThomas.Grass@ARM.com 7268514SThomas.Grass@ARM.comvoid 7278514SThomas.Grass@ARM.comText::visit(const SparseHistInfo &info) 7288514SThomas.Grass@ARM.com{ 7298514SThomas.Grass@ARM.com if (noOutput(info)) 7308514SThomas.Grass@ARM.com return; 7318514SThomas.Grass@ARM.com 7328514SThomas.Grass@ARM.com SparseHistPrint print(this, info); 7338514SThomas.Grass@ARM.com print(*stream); 7348514SThomas.Grass@ARM.com} 7358514SThomas.Grass@ARM.com 7368296Snate@binkert.orgOutput * 7376126Snate@binkert.orginitText(const string &filename, bool desc) 7384078Sbinkertn@umich.edu{ 7394078Sbinkertn@umich.edu static Text text; 7404078Sbinkertn@umich.edu static bool connected = false; 7414078Sbinkertn@umich.edu 7428296Snate@binkert.org if (!connected) { 7438634Schris.emmons@arm.com ostream *os = simout.find(filename); 7448634Schris.emmons@arm.com if (!os) 7458634Schris.emmons@arm.com os = simout.create(filename); 7468634Schris.emmons@arm.com 7478634Schris.emmons@arm.com text.open(*os); 7488296Snate@binkert.org text.descriptions = desc; 7498296Snate@binkert.org connected = true; 7508296Snate@binkert.org } 7514078Sbinkertn@umich.edu 7528296Snate@binkert.org return &text; 7534078Sbinkertn@umich.edu} 7544078Sbinkertn@umich.edu 7557811Ssteve.reinhardt@amd.com} // namespace Stats 756