__init__.py revision 13681
113685Sjavier.bueno@metempsy.com# Copyright (c) 2017 ARM Limited
213685Sjavier.bueno@metempsy.com# All rights reserved.
313685Sjavier.bueno@metempsy.com#
413685Sjavier.bueno@metempsy.com# The license below extends only to copyright in the software and shall
513685Sjavier.bueno@metempsy.com# not be construed as granting a license to any other intellectual
613685Sjavier.bueno@metempsy.com# property including but not limited to intellectual property relating
713685Sjavier.bueno@metempsy.com# to a hardware implementation of the functionality of the software
813685Sjavier.bueno@metempsy.com# licensed hereunder.  You may use the software subject to the license
913685Sjavier.bueno@metempsy.com# terms below provided that you ensure that this notice is replicated
1013685Sjavier.bueno@metempsy.com# unmodified and in its entirety in all distributions of the software,
1113685Sjavier.bueno@metempsy.com# modified or unmodified, in source code or in binary form.
1213685Sjavier.bueno@metempsy.com#
1313685Sjavier.bueno@metempsy.com# Copyright (c) 2007 The Regents of The University of Michigan
1413685Sjavier.bueno@metempsy.com# Copyright (c) 2010 The Hewlett-Packard Development Company
1513685Sjavier.bueno@metempsy.com# All rights reserved.
1613685Sjavier.bueno@metempsy.com#
1713685Sjavier.bueno@metempsy.com# Redistribution and use in source and binary forms, with or without
1813685Sjavier.bueno@metempsy.com# modification, are permitted provided that the following conditions are
1913685Sjavier.bueno@metempsy.com# met: redistributions of source code must retain the above copyright
2013685Sjavier.bueno@metempsy.com# notice, this list of conditions and the following disclaimer;
2113685Sjavier.bueno@metempsy.com# redistributions in binary form must reproduce the above copyright
2213685Sjavier.bueno@metempsy.com# notice, this list of conditions and the following disclaimer in the
2313685Sjavier.bueno@metempsy.com# documentation and/or other materials provided with the distribution;
2413685Sjavier.bueno@metempsy.com# neither the name of the copyright holders nor the names of its
2513685Sjavier.bueno@metempsy.com# contributors may be used to endorse or promote products derived from
2613685Sjavier.bueno@metempsy.com# this software without specific prior written permission.
2713685Sjavier.bueno@metempsy.com#
2813685Sjavier.bueno@metempsy.com# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
2913685Sjavier.bueno@metempsy.com# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
3013685Sjavier.bueno@metempsy.com# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
3113685Sjavier.bueno@metempsy.com# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
3213685Sjavier.bueno@metempsy.com# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
3313685Sjavier.bueno@metempsy.com# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
3413685Sjavier.bueno@metempsy.com# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
3513685Sjavier.bueno@metempsy.com# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
3613685Sjavier.bueno@metempsy.com# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
3713685Sjavier.bueno@metempsy.com# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
3813685Sjavier.bueno@metempsy.com# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3913685Sjavier.bueno@metempsy.com#
4013685Sjavier.bueno@metempsy.com# Authors: Nathan Binkert
4113685Sjavier.bueno@metempsy.com#          Andreas Sandberg
4213685Sjavier.bueno@metempsy.com
4313685Sjavier.bueno@metempsy.comimport m5
4413685Sjavier.bueno@metempsy.com
4513685Sjavier.bueno@metempsy.comimport _m5.stats
4613685Sjavier.bueno@metempsy.comfrom m5.objects import Root
4714081Sjavier.bueno@metempsy.comfrom m5.util import attrdict, fatal
4813685Sjavier.bueno@metempsy.com
4913685Sjavier.bueno@metempsy.com# Stat exports
5013685Sjavier.bueno@metempsy.comfrom _m5.stats import schedStatEvent as schedEvent
5113685Sjavier.bueno@metempsy.comfrom _m5.stats import periodicStatDump
5213685Sjavier.bueno@metempsy.com
5313685Sjavier.bueno@metempsy.comoutputList = []
5414081Sjavier.bueno@metempsy.com
5513685Sjavier.bueno@metempsy.comdef _url_factory(func):
5613685Sjavier.bueno@metempsy.com    """Wrap a plain Python function with URL parsing helpers
5713685Sjavier.bueno@metempsy.com
5814081Sjavier.bueno@metempsy.com    Wrap a plain Python function f(fn, **kwargs) to expect a URL that
5914081Sjavier.bueno@metempsy.com    has been split using urlparse.urlsplit. First positional argument
6014081Sjavier.bueno@metempsy.com    is assumed to be a filename, this is created as the concatenation
6114081Sjavier.bueno@metempsy.com    of the netloc (~hostname) and path in the parsed URL. Keyword
6214081Sjavier.bueno@metempsy.com    arguments are derived from the query values in the URL.
6314081Sjavier.bueno@metempsy.com
6414081Sjavier.bueno@metempsy.com    For example:
6514081Sjavier.bueno@metempsy.com        wrapped_f(urlparse.urlsplit("text://stats.txt?desc=False")) ->
6613685Sjavier.bueno@metempsy.com        f("stats.txt", desc=False)
6713685Sjavier.bueno@metempsy.com
6813685Sjavier.bueno@metempsy.com    """
6913685Sjavier.bueno@metempsy.com
7013685Sjavier.bueno@metempsy.com    from functools import wraps
7113685Sjavier.bueno@metempsy.com
7213685Sjavier.bueno@metempsy.com    @wraps(func)
7313685Sjavier.bueno@metempsy.com    def wrapper(url):
7413685Sjavier.bueno@metempsy.com        from urlparse import parse_qs
7513685Sjavier.bueno@metempsy.com        from ast import literal_eval
7613685Sjavier.bueno@metempsy.com
7713685Sjavier.bueno@metempsy.com        qs = parse_qs(url.query, keep_blank_values=True)
7813685Sjavier.bueno@metempsy.com
7913685Sjavier.bueno@metempsy.com        # parse_qs returns a list of values for each parameter. Only
8013685Sjavier.bueno@metempsy.com        # use the last value since kwargs don't allow multiple values
8113685Sjavier.bueno@metempsy.com        # per parameter. Use literal_eval to transform string param
8213685Sjavier.bueno@metempsy.com        # values into proper Python types.
8313685Sjavier.bueno@metempsy.com        def parse_value(key, values):
8413685Sjavier.bueno@metempsy.com            if len(values) == 0 or (len(values) == 1 and not values[0]):
8513685Sjavier.bueno@metempsy.com                fatal("%s: '%s' doesn't have a value." % (url.geturl(), key))
8613685Sjavier.bueno@metempsy.com            elif len(values) > 1:
8713685Sjavier.bueno@metempsy.com                fatal("%s: '%s' has multiple values." % (url.geturl(), key))
8813685Sjavier.bueno@metempsy.com            else:
8913685Sjavier.bueno@metempsy.com                try:
9013685Sjavier.bueno@metempsy.com                    return key, literal_eval(values[0])
9113685Sjavier.bueno@metempsy.com                except ValueError:
9213685Sjavier.bueno@metempsy.com                    fatal("%s: %s isn't a valid Python literal" \
9313685Sjavier.bueno@metempsy.com                          % (url.geturl(), values[0]))
9413685Sjavier.bueno@metempsy.com
9513685Sjavier.bueno@metempsy.com        kwargs = dict([ parse_value(k, v) for k, v in qs.items() ])
9613685Sjavier.bueno@metempsy.com
9713685Sjavier.bueno@metempsy.com        try:
9813685Sjavier.bueno@metempsy.com            return func("%s%s" % (url.netloc, url.path), **kwargs)
9913685Sjavier.bueno@metempsy.com        except TypeError:
10013685Sjavier.bueno@metempsy.com            fatal("Illegal stat visitor parameter specified")
10113685Sjavier.bueno@metempsy.com
10213685Sjavier.bueno@metempsy.com    return wrapper
10313685Sjavier.bueno@metempsy.com
10413685Sjavier.bueno@metempsy.com@_url_factory
10513685Sjavier.bueno@metempsy.comdef _textFactory(fn, desc=True):
10613685Sjavier.bueno@metempsy.com    """Output stats in text format.
10713685Sjavier.bueno@metempsy.com
10813685Sjavier.bueno@metempsy.com    Text stat files contain one stat per line with an optional
10913685Sjavier.bueno@metempsy.com    description. The description is enabled by default, but can be
11013685Sjavier.bueno@metempsy.com    disabled by setting the desc parameter to False.
11113685Sjavier.bueno@metempsy.com
11213685Sjavier.bueno@metempsy.com    Example: text://stats.txt?desc=False
11313685Sjavier.bueno@metempsy.com
11413685Sjavier.bueno@metempsy.com    """
11513685Sjavier.bueno@metempsy.com
11613685Sjavier.bueno@metempsy.com    return _m5.stats.initText(fn, desc)
11713685Sjavier.bueno@metempsy.com
11813685Sjavier.bueno@metempsy.comfactories = {
11913685Sjavier.bueno@metempsy.com    # Default to the text factory if we're given a naked path
12013685Sjavier.bueno@metempsy.com    "" : _textFactory,
12113685Sjavier.bueno@metempsy.com    "file" : _textFactory,
12213685Sjavier.bueno@metempsy.com    "text" : _textFactory,
12313685Sjavier.bueno@metempsy.com}
12413685Sjavier.bueno@metempsy.com
12513685Sjavier.bueno@metempsy.comdef addStatVisitor(url):
12613685Sjavier.bueno@metempsy.com    """Add a stat visitor specified using a URL string
12713685Sjavier.bueno@metempsy.com
12813685Sjavier.bueno@metempsy.com    Stat visitors are specified using URLs on the following format:
12913685Sjavier.bueno@metempsy.com    format://path[?param=value[;param=value]]
13013685Sjavier.bueno@metempsy.com
13113685Sjavier.bueno@metempsy.com    The available formats are listed in the factories list. Factories
13213685Sjavier.bueno@metempsy.com    are called with the path as the first positional parameter and the
13313685Sjavier.bueno@metempsy.com    parameters are keyword arguments. Parameter values must be valid
13413685Sjavier.bueno@metempsy.com    Python literals.
13513685Sjavier.bueno@metempsy.com
13613685Sjavier.bueno@metempsy.com    """
13713685Sjavier.bueno@metempsy.com
13813685Sjavier.bueno@metempsy.com    from urlparse import urlsplit
13913685Sjavier.bueno@metempsy.com
14013685Sjavier.bueno@metempsy.com    parsed = urlsplit(url)
14113685Sjavier.bueno@metempsy.com
14213685Sjavier.bueno@metempsy.com    try:
14313685Sjavier.bueno@metempsy.com        factory = factories[parsed.scheme]
14413685Sjavier.bueno@metempsy.com    except KeyError:
14513685Sjavier.bueno@metempsy.com        fatal("Illegal stat file type specified.")
14613685Sjavier.bueno@metempsy.com
14713685Sjavier.bueno@metempsy.com    outputList.append(factory(parsed))
14813685Sjavier.bueno@metempsy.com
14913685Sjavier.bueno@metempsy.comdef initSimStats():
15013685Sjavier.bueno@metempsy.com    _m5.stats.initSimStats()
15113685Sjavier.bueno@metempsy.com    _m5.stats.registerPythonStatsHandlers()
15213685Sjavier.bueno@metempsy.com
15313685Sjavier.bueno@metempsy.comnames = []
15413685Sjavier.bueno@metempsy.comstats_dict = {}
15513685Sjavier.bueno@metempsy.comstats_list = []
15613685Sjavier.bueno@metempsy.comdef enable():
15713685Sjavier.bueno@metempsy.com    '''Enable the statistics package.  Before the statistics package is
15813685Sjavier.bueno@metempsy.com    enabled, all statistics must be created and initialized and once
15913685Sjavier.bueno@metempsy.com    the package is enabled, no more statistics can be created.'''
16013685Sjavier.bueno@metempsy.com
16113685Sjavier.bueno@metempsy.com    global stats_list
16213685Sjavier.bueno@metempsy.com    stats_list = list(_m5.stats.statsList())
16313685Sjavier.bueno@metempsy.com
16413685Sjavier.bueno@metempsy.com    for stat in stats_list:
16513685Sjavier.bueno@metempsy.com        if not stat.check() or not stat.baseCheck():
16613685Sjavier.bueno@metempsy.com            fatal("statistic '%s' (%d) was not properly initialized " \
16713685Sjavier.bueno@metempsy.com                  "by a regStats() function\n", stat.name, stat.id)
16813685Sjavier.bueno@metempsy.com
16913685Sjavier.bueno@metempsy.com        if not (stat.flags & flags.display):
17013685Sjavier.bueno@metempsy.com            stat.name = "__Stat%06d" % stat.id
17113685Sjavier.bueno@metempsy.com
17213685Sjavier.bueno@metempsy.com    stats_list.sort(key=lambda s: s.name.split('.'))
17313685Sjavier.bueno@metempsy.com    for stat in stats_list:
17413685Sjavier.bueno@metempsy.com        stats_dict[stat.name] = stat
17513685Sjavier.bueno@metempsy.com        stat.enable()
17613685Sjavier.bueno@metempsy.com
17713685Sjavier.bueno@metempsy.com    _m5.stats.enable();
17813685Sjavier.bueno@metempsy.com
17913685Sjavier.bueno@metempsy.comdef prepare():
18013685Sjavier.bueno@metempsy.com    '''Prepare all stats for data access.  This must be done before
18113685Sjavier.bueno@metempsy.com    dumping and serialization.'''
18213685Sjavier.bueno@metempsy.com
18313685Sjavier.bueno@metempsy.com    for stat in stats_list:
18413685Sjavier.bueno@metempsy.com        stat.prepare()
18513685Sjavier.bueno@metempsy.com
18613685Sjavier.bueno@metempsy.comlastDump = 0
18713685Sjavier.bueno@metempsy.comdef dump():
18813685Sjavier.bueno@metempsy.com    '''Dump all statistics data to the registered outputs'''
18913685Sjavier.bueno@metempsy.com
19013685Sjavier.bueno@metempsy.com    curTick = m5.curTick()
19113685Sjavier.bueno@metempsy.com
19213685Sjavier.bueno@metempsy.com    global lastDump
19313685Sjavier.bueno@metempsy.com    assert lastDump <= curTick
19413685Sjavier.bueno@metempsy.com    if lastDump == curTick:
19513685Sjavier.bueno@metempsy.com        return
19613685Sjavier.bueno@metempsy.com    lastDump = curTick
19713685Sjavier.bueno@metempsy.com
19813685Sjavier.bueno@metempsy.com    _m5.stats.processDumpQueue()
19913685Sjavier.bueno@metempsy.com
20013685Sjavier.bueno@metempsy.com    prepare()
20113685Sjavier.bueno@metempsy.com
20213685Sjavier.bueno@metempsy.com    for output in outputList:
20313685Sjavier.bueno@metempsy.com        if output.valid():
20413685Sjavier.bueno@metempsy.com            output.begin()
20513685Sjavier.bueno@metempsy.com            for stat in stats_list:
20613685Sjavier.bueno@metempsy.com                stat.visit(output)
20713685Sjavier.bueno@metempsy.com            output.end()
20813685Sjavier.bueno@metempsy.com
20913685Sjavier.bueno@metempsy.comdef reset():
21013685Sjavier.bueno@metempsy.com    '''Reset all statistics to the base state'''
21113685Sjavier.bueno@metempsy.com
21213685Sjavier.bueno@metempsy.com    # call reset stats on all SimObjects
21313685Sjavier.bueno@metempsy.com    root = Root.getInstance()
21413685Sjavier.bueno@metempsy.com    if root:
21514081Sjavier.bueno@metempsy.com        for obj in root.descendants(): obj.resetStats()
21614081Sjavier.bueno@metempsy.com
21714081Sjavier.bueno@metempsy.com    # call any other registered stats reset callbacks
21813685Sjavier.bueno@metempsy.com    for stat in stats_list:
21913685Sjavier.bueno@metempsy.com        stat.reset()
22013685Sjavier.bueno@metempsy.com
22114081Sjavier.bueno@metempsy.com    _m5.stats.processResetQueue()
22213685Sjavier.bueno@metempsy.com
22314081Sjavier.bueno@metempsy.comflags = attrdict({
22413685Sjavier.bueno@metempsy.com    'none'    : 0x0000,
22514081Sjavier.bueno@metempsy.com    'init'    : 0x0001,
22613685Sjavier.bueno@metempsy.com    'display' : 0x0002,
22713685Sjavier.bueno@metempsy.com    'total'   : 0x0010,
22813685Sjavier.bueno@metempsy.com    'pdf'     : 0x0020,
22913685Sjavier.bueno@metempsy.com    'cdf'     : 0x0040,
23014081Sjavier.bueno@metempsy.com    'dist'    : 0x0080,
23113685Sjavier.bueno@metempsy.com    'nozero'  : 0x0100,
23213685Sjavier.bueno@metempsy.com    'nonan'   : 0x0200,
23313685Sjavier.bueno@metempsy.com})
23413685Sjavier.bueno@metempsy.com