1#!/usr/bin/env python 2 3# Copyright (c) 2018, Cornell University 4# All rights reserved. 5# 6# Redistribution and use in source and binary forms, with or 7# without modification, are permitted provided that the following 8# conditions are met: 9# 10# Redistributions of source code must retain the above copyright 11# notice, this list of conditions and the following disclaimer. 12# 13# Redistributions in binary form must reproduce the above 14# copyright notice, this list of conditions and the following 15# disclaimer in the documentation and/or other materials provided 16# with the distribution. 17# 18# Neither the name of Cornell University nor the names of its 19# contributors may be used to endorse or promote products derived 20# from this software without specific prior written permission. 21# 22# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 23# CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 24# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 25# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 26# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 27# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 28# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 29# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF 30# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 31# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 32# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 33# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 34# POSSIBILITY OF SUCH DAMAGE. 35# 36# Authors: Tuan Ta 37 38import os 39import sys 40import argparse 41import subprocess 42 43from multiprocessing import Pool 44 45import clusterjob 46from clusterjob import * 47 48#------------------------------------------------------------------------- 49# utility function to run a process 50#------------------------------------------------------------------------- 51def execute(cmd): 52 try: 53 return subprocess.check_output(cmd, shell=True) 54 except subprocess.CalledProcessError, err: 55 print "ERROR: " + err.output 56 57#------------------------------------------------------------------------- 58# Input options 59#------------------------------------------------------------------------- 60 61# general options 62parser = argparse.ArgumentParser(description='run RISC-V assembly tests') 63parser.add_argument('--max-tick', 64 help = 'maximum simulated tick', 65 type = int, 66 default = 10000000000) 67parser.add_argument('--num-cpus', 68 help = 'number of CPUs\ 69 (some tests require at least 4 CPUs)', 70 type = int, 71 default = 4) 72parser.add_argument('--ruby', 73 help = 'Use Ruby memory?', 74 action = 'store_true') 75 76args = parser.parse_args() 77 78# convert all paths to absolute paths 79test_dir = os.path.abspath('../../bin/riscv/') 80test_summary_out = './test-summary.out' 81 82#------------------------------------------------------------------------- 83# gem5 variables 84#------------------------------------------------------------------------- 85gem5_dir = os.path.abspath('../../../../../') 86gem5_bin = os.path.join(gem5_dir, 'build', 'RISCV', 'gem5.opt') 87config = os.path.join(gem5_dir, 'configs', 'example', 'se.py') 88 89# list of CPU models to be tested 90cpu_models = ['AtomicSimpleCPU', 91 'TimingSimpleCPU', 92 'MinorCPU', 93 'DerivO3CPU'] 94 95# get a list of test binaries in the given directory 96tests = [] 97for line in execute("ls %s/*" % (test_dir)).splitlines(): 98 if line: 99 tests.append(line.split('/')[-1]) 100 101# total number of tests to run 102n_tests = len(tests) * len(cpu_models) 103 104# make a list of jobs 105job_cmds = [] 106job_names = [] 107for test in tests: 108 for model in cpu_models: 109 test_name = test + '-' + model 110 job_names.append(test_name) 111 job_cmds.append([gem5_bin, 112 config, 113 '-m', str(args.max_tick), 114 '--cpu-type', model, 115 '-n', str(args.num_cpus), 116 '-c', test_dir + '/' + test, 117 '--ruby' if args.ruby else '--caches', 118 ]) 119 120# execute all jobs 121job_pool = Pool(processes = n_tests) 122job_outputs = job_pool.map(subprocess.call, job_cmds) 123job_pool.close() 124 125# process job outputs 126file = open(test_summary_out, "w") 127 128job_outputs = zip(job_names, job_outputs) 129for entry in job_outputs: 130 # a negative return value indicates that the job was terminated 131 # by a signal 132 # a positive return value indicates that the job exited with a return 133 # value 134 if entry[1] < 0: 135 file.write("%-50s failed - signal = %d\n" % (entry[0], -1 * entry[1])) 136 elif entry[1] > 0: 137 file.write("%-50s failed - status = %d\n" % (entry[0], entry[1])) 138 else: 139 file.write("%-50s passed\n" % (entry[0])) 140 141file.close() 142