1#!/usr/bin/env python2.7 2 3# Copyright (c) 2010-2013 Advanced Micro Devices, Inc. 4# All rights reserved. 5# 6# Redistribution and use in source and binary forms, with or without 7# modification, are permitted provided that the following conditions are 8# met: redistributions of source code must retain the above copyright 9# notice, this list of conditions and the following disclaimer; 10# redistributions in binary form must reproduce the above copyright 11# notice, this list of conditions and the following disclaimer in the 12# documentation and/or other materials provided with the distribution; 13# neither the name of the copyright holders nor the names of its 14# contributors may be used to endorse or promote products derived from 15# this software without specific prior written permission. 16# 17# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 29""" 30SYNOPSIS 31 32 ./regression/regression.py ./regression/ 33 34DESCRIPTION 35 36 Runs regression tester for McPAT. 37 This tester can compile and runs McPAT on the input contained in the 38 specified directory, and then compares the output to that of a prior run in 39 order to ensure that specific power and area calculations do not change. 40 41AUTHORS 42 43 Joel Hestness <hestness@cs.wisc.edu> (while interning at AMD) 44 Yasuko Eckert <yasuko.eckert@amd.com> 45""" 46 47import os 48import sys 49import optparse 50import re 51 52################################ 53# Global Variables 54################################ 55 56global mcpat_binary 57mcpat_binary = "../../build/mcpat/mcpat" 58global optionsparser 59 60################################ 61# Global Functions 62################################ 63 64def run_test(testdir): 65 test_passed = True 66 testfiles = os.listdir(testdir) 67 for testfile in testfiles: 68 # For each power_region file, run McPAT on it and check the 69 # output created against the regression 70 if re.match("power_region.*\.xml$", testfile): 71 # Get the region index of the test 72 fileparts = testfile.split(".") 73 region_index = fileparts[0][12:] 74 regression_test = os.path.join(testdir, testfile) 75 regression_output = os.path.join( 76 testdir, "region%s.out" % region_index) 77 regression_correct = os.path.join( 78 testdir, "region%s.out.ref" % region_index) 79 print "Running test: %s..." % regression_test 80 # Run McPAT on the input 81 os.system( 82 "%s -infile %s -print_level 10 > %s" % 83 (mcpat_binary, regression_test, regression_output) ) 84 if os.path.exists(regression_correct): 85 diff = os.popen( 86 "diff %s %s" % (regression_output, regression_correct), 87 "r").read() 88 if diff != "": 89 print "WARN: Differences found in %s" % regression_output 90 if options.verbose: 91 print diff 92 test_passed = False 93 else: 94 print "WARN: Regression test not set up: %s..." % regression_test 95 print "WARN: Not able to verify test" 96 test_passed = False 97 98 if options.cleanup: 99 if options.verbose: 100 print "WARN: Cleaning (deleting) regression output file: "\ 101 "%s" % regression_output 102 os.system("rm -f %s" % regression_output) 103 104 if test_passed: 105 print "PASSED: %s\n\n" % testdir 106 else: 107 print "FAILED: %s\n\n" % testdir 108 109def has_power_region_files(testdir): 110 files = os.listdir(testdir) 111 for file in files: 112 if "power_region" in file and ".xml" in file: 113 return True 114 115def is_valid_test_directory(testdir): 116 valid_regression = True 117 power_region_file_found = False 118 119 files = os.listdir(testdir) 120 for file in files: 121 if "power_region" in file and ".xml" in file: 122 power_region_file_found = True 123 fileparts = file.split(".") 124 region_index = fileparts[0][12:] 125 regression_output = os.path.join( 126 testdir, "region%s.out.ref" % region_index) 127 if os.path.exists(regression_output): 128 if options.verbose: 129 print "Valid regression test: %s/%s" % (testdir, file) 130 else: 131 valid_regression = False 132 133 return valid_regression and power_region_file_found 134 135################################ 136# Execute here 137################################ 138 139optionsparser = optparse.OptionParser( 140 formatter = optparse.TitledHelpFormatter(), 141 usage = globals()['__doc__']) 142optionsparser.add_option( 143 "-b", "--build", action = "store_true", default = False, 144 help = "Build McPAT before running tests") 145optionsparser.add_option( 146 "-c", "--cleanup", action = "store_true", default = False, 147 help = "Clean up the specified regression directory") 148optionsparser.add_option( 149 "-f", "--force", action = "store_true", default = False, 150 help = "Force run regression even if directory isn't set up") 151optionsparser.add_option( 152 "-m", "--maketest", action = "store_true", default = False, 153 help = "Set up the specified test directory") 154optionsparser.add_option( 155 "-v", "--verbose", action = "store_true", default = False, 156 help = "Print verbose output") 157(options, args) = optionsparser.parse_args() 158 159if not os.path.exists(mcpat_binary) and not options.build: 160 print "ERROR: McPAT binary does not exist: %s" % mcpat_binary 161 exit(0) 162 163if options.build: 164 print "Building McPAT..." 165 bin_dir = os.path.dirname(mcpat_binary) 166 directory = os.path.join(bin_dir, "../../ext/mcpat") 167 build_output = os.popen( 168 "cd %s; make clean; make -j 8 dbg 2>&1" % directory).read() 169 if "error" in build_output.lower(): 170 print "Error during build: %s" % build_output 171 exit(0) 172 173if len(args) < 1: 174 print "ERROR: Must specify regressions directory" 175 exit(0) 176 177# check params 178rootdir = args[0]; 179if not os.path.exists(rootdir): 180 print "ERROR: Regressions directory does not exist: %s" % rootdir 181 exit(0) 182 183if options.maketest: 184 # The specified rootdir must exist since we got here 185 # Check if directory has tests 186 list = os.listdir(rootdir) 187 found_test = False 188 for file in list: 189 if "power_region" in file and "out" not in file and "ref" not in file: 190 found_test = True 191 # Prepare to run the test in order to set it up 192 fileparts = file.split(".") 193 region_index = fileparts[0][12:] 194 regression_test = os.path.join(rootdir, file) 195 regression_output = os.path.join( 196 rootdir, "region%s.out.ref" % region_index) 197 if os.path.exists(regression_output): 198 print "WARN: Overwriting old regression output: " \ 199 "%s" % regression_output 200 # Run the test to set it up 201 print "Writing new regression output..." 202 os.system( 203 "%s -infile %s -print_level 10 > %s" % 204 (mcpat_binary, regression_test, regression_output)) 205 206 if not found_test: 207 print "ERROR: Invalid test directory: %s" % rootdir 208 print "ERROR: Must contain XML file power_region*.xml" 209 210 exit(0) 211 212found_test = False 213if has_power_region_files(rootdir): 214 found_test = True 215 if is_valid_test_directory(rootdir) or options.force: 216 run_test(rootdir) 217 else: 218 print "WARN: Regression directory is not set up: %s" % rootdir 219else: 220 folders = os.listdir(rootdir) 221 folders.sort() 222 for folder in folders: 223 testdir = os.path.join(rootdir, folder) 224 if os.path.isdir(testdir): 225 if has_power_region_files(testdir): 226 found_test = True 227 if is_valid_test_directory(testdir): 228 run_test(testdir) 229 else: 230 if options.force: 231 print "WARN: Regression directory is not set up: " \ 232 "%s" % testdir 233 print "WARN: Running test anyway: %s..." % testdir 234 run_test(testdir) 235 else: 236 print "Regression directory is not set up: %s" % testdir 237 else: 238 print "Not a valid test directory: %s" % testdir 239 240if not found_test: 241 print "No valid regressions found in %s" % rootdir 242