__init__.py revision 13681
111878Sandreas.sandberg@arm.com# Copyright (c) 2017 ARM Limited 211878Sandreas.sandberg@arm.com# All rights reserved. 311878Sandreas.sandberg@arm.com# 411878Sandreas.sandberg@arm.com# The license below extends only to copyright in the software and shall 511878Sandreas.sandberg@arm.com# not be construed as granting a license to any other intellectual 611878Sandreas.sandberg@arm.com# property including but not limited to intellectual property relating 711878Sandreas.sandberg@arm.com# to a hardware implementation of the functionality of the software 811878Sandreas.sandberg@arm.com# licensed hereunder. You may use the software subject to the license 911878Sandreas.sandberg@arm.com# terms below provided that you ensure that this notice is replicated 1011878Sandreas.sandberg@arm.com# unmodified and in its entirety in all distributions of the software, 1111878Sandreas.sandberg@arm.com# modified or unmodified, in source code or in binary form. 1211878Sandreas.sandberg@arm.com# 134126SN/A# Copyright (c) 2007 The Regents of The University of Michigan 148295Snate@binkert.org# Copyright (c) 2010 The Hewlett-Packard Development Company 154126SN/A# All rights reserved. 164126SN/A# 174126SN/A# Redistribution and use in source and binary forms, with or without 184126SN/A# modification, are permitted provided that the following conditions are 194126SN/A# met: redistributions of source code must retain the above copyright 204126SN/A# notice, this list of conditions and the following disclaimer; 214126SN/A# redistributions in binary form must reproduce the above copyright 224126SN/A# notice, this list of conditions and the following disclaimer in the 234126SN/A# documentation and/or other materials provided with the distribution; 244126SN/A# neither the name of the copyright holders nor the names of its 254126SN/A# contributors may be used to endorse or promote products derived from 264126SN/A# this software without specific prior written permission. 274126SN/A# 284126SN/A# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 294126SN/A# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 304126SN/A# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 314126SN/A# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 324126SN/A# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 334126SN/A# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 344126SN/A# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 354126SN/A# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 364126SN/A# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 374126SN/A# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 384126SN/A# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 394126SN/A# 404126SN/A# Authors: Nathan Binkert 4111878Sandreas.sandberg@arm.com# Andreas Sandberg 424126SN/A 438296Snate@binkert.orgimport m5 448296Snate@binkert.org 4511802Sandreas.sandberg@arm.comimport _m5.stats 468295Snate@binkert.orgfrom m5.objects import Root 478296Snate@binkert.orgfrom m5.util import attrdict, fatal 484126SN/A 4911766Sandreas.sandberg@arm.com# Stat exports 5011802Sandreas.sandberg@arm.comfrom _m5.stats import schedStatEvent as schedEvent 5111802Sandreas.sandberg@arm.comfrom _m5.stats import periodicStatDump 5211766Sandreas.sandberg@arm.com 538296Snate@binkert.orgoutputList = [] 5411878Sandreas.sandberg@arm.com 5511878Sandreas.sandberg@arm.comdef _url_factory(func): 5611878Sandreas.sandberg@arm.com """Wrap a plain Python function with URL parsing helpers 5711878Sandreas.sandberg@arm.com 5811878Sandreas.sandberg@arm.com Wrap a plain Python function f(fn, **kwargs) to expect a URL that 5911878Sandreas.sandberg@arm.com has been split using urlparse.urlsplit. First positional argument 6011878Sandreas.sandberg@arm.com is assumed to be a filename, this is created as the concatenation 6111878Sandreas.sandberg@arm.com of the netloc (~hostname) and path in the parsed URL. Keyword 6211878Sandreas.sandberg@arm.com arguments are derived from the query values in the URL. 6311878Sandreas.sandberg@arm.com 6411878Sandreas.sandberg@arm.com For example: 6511878Sandreas.sandberg@arm.com wrapped_f(urlparse.urlsplit("text://stats.txt?desc=False")) -> 6611878Sandreas.sandberg@arm.com f("stats.txt", desc=False) 6711878Sandreas.sandberg@arm.com 6811878Sandreas.sandberg@arm.com """ 6911878Sandreas.sandberg@arm.com 7011878Sandreas.sandberg@arm.com from functools import wraps 7111878Sandreas.sandberg@arm.com 7211878Sandreas.sandberg@arm.com @wraps(func) 7311878Sandreas.sandberg@arm.com def wrapper(url): 7411878Sandreas.sandberg@arm.com from urlparse import parse_qs 7511878Sandreas.sandberg@arm.com from ast import literal_eval 7611878Sandreas.sandberg@arm.com 7711878Sandreas.sandberg@arm.com qs = parse_qs(url.query, keep_blank_values=True) 7811878Sandreas.sandberg@arm.com 7911878Sandreas.sandberg@arm.com # parse_qs returns a list of values for each parameter. Only 8011878Sandreas.sandberg@arm.com # use the last value since kwargs don't allow multiple values 8111878Sandreas.sandberg@arm.com # per parameter. Use literal_eval to transform string param 8211878Sandreas.sandberg@arm.com # values into proper Python types. 8311878Sandreas.sandberg@arm.com def parse_value(key, values): 8411878Sandreas.sandberg@arm.com if len(values) == 0 or (len(values) == 1 and not values[0]): 8511878Sandreas.sandberg@arm.com fatal("%s: '%s' doesn't have a value." % (url.geturl(), key)) 8611878Sandreas.sandberg@arm.com elif len(values) > 1: 8711878Sandreas.sandberg@arm.com fatal("%s: '%s' has multiple values." % (url.geturl(), key)) 8811878Sandreas.sandberg@arm.com else: 8911878Sandreas.sandberg@arm.com try: 9011878Sandreas.sandberg@arm.com return key, literal_eval(values[0]) 9111878Sandreas.sandberg@arm.com except ValueError: 9211878Sandreas.sandberg@arm.com fatal("%s: %s isn't a valid Python literal" \ 9311878Sandreas.sandberg@arm.com % (url.geturl(), values[0])) 9411878Sandreas.sandberg@arm.com 9511878Sandreas.sandberg@arm.com kwargs = dict([ parse_value(k, v) for k, v in qs.items() ]) 9611878Sandreas.sandberg@arm.com 9711878Sandreas.sandberg@arm.com try: 9811878Sandreas.sandberg@arm.com return func("%s%s" % (url.netloc, url.path), **kwargs) 9911878Sandreas.sandberg@arm.com except TypeError: 10011878Sandreas.sandberg@arm.com fatal("Illegal stat visitor parameter specified") 10111878Sandreas.sandberg@arm.com 10211878Sandreas.sandberg@arm.com return wrapper 10311878Sandreas.sandberg@arm.com 10411878Sandreas.sandberg@arm.com@_url_factory 10511878Sandreas.sandberg@arm.comdef _textFactory(fn, desc=True): 10611878Sandreas.sandberg@arm.com """Output stats in text format. 10711878Sandreas.sandberg@arm.com 10811878Sandreas.sandberg@arm.com Text stat files contain one stat per line with an optional 10911878Sandreas.sandberg@arm.com description. The description is enabled by default, but can be 11011878Sandreas.sandberg@arm.com disabled by setting the desc parameter to False. 11111878Sandreas.sandberg@arm.com 11211878Sandreas.sandberg@arm.com Example: text://stats.txt?desc=False 11311878Sandreas.sandberg@arm.com 11411878Sandreas.sandberg@arm.com """ 11511878Sandreas.sandberg@arm.com 11611878Sandreas.sandberg@arm.com return _m5.stats.initText(fn, desc) 11711878Sandreas.sandberg@arm.com 11811878Sandreas.sandberg@arm.comfactories = { 11911878Sandreas.sandberg@arm.com # Default to the text factory if we're given a naked path 12011878Sandreas.sandberg@arm.com "" : _textFactory, 12111878Sandreas.sandberg@arm.com "file" : _textFactory, 12211878Sandreas.sandberg@arm.com "text" : _textFactory, 12311878Sandreas.sandberg@arm.com} 12411878Sandreas.sandberg@arm.com 12511878Sandreas.sandberg@arm.comdef addStatVisitor(url): 12611878Sandreas.sandberg@arm.com """Add a stat visitor specified using a URL string 12711878Sandreas.sandberg@arm.com 12811878Sandreas.sandberg@arm.com Stat visitors are specified using URLs on the following format: 12911878Sandreas.sandberg@arm.com format://path[?param=value[;param=value]] 13011878Sandreas.sandberg@arm.com 13111878Sandreas.sandberg@arm.com The available formats are listed in the factories list. Factories 13211878Sandreas.sandberg@arm.com are called with the path as the first positional parameter and the 13311878Sandreas.sandberg@arm.com parameters are keyword arguments. Parameter values must be valid 13411878Sandreas.sandberg@arm.com Python literals. 13511878Sandreas.sandberg@arm.com 13611878Sandreas.sandberg@arm.com """ 13711878Sandreas.sandberg@arm.com 13811878Sandreas.sandberg@arm.com from urlparse import urlsplit 13911878Sandreas.sandberg@arm.com 14011878Sandreas.sandberg@arm.com parsed = urlsplit(url) 14111878Sandreas.sandberg@arm.com 14211878Sandreas.sandberg@arm.com try: 14311878Sandreas.sandberg@arm.com factory = factories[parsed.scheme] 14411878Sandreas.sandberg@arm.com except KeyError: 14511878Sandreas.sandberg@arm.com fatal("Illegal stat file type specified.") 14611878Sandreas.sandberg@arm.com 14711878Sandreas.sandberg@arm.com outputList.append(factory(parsed)) 1484126SN/A 1496001SN/Adef initSimStats(): 15011802Sandreas.sandberg@arm.com _m5.stats.initSimStats() 15111802Sandreas.sandberg@arm.com _m5.stats.registerPythonStatsHandlers() 1526001SN/A 1538295Snate@binkert.orgnames = [] 1548295Snate@binkert.orgstats_dict = {} 1558295Snate@binkert.orgstats_list = [] 1566001SN/Adef enable(): 1578295Snate@binkert.org '''Enable the statistics package. Before the statistics package is 1588295Snate@binkert.org enabled, all statistics must be created and initialized and once 1598295Snate@binkert.org the package is enabled, no more statistics can be created.''' 1608295Snate@binkert.org 16111788Sandreas.sandberg@arm.com global stats_list 16211802Sandreas.sandberg@arm.com stats_list = list(_m5.stats.statsList()) 1638295Snate@binkert.org 1648296Snate@binkert.org for stat in stats_list: 1658296Snate@binkert.org if not stat.check() or not stat.baseCheck(): 16610169SCurtis.Dunham@arm.com fatal("statistic '%s' (%d) was not properly initialized " \ 16710169SCurtis.Dunham@arm.com "by a regStats() function\n", stat.name, stat.id) 1688296Snate@binkert.org 1698296Snate@binkert.org if not (stat.flags & flags.display): 1708296Snate@binkert.org stat.name = "__Stat%06d" % stat.id 1718296Snate@binkert.org 17213681Sandreas.sandberg@arm.com stats_list.sort(key=lambda s: s.name.split('.')) 1738295Snate@binkert.org for stat in stats_list: 1748295Snate@binkert.org stats_dict[stat.name] = stat 1758296Snate@binkert.org stat.enable() 1768295Snate@binkert.org 17711802Sandreas.sandberg@arm.com _m5.stats.enable(); 1788986SAli.Saidi@ARM.com 1798296Snate@binkert.orgdef prepare(): 1808296Snate@binkert.org '''Prepare all stats for data access. This must be done before 1818296Snate@binkert.org dumping and serialization.''' 1826001SN/A 1838296Snate@binkert.org for stat in stats_list: 1848296Snate@binkert.org stat.prepare() 1858296Snate@binkert.org 1868296Snate@binkert.orglastDump = 0 1876001SN/Adef dump(): 1888296Snate@binkert.org '''Dump all statistics data to the registered outputs''' 1896001SN/A 1908296Snate@binkert.org curTick = m5.curTick() 1918296Snate@binkert.org 1928296Snate@binkert.org global lastDump 1938296Snate@binkert.org assert lastDump <= curTick 1948296Snate@binkert.org if lastDump == curTick: 1958296Snate@binkert.org return 1968296Snate@binkert.org lastDump = curTick 1978296Snate@binkert.org 19811802Sandreas.sandberg@arm.com _m5.stats.processDumpQueue() 1999042SMitchell.Hayenga@ARM.com 2008296Snate@binkert.org prepare() 2018296Snate@binkert.org 2028296Snate@binkert.org for output in outputList: 2038296Snate@binkert.org if output.valid(): 2048296Snate@binkert.org output.begin() 2058296Snate@binkert.org for stat in stats_list: 20611788Sandreas.sandberg@arm.com stat.visit(output) 2078296Snate@binkert.org output.end() 2086001SN/A 2096001SN/Adef reset(): 2108296Snate@binkert.org '''Reset all statistics to the base state''' 2118296Snate@binkert.org 2127527SN/A # call reset stats on all SimObjects 2137527SN/A root = Root.getInstance() 2147802SN/A if root: 2157802SN/A for obj in root.descendants(): obj.resetStats() 2167802SN/A 2177527SN/A # call any other registered stats reset callbacks 2188296Snate@binkert.org for stat in stats_list: 2198296Snate@binkert.org stat.reset() 2208296Snate@binkert.org 22111802Sandreas.sandberg@arm.com _m5.stats.processResetQueue() 2228295Snate@binkert.org 2238295Snate@binkert.orgflags = attrdict({ 2248295Snate@binkert.org 'none' : 0x0000, 2258295Snate@binkert.org 'init' : 0x0001, 2268295Snate@binkert.org 'display' : 0x0002, 2278295Snate@binkert.org 'total' : 0x0010, 2288295Snate@binkert.org 'pdf' : 0x0020, 2298295Snate@binkert.org 'cdf' : 0x0040, 2308295Snate@binkert.org 'dist' : 0x0080, 2318295Snate@binkert.org 'nozero' : 0x0100, 2328295Snate@binkert.org 'nonan' : 0x0200, 2338295Snate@binkert.org}) 234