1695SN/A/* 214205Sandreas.sandberg@arm.com * Copyright (c) 2019 Arm Limited 314205Sandreas.sandberg@arm.com * All rights reserved. 414205Sandreas.sandberg@arm.com * 514205Sandreas.sandberg@arm.com * The license below extends only to copyright in the software and shall 614205Sandreas.sandberg@arm.com * not be construed as granting a license to any other intellectual 714205Sandreas.sandberg@arm.com * property including but not limited to intellectual property relating 814205Sandreas.sandberg@arm.com * to a hardware implementation of the functionality of the software 914205Sandreas.sandberg@arm.com * licensed hereunder. You may use the software subject to the license 1014205Sandreas.sandberg@arm.com * terms below provided that you ensure that this notice is replicated 1114205Sandreas.sandberg@arm.com * unmodified and in its entirety in all distributions of the software, 1214205Sandreas.sandberg@arm.com * modified or unmodified, in source code or in binary form. 1314205Sandreas.sandberg@arm.com * 141762SN/A * Copyright (c) 2004-2005 The Regents of The University of Michigan 15695SN/A * All rights reserved. 16695SN/A * 17695SN/A * Redistribution and use in source and binary forms, with or without 18695SN/A * modification, are permitted provided that the following conditions are 19695SN/A * met: redistributions of source code must retain the above copyright 20695SN/A * notice, this list of conditions and the following disclaimer; 21695SN/A * redistributions in binary form must reproduce the above copyright 22695SN/A * notice, this list of conditions and the following disclaimer in the 23695SN/A * documentation and/or other materials provided with the distribution; 24695SN/A * neither the name of the copyright holders nor the names of its 25695SN/A * contributors may be used to endorse or promote products derived from 26695SN/A * this software without specific prior written permission. 27695SN/A * 28695SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 29695SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 30695SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 31695SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 32695SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 33695SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 34695SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 35695SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 36695SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 37695SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 38695SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 392665Ssaidi@eecs.umich.edu * 402665Ssaidi@eecs.umich.edu * Authors: Nathan Binkert 41695SN/A */ 42695SN/A 43873SN/A#if defined(__APPLE__) 44873SN/A#define _GLIBCPP_USE_C99 1 45873SN/A#endif 46873SN/A 473918Ssaidi@eecs.umich.edu#if defined(__sun) 4811793Sbrandon.potter@amd.com#include <cmath> 4911793Sbrandon.potter@amd.com 503918Ssaidi@eecs.umich.edu#endif 513918Ssaidi@eecs.umich.edu 526129Snate@binkert.org#include <cassert> 5311793Sbrandon.potter@amd.com 546129Snate@binkert.org#ifdef __SUNPRO_CC 5511793Sbrandon.potter@amd.com#include <cmath> 5611793Sbrandon.potter@amd.com 576129Snate@binkert.org#endif 5811793Sbrandon.potter@amd.com#include "base/stats/text.hh" 5911793Sbrandon.potter@amd.com 606129Snate@binkert.org#include <cmath> 618229Snate@binkert.org#include <fstream> 62695SN/A#include <iostream> 632621SN/A#include <sstream> 64695SN/A#include <string> 65695SN/A 666129Snate@binkert.org#include "base/cast.hh" 6712334Sgabeblack@google.com#include "base/logging.hh" 6811793Sbrandon.potter@amd.com#include "base/stats/info.hh" 696129Snate@binkert.org#include "base/str.hh" 70695SN/A 71695SN/Ausing namespace std; 72695SN/A 73695SN/A#ifndef NAN 74695SN/Afloat __nan(); 75695SN/A/** Define Not a number. */ 76695SN/A#define NAN (__nan()) 77695SN/A/** Need to define __nan() */ 78695SN/A#define __M5_NAN 79695SN/A#endif 80695SN/A 81695SN/A#ifdef __M5_NAN 82695SN/Afloat 83695SN/A__nan() 84695SN/A{ 85695SN/A union { 86695SN/A uint32_t ui; 87695SN/A float f; 88695SN/A } nan; 89695SN/A 90695SN/A nan.ui = 0x7fc00000; 91695SN/A return nan.f; 92695SN/A} 93695SN/A#endif 94695SN/A 95729SN/Anamespace Stats { 96695SN/A 976129Snate@binkert.orgstd::list<Info *> &statsList(); 986129Snate@binkert.org 99695SN/AText::Text() 1006126Snate@binkert.org : mystream(false), stream(NULL), descriptions(false) 101695SN/A{ 102695SN/A} 103695SN/A 104695SN/AText::Text(std::ostream &stream) 1056126Snate@binkert.org : mystream(false), stream(NULL), descriptions(false) 106695SN/A{ 107695SN/A open(stream); 108695SN/A} 109695SN/A 110695SN/AText::Text(const std::string &file) 1116126Snate@binkert.org : mystream(false), stream(NULL), descriptions(false) 112695SN/A{ 113695SN/A open(file); 114695SN/A} 115695SN/A 116695SN/A 117695SN/AText::~Text() 118695SN/A{ 119695SN/A if (mystream) { 120695SN/A assert(stream); 121695SN/A delete stream; 122695SN/A } 123695SN/A} 124695SN/A 125695SN/Avoid 126695SN/AText::open(std::ostream &_stream) 127695SN/A{ 128695SN/A if (stream) 129695SN/A panic("stream already set!"); 130695SN/A 131695SN/A mystream = false; 132695SN/A stream = &_stream; 1335581Ssaidi@eecs.umich.edu if (!valid()) 1345581Ssaidi@eecs.umich.edu fatal("Unable to open output stream for writing\n"); 135695SN/A} 136695SN/A 137695SN/Avoid 138695SN/AText::open(const std::string &file) 139695SN/A{ 140695SN/A if (stream) 141695SN/A panic("stream already set!"); 142695SN/A 143695SN/A mystream = true; 144695SN/A stream = new ofstream(file.c_str(), ios::trunc); 1455581Ssaidi@eecs.umich.edu if (!valid()) 1465581Ssaidi@eecs.umich.edu fatal("Unable to open statistics file for writing\n"); 147695SN/A} 148695SN/A 149695SN/Abool 150695SN/AText::valid() const 151695SN/A{ 1525581Ssaidi@eecs.umich.edu return stream != NULL && stream->good(); 153695SN/A} 154695SN/A 155695SN/Avoid 1568296Snate@binkert.orgText::begin() 157695SN/A{ 158695SN/A ccprintf(*stream, "\n---------- Begin Simulation Statistics ----------\n"); 1598296Snate@binkert.org} 1608296Snate@binkert.org 1618296Snate@binkert.orgvoid 1628296Snate@binkert.orgText::end() 1638296Snate@binkert.org{ 164695SN/A ccprintf(*stream, "\n---------- End Simulation Statistics ----------\n"); 165695SN/A stream->flush(); 166695SN/A} 167695SN/A 16814205Sandreas.sandberg@arm.comstd::string 16914205Sandreas.sandberg@arm.comText::statName(const std::string &name) const 17014205Sandreas.sandberg@arm.com{ 17114205Sandreas.sandberg@arm.com if (path.empty()) 17214205Sandreas.sandberg@arm.com return name; 17314205Sandreas.sandberg@arm.com else 17414205Sandreas.sandberg@arm.com return csprintf("%s.%s", path.top(), name); 17514205Sandreas.sandberg@arm.com} 17614205Sandreas.sandberg@arm.com 17714205Sandreas.sandberg@arm.comvoid 17814205Sandreas.sandberg@arm.comText::beginGroup(const char *name) 17914205Sandreas.sandberg@arm.com{ 18014205Sandreas.sandberg@arm.com if (path.empty()) { 18114205Sandreas.sandberg@arm.com path.push(name); 18214205Sandreas.sandberg@arm.com } else { 18314205Sandreas.sandberg@arm.com path.push(csprintf("%s.%s", path.top(), name)); 18414205Sandreas.sandberg@arm.com } 18514205Sandreas.sandberg@arm.com} 18614205Sandreas.sandberg@arm.com 18714205Sandreas.sandberg@arm.comvoid 18814205Sandreas.sandberg@arm.comText::endGroup() 18914205Sandreas.sandberg@arm.com{ 19014205Sandreas.sandberg@arm.com assert(!path.empty()); 19114205Sandreas.sandberg@arm.com path.pop(); 19214205Sandreas.sandberg@arm.com} 19314205Sandreas.sandberg@arm.com 194695SN/Abool 1955886Snate@binkert.orgText::noOutput(const Info &info) 196695SN/A{ 1977462Snate@binkert.org if (!info.flags.isSet(display)) 198695SN/A return true; 199695SN/A 2005886Snate@binkert.org if (info.prereq && info.prereq->zero()) 201695SN/A return true; 202695SN/A 203695SN/A return false; 204695SN/A} 205695SN/A 206695SN/Astring 2076126Snate@binkert.orgValueToString(Result value, int precision) 208695SN/A{ 209695SN/A stringstream val; 210695SN/A 2118946Sandreas.hansson@arm.com if (!std::isnan(value)) { 212695SN/A if (precision != -1) 213695SN/A val.precision(precision); 214695SN/A else if (value == rint(value)) 215695SN/A val.precision(0); 216695SN/A 217695SN/A val.unsetf(ios::showpoint); 218695SN/A val.setf(ios::fixed); 219695SN/A val << value; 220695SN/A } else { 2218982Snate@binkert.org val << "nan"; 222695SN/A } 223695SN/A 224695SN/A return val.str(); 225695SN/A} 226695SN/A 227695SN/Astruct ScalarPrint 228695SN/A{ 229695SN/A Result value; 230695SN/A string name; 231695SN/A string desc; 2326130Snate@binkert.org Flags flags; 233695SN/A bool descriptions; 234695SN/A int precision; 235695SN/A Result pdf; 236695SN/A Result cdf; 237695SN/A 2386211Snate@binkert.org void update(Result val, Result total); 2399743Snilay@cs.wisc.edu void operator()(ostream &stream, bool oneLine = false) const; 240695SN/A}; 241695SN/A 242695SN/Avoid 2436211Snate@binkert.orgScalarPrint::update(Result val, Result total) 2446211Snate@binkert.org{ 2456211Snate@binkert.org value = val; 2466211Snate@binkert.org if (total) { 2476211Snate@binkert.org pdf = val / total; 2486211Snate@binkert.org cdf += pdf; 2496211Snate@binkert.org } 2506211Snate@binkert.org} 2516211Snate@binkert.org 2526211Snate@binkert.orgvoid 2539743Snilay@cs.wisc.eduScalarPrint::operator()(ostream &stream, bool oneLine) const 254695SN/A{ 25510011Snilay@cs.wisc.edu if ((flags.isSet(nozero) && (!oneLine) && value == 0.0) || 2568946Sandreas.hansson@arm.com (flags.isSet(nonan) && std::isnan(value))) 257695SN/A return; 258695SN/A 259695SN/A stringstream pdfstr, cdfstr; 260695SN/A 2618946Sandreas.hansson@arm.com if (!std::isnan(pdf)) 262695SN/A ccprintf(pdfstr, "%.2f%%", pdf * 100.0); 263695SN/A 2648946Sandreas.hansson@arm.com if (!std::isnan(cdf)) 265695SN/A ccprintf(cdfstr, "%.2f%%", cdf * 100.0); 266695SN/A 2679743Snilay@cs.wisc.edu if (oneLine) { 2689743Snilay@cs.wisc.edu ccprintf(stream, " |%12s %10s %10s", 2699743Snilay@cs.wisc.edu ValueToString(value, precision), pdfstr.str(), cdfstr.str()); 2709743Snilay@cs.wisc.edu } else { 2719743Snilay@cs.wisc.edu ccprintf(stream, "%-40s %12s %10s %10s", name, 2729743Snilay@cs.wisc.edu ValueToString(value, precision), pdfstr.str(), cdfstr.str()); 273695SN/A 2749743Snilay@cs.wisc.edu if (descriptions) { 2759743Snilay@cs.wisc.edu if (!desc.empty()) 2769743Snilay@cs.wisc.edu ccprintf(stream, " # %s", desc); 2779743Snilay@cs.wisc.edu } 2789743Snilay@cs.wisc.edu stream << endl; 279695SN/A } 280695SN/A} 281695SN/A 282695SN/Astruct VectorPrint 283695SN/A{ 284695SN/A string name; 2858243Sbradley.danofsky@amd.com string separatorString; 286695SN/A string desc; 287695SN/A vector<string> subnames; 288695SN/A vector<string> subdescs; 2896130Snate@binkert.org Flags flags; 290695SN/A bool descriptions; 291695SN/A int precision; 292695SN/A VResult vec; 293695SN/A Result total; 2949839Sandreas.hansson@arm.com bool forceSubnames; 295695SN/A 296695SN/A void operator()(ostream &stream) const; 297695SN/A}; 298695SN/A 299695SN/Avoid 300695SN/AVectorPrint::operator()(std::ostream &stream) const 301695SN/A{ 3025599Snate@binkert.org size_type _size = vec.size(); 303695SN/A Result _total = 0.0; 304695SN/A 3056130Snate@binkert.org if (flags.isSet(pdf | cdf)) { 3065599Snate@binkert.org for (off_type i = 0; i < _size; ++i) { 307695SN/A _total += vec[i]; 308695SN/A } 309695SN/A } 310695SN/A 3118243Sbradley.danofsky@amd.com string base = name + separatorString; 312695SN/A 313695SN/A ScalarPrint print; 314695SN/A print.name = name; 315695SN/A print.desc = desc; 316695SN/A print.precision = precision; 317695SN/A print.descriptions = descriptions; 318695SN/A print.flags = flags; 3196211Snate@binkert.org print.pdf = _total ? 0.0 : NAN; 3206211Snate@binkert.org print.cdf = _total ? 0.0 : NAN; 321695SN/A 322695SN/A bool havesub = !subnames.empty(); 323695SN/A 324695SN/A if (_size == 1) { 3259828Ssascha.bischoff@arm.com // If forceSubnames is set, get the first subname (or index in 3269828Ssascha.bischoff@arm.com // the case where there are no subnames) and append it to the 3279828Ssascha.bischoff@arm.com // base name. 3289828Ssascha.bischoff@arm.com if (forceSubnames) 32910386Sandreas.hansson@arm.com print.name = base + (havesub ? subnames[0] : std::to_string(0)); 330695SN/A print.value = vec[0]; 331695SN/A print(stream); 3326126Snate@binkert.org return; 3336126Snate@binkert.org } 334695SN/A 3359743Snilay@cs.wisc.edu if ((!flags.isSet(nozero)) || (total != 0)) { 3369743Snilay@cs.wisc.edu if (flags.isSet(oneline)) { 3379743Snilay@cs.wisc.edu ccprintf(stream, "%-40s", name); 3389743Snilay@cs.wisc.edu print.flags = print.flags & (~nozero); 3399743Snilay@cs.wisc.edu } 340695SN/A 3419743Snilay@cs.wisc.edu for (off_type i = 0; i < _size; ++i) { 3429743Snilay@cs.wisc.edu if (havesub && (i >= subnames.size() || subnames[i].empty())) 3439743Snilay@cs.wisc.edu continue; 344695SN/A 34510386Sandreas.hansson@arm.com print.name = base + (havesub ? subnames[i] : std::to_string(i)); 3469743Snilay@cs.wisc.edu print.desc = subdescs.empty() ? desc : subdescs[i]; 3479743Snilay@cs.wisc.edu 3489743Snilay@cs.wisc.edu print.update(vec[i], _total); 3499743Snilay@cs.wisc.edu print(stream, flags.isSet(oneline)); 3509743Snilay@cs.wisc.edu } 3519743Snilay@cs.wisc.edu 3529743Snilay@cs.wisc.edu if (flags.isSet(oneline)) { 3539743Snilay@cs.wisc.edu if (descriptions) { 3549743Snilay@cs.wisc.edu if (!desc.empty()) 3559743Snilay@cs.wisc.edu ccprintf(stream, " # %s", desc); 3569743Snilay@cs.wisc.edu } 3579743Snilay@cs.wisc.edu stream << endl; 3589743Snilay@cs.wisc.edu } 3596126Snate@binkert.org } 360695SN/A 3616130Snate@binkert.org if (flags.isSet(::Stats::total)) { 3626126Snate@binkert.org print.pdf = NAN; 3636126Snate@binkert.org print.cdf = NAN; 3646126Snate@binkert.org print.name = base + "total"; 3656126Snate@binkert.org print.desc = desc; 3666126Snate@binkert.org print.value = total; 3676126Snate@binkert.org print(stream); 368695SN/A } 369695SN/A} 370695SN/A 371695SN/Astruct DistPrint 372695SN/A{ 373695SN/A string name; 3748243Sbradley.danofsky@amd.com string separatorString; 375695SN/A string desc; 3766130Snate@binkert.org Flags flags; 377695SN/A bool descriptions; 378695SN/A int precision; 379695SN/A 3806004Snate@binkert.org const DistData &data; 3816004Snate@binkert.org 3826128Snate@binkert.org DistPrint(const Text *text, const DistInfo &info); 3836128Snate@binkert.org DistPrint(const Text *text, const VectorDistInfo &info, int i); 3847505Snate@binkert.org void init(const Text *text, const Info &info); 385695SN/A void operator()(ostream &stream) const; 386695SN/A}; 387695SN/A 3886128Snate@binkert.orgDistPrint::DistPrint(const Text *text, const DistInfo &info) 3896004Snate@binkert.org : data(info.data) 3906004Snate@binkert.org{ 3917505Snate@binkert.org init(text, info); 3926004Snate@binkert.org} 3936004Snate@binkert.org 3946128Snate@binkert.orgDistPrint::DistPrint(const Text *text, const VectorDistInfo &info, int i) 3956004Snate@binkert.org : data(info.data[i]) 3966004Snate@binkert.org{ 3977505Snate@binkert.org init(text, info); 3986004Snate@binkert.org 3996004Snate@binkert.org name = info.name + "_" + 40010386Sandreas.hansson@arm.com (info.subnames[i].empty() ? (std::to_string(i)) : info.subnames[i]); 4016004Snate@binkert.org 4026004Snate@binkert.org if (!info.subdescs[i].empty()) 4036004Snate@binkert.org desc = info.subdescs[i]; 4046004Snate@binkert.org} 4056004Snate@binkert.org 4066004Snate@binkert.orgvoid 4077505Snate@binkert.orgDistPrint::init(const Text *text, const Info &info) 4086004Snate@binkert.org{ 40914205Sandreas.sandberg@arm.com name = text->statName(info.name); 4108243Sbradley.danofsky@amd.com separatorString = info.separatorString; 4116004Snate@binkert.org desc = info.desc; 4126004Snate@binkert.org flags = info.flags; 4136004Snate@binkert.org precision = info.precision; 4146125Snate@binkert.org descriptions = text->descriptions; 4156004Snate@binkert.org} 4166004Snate@binkert.org 417695SN/Avoid 418695SN/ADistPrint::operator()(ostream &stream) const 419695SN/A{ 42010011Snilay@cs.wisc.edu if (flags.isSet(nozero) && data.samples == 0) return; 4218243Sbradley.danofsky@amd.com string base = name + separatorString; 422695SN/A 423695SN/A ScalarPrint print; 4246211Snate@binkert.org print.precision = precision; 425695SN/A print.flags = flags; 426695SN/A print.descriptions = descriptions; 4276211Snate@binkert.org print.desc = desc; 428695SN/A print.pdf = NAN; 429695SN/A print.cdf = NAN; 430695SN/A 43110011Snilay@cs.wisc.edu if (flags.isSet(oneline)) { 43210011Snilay@cs.wisc.edu print.name = base + "bucket_size"; 43310011Snilay@cs.wisc.edu print.value = data.bucket_size; 43410011Snilay@cs.wisc.edu print(stream); 43510011Snilay@cs.wisc.edu 43610011Snilay@cs.wisc.edu print.name = base + "min_bucket"; 43710011Snilay@cs.wisc.edu print.value = data.min; 43810011Snilay@cs.wisc.edu print(stream); 43910011Snilay@cs.wisc.edu 44010011Snilay@cs.wisc.edu print.name = base + "max_bucket"; 44110011Snilay@cs.wisc.edu print.value = data.max; 44210011Snilay@cs.wisc.edu print(stream); 44310011Snilay@cs.wisc.edu } 44410011Snilay@cs.wisc.edu 445695SN/A print.name = base + "samples"; 4466004Snate@binkert.org print.value = data.samples; 447695SN/A print(stream); 448695SN/A 4496211Snate@binkert.org print.name = base + "mean"; 4506211Snate@binkert.org print.value = data.samples ? data.sum / data.samples : NAN; 451695SN/A print(stream); 452695SN/A 4538666SPrakash.Ramrakhyani@arm.com if (data.type == Hist) { 4548666SPrakash.Ramrakhyani@arm.com print.name = base + "gmean"; 4558666SPrakash.Ramrakhyani@arm.com print.value = data.samples ? exp(data.logs / data.samples) : NAN; 4568666SPrakash.Ramrakhyani@arm.com print(stream); 4578666SPrakash.Ramrakhyani@arm.com } 4588666SPrakash.Ramrakhyani@arm.com 4596211Snate@binkert.org Result stdev = NAN; 4606211Snate@binkert.org if (data.samples) 4616211Snate@binkert.org stdev = sqrt((data.samples * data.squares - data.sum * data.sum) / 4626211Snate@binkert.org (data.samples * (data.samples - 1.0))); 4636211Snate@binkert.org print.name = base + "stdev"; 4646211Snate@binkert.org print.value = stdev; 4656211Snate@binkert.org print(stream); 4666211Snate@binkert.org 4677505Snate@binkert.org if (data.type == Deviation) 4686211Snate@binkert.org return; 4696211Snate@binkert.org 4707505Snate@binkert.org size_t size = data.cvec.size(); 4716211Snate@binkert.org 4726211Snate@binkert.org Result total = 0.0; 4737831Snate@binkert.org if (data.type == Dist && data.underflow != NAN) 4746211Snate@binkert.org total += data.underflow; 4756211Snate@binkert.org for (off_type i = 0; i < size; ++i) 4766211Snate@binkert.org total += data.cvec[i]; 4777831Snate@binkert.org if (data.type == Dist && data.overflow != NAN) 4786211Snate@binkert.org total += data.overflow; 4796211Snate@binkert.org 4806126Snate@binkert.org if (total) { 4816211Snate@binkert.org print.pdf = 0.0; 4826211Snate@binkert.org print.cdf = 0.0; 4836126Snate@binkert.org } 4846211Snate@binkert.org 4857831Snate@binkert.org if (data.type == Dist && data.underflow != NAN) { 4866211Snate@binkert.org print.name = base + "underflows"; 4876211Snate@binkert.org print.update(data.underflow, total); 4886211Snate@binkert.org print(stream); 4896211Snate@binkert.org } 4906126Snate@binkert.org 49110011Snilay@cs.wisc.edu if (flags.isSet(oneline)) { 49210011Snilay@cs.wisc.edu ccprintf(stream, "%-40s", name); 49310011Snilay@cs.wisc.edu } 49410011Snilay@cs.wisc.edu 4956126Snate@binkert.org for (off_type i = 0; i < size; ++i) { 4966126Snate@binkert.org stringstream namestr; 4976126Snate@binkert.org namestr << base; 4986126Snate@binkert.org 4997505Snate@binkert.org Counter low = i * data.bucket_size + data.min; 5007505Snate@binkert.org Counter high = ::min(low + data.bucket_size - 1.0, data.max); 5016126Snate@binkert.org namestr << low; 5026126Snate@binkert.org if (low < high) 5036126Snate@binkert.org namestr << "-" << high; 5046126Snate@binkert.org 5056126Snate@binkert.org print.name = namestr.str(); 5066211Snate@binkert.org print.update(data.cvec[i], total); 50710011Snilay@cs.wisc.edu print(stream, flags.isSet(oneline)); 50810011Snilay@cs.wisc.edu } 50910011Snilay@cs.wisc.edu 51010011Snilay@cs.wisc.edu if (flags.isSet(oneline)) { 51110011Snilay@cs.wisc.edu if (descriptions) { 51210011Snilay@cs.wisc.edu if (!desc.empty()) 51310011Snilay@cs.wisc.edu ccprintf(stream, " # %s", desc); 51410011Snilay@cs.wisc.edu } 51510011Snilay@cs.wisc.edu stream << endl; 516695SN/A } 517695SN/A 5187831Snate@binkert.org if (data.type == Dist && data.overflow != NAN) { 5196211Snate@binkert.org print.name = base + "overflows"; 5206211Snate@binkert.org print.update(data.overflow, total); 5216211Snate@binkert.org print(stream); 522695SN/A } 523695SN/A 524695SN/A print.pdf = NAN; 525695SN/A print.cdf = NAN; 526695SN/A 5277831Snate@binkert.org if (data.type == Dist && data.min_val != NAN) { 5286211Snate@binkert.org print.name = base + "min_value"; 5296211Snate@binkert.org print.value = data.min_val; 5306211Snate@binkert.org print(stream); 5316211Snate@binkert.org } 5326211Snate@binkert.org 5337831Snate@binkert.org if (data.type == Dist && data.max_val != NAN) { 5346211Snate@binkert.org print.name = base + "max_value"; 5356211Snate@binkert.org print.value = data.max_val; 5366211Snate@binkert.org print(stream); 5376211Snate@binkert.org } 5386211Snate@binkert.org 5396126Snate@binkert.org print.name = base + "total"; 5406126Snate@binkert.org print.value = total; 5416126Snate@binkert.org print(stream); 542695SN/A} 543695SN/A 544695SN/Avoid 5456128Snate@binkert.orgText::visit(const ScalarInfo &info) 546695SN/A{ 5475886Snate@binkert.org if (noOutput(info)) 548695SN/A return; 549695SN/A 550695SN/A ScalarPrint print; 5515886Snate@binkert.org print.value = info.result(); 55214205Sandreas.sandberg@arm.com print.name = statName(info.name); 5535886Snate@binkert.org print.desc = info.desc; 5545886Snate@binkert.org print.flags = info.flags; 555695SN/A print.descriptions = descriptions; 5565886Snate@binkert.org print.precision = info.precision; 557695SN/A print.pdf = NAN; 558695SN/A print.cdf = NAN; 559695SN/A 560695SN/A print(*stream); 561695SN/A} 562695SN/A 563695SN/Avoid 5646128Snate@binkert.orgText::visit(const VectorInfo &info) 565695SN/A{ 5665886Snate@binkert.org if (noOutput(info)) 567695SN/A return; 568695SN/A 5695886Snate@binkert.org size_type size = info.size(); 570695SN/A VectorPrint print; 571695SN/A 57214205Sandreas.sandberg@arm.com print.name = statName(info.name); 5738243Sbradley.danofsky@amd.com print.separatorString = info.separatorString; 5745886Snate@binkert.org print.desc = info.desc; 5755886Snate@binkert.org print.flags = info.flags; 576695SN/A print.descriptions = descriptions; 5775886Snate@binkert.org print.precision = info.precision; 5785886Snate@binkert.org print.vec = info.result(); 5795886Snate@binkert.org print.total = info.total(); 5809839Sandreas.hansson@arm.com print.forceSubnames = false; 581695SN/A 5825886Snate@binkert.org if (!info.subnames.empty()) { 5835599Snate@binkert.org for (off_type i = 0; i < size; ++i) { 5845886Snate@binkert.org if (!info.subnames[i].empty()) { 5855886Snate@binkert.org print.subnames = info.subnames; 586695SN/A print.subnames.resize(size); 5875599Snate@binkert.org for (off_type i = 0; i < size; ++i) { 5885886Snate@binkert.org if (!info.subnames[i].empty() && 5895886Snate@binkert.org !info.subdescs[i].empty()) { 5905886Snate@binkert.org print.subdescs = info.subdescs; 591695SN/A print.subdescs.resize(size); 592695SN/A break; 593695SN/A } 594695SN/A } 595695SN/A break; 596695SN/A } 597695SN/A } 598695SN/A } 599695SN/A 600695SN/A print(*stream); 601695SN/A} 602695SN/A 603695SN/Avoid 6046128Snate@binkert.orgText::visit(const Vector2dInfo &info) 605695SN/A{ 6065886Snate@binkert.org if (noOutput(info)) 607695SN/A return; 608695SN/A 609695SN/A bool havesub = false; 610695SN/A VectorPrint print; 611695SN/A 6128667Sdam.sunwoo@arm.com if (!info.y_subnames.empty()) { 6138667Sdam.sunwoo@arm.com for (off_type i = 0; i < info.y; ++i) { 6148667Sdam.sunwoo@arm.com if (!info.y_subnames[i].empty()) { 6158667Sdam.sunwoo@arm.com print.subnames = info.y_subnames; 61610374Sandreas.hansson@arm.com break; 6178667Sdam.sunwoo@arm.com } 6188667Sdam.sunwoo@arm.com } 6198667Sdam.sunwoo@arm.com } 6205886Snate@binkert.org print.flags = info.flags; 6218243Sbradley.danofsky@amd.com print.separatorString = info.separatorString; 622695SN/A print.descriptions = descriptions; 6235886Snate@binkert.org print.precision = info.precision; 6249828Ssascha.bischoff@arm.com print.forceSubnames = true; 625695SN/A 6265886Snate@binkert.org if (!info.subnames.empty()) { 6275886Snate@binkert.org for (off_type i = 0; i < info.x; ++i) 6285886Snate@binkert.org if (!info.subnames[i].empty()) 629695SN/A havesub = true; 630695SN/A } 631695SN/A 6325886Snate@binkert.org VResult tot_vec(info.y); 6335886Snate@binkert.org for (off_type i = 0; i < info.x; ++i) { 6345886Snate@binkert.org if (havesub && (i >= info.subnames.size() || info.subnames[i].empty())) 635695SN/A continue; 636695SN/A 6375886Snate@binkert.org off_type iy = i * info.y; 6385886Snate@binkert.org VResult yvec(info.y); 639695SN/A 640695SN/A Result total = 0.0; 6415886Snate@binkert.org for (off_type j = 0; j < info.y; ++j) { 6425886Snate@binkert.org yvec[j] = info.cvec[iy + j]; 643695SN/A tot_vec[j] += yvec[j]; 644695SN/A total += yvec[j]; 645695SN/A } 646695SN/A 64714205Sandreas.sandberg@arm.com print.name = statName( 64814205Sandreas.sandberg@arm.com info.name + "_" + 64914205Sandreas.sandberg@arm.com (havesub ? info.subnames[i] : std::to_string(i))); 6505886Snate@binkert.org print.desc = info.desc; 651695SN/A print.vec = yvec; 652695SN/A print.total = total; 653695SN/A print(*stream); 654695SN/A } 655695SN/A 6569828Ssascha.bischoff@arm.com // Create a subname for printing the total 6579828Ssascha.bischoff@arm.com vector<string> total_subname; 6589828Ssascha.bischoff@arm.com total_subname.push_back("total"); 6599828Ssascha.bischoff@arm.com 6606130Snate@binkert.org if (info.flags.isSet(::Stats::total) && (info.x > 1)) { 66114205Sandreas.sandberg@arm.com print.name = statName(info.name); 6629828Ssascha.bischoff@arm.com print.subnames = total_subname; 6635886Snate@binkert.org print.desc = info.desc; 66411565Sdavid.guillen@arm.com print.vec = VResult(1, info.total()); 6659828Ssascha.bischoff@arm.com print.flags = print.flags & ~total; 666695SN/A print(*stream); 667695SN/A } 668695SN/A} 669695SN/A 670695SN/Avoid 6716128Snate@binkert.orgText::visit(const DistInfo &info) 672695SN/A{ 6735886Snate@binkert.org if (noOutput(info)) 674695SN/A return; 675695SN/A 6766125Snate@binkert.org DistPrint print(this, info); 677695SN/A print(*stream); 678695SN/A} 679695SN/A 680695SN/Avoid 6816128Snate@binkert.orgText::visit(const VectorDistInfo &info) 682695SN/A{ 6835886Snate@binkert.org if (noOutput(info)) 684695SN/A return; 685695SN/A 6865886Snate@binkert.org for (off_type i = 0; i < info.size(); ++i) { 6876125Snate@binkert.org DistPrint print(this, info, i); 688695SN/A print(*stream); 689695SN/A } 690695SN/A} 691695SN/A 692695SN/Avoid 6936128Snate@binkert.orgText::visit(const FormulaInfo &info) 694695SN/A{ 6956128Snate@binkert.org visit((const VectorInfo &)info); 696695SN/A} 697695SN/A 6988514SThomas.Grass@ARM.com/* 6998514SThomas.Grass@ARM.com This struct implements the output methods for the sparse 7008514SThomas.Grass@ARM.com histogram stat 7018514SThomas.Grass@ARM.com*/ 7028514SThomas.Grass@ARM.comstruct SparseHistPrint 7038514SThomas.Grass@ARM.com{ 7048514SThomas.Grass@ARM.com string name; 7058514SThomas.Grass@ARM.com string separatorString; 7068514SThomas.Grass@ARM.com string desc; 7078514SThomas.Grass@ARM.com Flags flags; 7088514SThomas.Grass@ARM.com bool descriptions; 7098514SThomas.Grass@ARM.com int precision; 7108514SThomas.Grass@ARM.com 7118514SThomas.Grass@ARM.com const SparseHistData &data; 7128514SThomas.Grass@ARM.com 7138514SThomas.Grass@ARM.com SparseHistPrint(const Text *text, const SparseHistInfo &info); 7148514SThomas.Grass@ARM.com void init(const Text *text, const Info &info); 7158514SThomas.Grass@ARM.com void operator()(ostream &stream) const; 7168514SThomas.Grass@ARM.com}; 7178514SThomas.Grass@ARM.com 7188514SThomas.Grass@ARM.com/* Call initialization function */ 7198514SThomas.Grass@ARM.comSparseHistPrint::SparseHistPrint(const Text *text, const SparseHistInfo &info) 7208514SThomas.Grass@ARM.com : data(info.data) 7218514SThomas.Grass@ARM.com{ 7228514SThomas.Grass@ARM.com init(text, info); 7238514SThomas.Grass@ARM.com} 7248514SThomas.Grass@ARM.com 7258514SThomas.Grass@ARM.com/* Initialization function */ 7268514SThomas.Grass@ARM.comvoid 7278514SThomas.Grass@ARM.comSparseHistPrint::init(const Text *text, const Info &info) 7288514SThomas.Grass@ARM.com{ 72914205Sandreas.sandberg@arm.com name = text->statName(info.name); 7308514SThomas.Grass@ARM.com separatorString = info.separatorString; 7318514SThomas.Grass@ARM.com desc = info.desc; 7328514SThomas.Grass@ARM.com flags = info.flags; 7338514SThomas.Grass@ARM.com precision = info.precision; 7348514SThomas.Grass@ARM.com descriptions = text->descriptions; 7358514SThomas.Grass@ARM.com} 7368514SThomas.Grass@ARM.com 7378514SThomas.Grass@ARM.com/* Grab data from map and write to output stream */ 7388514SThomas.Grass@ARM.comvoid 7398514SThomas.Grass@ARM.comSparseHistPrint::operator()(ostream &stream) const 7408514SThomas.Grass@ARM.com{ 7418514SThomas.Grass@ARM.com string base = name + separatorString; 7428514SThomas.Grass@ARM.com 7438514SThomas.Grass@ARM.com ScalarPrint print; 7448514SThomas.Grass@ARM.com print.precision = precision; 7458514SThomas.Grass@ARM.com print.flags = flags; 7468514SThomas.Grass@ARM.com print.descriptions = descriptions; 7478514SThomas.Grass@ARM.com print.desc = desc; 7488514SThomas.Grass@ARM.com print.pdf = NAN; 7498514SThomas.Grass@ARM.com print.cdf = NAN; 7508514SThomas.Grass@ARM.com 7518514SThomas.Grass@ARM.com print.name = base + "samples"; 7528514SThomas.Grass@ARM.com print.value = data.samples; 7538514SThomas.Grass@ARM.com print(stream); 7548514SThomas.Grass@ARM.com 7558514SThomas.Grass@ARM.com MCounter::const_iterator it; 7568514SThomas.Grass@ARM.com for (it = data.cmap.begin(); it != data.cmap.end(); it++) { 7578514SThomas.Grass@ARM.com stringstream namestr; 7588514SThomas.Grass@ARM.com namestr << base; 7598514SThomas.Grass@ARM.com 7608514SThomas.Grass@ARM.com namestr <<(*it).first; 7618514SThomas.Grass@ARM.com print.name = namestr.str(); 7628514SThomas.Grass@ARM.com print.value = (*it).second; 7638514SThomas.Grass@ARM.com print(stream); 7648514SThomas.Grass@ARM.com } 7658514SThomas.Grass@ARM.com} 7668514SThomas.Grass@ARM.com 7678514SThomas.Grass@ARM.comvoid 7688514SThomas.Grass@ARM.comText::visit(const SparseHistInfo &info) 7698514SThomas.Grass@ARM.com{ 7708514SThomas.Grass@ARM.com if (noOutput(info)) 7718514SThomas.Grass@ARM.com return; 7728514SThomas.Grass@ARM.com 7738514SThomas.Grass@ARM.com SparseHistPrint print(this, info); 7748514SThomas.Grass@ARM.com print(*stream); 7758514SThomas.Grass@ARM.com} 7768514SThomas.Grass@ARM.com 7778296Snate@binkert.orgOutput * 7786126Snate@binkert.orginitText(const string &filename, bool desc) 7794078Sbinkertn@umich.edu{ 7804078Sbinkertn@umich.edu static Text text; 7814078Sbinkertn@umich.edu static bool connected = false; 7824078Sbinkertn@umich.edu 7838296Snate@binkert.org if (!connected) { 78411359Sandreas@sandberg.pp.se text.open(*simout.findOrCreate(filename)->stream()); 7858296Snate@binkert.org text.descriptions = desc; 7868296Snate@binkert.org connected = true; 7878296Snate@binkert.org } 7884078Sbinkertn@umich.edu 7898296Snate@binkert.org return &text; 7904078Sbinkertn@umich.edu} 7914078Sbinkertn@umich.edu 7927811Ssteve.reinhardt@amd.com} // namespace Stats 793