#!/usr/bin/env python2.7 # Copyright (c) 2010-2013 Advanced Micro Devices, Inc. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer; # redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution; # neither the name of the copyright holders nor the names of its # contributors may be used to endorse or promote products derived from # this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. """ SYNOPSIS ./regression/regression.py ./regression/ DESCRIPTION Runs regression tester for McPAT. This tester can compile and runs McPAT on the input contained in the specified directory, and then compares the output to that of a prior run in order to ensure that specific power and area calculations do not change. AUTHORS Joel Hestness <hestness@cs.wisc.edu> (while interning at AMD) Yasuko Eckert <yasuko.eckert@amd.com> """ import os import sys import optparse import re ################################ # Global Variables ################################ global mcpat_binary mcpat_binary = "../../build/mcpat/mcpat" global optionsparser ################################ # Global Functions ################################ def run_test(testdir): test_passed = True testfiles = os.listdir(testdir) for testfile in testfiles: # For each power_region file, run McPAT on it and check the # output created against the regression if re.match("power_region.*\.xml$", testfile): # Get the region index of the test fileparts = testfile.split(".") region_index = fileparts[0][12:] regression_test = os.path.join(testdir, testfile) regression_output = os.path.join( testdir, "region%s.out" % region_index) regression_correct = os.path.join( testdir, "region%s.out.ref" % region_index) print "Running test: %s..." % regression_test # Run McPAT on the input os.system( "%s -infile %s -print_level 10 > %s" % (mcpat_binary, regression_test, regression_output) ) if os.path.exists(regression_correct): diff = os.popen( "diff %s %s" % (regression_output, regression_correct), "r").read() if diff != "": print "WARN: Differences found in %s" % regression_output if options.verbose: print diff test_passed = False else: print "WARN: Regression test not set up: %s..." % regression_test print "WARN: Not able to verify test" test_passed = False if options.cleanup: if options.verbose: print "WARN: Cleaning (deleting) regression output file: "\ "%s" % regression_output os.system("rm -f %s" % regression_output) if test_passed: print "PASSED: %s\n\n" % testdir else: print "FAILED: %s\n\n" % testdir def has_power_region_files(testdir): files = os.listdir(testdir) for file in files: if "power_region" in file and ".xml" in file: return True def is_valid_test_directory(testdir): valid_regression = True power_region_file_found = False files = os.listdir(testdir) for file in files: if "power_region" in file and ".xml" in file: power_region_file_found = True fileparts = file.split(".") region_index = fileparts[0][12:] regression_output = os.path.join( testdir, "region%s.out.ref" % region_index) if os.path.exists(regression_output): if options.verbose: print "Valid regression test: %s/%s" % (testdir, file) else: valid_regression = False return valid_regression and power_region_file_found ################################ # Execute here ################################ optionsparser = optparse.OptionParser( formatter = optparse.TitledHelpFormatter(), usage = globals()['__doc__']) optionsparser.add_option( "-b", "--build", action = "store_true", default = False, help = "Build McPAT before running tests") optionsparser.add_option( "-c", "--cleanup", action = "store_true", default = False, help = "Clean up the specified regression directory") optionsparser.add_option( "-f", "--force", action = "store_true", default = False, help = "Force run regression even if directory isn't set up") optionsparser.add_option( "-m", "--maketest", action = "store_true", default = False, help = "Set up the specified test directory") optionsparser.add_option( "-v", "--verbose", action = "store_true", default = False, help = "Print verbose output") (options, args) = optionsparser.parse_args() if not os.path.exists(mcpat_binary) and not options.build: print "ERROR: McPAT binary does not exist: %s" % mcpat_binary exit(0) if options.build: print "Building McPAT..." bin_dir = os.path.dirname(mcpat_binary) directory = os.path.join(bin_dir, "../../ext/mcpat") build_output = os.popen( "cd %s; make clean; make -j 8 dbg 2>&1" % directory).read() if "error" in build_output.lower(): print "Error during build: %s" % build_output exit(0) if len(args) < 1: print "ERROR: Must specify regressions directory" exit(0) # check params rootdir = args[0]; if not os.path.exists(rootdir): print "ERROR: Regressions directory does not exist: %s" % rootdir exit(0) if options.maketest: # The specified rootdir must exist since we got here # Check if directory has tests list = os.listdir(rootdir) found_test = False for file in list: if "power_region" in file and "out" not in file and "ref" not in file: found_test = True # Prepare to run the test in order to set it up fileparts = file.split(".") region_index = fileparts[0][12:] regression_test = os.path.join(rootdir, file) regression_output = os.path.join( rootdir, "region%s.out.ref" % region_index) if os.path.exists(regression_output): print "WARN: Overwriting old regression output: " \ "%s" % regression_output # Run the test to set it up print "Writing new regression output..." os.system( "%s -infile %s -print_level 10 > %s" % (mcpat_binary, regression_test, regression_output)) if not found_test: print "ERROR: Invalid test directory: %s" % rootdir print "ERROR: Must contain XML file power_region*.xml" exit(0) found_test = False if has_power_region_files(rootdir): found_test = True if is_valid_test_directory(rootdir) or options.force: run_test(rootdir) else: print "WARN: Regression directory is not set up: %s" % rootdir else: folders = os.listdir(rootdir) folders.sort() for folder in folders: testdir = os.path.join(rootdir, folder) if os.path.isdir(testdir): if has_power_region_files(testdir): found_test = True if is_valid_test_directory(testdir): run_test(testdir) else: if options.force: print "WARN: Regression directory is not set up: " \ "%s" % testdir print "WARN: Running test anyway: %s..." % testdir run_test(testdir) else: print "Regression directory is not set up: %s" % testdir else: print "Not a valid test directory: %s" % testdir if not found_test: print "No valid regressions found in %s" % rootdir