__init__.py revision 8224
14312SN/A# Copyright (c) 2008-2009 The Hewlett-Packard Development Company
24312SN/A# Copyright (c) 2004-2006 The Regents of The University of Michigan
34312SN/A# All rights reserved.
410036SN/A#
58835SN/A# Redistribution and use in source and binary forms, with or without
610036SN/A# modification, are permitted provided that the following conditions are
77935SN/A# met: redistributions of source code must retain the above copyright
87935SN/A# notice, this list of conditions and the following disclaimer;
97935SN/A# redistributions in binary form must reproduce the above copyright
104312SN/A# notice, this list of conditions and the following disclaimer in the
114312SN/A# documentation and/or other materials provided with the distribution;
124312SN/A# neither the name of the copyright holders nor the names of its
1310315SN/A# contributors may be used to endorse or promote products derived from
148835SN/A# this software without specific prior written permission.
159885SN/A#
169885SN/A# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1710036SN/A# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
188835SN/A# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
198835SN/A# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2010315SN/A# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
218835SN/A# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2210315SN/A# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
239481SN/A# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
249481SN/A# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
258625SN/A# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2611066Snilay@cs.wisc.edu# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2711219Snilay@cs.wisc.edu#
288721SN/A# Authors: Nathan Binkert
298835SN/A
308835SN/Aimport os
317935SN/Aimport re
327935SN/Aimport sys
337935SN/A
347935SN/Aimport convert
357935SN/Aimport jobfile
367935SN/A
377935SN/Afrom attrdict import attrdict, multiattrdict, optiondict
388983SN/Afrom code_formatter import code_formatter
394312SN/Afrom multidict import multidict
409885SN/Afrom orderdict import orderdict
419885SN/Afrom smartdict import SmartDict
429885SN/Afrom sorteddict import SortedDict
4310315SN/Afrom region import neg_inf, pos_inf, Region, Regions
4410036SN/A
4510315SN/A# define this here so we can use it right away if necessary
469885SN/Adef errorURL(prefix, s):
479885SN/A    try:
484312SN/A        import zlib
494312SN/A        hashstr = "%x" % zlib.crc32(s)
509481SN/A    except:
5110315SN/A        hashstr = "UnableToHash"
525876SN/A    return "For more information see: http://www.m5sim.org/%s/%s" % \
539885SN/A            (prefix, hashstr)
544312SN/A
555876SN/A# panic() should be called when something happens that should never
568835SN/A# ever happen regardless of what the user does (i.e., an acutal m5
575876SN/A# bug).
585000SN/Adef panic(fmt, *args):
5910036SN/A    print >>sys.stderr, 'panic:', fmt % args
604312SN/A    print >>sys.stderr, errorURL('panic',fmt)
614312SN/A    sys.exit(1)
628835SN/A
639481SN/A# fatal() should be called when the simulation cannot continue due to
645000SN/A# some condition that is the user's fault (bad configuration, invalid
654312SN/A# arguments, etc.) and not a simulator bug.
664312SN/Adef fatal(fmt, *args):
674312SN/A    print >>sys.stderr, 'fatal:', fmt % args
684312SN/A    print >>sys.stderr, errorURL('fatal',fmt)
695575SN/A    sys.exit(1)
708835SN/A
714312SN/Aclass Singleton(type):
729885SN/A    def __call__(cls, *args, **kwargs):
7310315SN/A        if hasattr(cls, '_instance'):
749481SN/A            return cls._instance
754312SN/A
764971SN/A        cls._instance = super(Singleton, cls).__call__(*args, **kwargs)
774312SN/A        return cls._instance
784312SN/A
794312SN/Adef addToPath(path):
804312SN/A    """Prepend given directory to system module search path.  We may not
814312SN/A    need this anymore if we can structure our config library more like a
8211066Snilay@cs.wisc.edu    Python package."""
839885SN/A
848983SN/A    # if it's a relative path and we know what directory the current
854312SN/A    # python script is in, make the path relative to that directory.
869885SN/A    if not os.path.isabs(path) and sys.path[0]:
8711219Snilay@cs.wisc.edu        path = os.path.join(sys.path[0], path)
8811066Snilay@cs.wisc.edu    path = os.path.realpath(path)
8910036SN/A    # sys.path[0] should always refer to the current script's directory,
906123SN/A    # so place the new dir right after that.
919481SN/A    sys.path.insert(1, path)
9211066Snilay@cs.wisc.edu
934312SN/A# Apply method to object.
949481SN/A# applyMethod(obj, 'meth', <args>) is equivalent to obj.meth(<args>)
955876SN/Adef applyMethod(obj, meth, *args, **kwargs):
968835SN/A    return getattr(obj, meth)(*args, **kwargs)
979481SN/A
9810036SN/A# If the first argument is an (non-sequence) object, apply the named
994312SN/A# method with the given arguments.  If the first argument is a
1008835SN/A# sequence, apply the method to each element of the sequence (a la
1019885SN/A# 'map').
1029481SN/Adef applyOrMap(objOrSeq, meth, *args, **kwargs):
1034312SN/A    if not isinstance(objOrSeq, (list, tuple)):
10411219Snilay@cs.wisc.edu        return applyMethod(objOrSeq, meth, *args, **kwargs)
1054312SN/A    else:
1068983SN/A        return [applyMethod(o, meth, *args, **kwargs) for o in objOrSeq]
1074312SN/A
1089885SN/Adef compareVersions(v1, v2):
1099885SN/A    """helper function: compare arrays or strings of version numbers.
1109885SN/A    E.g., compare_version((1,3,25), (1,4,1)')
1119885SN/A    returns -1, 0, 1 if v1 is <, ==, > v2
1129885SN/A    """
11310036SN/A    def make_version_list(v):
1149885SN/A        if isinstance(v, (list,tuple)):
11510036SN/A            return v
1169885SN/A        elif isinstance(v, str):
1179885SN/A            return map(lambda x: int(re.match('\d+', x).group()), v.split('.'))
1185000SN/A        else:
1196024SN/A            raise TypeError
12010036SN/A
1215000SN/A    v1 = make_version_list(v1)
1225000SN/A    v2 = make_version_list(v2)
1234312SN/A    # Compare corresponding elements of lists
12411066Snilay@cs.wisc.edu    for n1,n2 in zip(v1, v2):
1259885SN/A        if n1 < n2: return -1
1268983SN/A        if n1 > n2: return  1
1274312SN/A    # all corresponding values are equal... see if one has extra values
1289885SN/A    if len(v1) < len(v2): return -1
12911219Snilay@cs.wisc.edu    if len(v1) > len(v2): return  1
13011066Snilay@cs.wisc.edu    return 0
13110036SN/A
1326123SN/Adef crossproduct(items):
1339481SN/A    if len(items) == 1:
13411066Snilay@cs.wisc.edu        for i in items[0]:
1354312SN/A            yield (i,)
1369481SN/A    else:
1375876SN/A        for i in items[0]:
1388835SN/A            for j in crossproduct(items[1:]):
1399481SN/A                yield (i,) + j
14010036SN/A
1414312SN/Adef flatten(items):
1428835SN/A    while items:
1439885SN/A        item = items.pop(0)
1449481SN/A        if isinstance(item, (list, tuple)):
1454312SN/A            items[0:0] = item
14611219Snilay@cs.wisc.edu        else:
1474312SN/A            yield item
1488983SN/A
1494312SN/A# force scalars to one-element lists for uniformity
1509885SN/Adef makeList(objOrList):
1519885SN/A    if isinstance(objOrList, list):
1529885SN/A        return objOrList
1539885SN/A    return [objOrList]
1549885SN/A
15510036SN/Adef printList(items, indent=4):
1569885SN/A    line = ' ' * indent
15710036SN/A    for i,item in enumerate(items):
1589885SN/A        if len(line) + len(item) > 76:
1599885SN/A            print line
1608835SN/A            line = ' ' * indent
1618835SN/A
16210036SN/A        if i < len(items) - 1:
1638835SN/A            line += '%s, ' % item
1649481SN/A        else:
1659481SN/A            line += item
16610036SN/A            print line
1679481SN/A
1685000SN/Adef readCommand(cmd, **kwargs):
1696024SN/A    """run the command cmd, read the results and return them
17010036SN/A    this is sorta like `cmd` in shell"""
1715000SN/A    from subprocess import Popen, PIPE, STDOUT
1725000SN/A
1734312SN/A    if isinstance(cmd, str):
17411066Snilay@cs.wisc.edu        cmd = cmd.split()
1759885SN/A
1768983SN/A    no_exception = 'exception' in kwargs
1779481SN/A    exception = kwargs.pop('exception', None)
1789885SN/A
17911219Snilay@cs.wisc.edu    kwargs.setdefault('shell', False)
18011066Snilay@cs.wisc.edu    kwargs.setdefault('stdout', PIPE)
18110036SN/A    kwargs.setdefault('stderr', STDOUT)
1826123SN/A    kwargs.setdefault('close_fds', True)
1839481SN/A    try:
18411066Snilay@cs.wisc.edu        subp = Popen(cmd, **kwargs)
1854312SN/A    except Exception, e:
1869481SN/A        if no_exception:
1875876SN/A            return exception
1888835SN/A        raise
1899481SN/A
19010036SN/A    return subp.communicate()[0]
1914312SN/A