regression.py revision 13540
12810SN/A#!/usr/bin/env python2.7
28856Sandreas.hansson@arm.com
38856Sandreas.hansson@arm.com# Copyright (c) 2010-2013 Advanced Micro Devices, Inc.
48856Sandreas.hansson@arm.com# All rights reserved.
58856Sandreas.hansson@arm.com#
68856Sandreas.hansson@arm.com# Redistribution and use in source and binary forms, with or without
78856Sandreas.hansson@arm.com# modification, are permitted provided that the following conditions are
88856Sandreas.hansson@arm.com# met: redistributions of source code must retain the above copyright
98856Sandreas.hansson@arm.com# notice, this list of conditions and the following disclaimer;
108856Sandreas.hansson@arm.com# redistributions in binary form must reproduce the above copyright
118856Sandreas.hansson@arm.com# notice, this list of conditions and the following disclaimer in the
128856Sandreas.hansson@arm.com# documentation and/or other materials provided with the distribution;
138856Sandreas.hansson@arm.com# neither the name of the copyright holders nor the names of its
142810SN/A# contributors may be used to endorse or promote products derived from
152810SN/A# this software without specific prior written permission.
162810SN/A#
172810SN/A# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
182810SN/A# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
192810SN/A# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
202810SN/A# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
212810SN/A# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
222810SN/A# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
232810SN/A# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
242810SN/A# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
252810SN/A# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
262810SN/A# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
272810SN/A# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
282810SN/A
292810SN/A"""
302810SN/ASYNOPSIS
312810SN/A
322810SN/A    ./regression/regression.py ./regression/
332810SN/A
342810SN/ADESCRIPTION
352810SN/A
362810SN/A    Runs regression tester for McPAT.
372810SN/A    This tester can compile and runs McPAT on the input contained in the
382810SN/A    specified directory, and then compares the output to that of a prior run in
392810SN/A    order to ensure that specific power and area calculations do not change.
402810SN/A
412810SN/AAUTHORS
422810SN/A
432810SN/A    Joel Hestness <hestness@cs.wisc.edu> (while interning at AMD)
442810SN/A    Yasuko Eckert <yasuko.eckert@amd.com>
452810SN/A"""
462810SN/A
472810SN/Aimport os
483348SN/Aimport sys
493348SN/Aimport optparse
508232Snate@binkert.orgimport re
519152Satgutier@umich.edu
525338Sstever@gmail.com################################
535338Sstever@gmail.com# Global Variables
548786Sgblack@eecs.umich.edu################################
552810SN/A
562810SN/Aglobal mcpat_binary
572810SN/Amcpat_binary = "../../build/mcpat/mcpat"
588856Sandreas.hansson@arm.comglobal optionsparser
598856Sandreas.hansson@arm.com
608856Sandreas.hansson@arm.com################################
618922Swilliam.wang@arm.com# Global Functions
628914Sandreas.hansson@arm.com################################
638856Sandreas.hansson@arm.com
648856Sandreas.hansson@arm.comdef run_test(testdir):
654475SN/A    test_passed = True
665034SN/A    testfiles = os.listdir(testdir)
675034SN/A    for testfile in testfiles:
685314SN/A        # For each power_region file, run McPAT on it and check the
695314SN/A        # output created against the regression
704628SN/A        if re.match("power_region.*\.xml$", testfile):
715034SN/A            # Get the region index of the test
729263Smrinmoy.ghosh@arm.com            fileparts = testfile.split(".")
739263Smrinmoy.ghosh@arm.com            region_index = fileparts[0][12:]
745034SN/A            regression_test = os.path.join(testdir, testfile)
756122SSteve.Reinhardt@amd.com            regression_output = os.path.join(
768134SAli.Saidi@ARM.com                    testdir, "region%s.out" % region_index)
774626SN/A            regression_correct = os.path.join(
784626SN/A                    testdir, "region%s.out.ref" % region_index)
795034SN/A            print "Running test: %s..." % regression_test
806122SSteve.Reinhardt@amd.com            # Run McPAT on the input
818883SAli.Saidi@ARM.com            os.system(
828833Sdam.sunwoo@arm.com                    "%s -infile %s -print_level 10 > %s" %
834458SN/A                    (mcpat_binary, regression_test, regression_output) )
842810SN/A            if os.path.exists(regression_correct):
852810SN/A                diff = os.popen(
863013SN/A                        "diff %s %s" % (regression_output, regression_correct),
878856Sandreas.hansson@arm.com                        "r").read()
882810SN/A                if diff != "":
893013SN/A                    print "WARN: Differences found in %s" % regression_output
908856Sandreas.hansson@arm.com                    if options.verbose:
912810SN/A                        print diff
922810SN/A                    test_passed = False
932810SN/A            else:
942810SN/A                print "WARN: Regression test not set up: %s..." % regression_test
958856Sandreas.hansson@arm.com                print "WARN: Not able to verify test"
962810SN/A                test_passed = False
973013SN/A
988856Sandreas.hansson@arm.com            if options.cleanup:
993013SN/A                if options.verbose:
1008856Sandreas.hansson@arm.com                    print "WARN: Cleaning (deleting) regression output file: "\
1018856Sandreas.hansson@arm.com                            "%s" % regression_output
1022897SN/A                os.system("rm -f %s" % regression_output)
1034666SN/A
1048922Swilliam.wang@arm.com    if test_passed:
1052897SN/A        print "PASSED: %s\n\n" % testdir
1062810SN/A    else:
1072810SN/A        print "FAILED: %s\n\n" % testdir
1082844SN/A
1092810SN/Adef has_power_region_files(testdir):
1102858SN/A    files = os.listdir(testdir)
1112858SN/A    for file in files:
1128856Sandreas.hansson@arm.com        if "power_region" in file and ".xml" in file:
1138922Swilliam.wang@arm.com            return True
1148711Sandreas.hansson@arm.com
1152858SN/Adef is_valid_test_directory(testdir):
1162858SN/A    valid_regression = True
1178922Swilliam.wang@arm.com    power_region_file_found = False
1188922Swilliam.wang@arm.com
1198922Swilliam.wang@arm.com    files = os.listdir(testdir)
1208922Swilliam.wang@arm.com    for file in files:
1218922Swilliam.wang@arm.com        if "power_region" in file and ".xml" in file:
1228922Swilliam.wang@arm.com            power_region_file_found = True
1238922Swilliam.wang@arm.com            fileparts = file.split(".")
1248922Swilliam.wang@arm.com            region_index = fileparts[0][12:]
1258922Swilliam.wang@arm.com            regression_output = os.path.join(
1268922Swilliam.wang@arm.com                    testdir, "region%s.out.ref" % region_index)
1278922Swilliam.wang@arm.com            if os.path.exists(regression_output):
1288922Swilliam.wang@arm.com                if options.verbose:
1298922Swilliam.wang@arm.com                    print "Valid regression test: %s/%s" % (testdir, file)
1308922Swilliam.wang@arm.com            else:
1318922Swilliam.wang@arm.com                valid_regression = False
1328922Swilliam.wang@arm.com
1338922Swilliam.wang@arm.com    return valid_regression and power_region_file_found
1348922Swilliam.wang@arm.com
1358922Swilliam.wang@arm.com################################
1364628SN/A# Execute here
1372858SN/A################################
1382810SN/A
1392810SN/Aoptionsparser = optparse.OptionParser(
1402810SN/A        formatter = optparse.TitledHelpFormatter(),
1412810SN/A        usage = globals()['__doc__'])
1422810SN/Aoptionsparser.add_option(
1434022SN/A        "-b", "--build", action = "store_true", default = False,
1444022SN/A        help = "Build McPAT before running tests")
1454022SN/Aoptionsparser.add_option(
1462810SN/A        "-c", "--cleanup", action = "store_true", default = False,
1472810SN/A        help = "Clean up the specified regression directory")
1488833Sdam.sunwoo@arm.comoptionsparser.add_option(
1492810SN/A        "-f", "--force", action = "store_true", default = False,
1502810SN/A        help = "Force run regression even if directory isn't set up")
1512810SN/Aoptionsparser.add_option(
1522810SN/A        "-m", "--maketest", action = "store_true", default = False,
1538833Sdam.sunwoo@arm.com        help = "Set up the specified test directory")
1548833Sdam.sunwoo@arm.comoptionsparser.add_option(
1558833Sdam.sunwoo@arm.com        "-v", "--verbose", action = "store_true", default = False,
1562810SN/A        help = "Print verbose output")
1572810SN/A(options, args) = optionsparser.parse_args()
1584871SN/A
1594871SN/Aif not os.path.exists(mcpat_binary) and not options.build:
1604871SN/A    print "ERROR: McPAT binary does not exist: %s" % mcpat_binary
1614871SN/A    exit(0)
1624871SN/A
1634871SN/Aif options.build:
1644871SN/A    print "Building McPAT..."
1654871SN/A    bin_dir = os.path.dirname(mcpat_binary)
1664871SN/A    directory = os.path.join(bin_dir, "../../ext/mcpat")
1674871SN/A    build_output = os.popen(
1682810SN/A            "cd %s; make clean; make -j 8 dbg 2>&1" % directory).read()
1692810SN/A    if "error" in build_output.lower():
1702810SN/A        print "Error during build: %s" % build_output
1718833Sdam.sunwoo@arm.com        exit(0)
1722810SN/A
1734871SN/Aif len(args) < 1:
1748833Sdam.sunwoo@arm.com    print "ERROR: Must specify regressions directory"
1758833Sdam.sunwoo@arm.com    exit(0)
1768833Sdam.sunwoo@arm.com
1772810SN/A# check params
1782810SN/Arootdir = args[0];
1792810SN/Aif not os.path.exists(rootdir):
1802810SN/A    print "ERROR: Regressions directory does not exist: %s" % rootdir
1818833Sdam.sunwoo@arm.com    exit(0)
1822810SN/A
1834871SN/Aif options.maketest:
1848833Sdam.sunwoo@arm.com    # The specified rootdir must exist since we got here
1858833Sdam.sunwoo@arm.com    # Check if directory has tests
1868833Sdam.sunwoo@arm.com    list = os.listdir(rootdir)
1872810SN/A    found_test = False
1882810SN/A    for file in list:
1894022SN/A        if "power_region" in file and "out" not in file and "ref" not in file:
1904022SN/A            found_test = True
1914022SN/A            # Prepare to run the test in order to set it up
1922810SN/A            fileparts = file.split(".")
1932810SN/A            region_index = fileparts[0][12:]
1948833Sdam.sunwoo@arm.com            regression_test = os.path.join(rootdir, file)
1952810SN/A            regression_output = os.path.join(
1962810SN/A                    rootdir, "region%s.out.ref" % region_index)
1972810SN/A            if os.path.exists(regression_output):
1982810SN/A                print "WARN: Overwriting old regression output: " \
1998833Sdam.sunwoo@arm.com                        "%s" % regression_output
2008833Sdam.sunwoo@arm.com            # Run the test to set it up
2018833Sdam.sunwoo@arm.com            print "Writing new regression output..."
2022810SN/A            os.system(
2032810SN/A                    "%s -infile %s -print_level 10 > %s" %
2042810SN/A                    (mcpat_binary, regression_test, regression_output))
2052810SN/A
2062810SN/A    if not found_test:
2078833Sdam.sunwoo@arm.com        print "ERROR: Invalid test directory: %s" % rootdir
2082810SN/A        print "ERROR: Must contain XML file power_region*.xml"
2094871SN/A
2108833Sdam.sunwoo@arm.com    exit(0)
2118833Sdam.sunwoo@arm.com
2128833Sdam.sunwoo@arm.comfound_test = False
2132810SN/Aif has_power_region_files(rootdir):
2142810SN/A    found_test = True
2152810SN/A    if is_valid_test_directory(rootdir) or options.force:
2162810SN/A        run_test(rootdir)
2178833Sdam.sunwoo@arm.com    else:
2182810SN/A        print "WARN: Regression directory is not set up: %s" % rootdir
2194871SN/Aelse:
2208833Sdam.sunwoo@arm.com    folders = os.listdir(rootdir)
2218833Sdam.sunwoo@arm.com    folders.sort()
2228833Sdam.sunwoo@arm.com    for folder in folders:
2232810SN/A        testdir = os.path.join(rootdir, folder)
2242810SN/A        if os.path.isdir(testdir):
2254022SN/A            if has_power_region_files(testdir):
2264022SN/A                found_test = True
2274022SN/A                if is_valid_test_directory(testdir):
2282810SN/A                    run_test(testdir)
2292810SN/A                else:
2308833Sdam.sunwoo@arm.com                    if options.force:
2312810SN/A                        print "WARN: Regression directory is not set up: " \
2322810SN/A                                "%s" % testdir
2332810SN/A                        print "WARN: Running test anyway: %s..." % testdir
2342810SN/A                        run_test(testdir)
2358833Sdam.sunwoo@arm.com                    else:
2368833Sdam.sunwoo@arm.com                        print "Regression directory is not set up: %s" % testdir
2378833Sdam.sunwoo@arm.com            else:
2382810SN/A                print "Not a valid test directory: %s" % testdir
2392810SN/A
2402810SN/Aif not found_test:
2412810SN/A    print "No valid regressions found in %s" % rootdir
2422810SN/A