diff --git a/src/scripts/perf/fftPerformanceTesting.py b/src/scripts/perf/fftPerformanceTesting.py index 2d1df690..133062df 100644 --- a/src/scripts/perf/fftPerformanceTesting.py +++ b/src/scripts/perf/fftPerformanceTesting.py @@ -91,18 +91,18 @@ def executable(library): if library == 'clFFT' or library == 'null': if sys.platform == 'win32': - exe = 'Client.exe' + exe = 'clFFT-client-2.5.0.exe' elif sys.platform == 'linux2': - exe = 'Client' + exe = 'clFFT-client-2.5.0' + elif library == 'cuFFT': + if sys.platform == 'win32': + exe = 'cuFFT-Client.exe' + elif sys.platform == 'linux2': + exe = 'cuFFT-Client' else: print 'ERROR: unknown library -- cannot determine executable name' quit() - if not os.path.isfile(exe): - error_message = 'ERROR: could not find client named ' + exe - print error_message - quit() - return exe def max_mem_available_in_bytes(exe, device): @@ -115,11 +115,8 @@ def max_mem_available_in_bytes(exe, device): return int(maxMemoryAvailable.group(0)) def max_problem_size(exe, layout, precision, device): - if layout == 'ci' or layout == 'cp': + if layout == 1 or layout == 1: numbers_in_one_datapoint = 2 - else: - print 'max_problem_size(): unknown layout' - quit() if precision == 'single': bytes_in_one_number = 4 @@ -129,18 +126,22 @@ def max_problem_size(exe, layout, precision, device): print 'max_problem_size(): unknown precision' quit() - max_problem_size = max_mem_available_in_bytes(exe, device) / (numbers_in_one_datapoint * bytes_in_one_number) - max_problem_size = max_problem_size / 16 + max_problem_size = pow(2,25) #max_mem_available_in_bytes(exe, device) + if layout == '5': + max_problem_size = pow(2,24) #max_mem_available_in_bytes(exe, device) + #max_problem_size=max_problem_size/ (numbers_in_one_datapoint * bytes_in_one_number) + #max_problem_size = max_problem_size / 16 return max_problem_size def maxBatchSize(lengthx, lengthy, lengthz, layout, precision, exe, device): problemSize = int(lengthx) * int(lengthy) * int(lengthz) maxBatchSize = max_problem_size(exe, layout, precision, device) / problemSize - if int(lengthx) == pow(2,16) or int(lengthx) == pow(2,17): - # special cases in the kernel. extra padding is added in, so we need to shrink the batch size to accommodate - return str(maxBatchSize/2) - else: - return str(maxBatchSize) + return str(maxBatchSize) + #if int(lengthx) == pow(2,16) or int(lengthx) == pow(2,17): + # # special cases in the kernel. extra padding is added in, so we need to shrink the batch size to accommodate + # return str(maxBatchSize/2) + #else: + # return str(maxBatchSize) def create_ini_file_if_requested(args): if args.createIniFilename: diff --git a/src/scripts/perf/measurePerformance.py b/src/scripts/perf/measurePerformance.py index c0cbc6a0..e6cf596d 100644 --- a/src/scripts/perf/measurePerformance.py +++ b/src/scripts/perf/measurePerformance.py @@ -20,9 +20,11 @@ import itertools import re#gex import os +import math from threading import Timer, Thread import thread, time from platform import system +import numpy as np from datetime import datetime @@ -33,20 +35,20 @@ IAM = 'FFT' TIMOUT_VAL = 900 #In seconds -devicevalues = ['gpu', 'cpu'] +devicevalues = ['g', 'c'] layoutvalues = ['cp', 'ci'] placevalues = ['in', 'out'] precisionvalues = ['single', 'double'] -libraryvalues = ['clFFT'] +libraryvalues = ['clFFT','cuFFT'] pow10 = '1-9,10-90:10,100-900:100,1000-9000:1000,10000-90000:10000,100000-900000:100000,1000000-9000000:1000000' parser = argparse.ArgumentParser(description='Measure performance of the clFFT library') parser.add_argument('--device', - dest='device', default='gpu', + dest='device', default='g', help='device(s) to run on; may be a comma-delimited list. choices are ' + str(devicevalues) + '. (default gpu)') parser.add_argument('-b', '--batchsize', dest='batchSize', default='1', - help='number of FFTs to perform with one invocation of the client. the special value \'max\' may be used to adjust the batch size on a per-transform basis to the maximum problem size possible on the device. may be a range or a comma-delimited list. if a range is entered, you may follow it with \':X\', where X is the stepping of the range (if omitted, it defaults to a stepping of 1). e.g., 1-15 or 12,18 or 7,10-30:10,1050-1054. the special value \'pow10\' expands to \'{}\'. Note that \'max\' and \'pow10\' may not be used in a list; they must be used by themselves; max may only be used with --library clFFT. (default 1)'.format(pow10)) + help='number of FFTs to perform with one invocation of the client. the special value \'adapt\' may be used to adjust the batch size on a per-transform basis to the maximum problem size possible on the device. (default 1)'.format(pow10)) parser.add_argument('-a', '--adaptivemax', dest='constProbSize', default='-1', help='Max problem size that you want to maintain across the invocations of client with different lengths. This is adaptive and adjusts itself automtically.'.format(pow10)) @@ -59,36 +61,48 @@ parser.add_argument('-z', '--lengthz', dest='lengthz', default='1', help='length(s) of z to test; must be factors of 1, 2, 3, or 5 with clFFT; may be a range or a comma-delimited list. e.g., 16-128 or 1200 or 16,32768 (default 1)') +parser.add_argument('-reps', + dest='reps', default='10', + help='Number of repetitions (default 10)') +parser.add_argument('-prime_factor', '--prime_factor', + dest='prime_factor', default='2', + help='only test the prime factors within the specified range of lengthx/y/z. Select from 2,3,5, and 7. Example: -prime_factor 2,3') +parser.add_argument('-test_count', '--test_count', + dest='test_count', default='100', + help='Number of tests to perform') parser.add_argument('--problemsize', - dest='problemsize', default=None, - help='additional problems of a set size. may be used in addition to lengthx/y/z. each indicated problem size will be added to the list of FFTs to perform. should be entered in AxBxC:D format. A, B, and C indicate the sizes of the X, Y, and Z dimensions (respectively). D is the batch size. All values except the length of X are optional. may enter multiple in a comma-delimited list. e.g., 2x2x2:32768 or 256x256:100,512x512:256') + dest='problemsize', default=None) +# help='additional problems of a set size. may be used in addition to lengthx/y/z. each indicated problem size will be added to the list of FFTs to perform. should be entered in AxBxC:D format. A, B, and C indicate the sizes of the X, Y, and Z dimensions (respectively). D is the batch size. All values except the length of X are optional. may enter multiple in a comma-delimited list. e.g., 2x2x2:32768 or 256x256:100,512x512:256') parser.add_argument('-i', '--inputlayout', - dest='inputlayout', default='ci', - help='may enter multiple in a comma-delimited list. choices are ' + str(layoutvalues) + '. ci = complex interleaved, cp = complex planar (default ci)') + dest='inputlayout', default='1', + help=' 1. interleaved (default) 2. planar 3. hermitian interleaved 4. hermitian planar 5. real' ) parser.add_argument('-o', '--outputlayout', - dest='outputlayout', default='ci', - help='may enter multiple in a comma-delimited list. choices are ' + str(layoutvalues) + '. ci = complex interleaved, cp = complex planar (default ci)') -parser.add_argument('-p', '--placeness', + dest='outputlayout', default='1', + help=' 1. interleaved (default) 2. planar 3. hermitian interleaved 4. hermitian planar 5. real' ) +parser.add_argument('--placeness', dest='placeness', default='in', - help='may enter multiple in a comma-delimited list. choices are ' + str(placevalues) + '. in = in place, out = out of place (default in)') + help='Choices are ' + str(placevalues) + '. in = in place, out = out of place (default in)') parser.add_argument('-r', '--precision', dest='precision', default='single', - help='may enter multiple in a comma-delimited list. choices are ' + str(precisionvalues) + '. (default single)') + help='Choices are ' + str(precisionvalues) + '. (default single)') parser.add_argument('--library', dest='library', default='clFFT', choices=libraryvalues, help='indicates the library to use for testing on this run') parser.add_argument('--label', dest='label', default=None, help='a label to be associated with all transforms performed in this run. if LABEL includes any spaces, it must be in \"double quotes\". note that the label is not saved to an .ini file. e.g., --label cayman may indicate that a test was performed on a cayman card or --label \"Windows 32\" may indicate that the test was performed on Windows 32') -parser.add_argument('--createini', - dest='createIniFilename', default=None, - help='create an .ini file with the given name that saves the other parameters given at the command line, then quit. e.g., \'measureperformance.py -x 2048 --createini my_favorite_setup.ini\' will create an .ini file that will save the configuration for a 2048-datapoint 1D FFT.') +#parser.add_argument('--createini', +# dest='createIniFilename', default=None, +# help='create an .ini file with the given name that saves the other parameters given at the command line, then quit. e.g., \'measureperformance.py -x 2048 --createini my_favorite_setup.ini\' will create an .ini file that will save the configuration for a 2048-datapoint 1D FFT.') parser.add_argument('--ini', dest='iniFilename', default=None, help='use the parameters in the named .ini file instead of the command line parameters.') parser.add_argument('--tablefile', dest='tableOutputFilename', default=None, help='save the results to a plaintext table with the file name indicated. this can be used with plotPerformance.py to generate graphs of the data (default: table prints to screen)') +parser.add_argument('--prefix', + dest='prefix', default='./', + help='Path where the library client is located (default current directory)') args = parser.parse_args() @@ -145,7 +159,7 @@ def executeCommand(): except: printLog("ERROR: UNKNOWN Exception - +checkWinTimeOutPut()::executeCommand()") - currCommandProcess = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + currCommandProcess = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE,shell=True) thread = Thread(target=executeCommand) thread.start() thread.join(TIMOUT_VAL) #wait for the thread to complete @@ -165,75 +179,85 @@ def executeCommand(): # don't try to create and use an .ini file at the same time (it will open a portal through which demons will emerge) -if args.iniFilename and args.createIniFilename: - printLog('ERROR: --ini and --createini are mutually exclusive. Please choose only one.') - quit() +#if args.iniFilename and args.createIniFilename: +# printLog('ERROR: --ini and --createini are mutually exclusive. Please choose only one.') +# quit() #read in .ini parameters if --ini is used -if args.iniFilename != None: - if not os.path.isfile(args.iniFilename): - printLog("No file with the name \'{}\' exists. Please indicate another filename.".format(args.iniFilename)) - quit() - - ini = open(args.iniFilename, 'r') - iniContents = ini.read() - iniContents = iniContents.split(';') - for i in range(0,len(iniContents)): - line = iniContents.pop() - line = line.partition(' ') - parameter = line[0] - value = line[2] - value = value.replace('\'','').replace('[','').replace(']','').replace(' ','') - - if parameter == 'batchSize': - args.batchSize = value - elif parameter == 'constProbSize': - args.constProbSize = value - elif parameter == 'lengthx': - args.lengthx = value - elif parameter == 'lengthy': - args.lengthy = value - elif parameter == 'lengthz': - args.lengthz = value - elif parameter == 'problemsize': - args.problemsize = value - elif parameter == 'device': - args.device = value - elif parameter == 'inputlayout': - args.inputlayout = value - elif parameter == 'outputlayout': - args.outputlayout = value - elif parameter == 'placeness': - args.placeness = value - elif parameter == 'precision': - args.precision = value - else: - printLog('{} corrupted. Please re-create a .ini file with the --createini flag.'.format(args.iniFilename)) - quit() +#if args.iniFilename != None: +# if not os.path.isfile(args.iniFilename): +# printLog("No file with the name \'{}\' exists. Please indicate another filename.".format(args.iniFilename)) +# quit() +# +# ini = open(args.iniFilename, 'r') +# iniContents = ini.read() +# iniContents = iniContents.split(';') +# for i in range(0,len(iniContents)): +# line = iniContents.pop() +# line = line.partition(' ') +# parameter = line[0] +# value = line[2] +# value = value.replace('\'','').replace('[','').replace(']','').replace(' ','') +# print"value= ",value +# +# if parameter == 'batchSize': +# args.batchSize = value +# elif parameter == 'constProbSize': +# args.constProbSize = value +# elif parameter == 'lengthx': +# args.lengthx = value +# elif parameter == 'reps': +# args.reps = value +# elif parameter == 'prime_factor': +# args.prime_factor = value +# elif parameter == 'test_count': +# args.test_count = value +# elif parameter == 'lengthy': +# args.lengthy = value +# elif parameter == 'lengthz': +# args.lengthz = value +# elif parameter == 'problemsize': +# args.problemsize = value +# elif parameter == 'device': +# args.device = value +# elif parameter == 'inputlayout': +# args.inputlayout = value +# elif parameter == 'outputlayout': +# args.outputlayout = value +# elif parameter == 'placeness': +# args.placeness = value +# elif parameter == 'precision': +# args.precision = value +# else: +# printLog('{} corrupted. Please re-create a .ini file with the --createini flag.'.format(args.iniFilename)) +# #quit() #create ini file if requested -if args.createIniFilename != None: - printLog('Creating Ini files') - if os.path.isfile(args.createIniFilename): - printLog('A file with the name \'{}\' already exists. Please delete the file or choose another name.'.format(args.createIniFilename)) - quit() - printLog('Creating Ini file:'+args.createIniFilename+'\n') - ini = open(args.createIniFilename, 'w') - ini.write('batchSize {} ;'.format(args.batchSize)) - ini.write('constProbSize {} ;'.format(args.constProbSize)) - ini.write('lengthx {} ;'.format(args.lengthx)) - ini.write('lengthy {} ;'.format(args.lengthy)) - ini.write('lengthz {} ;'.format(args.lengthz)) - ini.write('problemsize {} ;'.format(args.problemsize)) - ini.write('device {} ;'.format(args.device)) - ini.write('inputlayout {} ;'.format(args.inputlayout)) - ini.write('outputlayout {} ;'.format(args.outputlayout)) - ini.write('placeness {} ;'.format(args.placeness)) - ini.write('precision {} ;'.format(args.precision)) - printLog('Created Ini file:'+args.createIniFilename+'\n') - printLog("=========================MEASURE PERFORMANCE START===========================\n") - quit() - +#if args.createIniFilename != None: +# printLog('Creating Ini files') +# if os.path.isfile(args.createIniFilename): +# printLog('A file with the name \'{}\' already exists. Please delete the file or choose another name.'.format(args.createIniFilename)) +# quit() +# printLog('Creating Ini file:'+args.createIniFilename+'\n') +# ini = open(args.createIniFilename, 'w') +# ini.write('batchSize {} ;'.format(args.batchSize)) +# ini.write('constProbSize {} ;'.format(args.constProbSize)) +# ini.write('lengthx {} ;'.format(args.lengthx)) +# ini.write('lengthy {} ;'.format(args.lengthy)) +# ini.write('lengthz {} ;'.format(args.lengthz)) +# ini.write('prime_factor {} ;'.format(args.prime_factor)) +# ini.write('test_count {} ;'.format(args.test_count)) +# ini.write('reps {} ;'.format(args.reps)) +# ini.write('problemsize {} ;'.format(args.problemsize)) +# ini.write('device {} ;'.format(args.device)) +# ini.write('inputlayout {} ;'.format(args.inputlayout)) +# ini.write('outputlayout {} ;'.format(args.outputlayout)) +# ini.write('placeness {} ;'.format(args.placeness)) +# ini.write('precision {} ;'.format(args.precision)) +# printLog('Created Ini file:'+args.createIniFilename+'\n') +# printLog("=========================MEASURE PERFORMANCE START===========================\n") +# quit() +# #turn pow10 into its range list if args.batchSize.count('pow10'): @@ -246,6 +270,7 @@ def executeCommand(): args.lengthx = args.lengthx.split(',') args.lengthy = args.lengthy.split(',') args.lengthz = args.lengthz.split(',') +args.prime_factor = args.prime_factor.split(',') if args.problemsize: args.problemsize = args.problemsize.split(',') args.inputlayout = args.inputlayout.split(',') @@ -266,11 +291,11 @@ def executeCommand(): # in case of an in-place transform, input and output layouts must be the same (otherwise: *boom*) -for n in args.placeness: - if n == 'in' or n == 'inplace': - if len(args.inputlayout) > 1 or len(args.outputlayout) > 1 or args.inputlayout[0] != args.outputlayout[0]: - printLog('ERROR: if transformation is in-place, input and output layouts must match') - quit() +#for n in args.placeness: +# if n == 'in' or n == 'inplace': +# if len(args.inputlayout) > 1 or len(args.outputlayout) > 1 or args.inputlayout[0] != args.outputlayout[0]: +# printLog('ERROR: if transformation is in-place, input and output layouts must match') +# quit() # check for valid values in precision for n in args.precision: @@ -393,7 +418,7 @@ def check_for_1235_factors(values, option): -if not os.path.isfile(executable(args.library)): +if not os.path.isfile(args.prefix+executable(args.library)): printLog("ERROR: Could not find client named {0}".format(executable(args.library))) quit() @@ -477,6 +502,37 @@ def _next_num_with_1235_factor(self): args.lengthz = Range(args.lengthz, 'l').expanded +def create_prime_factors(args,input_list): + powers2=[1] + powers3=[1] + powers5=[1] + powers7=[1] + if '2' in args.prime_factor: + powers2+=[2**x for x in range(1,int(math.floor(math.log(max(input_list),2)+1)))] + if '3' in args.prime_factor: + powers3+=[3**x for x in range(1,int(math.floor(math.log(max(input_list),3)+1)))] + if '5' in args.prime_factor: + powers5+=[5**x for x in range(1,int(math.floor(math.log(max(input_list),5)+1)))] + if '7' in args.prime_factor: + powers7+=[7**x for x in range(1,int(math.floor(math.log(max(input_list),7)+1)))] + + + xlist=[] + for i in powers2: + for j in powers3: + for k in powers5: + for l in powers7: + dummy=int(i)*int(j)*int(k)*int(l) + if(dummy<=max(input_list)) and (dummy>=min(input_list)): + xlist.append(dummy) + + xlist=sorted(xlist) + xlist=xlist[:int(args.test_count)] #snafu + return xlist + +args.lengthx=create_prime_factors(args,args.lengthx) +args.lengthy=create_prime_factors(args,args.lengthy) +args.lengthz=create_prime_factors(args,args.lengthz) #expand problemsizes ('XxYxZ:batch') #print "args.problemsize--1-->", args.problemsize @@ -489,15 +545,21 @@ def _next_num_with_1235_factor(self): #create the problem size combinations for each run of the client -problem_size_combinations = itertools.product(args.lengthx, args.lengthy, args.lengthz, args.batchSize) +# A: This part creats a product of all possible combinations. Too many cases in 2/3D +#problem_size_combinations = itertools.product(args.lengthx, args.lengthy, args.lengthz, args.batchSize) +#problem_size_combinations = list(itertools.islice(problem_size_combinations, None)) -problem_size_combinations = list(itertools.islice(problem_size_combinations, None)) +if args.lengthy[0]==1: + args.lengthy=[1]*len(args.lengthx) +if args.lengthz[0]==1: + args.lengthz=[1]*len(args.lengthx) -#print "args.problemsize--2-->", args.problemsize +dummy=[args.batchSize[0]]*len(args.lengthx) +problem_size_combinations=zip(args.lengthx,args.lengthy,args.lengthz,dummy) +#print "args.problemsize--2-->", args.problemsize #add manually entered problem sizes to the list of FFTs to crank out manual_test_combinations = [] - if args.problemsize and args.problemsize[0] != 'None': for n in args.problemsize: x = [] @@ -536,6 +598,16 @@ def _next_num_with_1235_factor(self): test_combinations = list(itertools.islice(test_combinations, None)) test_combinations = [TestCombination(params[0][0], params[0][1], params[0][2], params[0][3], params[1], params[2], params[3], params[4], params[5], args.label) for params in test_combinations] +if args.iniFilename != None: + array=np.genfromtxt(args.iniFilename, names=True, delimiter=',', dtype=None) + test_combinations = [TestCombination(params[0],params[1], params[2], params[3], params[4],params[5],params[6],params[7],params[8],args.label) for params in array] + +#print("lenghtx= ",test_combinations[0].x) +#print("lenghty= ",test_combinations[0].y) +#print("lenghtz= ",test_combinations[0].z) +#print("placeness= ",test_combinations[0].placeness) + + #turn each test combination into a command, run the command, and then stash the gflops result = [] # this is where we'll store the results for the table @@ -544,7 +616,10 @@ def _next_num_with_1235_factor(self): #open output file and write the header if args.tableOutputFilename == None: - args.tableOutputFilename = 'results' + datetime.now().isoformat().replace(':','.') + '.txt' + if args.library == 'cuFFT': + args.tableOutputFilename = 'cuFFT_' + 'x_'+ str(args.lengthx[0]) + '_y_'+str(args.lengthy[0])+'_z_'+str(args.lengthz[0])+'_'+str(args.precision[0]) +'_'+datetime.now().isoformat().replace(':','.') + '.txt' + elif args.library=='clFFT': + args.tableOutputFilename = 'clFFT_' + 'x_'+ str(args.lengthx[0]) + '_y_'+str(args.lengthy[0])+'_z_'+str(args.lengthz[0])+'_'+str(args.precision[0])+ '_'+datetime.now().isoformat().replace(':','.') + '.txt' else: if os.path.isfile(args.tableOutputFilename): oldname = args.tableOutputFilename @@ -558,17 +633,17 @@ def _next_num_with_1235_factor(self): table = open(args.tableOutputFilename, 'w') table.write(tableHeader + '\n') table.flush() - if args.constProbSize == -1: - args.constProbSize = maxBatchSize(1, 1, 1, args.inputlayout[0], args.precision[0], executable(args.library), '--' + args.device[0]) + args.constProbSize = maxBatchSize(1, 1, 1, args.inputlayout[0], args.precision[0], executable(args.library), '-' + args.device[0]) args.constProbSize = int(args.constProbSize) printLog('Total combinations = '+str(len(test_combinations))) vi = 0 -#test_combinations = test_combinations[825:830] for params in test_combinations: + if vi>=int(args.test_count): + break vi = vi+1 printLog("") printLog('preparing command: '+ str(vi)) @@ -576,28 +651,18 @@ def _next_num_with_1235_factor(self): lengthx = str(params.x) lengthy = str(params.y) lengthz = str(params.z) + inlayout=str(params.inlayout) + outlayout=str(params.outlayout) + prefix=str(args.prefix) + if params.batchsize == 'max': - batchSize = maxBatchSize(lengthx, lengthy, lengthz, params.inlayout, params.precision, executable(args.library), '--' + device) + batchSize = maxBatchSize(lengthx, lengthy, lengthz, params.inlayout, params.precision, executable(args.library), '-' + device) elif params.batchsize == 'adapt': batchSize = str(args.constProbSize/(int(lengthx)*int(lengthy)*int(lengthz))) else: batchSize = str(params.batchsize) - if params.inlayout == 'complexinterleaved' or params.inlayout == 'ci': - inputlayout = '1' - elif params.inlayout == 'complexplanar' or params.inlayout == 'cp': - inputlayout = '2' - else: - printLog('ERROR: invalid value for input layout when assembling client command') - - if params.outlayout == 'complexinterleaved' or params.outlayout == 'ci': - outputlayout = '1' - elif params.outlayout == 'complexplanar' or params.outlayout == 'cp': - outputlayout = '2' - else: - printLog('ERROR: invalid value for output layout when assembling client command') - if params.placeness == 'inplace' or params.placeness == 'in': placeness = '' elif params.placeness == 'outofplace' or params.placeness == 'out': @@ -615,20 +680,39 @@ def _next_num_with_1235_factor(self): #set up arguments here if args.library == 'clFFT': - arguments = [executable(args.library), - '--' + device, + arguments = [prefix+ executable(args.library), + '-' + device, '-x', lengthx, '-y', lengthy, '-z', lengthz, '--batchSize', batchSize, - '--inLayout', inputlayout, - '--outLayout', outputlayout, + '--inLayout', inlayout, + '--outLayout',outlayout, placeness, precision, - '-p', '10'] + '-p', args.reps] + elif args.library == 'cuFFT': + if inlayout[0]=='1' and outlayout[0]=='1': + cuFFT_type='1' + elif inlayout[0]=='3' and outlayout[0]=='5': + cuFFT_type='3' + elif inlayout[0]=='5' and outlayout[0]=='3': + cuFFT_type='2' + else: + print"Wrong input/outputlayout. Only C2C/R2C/C2R are supported for Cuda" + exit() + arguments=[prefix+'cuFFT-Client', + '-x', lengthx, + '-y', lengthy, + '-z', lengthz, + '-b', batchSize, + '-p',args.reps, + '-d',str(int(args.precision[0]=='double')), + '-type',cuFFT_type] writeline = True try: + arguments=' '.join(arguments) printLog('Executing Command: '+str(arguments)) output = checkTimeOutPut(arguments) output = output.split(os.linesep); @@ -656,10 +740,19 @@ def _next_num_with_1235_factor(self): if writeline: try: - output = itertools.ifilter( lambda x: x.count('Gflops'), output) + if args.library == 'cuFFT': + output = itertools.ifilter( lambda x: x.count('gflops'), output) + else: + output = itertools.ifilter( lambda x: x.count('Gflops'), output) + output = list(itertools.islice(output, None)) thisResult = re.search('\d+\.*\d*e*-*\d*$', output[-1]) + if args.library == 'cuFFT': + thisResult = re.search('[-+]?\d*\.\d+|\d+$', output[-1]) thisResult = float(thisResult.group(0)) + + if args.library=='clFFT' and params.inlayout=='5': + thisResult=thisResult/2; thisResult = (params.x, params.y, params.z, batchSize, params.device, params.inlayout, params.outlayout, params.placeness, params.precision, params.label, thisResult) outputRow = '' diff --git a/src/scripts/perf/plotPerformance.py b/src/scripts/perf/plotPerformance.py index 3976512a..0fe14a5b 100644 --- a/src/scripts/perf/plotPerformance.py +++ b/src/scripts/perf/plotPerformance.py @@ -41,7 +41,7 @@ def plotGraph(dataForAllPlots, title, plottype, plotkwargs, xaxislabel, yaxislab display a pretty graph """ dh.write('Making graph\n') - colors = ['k','y','m','c','r','b','g'] + colors = ['k','y','m','c','b','r','g'] #plottype = 'plot' for thisPlot in dataForAllPlots: getattr(pylab, plottype)(thisPlot.xdata, thisPlot.ydata, @@ -150,18 +150,35 @@ def plotFromDataFile(): else: # small numbers on x-axis args.xaxisscale = 'linear' + if args.yaxisscale == None: + args.yaxisscale = 'linear' + + plotkwargs = {} if args.xaxisscale == 'linear': - plotkwargs = {} plottype = 'plot' elif args.xaxisscale == 'log2': plottype = 'semilogx' - plotkwargs = {'basex':2} + if (args.yaxisscale=='log2'): + plottype = 'loglog' + plotkwargs = {'basex':2,'basey':2} + elif (args.yaxisscale=='log10'): + plottype = 'loglog' + plotkwargs = {'basex':2,'basey':10} + elif (args.yaxisscale=='linear'): + plottype = 'semilogx' + plotkwargs = {'basex':2} elif args.xaxisscale == 'log10': plottype = 'semilogx' - plotkwargs = {'basex':10} + if (args.yaxisscale=='log2'): + plottype = 'loglog' + plotkwargs = {'basex':10,'basey':2} + elif (args.yaxisscale=='log10'): + plottype = 'loglog' + plotkwargs = {'basex':10,'basey':10} else: print 'ERROR: invalid value for x-axis scale' quit() + plots = set(getattr(row, multiplePlots) for row in data) @@ -171,7 +188,7 @@ def __init__(self, inlabel, inxdata, inydata): self.xdata = inxdata self.ydata = inydata - dataForAllPlots = [] + dataForAllPlots=[] for plot in plots: dataForThisPlot = itertools.ifilter( lambda x: getattr(x, multiplePlots) == plot, data) dataForThisPlot = list(itertools.islice(dataForThisPlot, None)) @@ -216,9 +233,12 @@ def __init__(self, inlabel, inxdata, inydata): """ display a pretty graph """ - colors = ['k','y','m','c','r','b','g'] - - for thisPlot in dataForAllPlots: + colors = ['k','y','m','c','b','g','r'] + def getkey(item): + return str(item.label) + dataForAllPlots.sort(key=getkey) + #for thisPlot in sorted(dataForAllPlots,key=getkey): + for thisPlot in sorted(dataForAllPlots,key=getkey): getattr(pylab, plottype)(thisPlot.xdata, thisPlot.ydata, '{}.-'.format(colors.pop()), label=thisPlot.label, **plotkwargs) if len(dataForAllPlots) > 1: @@ -287,6 +307,10 @@ def __init__(self, inlabel, inxdata, inydata): dest='xaxisscale', default=None, choices=['linear','log2','log10'], help='the desired scale for the graph\'s x-axis. if nothing is specified,\ it will be selected automatically') +parser.add_argument('--y_axis_scale', + dest='yaxisscale', default=None, choices=['linear','log2','log10'], + help='the desired scale for the graph\'s y-axis. if nothing is specified,\ + linear will be selected') parser.add_argument('--y_axis_label', dest='yaxislabel', default=None, help='the desired label for the graph\'s y-axis. if YAXISLABEL contains any\