text.cc revision 12334
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) 3611793Sbrandon.potter@amd.com#include <cmath> 3711793Sbrandon.potter@amd.com 383918Ssaidi@eecs.umich.edu#endif 393918Ssaidi@eecs.umich.edu 406129Snate@binkert.org#include <cassert> 4111793Sbrandon.potter@amd.com 426129Snate@binkert.org#ifdef __SUNPRO_CC 4311793Sbrandon.potter@amd.com#include <cmath> 4411793Sbrandon.potter@amd.com 456129Snate@binkert.org#endif 4611793Sbrandon.potter@amd.com#include "base/stats/text.hh" 4711793Sbrandon.potter@amd.com 486129Snate@binkert.org#include <cmath> 498229Snate@binkert.org#include <fstream> 50695SN/A#include <iostream> 512621SN/A#include <sstream> 52695SN/A#include <string> 53695SN/A 546129Snate@binkert.org#include "base/cast.hh" 5512334Sgabeblack@google.com#include "base/logging.hh" 5611793Sbrandon.potter@amd.com#include "base/stats/info.hh" 576129Snate@binkert.org#include "base/str.hh" 58695SN/A 59695SN/Ausing namespace std; 60695SN/A 61695SN/A#ifndef NAN 62695SN/Afloat __nan(); 63695SN/A/** Define Not a number. */ 64695SN/A#define NAN (__nan()) 65695SN/A/** Need to define __nan() */ 66695SN/A#define __M5_NAN 67695SN/A#endif 68695SN/A 69695SN/A#ifdef __M5_NAN 70695SN/Afloat 71695SN/A__nan() 72695SN/A{ 73695SN/A union { 74695SN/A uint32_t ui; 75695SN/A float f; 76695SN/A } nan; 77695SN/A 78695SN/A nan.ui = 0x7fc00000; 79695SN/A return nan.f; 80695SN/A} 81695SN/A#endif 82695SN/A 83729SN/Anamespace Stats { 84695SN/A 856129Snate@binkert.orgstd::list<Info *> &statsList(); 866129Snate@binkert.org 87695SN/AText::Text() 886126Snate@binkert.org : mystream(false), stream(NULL), descriptions(false) 89695SN/A{ 90695SN/A} 91695SN/A 92695SN/AText::Text(std::ostream &stream) 936126Snate@binkert.org : mystream(false), stream(NULL), descriptions(false) 94695SN/A{ 95695SN/A open(stream); 96695SN/A} 97695SN/A 98695SN/AText::Text(const std::string &file) 996126Snate@binkert.org : mystream(false), stream(NULL), descriptions(false) 100695SN/A{ 101695SN/A open(file); 102695SN/A} 103695SN/A 104695SN/A 105695SN/AText::~Text() 106695SN/A{ 107695SN/A if (mystream) { 108695SN/A assert(stream); 109695SN/A delete stream; 110695SN/A } 111695SN/A} 112695SN/A 113695SN/Avoid 114695SN/AText::open(std::ostream &_stream) 115695SN/A{ 116695SN/A if (stream) 117695SN/A panic("stream already set!"); 118695SN/A 119695SN/A mystream = false; 120695SN/A stream = &_stream; 1215581Ssaidi@eecs.umich.edu if (!valid()) 1225581Ssaidi@eecs.umich.edu fatal("Unable to open output stream for writing\n"); 123695SN/A} 124695SN/A 125695SN/Avoid 126695SN/AText::open(const std::string &file) 127695SN/A{ 128695SN/A if (stream) 129695SN/A panic("stream already set!"); 130695SN/A 131695SN/A mystream = true; 132695SN/A stream = new ofstream(file.c_str(), ios::trunc); 1335581Ssaidi@eecs.umich.edu if (!valid()) 1345581Ssaidi@eecs.umich.edu fatal("Unable to open statistics file for writing\n"); 135695SN/A} 136695SN/A 137695SN/Abool 138695SN/AText::valid() const 139695SN/A{ 1405581Ssaidi@eecs.umich.edu return stream != NULL && stream->good(); 141695SN/A} 142695SN/A 143695SN/Avoid 1448296Snate@binkert.orgText::begin() 145695SN/A{ 146695SN/A ccprintf(*stream, "\n---------- Begin Simulation Statistics ----------\n"); 1478296Snate@binkert.org} 1488296Snate@binkert.org 1498296Snate@binkert.orgvoid 1508296Snate@binkert.orgText::end() 1518296Snate@binkert.org{ 152695SN/A ccprintf(*stream, "\n---------- End Simulation Statistics ----------\n"); 153695SN/A stream->flush(); 154695SN/A} 155695SN/A 156695SN/Abool 1575886Snate@binkert.orgText::noOutput(const Info &info) 158695SN/A{ 1597462Snate@binkert.org if (!info.flags.isSet(display)) 160695SN/A return true; 161695SN/A 1625886Snate@binkert.org if (info.prereq && info.prereq->zero()) 163695SN/A return true; 164695SN/A 165695SN/A return false; 166695SN/A} 167695SN/A 168695SN/Astring 1696126Snate@binkert.orgValueToString(Result value, int precision) 170695SN/A{ 171695SN/A stringstream val; 172695SN/A 1738946Sandreas.hansson@arm.com if (!std::isnan(value)) { 174695SN/A if (precision != -1) 175695SN/A val.precision(precision); 176695SN/A else if (value == rint(value)) 177695SN/A val.precision(0); 178695SN/A 179695SN/A val.unsetf(ios::showpoint); 180695SN/A val.setf(ios::fixed); 181695SN/A val << value; 182695SN/A } else { 1838982Snate@binkert.org val << "nan"; 184695SN/A } 185695SN/A 186695SN/A return val.str(); 187695SN/A} 188695SN/A 189695SN/Astruct ScalarPrint 190695SN/A{ 191695SN/A Result value; 192695SN/A string name; 193695SN/A string desc; 1946130Snate@binkert.org Flags flags; 195695SN/A bool descriptions; 196695SN/A int precision; 197695SN/A Result pdf; 198695SN/A Result cdf; 199695SN/A 2006211Snate@binkert.org void update(Result val, Result total); 2019743Snilay@cs.wisc.edu void operator()(ostream &stream, bool oneLine = false) const; 202695SN/A}; 203695SN/A 204695SN/Avoid 2056211Snate@binkert.orgScalarPrint::update(Result val, Result total) 2066211Snate@binkert.org{ 2076211Snate@binkert.org value = val; 2086211Snate@binkert.org if (total) { 2096211Snate@binkert.org pdf = val / total; 2106211Snate@binkert.org cdf += pdf; 2116211Snate@binkert.org } 2126211Snate@binkert.org} 2136211Snate@binkert.org 2146211Snate@binkert.orgvoid 2159743Snilay@cs.wisc.eduScalarPrint::operator()(ostream &stream, bool oneLine) const 216695SN/A{ 21710011Snilay@cs.wisc.edu if ((flags.isSet(nozero) && (!oneLine) && value == 0.0) || 2188946Sandreas.hansson@arm.com (flags.isSet(nonan) && std::isnan(value))) 219695SN/A return; 220695SN/A 221695SN/A stringstream pdfstr, cdfstr; 222695SN/A 2238946Sandreas.hansson@arm.com if (!std::isnan(pdf)) 224695SN/A ccprintf(pdfstr, "%.2f%%", pdf * 100.0); 225695SN/A 2268946Sandreas.hansson@arm.com if (!std::isnan(cdf)) 227695SN/A ccprintf(cdfstr, "%.2f%%", cdf * 100.0); 228695SN/A 2299743Snilay@cs.wisc.edu if (oneLine) { 2309743Snilay@cs.wisc.edu ccprintf(stream, " |%12s %10s %10s", 2319743Snilay@cs.wisc.edu ValueToString(value, precision), pdfstr.str(), cdfstr.str()); 2329743Snilay@cs.wisc.edu } else { 2339743Snilay@cs.wisc.edu ccprintf(stream, "%-40s %12s %10s %10s", name, 2349743Snilay@cs.wisc.edu ValueToString(value, precision), pdfstr.str(), cdfstr.str()); 235695SN/A 2369743Snilay@cs.wisc.edu if (descriptions) { 2379743Snilay@cs.wisc.edu if (!desc.empty()) 2389743Snilay@cs.wisc.edu ccprintf(stream, " # %s", desc); 2399743Snilay@cs.wisc.edu } 2409743Snilay@cs.wisc.edu stream << endl; 241695SN/A } 242695SN/A} 243695SN/A 244695SN/Astruct VectorPrint 245695SN/A{ 246695SN/A string name; 2478243Sbradley.danofsky@amd.com string separatorString; 248695SN/A string desc; 249695SN/A vector<string> subnames; 250695SN/A vector<string> subdescs; 2516130Snate@binkert.org Flags flags; 252695SN/A bool descriptions; 253695SN/A int precision; 254695SN/A VResult vec; 255695SN/A Result total; 2569839Sandreas.hansson@arm.com bool forceSubnames; 257695SN/A 258695SN/A void operator()(ostream &stream) const; 259695SN/A}; 260695SN/A 261695SN/Avoid 262695SN/AVectorPrint::operator()(std::ostream &stream) const 263695SN/A{ 2645599Snate@binkert.org size_type _size = vec.size(); 265695SN/A Result _total = 0.0; 266695SN/A 2676130Snate@binkert.org if (flags.isSet(pdf | cdf)) { 2685599Snate@binkert.org for (off_type i = 0; i < _size; ++i) { 269695SN/A _total += vec[i]; 270695SN/A } 271695SN/A } 272695SN/A 2738243Sbradley.danofsky@amd.com string base = name + separatorString; 274695SN/A 275695SN/A ScalarPrint print; 276695SN/A print.name = name; 277695SN/A print.desc = desc; 278695SN/A print.precision = precision; 279695SN/A print.descriptions = descriptions; 280695SN/A print.flags = flags; 2816211Snate@binkert.org print.pdf = _total ? 0.0 : NAN; 2826211Snate@binkert.org print.cdf = _total ? 0.0 : NAN; 283695SN/A 284695SN/A bool havesub = !subnames.empty(); 285695SN/A 286695SN/A if (_size == 1) { 2879828Ssascha.bischoff@arm.com // If forceSubnames is set, get the first subname (or index in 2889828Ssascha.bischoff@arm.com // the case where there are no subnames) and append it to the 2899828Ssascha.bischoff@arm.com // base name. 2909828Ssascha.bischoff@arm.com if (forceSubnames) 29110386Sandreas.hansson@arm.com print.name = base + (havesub ? subnames[0] : std::to_string(0)); 292695SN/A print.value = vec[0]; 293695SN/A print(stream); 2946126Snate@binkert.org return; 2956126Snate@binkert.org } 296695SN/A 2979743Snilay@cs.wisc.edu if ((!flags.isSet(nozero)) || (total != 0)) { 2989743Snilay@cs.wisc.edu if (flags.isSet(oneline)) { 2999743Snilay@cs.wisc.edu ccprintf(stream, "%-40s", name); 3009743Snilay@cs.wisc.edu print.flags = print.flags & (~nozero); 3019743Snilay@cs.wisc.edu } 302695SN/A 3039743Snilay@cs.wisc.edu for (off_type i = 0; i < _size; ++i) { 3049743Snilay@cs.wisc.edu if (havesub && (i >= subnames.size() || subnames[i].empty())) 3059743Snilay@cs.wisc.edu continue; 306695SN/A 30710386Sandreas.hansson@arm.com print.name = base + (havesub ? subnames[i] : std::to_string(i)); 3089743Snilay@cs.wisc.edu print.desc = subdescs.empty() ? desc : subdescs[i]; 3099743Snilay@cs.wisc.edu 3109743Snilay@cs.wisc.edu print.update(vec[i], _total); 3119743Snilay@cs.wisc.edu print(stream, flags.isSet(oneline)); 3129743Snilay@cs.wisc.edu } 3139743Snilay@cs.wisc.edu 3149743Snilay@cs.wisc.edu if (flags.isSet(oneline)) { 3159743Snilay@cs.wisc.edu if (descriptions) { 3169743Snilay@cs.wisc.edu if (!desc.empty()) 3179743Snilay@cs.wisc.edu ccprintf(stream, " # %s", desc); 3189743Snilay@cs.wisc.edu } 3199743Snilay@cs.wisc.edu stream << endl; 3209743Snilay@cs.wisc.edu } 3216126Snate@binkert.org } 322695SN/A 3236130Snate@binkert.org if (flags.isSet(::Stats::total)) { 3246126Snate@binkert.org print.pdf = NAN; 3256126Snate@binkert.org print.cdf = NAN; 3266126Snate@binkert.org print.name = base + "total"; 3276126Snate@binkert.org print.desc = desc; 3286126Snate@binkert.org print.value = total; 3296126Snate@binkert.org print(stream); 330695SN/A } 331695SN/A} 332695SN/A 333695SN/Astruct DistPrint 334695SN/A{ 335695SN/A string name; 3368243Sbradley.danofsky@amd.com string separatorString; 337695SN/A string desc; 3386130Snate@binkert.org Flags flags; 339695SN/A bool descriptions; 340695SN/A int precision; 341695SN/A 3426004Snate@binkert.org const DistData &data; 3436004Snate@binkert.org 3446128Snate@binkert.org DistPrint(const Text *text, const DistInfo &info); 3456128Snate@binkert.org DistPrint(const Text *text, const VectorDistInfo &info, int i); 3467505Snate@binkert.org void init(const Text *text, const Info &info); 347695SN/A void operator()(ostream &stream) const; 348695SN/A}; 349695SN/A 3506128Snate@binkert.orgDistPrint::DistPrint(const Text *text, const DistInfo &info) 3516004Snate@binkert.org : data(info.data) 3526004Snate@binkert.org{ 3537505Snate@binkert.org init(text, info); 3546004Snate@binkert.org} 3556004Snate@binkert.org 3566128Snate@binkert.orgDistPrint::DistPrint(const Text *text, const VectorDistInfo &info, int i) 3576004Snate@binkert.org : data(info.data[i]) 3586004Snate@binkert.org{ 3597505Snate@binkert.org init(text, info); 3606004Snate@binkert.org 3616004Snate@binkert.org name = info.name + "_" + 36210386Sandreas.hansson@arm.com (info.subnames[i].empty() ? (std::to_string(i)) : info.subnames[i]); 3636004Snate@binkert.org 3646004Snate@binkert.org if (!info.subdescs[i].empty()) 3656004Snate@binkert.org desc = info.subdescs[i]; 3666004Snate@binkert.org} 3676004Snate@binkert.org 3686004Snate@binkert.orgvoid 3697505Snate@binkert.orgDistPrint::init(const Text *text, const Info &info) 3706004Snate@binkert.org{ 3716004Snate@binkert.org name = info.name; 3728243Sbradley.danofsky@amd.com separatorString = info.separatorString; 3736004Snate@binkert.org desc = info.desc; 3746004Snate@binkert.org flags = info.flags; 3756004Snate@binkert.org precision = info.precision; 3766125Snate@binkert.org descriptions = text->descriptions; 3776004Snate@binkert.org} 3786004Snate@binkert.org 379695SN/Avoid 380695SN/ADistPrint::operator()(ostream &stream) const 381695SN/A{ 38210011Snilay@cs.wisc.edu if (flags.isSet(nozero) && data.samples == 0) return; 3838243Sbradley.danofsky@amd.com string base = name + separatorString; 384695SN/A 385695SN/A ScalarPrint print; 3866211Snate@binkert.org print.precision = precision; 387695SN/A print.flags = flags; 388695SN/A print.descriptions = descriptions; 3896211Snate@binkert.org print.desc = desc; 390695SN/A print.pdf = NAN; 391695SN/A print.cdf = NAN; 392695SN/A 39310011Snilay@cs.wisc.edu if (flags.isSet(oneline)) { 39410011Snilay@cs.wisc.edu print.name = base + "bucket_size"; 39510011Snilay@cs.wisc.edu print.value = data.bucket_size; 39610011Snilay@cs.wisc.edu print(stream); 39710011Snilay@cs.wisc.edu 39810011Snilay@cs.wisc.edu print.name = base + "min_bucket"; 39910011Snilay@cs.wisc.edu print.value = data.min; 40010011Snilay@cs.wisc.edu print(stream); 40110011Snilay@cs.wisc.edu 40210011Snilay@cs.wisc.edu print.name = base + "max_bucket"; 40310011Snilay@cs.wisc.edu print.value = data.max; 40410011Snilay@cs.wisc.edu print(stream); 40510011Snilay@cs.wisc.edu } 40610011Snilay@cs.wisc.edu 407695SN/A print.name = base + "samples"; 4086004Snate@binkert.org print.value = data.samples; 409695SN/A print(stream); 410695SN/A 4116211Snate@binkert.org print.name = base + "mean"; 4126211Snate@binkert.org print.value = data.samples ? data.sum / data.samples : NAN; 413695SN/A print(stream); 414695SN/A 4158666SPrakash.Ramrakhyani@arm.com if (data.type == Hist) { 4168666SPrakash.Ramrakhyani@arm.com print.name = base + "gmean"; 4178666SPrakash.Ramrakhyani@arm.com print.value = data.samples ? exp(data.logs / data.samples) : NAN; 4188666SPrakash.Ramrakhyani@arm.com print(stream); 4198666SPrakash.Ramrakhyani@arm.com } 4208666SPrakash.Ramrakhyani@arm.com 4216211Snate@binkert.org Result stdev = NAN; 4226211Snate@binkert.org if (data.samples) 4236211Snate@binkert.org stdev = sqrt((data.samples * data.squares - data.sum * data.sum) / 4246211Snate@binkert.org (data.samples * (data.samples - 1.0))); 4256211Snate@binkert.org print.name = base + "stdev"; 4266211Snate@binkert.org print.value = stdev; 4276211Snate@binkert.org print(stream); 4286211Snate@binkert.org 4297505Snate@binkert.org if (data.type == Deviation) 4306211Snate@binkert.org return; 4316211Snate@binkert.org 4327505Snate@binkert.org size_t size = data.cvec.size(); 4336211Snate@binkert.org 4346211Snate@binkert.org Result total = 0.0; 4357831Snate@binkert.org if (data.type == Dist && data.underflow != NAN) 4366211Snate@binkert.org total += data.underflow; 4376211Snate@binkert.org for (off_type i = 0; i < size; ++i) 4386211Snate@binkert.org total += data.cvec[i]; 4397831Snate@binkert.org if (data.type == Dist && data.overflow != NAN) 4406211Snate@binkert.org total += data.overflow; 4416211Snate@binkert.org 4426126Snate@binkert.org if (total) { 4436211Snate@binkert.org print.pdf = 0.0; 4446211Snate@binkert.org print.cdf = 0.0; 4456126Snate@binkert.org } 4466211Snate@binkert.org 4477831Snate@binkert.org if (data.type == Dist && data.underflow != NAN) { 4486211Snate@binkert.org print.name = base + "underflows"; 4496211Snate@binkert.org print.update(data.underflow, total); 4506211Snate@binkert.org print(stream); 4516211Snate@binkert.org } 4526126Snate@binkert.org 45310011Snilay@cs.wisc.edu if (flags.isSet(oneline)) { 45410011Snilay@cs.wisc.edu ccprintf(stream, "%-40s", name); 45510011Snilay@cs.wisc.edu } 45610011Snilay@cs.wisc.edu 4576126Snate@binkert.org for (off_type i = 0; i < size; ++i) { 4586126Snate@binkert.org stringstream namestr; 4596126Snate@binkert.org namestr << base; 4606126Snate@binkert.org 4617505Snate@binkert.org Counter low = i * data.bucket_size + data.min; 4627505Snate@binkert.org Counter high = ::min(low + data.bucket_size - 1.0, data.max); 4636126Snate@binkert.org namestr << low; 4646126Snate@binkert.org if (low < high) 4656126Snate@binkert.org namestr << "-" << high; 4666126Snate@binkert.org 4676126Snate@binkert.org print.name = namestr.str(); 4686211Snate@binkert.org print.update(data.cvec[i], total); 46910011Snilay@cs.wisc.edu print(stream, flags.isSet(oneline)); 47010011Snilay@cs.wisc.edu } 47110011Snilay@cs.wisc.edu 47210011Snilay@cs.wisc.edu if (flags.isSet(oneline)) { 47310011Snilay@cs.wisc.edu if (descriptions) { 47410011Snilay@cs.wisc.edu if (!desc.empty()) 47510011Snilay@cs.wisc.edu ccprintf(stream, " # %s", desc); 47610011Snilay@cs.wisc.edu } 47710011Snilay@cs.wisc.edu stream << endl; 478695SN/A } 479695SN/A 4807831Snate@binkert.org if (data.type == Dist && data.overflow != NAN) { 4816211Snate@binkert.org print.name = base + "overflows"; 4826211Snate@binkert.org print.update(data.overflow, total); 4836211Snate@binkert.org print(stream); 484695SN/A } 485695SN/A 486695SN/A print.pdf = NAN; 487695SN/A print.cdf = NAN; 488695SN/A 4897831Snate@binkert.org if (data.type == Dist && data.min_val != NAN) { 4906211Snate@binkert.org print.name = base + "min_value"; 4916211Snate@binkert.org print.value = data.min_val; 4926211Snate@binkert.org print(stream); 4936211Snate@binkert.org } 4946211Snate@binkert.org 4957831Snate@binkert.org if (data.type == Dist && data.max_val != NAN) { 4966211Snate@binkert.org print.name = base + "max_value"; 4976211Snate@binkert.org print.value = data.max_val; 4986211Snate@binkert.org print(stream); 4996211Snate@binkert.org } 5006211Snate@binkert.org 5016126Snate@binkert.org print.name = base + "total"; 5026126Snate@binkert.org print.value = total; 5036126Snate@binkert.org print(stream); 504695SN/A} 505695SN/A 506695SN/Avoid 5076128Snate@binkert.orgText::visit(const ScalarInfo &info) 508695SN/A{ 5095886Snate@binkert.org if (noOutput(info)) 510695SN/A return; 511695SN/A 512695SN/A ScalarPrint print; 5135886Snate@binkert.org print.value = info.result(); 5145886Snate@binkert.org print.name = info.name; 5155886Snate@binkert.org print.desc = info.desc; 5165886Snate@binkert.org print.flags = info.flags; 517695SN/A print.descriptions = descriptions; 5185886Snate@binkert.org print.precision = info.precision; 519695SN/A print.pdf = NAN; 520695SN/A print.cdf = NAN; 521695SN/A 522695SN/A print(*stream); 523695SN/A} 524695SN/A 525695SN/Avoid 5266128Snate@binkert.orgText::visit(const VectorInfo &info) 527695SN/A{ 5285886Snate@binkert.org if (noOutput(info)) 529695SN/A return; 530695SN/A 5315886Snate@binkert.org size_type size = info.size(); 532695SN/A VectorPrint print; 533695SN/A 5345886Snate@binkert.org print.name = info.name; 5358243Sbradley.danofsky@amd.com print.separatorString = info.separatorString; 5365886Snate@binkert.org print.desc = info.desc; 5375886Snate@binkert.org print.flags = info.flags; 538695SN/A print.descriptions = descriptions; 5395886Snate@binkert.org print.precision = info.precision; 5405886Snate@binkert.org print.vec = info.result(); 5415886Snate@binkert.org print.total = info.total(); 5429839Sandreas.hansson@arm.com print.forceSubnames = false; 543695SN/A 5445886Snate@binkert.org if (!info.subnames.empty()) { 5455599Snate@binkert.org for (off_type i = 0; i < size; ++i) { 5465886Snate@binkert.org if (!info.subnames[i].empty()) { 5475886Snate@binkert.org print.subnames = info.subnames; 548695SN/A print.subnames.resize(size); 5495599Snate@binkert.org for (off_type i = 0; i < size; ++i) { 5505886Snate@binkert.org if (!info.subnames[i].empty() && 5515886Snate@binkert.org !info.subdescs[i].empty()) { 5525886Snate@binkert.org print.subdescs = info.subdescs; 553695SN/A print.subdescs.resize(size); 554695SN/A break; 555695SN/A } 556695SN/A } 557695SN/A break; 558695SN/A } 559695SN/A } 560695SN/A } 561695SN/A 562695SN/A print(*stream); 563695SN/A} 564695SN/A 565695SN/Avoid 5666128Snate@binkert.orgText::visit(const Vector2dInfo &info) 567695SN/A{ 5685886Snate@binkert.org if (noOutput(info)) 569695SN/A return; 570695SN/A 571695SN/A bool havesub = false; 572695SN/A VectorPrint print; 573695SN/A 5748667Sdam.sunwoo@arm.com if (!info.y_subnames.empty()) { 5758667Sdam.sunwoo@arm.com for (off_type i = 0; i < info.y; ++i) { 5768667Sdam.sunwoo@arm.com if (!info.y_subnames[i].empty()) { 5778667Sdam.sunwoo@arm.com print.subnames = info.y_subnames; 57810374Sandreas.hansson@arm.com break; 5798667Sdam.sunwoo@arm.com } 5808667Sdam.sunwoo@arm.com } 5818667Sdam.sunwoo@arm.com } 5825886Snate@binkert.org print.flags = info.flags; 5838243Sbradley.danofsky@amd.com print.separatorString = info.separatorString; 584695SN/A print.descriptions = descriptions; 5855886Snate@binkert.org print.precision = info.precision; 5869828Ssascha.bischoff@arm.com print.forceSubnames = true; 587695SN/A 5885886Snate@binkert.org if (!info.subnames.empty()) { 5895886Snate@binkert.org for (off_type i = 0; i < info.x; ++i) 5905886Snate@binkert.org if (!info.subnames[i].empty()) 591695SN/A havesub = true; 592695SN/A } 593695SN/A 5945886Snate@binkert.org VResult tot_vec(info.y); 5955886Snate@binkert.org for (off_type i = 0; i < info.x; ++i) { 5965886Snate@binkert.org if (havesub && (i >= info.subnames.size() || info.subnames[i].empty())) 597695SN/A continue; 598695SN/A 5995886Snate@binkert.org off_type iy = i * info.y; 6005886Snate@binkert.org VResult yvec(info.y); 601695SN/A 602695SN/A Result total = 0.0; 6035886Snate@binkert.org for (off_type j = 0; j < info.y; ++j) { 6045886Snate@binkert.org yvec[j] = info.cvec[iy + j]; 605695SN/A tot_vec[j] += yvec[j]; 606695SN/A total += yvec[j]; 607695SN/A } 608695SN/A 6095886Snate@binkert.org print.name = info.name + "_" + 61010386Sandreas.hansson@arm.com (havesub ? info.subnames[i] : std::to_string(i)); 6115886Snate@binkert.org print.desc = info.desc; 612695SN/A print.vec = yvec; 613695SN/A print.total = total; 614695SN/A print(*stream); 615695SN/A } 616695SN/A 6179828Ssascha.bischoff@arm.com // Create a subname for printing the total 6189828Ssascha.bischoff@arm.com vector<string> total_subname; 6199828Ssascha.bischoff@arm.com total_subname.push_back("total"); 6209828Ssascha.bischoff@arm.com 6216130Snate@binkert.org if (info.flags.isSet(::Stats::total) && (info.x > 1)) { 6225886Snate@binkert.org print.name = info.name; 6239828Ssascha.bischoff@arm.com print.subnames = total_subname; 6245886Snate@binkert.org print.desc = info.desc; 62511565Sdavid.guillen@arm.com print.vec = VResult(1, info.total()); 6269828Ssascha.bischoff@arm.com print.flags = print.flags & ~total; 627695SN/A print(*stream); 628695SN/A } 629695SN/A} 630695SN/A 631695SN/Avoid 6326128Snate@binkert.orgText::visit(const DistInfo &info) 633695SN/A{ 6345886Snate@binkert.org if (noOutput(info)) 635695SN/A return; 636695SN/A 6376125Snate@binkert.org DistPrint print(this, info); 638695SN/A print(*stream); 639695SN/A} 640695SN/A 641695SN/Avoid 6426128Snate@binkert.orgText::visit(const VectorDistInfo &info) 643695SN/A{ 6445886Snate@binkert.org if (noOutput(info)) 645695SN/A return; 646695SN/A 6475886Snate@binkert.org for (off_type i = 0; i < info.size(); ++i) { 6486125Snate@binkert.org DistPrint print(this, info, i); 649695SN/A print(*stream); 650695SN/A } 651695SN/A} 652695SN/A 653695SN/Avoid 6546128Snate@binkert.orgText::visit(const FormulaInfo &info) 655695SN/A{ 6566128Snate@binkert.org visit((const VectorInfo &)info); 657695SN/A} 658695SN/A 6598514SThomas.Grass@ARM.com/* 6608514SThomas.Grass@ARM.com This struct implements the output methods for the sparse 6618514SThomas.Grass@ARM.com histogram stat 6628514SThomas.Grass@ARM.com*/ 6638514SThomas.Grass@ARM.comstruct SparseHistPrint 6648514SThomas.Grass@ARM.com{ 6658514SThomas.Grass@ARM.com string name; 6668514SThomas.Grass@ARM.com string separatorString; 6678514SThomas.Grass@ARM.com string desc; 6688514SThomas.Grass@ARM.com Flags flags; 6698514SThomas.Grass@ARM.com bool descriptions; 6708514SThomas.Grass@ARM.com int precision; 6718514SThomas.Grass@ARM.com 6728514SThomas.Grass@ARM.com const SparseHistData &data; 6738514SThomas.Grass@ARM.com 6748514SThomas.Grass@ARM.com SparseHistPrint(const Text *text, const SparseHistInfo &info); 6758514SThomas.Grass@ARM.com void init(const Text *text, const Info &info); 6768514SThomas.Grass@ARM.com void operator()(ostream &stream) const; 6778514SThomas.Grass@ARM.com}; 6788514SThomas.Grass@ARM.com 6798514SThomas.Grass@ARM.com/* Call initialization function */ 6808514SThomas.Grass@ARM.comSparseHistPrint::SparseHistPrint(const Text *text, const SparseHistInfo &info) 6818514SThomas.Grass@ARM.com : data(info.data) 6828514SThomas.Grass@ARM.com{ 6838514SThomas.Grass@ARM.com init(text, info); 6848514SThomas.Grass@ARM.com} 6858514SThomas.Grass@ARM.com 6868514SThomas.Grass@ARM.com/* Initialization function */ 6878514SThomas.Grass@ARM.comvoid 6888514SThomas.Grass@ARM.comSparseHistPrint::init(const Text *text, const Info &info) 6898514SThomas.Grass@ARM.com{ 6908514SThomas.Grass@ARM.com name = info.name; 6918514SThomas.Grass@ARM.com separatorString = info.separatorString; 6928514SThomas.Grass@ARM.com desc = info.desc; 6938514SThomas.Grass@ARM.com flags = info.flags; 6948514SThomas.Grass@ARM.com precision = info.precision; 6958514SThomas.Grass@ARM.com descriptions = text->descriptions; 6968514SThomas.Grass@ARM.com} 6978514SThomas.Grass@ARM.com 6988514SThomas.Grass@ARM.com/* Grab data from map and write to output stream */ 6998514SThomas.Grass@ARM.comvoid 7008514SThomas.Grass@ARM.comSparseHistPrint::operator()(ostream &stream) const 7018514SThomas.Grass@ARM.com{ 7028514SThomas.Grass@ARM.com string base = name + separatorString; 7038514SThomas.Grass@ARM.com 7048514SThomas.Grass@ARM.com ScalarPrint print; 7058514SThomas.Grass@ARM.com print.precision = precision; 7068514SThomas.Grass@ARM.com print.flags = flags; 7078514SThomas.Grass@ARM.com print.descriptions = descriptions; 7088514SThomas.Grass@ARM.com print.desc = desc; 7098514SThomas.Grass@ARM.com print.pdf = NAN; 7108514SThomas.Grass@ARM.com print.cdf = NAN; 7118514SThomas.Grass@ARM.com 7128514SThomas.Grass@ARM.com print.name = base + "samples"; 7138514SThomas.Grass@ARM.com print.value = data.samples; 7148514SThomas.Grass@ARM.com print(stream); 7158514SThomas.Grass@ARM.com 7168514SThomas.Grass@ARM.com MCounter::const_iterator it; 7178514SThomas.Grass@ARM.com for (it = data.cmap.begin(); it != data.cmap.end(); it++) { 7188514SThomas.Grass@ARM.com stringstream namestr; 7198514SThomas.Grass@ARM.com namestr << base; 7208514SThomas.Grass@ARM.com 7218514SThomas.Grass@ARM.com namestr <<(*it).first; 7228514SThomas.Grass@ARM.com print.name = namestr.str(); 7238514SThomas.Grass@ARM.com print.value = (*it).second; 7248514SThomas.Grass@ARM.com print(stream); 7258514SThomas.Grass@ARM.com } 7268514SThomas.Grass@ARM.com} 7278514SThomas.Grass@ARM.com 7288514SThomas.Grass@ARM.comvoid 7298514SThomas.Grass@ARM.comText::visit(const SparseHistInfo &info) 7308514SThomas.Grass@ARM.com{ 7318514SThomas.Grass@ARM.com if (noOutput(info)) 7328514SThomas.Grass@ARM.com return; 7338514SThomas.Grass@ARM.com 7348514SThomas.Grass@ARM.com SparseHistPrint print(this, info); 7358514SThomas.Grass@ARM.com print(*stream); 7368514SThomas.Grass@ARM.com} 7378514SThomas.Grass@ARM.com 7388296Snate@binkert.orgOutput * 7396126Snate@binkert.orginitText(const string &filename, bool desc) 7404078Sbinkertn@umich.edu{ 7414078Sbinkertn@umich.edu static Text text; 7424078Sbinkertn@umich.edu static bool connected = false; 7434078Sbinkertn@umich.edu 7448296Snate@binkert.org if (!connected) { 74511359Sandreas@sandberg.pp.se text.open(*simout.findOrCreate(filename)->stream()); 7468296Snate@binkert.org text.descriptions = desc; 7478296Snate@binkert.org connected = true; 7488296Snate@binkert.org } 7494078Sbinkertn@umich.edu 7508296Snate@binkert.org return &text; 7514078Sbinkertn@umich.edu} 7524078Sbinkertn@umich.edu 7537811Ssteve.reinhardt@amd.com} // namespace Stats 754