__init__.py revision 8224:75527411e636
111147Smitch.hayenga@arm.com# Copyright (c) 2008-2009 The Hewlett-Packard Development Company
213953Sgiacomo.gabrielli@arm.com# Copyright (c) 2004-2006 The Regents of The University of Michigan
311147Smitch.hayenga@arm.com# All rights reserved.
411147Smitch.hayenga@arm.com#
511147Smitch.hayenga@arm.com# Redistribution and use in source and binary forms, with or without
611147Smitch.hayenga@arm.com# modification, are permitted provided that the following conditions are
711147Smitch.hayenga@arm.com# met: redistributions of source code must retain the above copyright
811147Smitch.hayenga@arm.com# notice, this list of conditions and the following disclaimer;
911147Smitch.hayenga@arm.com# redistributions in binary form must reproduce the above copyright
1011147Smitch.hayenga@arm.com# notice, this list of conditions and the following disclaimer in the
1111147Smitch.hayenga@arm.com# documentation and/or other materials provided with the distribution;
1211147Smitch.hayenga@arm.com# neither the name of the copyright holders nor the names of its
1311147Smitch.hayenga@arm.com# contributors may be used to endorse or promote products derived from
1411147Smitch.hayenga@arm.com# this software without specific prior written permission.
1511147Smitch.hayenga@arm.com#
1611147Smitch.hayenga@arm.com# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1711147Smitch.hayenga@arm.com# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
1811147Smitch.hayenga@arm.com# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
1911147Smitch.hayenga@arm.com# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2011147Smitch.hayenga@arm.com# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2111147Smitch.hayenga@arm.com# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2211147Smitch.hayenga@arm.com# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2311147Smitch.hayenga@arm.com# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2411147Smitch.hayenga@arm.com# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2511147Smitch.hayenga@arm.com# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2611147Smitch.hayenga@arm.com# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2711147Smitch.hayenga@arm.com#
2811147Smitch.hayenga@arm.com# Authors: Nathan Binkert
2911147Smitch.hayenga@arm.com
3011147Smitch.hayenga@arm.comimport os
3111147Smitch.hayenga@arm.comimport re
3211147Smitch.hayenga@arm.comimport sys
3311147Smitch.hayenga@arm.com
3411147Smitch.hayenga@arm.comimport convert
3511147Smitch.hayenga@arm.comimport jobfile
3611147Smitch.hayenga@arm.com
3711147Smitch.hayenga@arm.comfrom attrdict import attrdict, multiattrdict, optiondict
3811147Smitch.hayenga@arm.comfrom code_formatter import code_formatter
3911147Smitch.hayenga@arm.comfrom multidict import multidict
4011147Smitch.hayenga@arm.comfrom orderdict import orderdict
4111147Smitch.hayenga@arm.comfrom smartdict import SmartDict
4211147Smitch.hayenga@arm.comfrom sorteddict import SortedDict
4311147Smitch.hayenga@arm.comfrom region import neg_inf, pos_inf, Region, Regions
4411147Smitch.hayenga@arm.com
4511147Smitch.hayenga@arm.com# define this here so we can use it right away if necessary
4611147Smitch.hayenga@arm.comdef errorURL(prefix, s):
4711147Smitch.hayenga@arm.com    try:
4811147Smitch.hayenga@arm.com        import zlib
4911147Smitch.hayenga@arm.com        hashstr = "%x" % zlib.crc32(s)
5011147Smitch.hayenga@arm.com    except:
5111147Smitch.hayenga@arm.com        hashstr = "UnableToHash"
5211147Smitch.hayenga@arm.com    return "For more information see: http://www.m5sim.org/%s/%s" % \
5312104Snathanael.premillieu@arm.com            (prefix, hashstr)
5411147Smitch.hayenga@arm.com
5511147Smitch.hayenga@arm.com# panic() should be called when something happens that should never
5611147Smitch.hayenga@arm.com# ever happen regardless of what the user does (i.e., an acutal m5
5711608Snikos.nikoleris@arm.com# bug).
5811147Smitch.hayenga@arm.comdef panic(fmt, *args):
5911147Smitch.hayenga@arm.com    print >>sys.stderr, 'panic:', fmt % args
6011147Smitch.hayenga@arm.com    print >>sys.stderr, errorURL('panic',fmt)
6111147Smitch.hayenga@arm.com    sys.exit(1)
6211147Smitch.hayenga@arm.com
6312109SRekai.GonzalezAlberquilla@arm.com# fatal() should be called when the simulation cannot continue due to
6412109SRekai.GonzalezAlberquilla@arm.com# some condition that is the user's fault (bad configuration, invalid
6511147Smitch.hayenga@arm.com# arguments, etc.) and not a simulator bug.
6611147Smitch.hayenga@arm.comdef fatal(fmt, *args):
6711147Smitch.hayenga@arm.com    print >>sys.stderr, 'fatal:', fmt % args
6811147Smitch.hayenga@arm.com    print >>sys.stderr, errorURL('fatal',fmt)
6911147Smitch.hayenga@arm.com    sys.exit(1)
7011147Smitch.hayenga@arm.com
7111147Smitch.hayenga@arm.comclass Singleton(type):
7211147Smitch.hayenga@arm.com    def __call__(cls, *args, **kwargs):
7311147Smitch.hayenga@arm.com        if hasattr(cls, '_instance'):
7411147Smitch.hayenga@arm.com            return cls._instance
7511147Smitch.hayenga@arm.com
7611147Smitch.hayenga@arm.com        cls._instance = super(Singleton, cls).__call__(*args, **kwargs)
7711147Smitch.hayenga@arm.com        return cls._instance
7811147Smitch.hayenga@arm.com
7911147Smitch.hayenga@arm.comdef addToPath(path):
8011147Smitch.hayenga@arm.com    """Prepend given directory to system module search path.  We may not
8111147Smitch.hayenga@arm.com    need this anymore if we can structure our config library more like a
8211147Smitch.hayenga@arm.com    Python package."""
8311147Smitch.hayenga@arm.com
8411147Smitch.hayenga@arm.com    # if it's a relative path and we know what directory the current
8511147Smitch.hayenga@arm.com    # python script is in, make the path relative to that directory.
8611147Smitch.hayenga@arm.com    if not os.path.isabs(path) and sys.path[0]:
8711147Smitch.hayenga@arm.com        path = os.path.join(sys.path[0], path)
8811147Smitch.hayenga@arm.com    path = os.path.realpath(path)
8911147Smitch.hayenga@arm.com    # sys.path[0] should always refer to the current script's directory,
9011147Smitch.hayenga@arm.com    # so place the new dir right after that.
9111147Smitch.hayenga@arm.com    sys.path.insert(1, path)
9211147Smitch.hayenga@arm.com
9312110SRekai.GonzalezAlberquilla@arm.com# Apply method to object.
9412110SRekai.GonzalezAlberquilla@arm.com# applyMethod(obj, 'meth', <args>) is equivalent to obj.meth(<args>)
9512110SRekai.GonzalezAlberquilla@arm.comdef applyMethod(obj, meth, *args, **kwargs):
9611147Smitch.hayenga@arm.com    return getattr(obj, meth)(*args, **kwargs)
9711147Smitch.hayenga@arm.com
9811147Smitch.hayenga@arm.com# If the first argument is an (non-sequence) object, apply the named
9911147Smitch.hayenga@arm.com# method with the given arguments.  If the first argument is a
10011147Smitch.hayenga@arm.com# sequence, apply the method to each element of the sequence (a la
10111147Smitch.hayenga@arm.com# 'map').
10211147Smitch.hayenga@arm.comdef applyOrMap(objOrSeq, meth, *args, **kwargs):
10311147Smitch.hayenga@arm.com    if not isinstance(objOrSeq, (list, tuple)):
10411147Smitch.hayenga@arm.com        return applyMethod(objOrSeq, meth, *args, **kwargs)
10511147Smitch.hayenga@arm.com    else:
10611147Smitch.hayenga@arm.com        return [applyMethod(o, meth, *args, **kwargs) for o in objOrSeq]
10711147Smitch.hayenga@arm.com
10812110SRekai.GonzalezAlberquilla@arm.comdef compareVersions(v1, v2):
10912110SRekai.GonzalezAlberquilla@arm.com    """helper function: compare arrays or strings of version numbers.
11012110SRekai.GonzalezAlberquilla@arm.com    E.g., compare_version((1,3,25), (1,4,1)')
11111147Smitch.hayenga@arm.com    returns -1, 0, 1 if v1 is <, ==, > v2
11211147Smitch.hayenga@arm.com    """
11311147Smitch.hayenga@arm.com    def make_version_list(v):
11411147Smitch.hayenga@arm.com        if isinstance(v, (list,tuple)):
11511147Smitch.hayenga@arm.com            return v
11611147Smitch.hayenga@arm.com        elif isinstance(v, str):
11711147Smitch.hayenga@arm.com            return map(lambda x: int(re.match('\d+', x).group()), v.split('.'))
11811147Smitch.hayenga@arm.com        else:
11912109SRekai.GonzalezAlberquilla@arm.com            raise TypeError
12012109SRekai.GonzalezAlberquilla@arm.com
12112109SRekai.GonzalezAlberquilla@arm.com    v1 = make_version_list(v1)
12212109SRekai.GonzalezAlberquilla@arm.com    v2 = make_version_list(v2)
12313610Sgiacomo.gabrielli@arm.com    # Compare corresponding elements of lists
12413610Sgiacomo.gabrielli@arm.com    for n1,n2 in zip(v1, v2):
12513610Sgiacomo.gabrielli@arm.com        if n1 < n2: return -1
12613610Sgiacomo.gabrielli@arm.com        if n1 > n2: return  1
12711147Smitch.hayenga@arm.com    # all corresponding values are equal... see if one has extra values
12811147Smitch.hayenga@arm.com    if len(v1) < len(v2): return -1
12911147Smitch.hayenga@arm.com    if len(v1) > len(v2): return  1
13011147Smitch.hayenga@arm.com    return 0
13111147Smitch.hayenga@arm.com
13211147Smitch.hayenga@arm.comdef crossproduct(items):
13311147Smitch.hayenga@arm.com    if len(items) == 1:
13411147Smitch.hayenga@arm.com        for i in items[0]:
13511147Smitch.hayenga@arm.com            yield (i,)
13611147Smitch.hayenga@arm.com    else:
13711147Smitch.hayenga@arm.com        for i in items[0]:
13811147Smitch.hayenga@arm.com            for j in crossproduct(items[1:]):
13911147Smitch.hayenga@arm.com                yield (i,) + j
14011147Smitch.hayenga@arm.com
14111147Smitch.hayenga@arm.comdef flatten(items):
14211147Smitch.hayenga@arm.com    while items:
14311147Smitch.hayenga@arm.com        item = items.pop(0)
14411147Smitch.hayenga@arm.com        if isinstance(item, (list, tuple)):
14511147Smitch.hayenga@arm.com            items[0:0] = item
14611147Smitch.hayenga@arm.com        else:
14711147Smitch.hayenga@arm.com            yield item
14811147Smitch.hayenga@arm.com
14911147Smitch.hayenga@arm.com# force scalars to one-element lists for uniformity
15011147Smitch.hayenga@arm.comdef makeList(objOrList):
15111147Smitch.hayenga@arm.com    if isinstance(objOrList, list):
15211147Smitch.hayenga@arm.com        return objOrList
15311147Smitch.hayenga@arm.com    return [objOrList]
15411147Smitch.hayenga@arm.com
15511147Smitch.hayenga@arm.comdef printList(items, indent=4):
15611147Smitch.hayenga@arm.com    line = ' ' * indent
15711147Smitch.hayenga@arm.com    for i,item in enumerate(items):
15811147Smitch.hayenga@arm.com        if len(line) + len(item) > 76:
15911147Smitch.hayenga@arm.com            print line
16011147Smitch.hayenga@arm.com            line = ' ' * indent
16111147Smitch.hayenga@arm.com
16211147Smitch.hayenga@arm.com        if i < len(items) - 1:
16311147Smitch.hayenga@arm.com            line += '%s, ' % item
16411147Smitch.hayenga@arm.com        else:
16511147Smitch.hayenga@arm.com            line += item
16611147Smitch.hayenga@arm.com            print line
16711147Smitch.hayenga@arm.com
16811147Smitch.hayenga@arm.comdef readCommand(cmd, **kwargs):
16911147Smitch.hayenga@arm.com    """run the command cmd, read the results and return them
17011147Smitch.hayenga@arm.com    this is sorta like `cmd` in shell"""
17111147Smitch.hayenga@arm.com    from subprocess import Popen, PIPE, STDOUT
17211147Smitch.hayenga@arm.com
17311147Smitch.hayenga@arm.com    if isinstance(cmd, str):
17411147Smitch.hayenga@arm.com        cmd = cmd.split()
17511147Smitch.hayenga@arm.com
17611147Smitch.hayenga@arm.com    no_exception = 'exception' in kwargs
17713557Sgabeblack@google.com    exception = kwargs.pop('exception', None)
17813557Sgabeblack@google.com
17911147Smitch.hayenga@arm.com    kwargs.setdefault('shell', False)
18011147Smitch.hayenga@arm.com    kwargs.setdefault('stdout', PIPE)
18112106SRekai.GonzalezAlberquilla@arm.com    kwargs.setdefault('stderr', STDOUT)
18212106SRekai.GonzalezAlberquilla@arm.com    kwargs.setdefault('close_fds', True)
18312106SRekai.GonzalezAlberquilla@arm.com    try:
18411147Smitch.hayenga@arm.com        subp = Popen(cmd, **kwargs)
18511147Smitch.hayenga@arm.com    except Exception, e:
18611147Smitch.hayenga@arm.com        if no_exception:
18713557Sgabeblack@google.com            return exception
18813557Sgabeblack@google.com        raise
18911147Smitch.hayenga@arm.com
19011147Smitch.hayenga@arm.com    return subp.communicate()[0]
19112106SRekai.GonzalezAlberquilla@arm.com