regression.py revision 10235
110235Syasuko.eckert@amd.com#!/usr/bin/env python 210235Syasuko.eckert@amd.com 310235Syasuko.eckert@amd.com# Copyright (c) 2010-2013 Advanced Micro Devices, Inc. 410235Syasuko.eckert@amd.com# All rights reserved. 510235Syasuko.eckert@amd.com# 610235Syasuko.eckert@amd.com# Redistribution and use in source and binary forms, with or without 710235Syasuko.eckert@amd.com# modification, are permitted provided that the following conditions are 810235Syasuko.eckert@amd.com# met: redistributions of source code must retain the above copyright 910235Syasuko.eckert@amd.com# notice, this list of conditions and the following disclaimer; 1010235Syasuko.eckert@amd.com# redistributions in binary form must reproduce the above copyright 1110235Syasuko.eckert@amd.com# notice, this list of conditions and the following disclaimer in the 1210235Syasuko.eckert@amd.com# documentation and/or other materials provided with the distribution; 1310235Syasuko.eckert@amd.com# neither the name of the copyright holders nor the names of its 1410235Syasuko.eckert@amd.com# contributors may be used to endorse or promote products derived from 1510235Syasuko.eckert@amd.com# this software without specific prior written permission. 1610235Syasuko.eckert@amd.com# 1710235Syasuko.eckert@amd.com# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1810235Syasuko.eckert@amd.com# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1910235Syasuko.eckert@amd.com# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 2010235Syasuko.eckert@amd.com# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2110235Syasuko.eckert@amd.com# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2210235Syasuko.eckert@amd.com# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 2310235Syasuko.eckert@amd.com# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2410235Syasuko.eckert@amd.com# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2510235Syasuko.eckert@amd.com# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2610235Syasuko.eckert@amd.com# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 2710235Syasuko.eckert@amd.com# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2810235Syasuko.eckert@amd.com 2910235Syasuko.eckert@amd.com""" 3010235Syasuko.eckert@amd.comSYNOPSIS 3110235Syasuko.eckert@amd.com 3210235Syasuko.eckert@amd.com ./regression/regression.py ./regression/ 3310235Syasuko.eckert@amd.com 3410235Syasuko.eckert@amd.comDESCRIPTION 3510235Syasuko.eckert@amd.com 3610235Syasuko.eckert@amd.com Runs regression tester for McPAT. 3710235Syasuko.eckert@amd.com This tester can compile and runs McPAT on the input contained in the 3810235Syasuko.eckert@amd.com specified directory, and then compares the output to that of a prior run in 3910235Syasuko.eckert@amd.com order to ensure that specific power and area calculations do not change. 4010235Syasuko.eckert@amd.com 4110235Syasuko.eckert@amd.comAUTHORS 4210235Syasuko.eckert@amd.com 4310235Syasuko.eckert@amd.com Joel Hestness <hestness@cs.wisc.edu> (while interning at AMD) 4410235Syasuko.eckert@amd.com Yasuko Eckert <yasuko.eckert@amd.com> 4510235Syasuko.eckert@amd.com""" 4610235Syasuko.eckert@amd.com 4710235Syasuko.eckert@amd.comimport os 4810235Syasuko.eckert@amd.comimport sys 4910235Syasuko.eckert@amd.comimport optparse 5010235Syasuko.eckert@amd.comimport re 5110235Syasuko.eckert@amd.com 5210235Syasuko.eckert@amd.com################################ 5310235Syasuko.eckert@amd.com# Global Variables 5410235Syasuko.eckert@amd.com################################ 5510235Syasuko.eckert@amd.com 5610235Syasuko.eckert@amd.comglobal mcpat_binary 5710235Syasuko.eckert@amd.commcpat_binary = "../../build/mcpat/mcpat" 5810235Syasuko.eckert@amd.comglobal optionsparser 5910235Syasuko.eckert@amd.com 6010235Syasuko.eckert@amd.com################################ 6110235Syasuko.eckert@amd.com# Global Functions 6210235Syasuko.eckert@amd.com################################ 6310235Syasuko.eckert@amd.com 6410235Syasuko.eckert@amd.comdef run_test(testdir): 6510235Syasuko.eckert@amd.com test_passed = True 6610235Syasuko.eckert@amd.com testfiles = os.listdir(testdir) 6710235Syasuko.eckert@amd.com for testfile in testfiles: 6810235Syasuko.eckert@amd.com # For each power_region file, run McPAT on it and check the 6910235Syasuko.eckert@amd.com # output created against the regression 7010235Syasuko.eckert@amd.com if re.match("power_region.*\.xml$", testfile): 7110235Syasuko.eckert@amd.com # Get the region index of the test 7210235Syasuko.eckert@amd.com fileparts = testfile.split(".") 7310235Syasuko.eckert@amd.com region_index = fileparts[0][12:] 7410235Syasuko.eckert@amd.com regression_test = os.path.join(testdir, testfile) 7510235Syasuko.eckert@amd.com regression_output = os.path.join( 7610235Syasuko.eckert@amd.com testdir, "region%s.out" % region_index) 7710235Syasuko.eckert@amd.com regression_correct = os.path.join( 7810235Syasuko.eckert@amd.com testdir, "region%s.out.ref" % region_index) 7910235Syasuko.eckert@amd.com print "Running test: %s..." % regression_test 8010235Syasuko.eckert@amd.com # Run McPAT on the input 8110235Syasuko.eckert@amd.com os.system( 8210235Syasuko.eckert@amd.com "%s -infile %s -print_level 10 > %s" % 8310235Syasuko.eckert@amd.com (mcpat_binary, regression_test, regression_output) ) 8410235Syasuko.eckert@amd.com if os.path.exists(regression_correct): 8510235Syasuko.eckert@amd.com diff = os.popen( 8610235Syasuko.eckert@amd.com "diff %s %s" % (regression_output, regression_correct), 8710235Syasuko.eckert@amd.com "r").read() 8810235Syasuko.eckert@amd.com if diff != "": 8910235Syasuko.eckert@amd.com print "WARN: Differences found in %s" % regression_output 9010235Syasuko.eckert@amd.com if options.verbose: 9110235Syasuko.eckert@amd.com print diff 9210235Syasuko.eckert@amd.com test_passed = False 9310235Syasuko.eckert@amd.com else: 9410235Syasuko.eckert@amd.com print "WARN: Regression test not set up: %s..." % regression_test 9510235Syasuko.eckert@amd.com print "WARN: Not able to verify test" 9610235Syasuko.eckert@amd.com test_passed = False 9710235Syasuko.eckert@amd.com 9810235Syasuko.eckert@amd.com if options.cleanup: 9910235Syasuko.eckert@amd.com if options.verbose: 10010235Syasuko.eckert@amd.com print "WARN: Cleaning (deleting) regression output file: "\ 10110235Syasuko.eckert@amd.com "%s" % regression_output 10210235Syasuko.eckert@amd.com os.system("rm -f %s" % regression_output) 10310235Syasuko.eckert@amd.com 10410235Syasuko.eckert@amd.com if test_passed: 10510235Syasuko.eckert@amd.com print "PASSED: %s\n\n" % testdir 10610235Syasuko.eckert@amd.com else: 10710235Syasuko.eckert@amd.com print "FAILED: %s\n\n" % testdir 10810235Syasuko.eckert@amd.com 10910235Syasuko.eckert@amd.comdef has_power_region_files(testdir): 11010235Syasuko.eckert@amd.com files = os.listdir(testdir) 11110235Syasuko.eckert@amd.com for file in files: 11210235Syasuko.eckert@amd.com if "power_region" in file and ".xml" in file: 11310235Syasuko.eckert@amd.com return True 11410235Syasuko.eckert@amd.com 11510235Syasuko.eckert@amd.comdef is_valid_test_directory(testdir): 11610235Syasuko.eckert@amd.com valid_regression = True 11710235Syasuko.eckert@amd.com power_region_file_found = False 11810235Syasuko.eckert@amd.com 11910235Syasuko.eckert@amd.com files = os.listdir(testdir) 12010235Syasuko.eckert@amd.com for file in files: 12110235Syasuko.eckert@amd.com if "power_region" in file and ".xml" in file: 12210235Syasuko.eckert@amd.com power_region_file_found = True 12310235Syasuko.eckert@amd.com fileparts = file.split(".") 12410235Syasuko.eckert@amd.com region_index = fileparts[0][12:] 12510235Syasuko.eckert@amd.com regression_output = os.path.join( 12610235Syasuko.eckert@amd.com testdir, "region%s.out.ref" % region_index) 12710235Syasuko.eckert@amd.com if os.path.exists(regression_output): 12810235Syasuko.eckert@amd.com if options.verbose: 12910235Syasuko.eckert@amd.com print "Valid regression test: %s/%s" % (testdir, file) 13010235Syasuko.eckert@amd.com else: 13110235Syasuko.eckert@amd.com valid_regression = False 13210235Syasuko.eckert@amd.com 13310235Syasuko.eckert@amd.com return valid_regression and power_region_file_found 13410235Syasuko.eckert@amd.com 13510235Syasuko.eckert@amd.com################################ 13610235Syasuko.eckert@amd.com# Execute here 13710235Syasuko.eckert@amd.com################################ 13810235Syasuko.eckert@amd.com 13910235Syasuko.eckert@amd.comoptionsparser = optparse.OptionParser( 14010235Syasuko.eckert@amd.com formatter = optparse.TitledHelpFormatter(), 14110235Syasuko.eckert@amd.com usage = globals()['__doc__']) 14210235Syasuko.eckert@amd.comoptionsparser.add_option( 14310235Syasuko.eckert@amd.com "-b", "--build", action = "store_true", default = False, 14410235Syasuko.eckert@amd.com help = "Build McPAT before running tests") 14510235Syasuko.eckert@amd.comoptionsparser.add_option( 14610235Syasuko.eckert@amd.com "-c", "--cleanup", action = "store_true", default = False, 14710235Syasuko.eckert@amd.com help = "Clean up the specified regression directory") 14810235Syasuko.eckert@amd.comoptionsparser.add_option( 14910235Syasuko.eckert@amd.com "-f", "--force", action = "store_true", default = False, 15010235Syasuko.eckert@amd.com help = "Force run regression even if directory isn't set up") 15110235Syasuko.eckert@amd.comoptionsparser.add_option( 15210235Syasuko.eckert@amd.com "-m", "--maketest", action = "store_true", default = False, 15310235Syasuko.eckert@amd.com help = "Set up the specified test directory") 15410235Syasuko.eckert@amd.comoptionsparser.add_option( 15510235Syasuko.eckert@amd.com "-v", "--verbose", action = "store_true", default = False, 15610235Syasuko.eckert@amd.com help = "Print verbose output") 15710235Syasuko.eckert@amd.com(options, args) = optionsparser.parse_args() 15810235Syasuko.eckert@amd.com 15910235Syasuko.eckert@amd.comif not os.path.exists(mcpat_binary) and not options.build: 16010235Syasuko.eckert@amd.com print "ERROR: McPAT binary does not exist: %s" % mcpat_binary 16110235Syasuko.eckert@amd.com exit(0) 16210235Syasuko.eckert@amd.com 16310235Syasuko.eckert@amd.comif options.build: 16410235Syasuko.eckert@amd.com print "Building McPAT..." 16510235Syasuko.eckert@amd.com bin_dir = os.path.dirname(mcpat_binary) 16610235Syasuko.eckert@amd.com directory = os.path.join(bin_dir, "../../ext/mcpat") 16710235Syasuko.eckert@amd.com build_output = os.popen( 16810235Syasuko.eckert@amd.com "cd %s; make clean; make -j 8 dbg 2>&1" % directory).read() 16910235Syasuko.eckert@amd.com if "error" in build_output.lower(): 17010235Syasuko.eckert@amd.com print "Error during build: %s" % build_output 17110235Syasuko.eckert@amd.com exit(0) 17210235Syasuko.eckert@amd.com 17310235Syasuko.eckert@amd.comif len(args) < 1: 17410235Syasuko.eckert@amd.com print "ERROR: Must specify regressions directory" 17510235Syasuko.eckert@amd.com exit(0) 17610235Syasuko.eckert@amd.com 17710235Syasuko.eckert@amd.com# check params 17810235Syasuko.eckert@amd.comrootdir = args[0]; 17910235Syasuko.eckert@amd.comif not os.path.exists(rootdir): 18010235Syasuko.eckert@amd.com print "ERROR: Regressions directory does not exist: %s" % rootdir 18110235Syasuko.eckert@amd.com exit(0) 18210235Syasuko.eckert@amd.com 18310235Syasuko.eckert@amd.comif options.maketest: 18410235Syasuko.eckert@amd.com # The specified rootdir must exist since we got here 18510235Syasuko.eckert@amd.com # Check if directory has tests 18610235Syasuko.eckert@amd.com list = os.listdir(rootdir) 18710235Syasuko.eckert@amd.com found_test = False 18810235Syasuko.eckert@amd.com for file in list: 18910235Syasuko.eckert@amd.com if "power_region" in file and "out" not in file and "ref" not in file: 19010235Syasuko.eckert@amd.com found_test = True 19110235Syasuko.eckert@amd.com # Prepare to run the test in order to set it up 19210235Syasuko.eckert@amd.com fileparts = file.split(".") 19310235Syasuko.eckert@amd.com region_index = fileparts[0][12:] 19410235Syasuko.eckert@amd.com regression_test = os.path.join(rootdir, file) 19510235Syasuko.eckert@amd.com regression_output = os.path.join( 19610235Syasuko.eckert@amd.com rootdir, "region%s.out.ref" % region_index) 19710235Syasuko.eckert@amd.com if os.path.exists(regression_output): 19810235Syasuko.eckert@amd.com print "WARN: Overwriting old regression output: " \ 19910235Syasuko.eckert@amd.com "%s" % regression_output 20010235Syasuko.eckert@amd.com # Run the test to set it up 20110235Syasuko.eckert@amd.com print "Writing new regression output..." 20210235Syasuko.eckert@amd.com os.system( 20310235Syasuko.eckert@amd.com "%s -infile %s -print_level 10 > %s" % 20410235Syasuko.eckert@amd.com (mcpat_binary, regression_test, regression_output)) 20510235Syasuko.eckert@amd.com 20610235Syasuko.eckert@amd.com if not found_test: 20710235Syasuko.eckert@amd.com print "ERROR: Invalid test directory: %s" % rootdir 20810235Syasuko.eckert@amd.com print "ERROR: Must contain XML file power_region*.xml" 20910235Syasuko.eckert@amd.com 21010235Syasuko.eckert@amd.com exit(0) 21110235Syasuko.eckert@amd.com 21210235Syasuko.eckert@amd.comfound_test = False 21310235Syasuko.eckert@amd.comif has_power_region_files(rootdir): 21410235Syasuko.eckert@amd.com found_test = True 21510235Syasuko.eckert@amd.com if is_valid_test_directory(rootdir) or options.force: 21610235Syasuko.eckert@amd.com run_test(rootdir) 21710235Syasuko.eckert@amd.com else: 21810235Syasuko.eckert@amd.com print "WARN: Regression directory is not set up: %s" % rootdir 21910235Syasuko.eckert@amd.comelse: 22010235Syasuko.eckert@amd.com folders = os.listdir(rootdir) 22110235Syasuko.eckert@amd.com folders.sort() 22210235Syasuko.eckert@amd.com for folder in folders: 22310235Syasuko.eckert@amd.com testdir = os.path.join(rootdir, folder) 22410235Syasuko.eckert@amd.com if os.path.isdir(testdir): 22510235Syasuko.eckert@amd.com if has_power_region_files(testdir): 22610235Syasuko.eckert@amd.com found_test = True 22710235Syasuko.eckert@amd.com if is_valid_test_directory(testdir): 22810235Syasuko.eckert@amd.com run_test(testdir) 22910235Syasuko.eckert@amd.com else: 23010235Syasuko.eckert@amd.com if options.force: 23110235Syasuko.eckert@amd.com print "WARN: Regression directory is not set up: " \ 23210235Syasuko.eckert@amd.com "%s" % testdir 23310235Syasuko.eckert@amd.com print "WARN: Running test anyway: %s..." % testdir 23410235Syasuko.eckert@amd.com run_test(testdir) 23510235Syasuko.eckert@amd.com else: 23610235Syasuko.eckert@amd.com print "Regression directory is not set up: %s" % testdir 23710235Syasuko.eckert@amd.com else: 23810235Syasuko.eckert@amd.com print "Not a valid test directory: %s" % testdir 23910235Syasuko.eckert@amd.com 24010235Syasuko.eckert@amd.comif not found_test: 24110235Syasuko.eckert@amd.com print "No valid regressions found in %s" % rootdir 242