13428b40fSMatthew G Knepley#!/usr/bin/env python 2eda8839fSMatthew G Knepleyimport os,sys 3683aebbfSMatthew G Knepleysys.path.append(os.path.join(os.environ['PETSC_DIR'], 'config')) 490dfb094SAndy R. Terrelsys.path.append(os.getcwd()) 5683aebbfSMatthew G Knepleyfrom builder2 import buildExample 619d5f70aSMatthew G Knepleyfrom benchmarkBatch import generateBatchScript 73428b40fSMatthew G Knepley 83428b40fSMatthew G Knepleyclass PETSc(object): 93428b40fSMatthew G Knepley def __init__(self): 103428b40fSMatthew G Knepley return 113428b40fSMatthew G Knepley 123428b40fSMatthew G Knepley def dir(self): 133428b40fSMatthew G Knepley '''Return the root directory for the PETSc tree (usually $PETSC_DIR)''' 143428b40fSMatthew G Knepley # This should search for a valid PETSc 153428b40fSMatthew G Knepley return os.environ['PETSC_DIR'] 163428b40fSMatthew G Knepley 173428b40fSMatthew G Knepley def arch(self): 183428b40fSMatthew G Knepley '''Return the PETSc build label (usually $PETSC_ARCH)''' 193428b40fSMatthew G Knepley # This should be configurable 203428b40fSMatthew G Knepley return os.environ['PETSC_ARCH'] 213428b40fSMatthew G Knepley 223428b40fSMatthew G Knepley def mpiexec(self): 233428b40fSMatthew G Knepley '''Return the path for the mpi launch executable''' 24e3da8a91SMatthew G Knepley mpiexec = os.path.join(self.dir(), self.arch(), 'bin', 'mpiexec') 256cbfa02cSMatthew G Knepley if not os.path.isfile(mpiexec): 26e3da8a91SMatthew G Knepley return None 27e3da8a91SMatthew G Knepley return mpiexec 283428b40fSMatthew G Knepley 29*d37947eaSMatthew G. Knepley def example(self, library, num): 303428b40fSMatthew G Knepley '''Return the path to the executable for a given example number''' 31*d37947eaSMatthew G. Knepley return os.path.join(self.dir(), self.arch(), 'lib', library.lower(), 'ex'+str(num)) 323428b40fSMatthew G Knepley 333973d8daSKarl Rupp def source(self, library, num, filenametail): 340790b1abSMatthew G Knepley '''Return the path to the sources for a given example number''' 350790b1abSMatthew G Knepley d = os.path.join(self.dir(), 'src', library.lower(), 'examples', 'tutorials') 360790b1abSMatthew G Knepley name = 'ex'+str(num) 370790b1abSMatthew G Knepley sources = [] 380790b1abSMatthew G Knepley for f in os.listdir(d): 390790b1abSMatthew G Knepley if f == name+'.c': 402642ea08SMatthew G Knepley sources.insert(0, f) 413973d8daSKarl Rupp elif f.startswith(name) and f.endswith(filenametail): 420790b1abSMatthew G Knepley sources.append(f) 430790b1abSMatthew G Knepley return map(lambda f: os.path.join(d, f), sources) 440790b1abSMatthew G Knepley 453428b40fSMatthew G Knepleyclass PETScExample(object): 463428b40fSMatthew G Knepley def __init__(self, library, num, **defaultOptions): 473428b40fSMatthew G Knepley self.petsc = PETSc() 483428b40fSMatthew G Knepley self.library = library 493428b40fSMatthew G Knepley self.num = num 503428b40fSMatthew G Knepley self.opts = defaultOptions 513428b40fSMatthew G Knepley return 523428b40fSMatthew G Knepley 533428b40fSMatthew G Knepley @staticmethod 54d006b754SMatthew G Knepley def runShellCommand(command, cwd = None, log = True): 553428b40fSMatthew G Knepley import subprocess 563428b40fSMatthew G Knepley 573428b40fSMatthew G Knepley Popen = subprocess.Popen 583428b40fSMatthew G Knepley PIPE = subprocess.PIPE 59d006b754SMatthew G Knepley if log: print 'Executing: %s\n' % (command,) 603428b40fSMatthew G Knepley pipe = Popen(command, cwd=cwd, stdin=None, stdout=PIPE, stderr=PIPE, bufsize=-1, shell=True, universal_newlines=True) 613428b40fSMatthew G Knepley (out, err) = pipe.communicate() 623428b40fSMatthew G Knepley ret = pipe.returncode 633428b40fSMatthew G Knepley return (out, err, ret) 643428b40fSMatthew G Knepley 653428b40fSMatthew G Knepley def optionsToString(self, **opts): 663428b40fSMatthew G Knepley '''Convert a dictionary of options to a command line argument string''' 673428b40fSMatthew G Knepley a = [] 683428b40fSMatthew G Knepley for key,value in opts.iteritems(): 693428b40fSMatthew G Knepley if value is None: 703428b40fSMatthew G Knepley a.append('-'+key) 713428b40fSMatthew G Knepley else: 723428b40fSMatthew G Knepley a.append('-'+key+' '+str(value)) 733428b40fSMatthew G Knepley return ' '.join(a) 743428b40fSMatthew G Knepley 75*d37947eaSMatthew G. Knepley def build(self, log = True): 76*d37947eaSMatthew G. Knepley sdir = os.path.join(self.petsc.dir(), 'src', self.library.lower(), 'examples', 'tutorials') 77*d37947eaSMatthew G. Knepley odir = os.getcwd() 78*d37947eaSMatthew G. Knepley os.chdir(sdir) 79*d37947eaSMatthew G. Knepley cmd = 'make ex'+str(self.num) 80*d37947eaSMatthew G. Knepley out, err, ret = self.runShellCommand(cmd, cwd = sdir, log = log) 81*d37947eaSMatthew G. Knepley if err: 82*d37947eaSMatthew G. Knepley raise RuntimeError('Unable to build example:\n'+err+out) 83*d37947eaSMatthew G. Knepley os.chdir(odir) 84*d37947eaSMatthew G. Knepley bdir = os.path.dirname(self.petsc.example(self.library, self.num)) 85*d37947eaSMatthew G. Knepley try: 86*d37947eaSMatthew G. Knepley os.makedirs(bdir) 87*d37947eaSMatthew G. Knepley except OSError: 88*d37947eaSMatthew G. Knepley if not os.path.isdir(bdir): 89*d37947eaSMatthew G. Knepley raise 90*d37947eaSMatthew G. Knepley cmd = 'mv '+os.path.join(sdir, 'ex'+str(self.num))+' '+self.petsc.example(self.library, self.num) 91*d37947eaSMatthew G. Knepley out, err, ret = self.runShellCommand(cmd, log = log) 92*d37947eaSMatthew G. Knepley if ret: 93*d37947eaSMatthew G. Knepley print err 94*d37947eaSMatthew G. Knepley print out 95*d37947eaSMatthew G. Knepley return 96*d37947eaSMatthew G. Knepley 97d006b754SMatthew G Knepley def run(self, numProcs = 1, log = True, **opts): 98b3efd4cdSAndy R. Terrel cmd = '' 99b3efd4cdSAndy R. Terrel if self.petsc.mpiexec() is not None: 100b3efd4cdSAndy R. Terrel cmd += self.petsc.mpiexec() + ' ' 101b3efd4cdSAndy R. Terrel numProcs = os.environ.get('NUM_RANKS', numProcs) 102b3efd4cdSAndy R. Terrel cmd += ' -n ' + str(numProcs) + ' ' 103b3efd4cdSAndy R. Terrel if os.environ.has_key('PE_HOSTFILE'): 104b3efd4cdSAndy R. Terrel cmd += ' -hostfile hostfile ' 105*d37947eaSMatthew G. Knepley cmd += ' '.join([self.petsc.example(self.library, self.num), self.optionsToString(**self.opts), self.optionsToString(**opts)]) 10619d5f70aSMatthew G Knepley if 'batch' in opts and opts['batch']: 10719d5f70aSMatthew G Knepley del opts['batch'] 1083849a283SMatthew G Knepley filename = generateBatchScript(self.num, numProcs, 120, ' '+self.optionsToString(**self.opts)+' '+self.optionsToString(**opts)) 1093849a283SMatthew G Knepley # Submit job 110d006b754SMatthew G Knepley out, err, ret = self.runShellCommand('qsub -q gpu '+filename, log = log) 1113849a283SMatthew G Knepley if ret: 1123849a283SMatthew G Knepley print err 1133849a283SMatthew G Knepley print out 11419d5f70aSMatthew G Knepley else: 115d006b754SMatthew G Knepley out, err, ret = self.runShellCommand(cmd, log = log) 1163428b40fSMatthew G Knepley if ret: 1173428b40fSMatthew G Knepley print err 1183428b40fSMatthew G Knepley print out 1190790b1abSMatthew G Knepley return out 1203428b40fSMatthew G Knepley 121eda8839fSMatthew G Knepleydef processSummary(moduleName, defaultStage, eventNames, times, events): 1223428b40fSMatthew G Knepley '''Process the Python log summary into plot data''' 1233428b40fSMatthew G Knepley m = __import__(moduleName) 1243428b40fSMatthew G Knepley reload(m) 1253428b40fSMatthew G Knepley # Total Time 1263428b40fSMatthew G Knepley times.append(m.Time[0]) 1273428b40fSMatthew G Knepley # Particular events 128eda8839fSMatthew G Knepley for name in eventNames: 129eda8839fSMatthew G Knepley if name.find(':') >= 0: 130eda8839fSMatthew G Knepley stageName, name = name.split(':', 1) 131eda8839fSMatthew G Knepley stage = getattr(m, stageName) 132eda8839fSMatthew G Knepley else: 133eda8839fSMatthew G Knepley stage = getattr(m, defaultStage) 134eda8839fSMatthew G Knepley if name in stage.event: 1353428b40fSMatthew G Knepley if not name in events: 1363428b40fSMatthew G Knepley events[name] = [] 137df494a56SMatthew G Knepley try: 1380bc2d6fdSMatthew G. Knepley events[name].append((max(stage.event[name].Time), sum(stage.event[name].Flops)/(max(stage.event[name].Time) * 1e6))) 139df494a56SMatthew G Knepley except ZeroDivisionError: 1400bc2d6fdSMatthew G. Knepley events[name].append((max(stage.event[name].Time), 0)) 1413428b40fSMatthew G Knepley return 1423428b40fSMatthew G Knepley 1436e25a272SMatthew G Knepleydef plotTime(library, num, eventNames, sizes, times, events): 1446e25a272SMatthew G Knepley from pylab import legend, plot, show, title, xlabel, ylabel 1456e25a272SMatthew G Knepley import numpy as np 1466e25a272SMatthew G Knepley 1476e25a272SMatthew G Knepley arches = sizes.keys() 1486e25a272SMatthew G Knepley data = [] 1496e25a272SMatthew G Knepley for arch in arches: 1506e25a272SMatthew G Knepley data.append(sizes[arch]) 1516e25a272SMatthew G Knepley data.append(times[arch]) 1526e25a272SMatthew G Knepley plot(*data) 1536e25a272SMatthew G Knepley title('Performance on '+library+' Example '+str(num)) 1546e25a272SMatthew G Knepley xlabel('Number of Dof') 1556e25a272SMatthew G Knepley ylabel('Time (s)') 1566e25a272SMatthew G Knepley legend(arches, 'upper left', shadow = True) 1576e25a272SMatthew G Knepley show() 1586e25a272SMatthew G Knepley return 1596e25a272SMatthew G Knepley 1606e25a272SMatthew G Knepleydef plotEventTime(library, num, eventNames, sizes, times, events, filename = None): 1616e25a272SMatthew G Knepley from pylab import close, legend, plot, savefig, show, title, xlabel, ylabel 1626e25a272SMatthew G Knepley import numpy as np 1636e25a272SMatthew G Knepley 1646e25a272SMatthew G Knepley close() 1656e25a272SMatthew G Knepley arches = sizes.keys() 1666e25a272SMatthew G Knepley bs = events[arches[0]].keys()[0] 1676e25a272SMatthew G Knepley data = [] 1686e25a272SMatthew G Knepley names = [] 1696e25a272SMatthew G Knepley for event, color in zip(eventNames, ['b', 'g', 'r', 'y']): 1706e25a272SMatthew G Knepley for arch, style in zip(arches, ['-', ':']): 1716e25a272SMatthew G Knepley if event in events[arch][bs]: 1726e25a272SMatthew G Knepley names.append(arch+'-'+str(bs)+' '+event) 1736e25a272SMatthew G Knepley data.append(sizes[arch][bs]) 1746e25a272SMatthew G Knepley data.append(np.array(events[arch][bs][event])[:,0]) 1756e25a272SMatthew G Knepley data.append(color+style) 1766e25a272SMatthew G Knepley else: 1776e25a272SMatthew G Knepley print 'Could not find %s in %s-%d events' % (event, arch, bs) 1786e25a272SMatthew G Knepley print data 1796e25a272SMatthew G Knepley plot(*data) 1806e25a272SMatthew G Knepley title('Performance on '+library+' Example '+str(num)) 1816e25a272SMatthew G Knepley xlabel('Number of Dof') 1826e25a272SMatthew G Knepley ylabel('Time (s)') 1836e25a272SMatthew G Knepley legend(names, 'upper left', shadow = True) 1846e25a272SMatthew G Knepley if filename is None: 1856e25a272SMatthew G Knepley show() 1866e25a272SMatthew G Knepley else: 1876e25a272SMatthew G Knepley savefig(filename) 1886e25a272SMatthew G Knepley return 1896e25a272SMatthew G Knepley 1906e25a272SMatthew G Knepleydef plotEventFlop(library, num, eventNames, sizes, times, events, filename = None): 1916e25a272SMatthew G Knepley from pylab import legend, plot, savefig, semilogy, show, title, xlabel, ylabel 1926e25a272SMatthew G Knepley import numpy as np 1936e25a272SMatthew G Knepley 1946e25a272SMatthew G Knepley arches = sizes.keys() 1956e25a272SMatthew G Knepley bs = events[arches[0]].keys()[0] 1966e25a272SMatthew G Knepley data = [] 1976e25a272SMatthew G Knepley names = [] 1986e25a272SMatthew G Knepley for event, color in zip(eventNames, ['b', 'g', 'r', 'y']): 1996e25a272SMatthew G Knepley for arch, style in zip(arches, ['-', ':']): 2006e25a272SMatthew G Knepley if event in events[arch][bs]: 2016e25a272SMatthew G Knepley names.append(arch+'-'+str(bs)+' '+event) 2026e25a272SMatthew G Knepley data.append(sizes[arch][bs]) 2036e25a272SMatthew G Knepley data.append(1e-3*np.array(events[arch][bs][event])[:,1]) 2046e25a272SMatthew G Knepley data.append(color+style) 2056e25a272SMatthew G Knepley else: 2066e25a272SMatthew G Knepley print 'Could not find %s in %s-%d events' % (event, arch, bs) 2076e25a272SMatthew G Knepley semilogy(*data) 2086e25a272SMatthew G Knepley title('Performance on '+library+' Example '+str(num)) 2096e25a272SMatthew G Knepley xlabel('Number of Dof') 2106e25a272SMatthew G Knepley ylabel('Computation Rate (GF/s)') 2116e25a272SMatthew G Knepley legend(names, 'upper left', shadow = True) 2126e25a272SMatthew G Knepley if filename is None: 2136e25a272SMatthew G Knepley show() 2146e25a272SMatthew G Knepley else: 2156e25a272SMatthew G Knepley savefig(filename) 2166e25a272SMatthew G Knepley return 2176e25a272SMatthew G Knepley 218929aa6beSMatthew G. Knepleydef plotEventScaling(library, num, eventNames, procs, events, filename = None): 219929aa6beSMatthew G. Knepley from pylab import legend, plot, savefig, semilogy, show, title, xlabel, ylabel 220929aa6beSMatthew G. Knepley import numpy as np 221929aa6beSMatthew G. Knepley 222929aa6beSMatthew G. Knepley arches = procs.keys() 223929aa6beSMatthew G. Knepley bs = events[arches[0]].keys()[0] 224929aa6beSMatthew G. Knepley data = [] 225929aa6beSMatthew G. Knepley names = [] 226929aa6beSMatthew G. Knepley for arch, style in zip(arches, ['-', ':']): 227929aa6beSMatthew G. Knepley for event, color in zip(eventNames, ['b', 'g', 'r', 'y']): 228929aa6beSMatthew G. Knepley if event in events[arch][bs]: 229929aa6beSMatthew G. Knepley names.append(arch+'-'+str(bs)+' '+event) 230929aa6beSMatthew G. Knepley data.append(procs[arch][bs]) 231929aa6beSMatthew G. Knepley data.append(1e-3*np.array(events[arch][bs][event])[:,1]) 232929aa6beSMatthew G. Knepley data.append(color+style) 233929aa6beSMatthew G. Knepley else: 234929aa6beSMatthew G. Knepley print 'Could not find %s in %s-%d events' % (event, arch, bs) 235929aa6beSMatthew G. Knepley plot(*data) 236929aa6beSMatthew G. Knepley title('Performance on '+library+' Example '+str(num)) 237929aa6beSMatthew G. Knepley xlabel('Number of Processors') 238929aa6beSMatthew G. Knepley ylabel('Computation Rate (GF/s)') 239929aa6beSMatthew G. Knepley legend(names, 'upper left', shadow = True) 240929aa6beSMatthew G. Knepley if filename is None: 241929aa6beSMatthew G. Knepley show() 242929aa6beSMatthew G. Knepley else: 243929aa6beSMatthew G. Knepley savefig(filename) 244929aa6beSMatthew G. Knepley return 245929aa6beSMatthew G. Knepley 246303b7b21SMatthew G Knepleydef plotSummaryLine(library, num, eventNames, sizes, times, events): 2473428b40fSMatthew G Knepley from pylab import legend, plot, show, title, xlabel, ylabel 2483428b40fSMatthew G Knepley import numpy as np 2493428b40fSMatthew G Knepley showTime = False 2503428b40fSMatthew G Knepley showEventTime = True 2513428b40fSMatthew G Knepley showEventFlops = True 2523428b40fSMatthew G Knepley arches = sizes.keys() 2533428b40fSMatthew G Knepley # Time 2543428b40fSMatthew G Knepley if showTime: 2553428b40fSMatthew G Knepley data = [] 2563428b40fSMatthew G Knepley for arch in arches: 2573428b40fSMatthew G Knepley data.append(sizes[arch]) 2583428b40fSMatthew G Knepley data.append(times[arch]) 2593428b40fSMatthew G Knepley plot(*data) 2603428b40fSMatthew G Knepley title('Performance on '+library+' Example '+str(num)) 2613428b40fSMatthew G Knepley xlabel('Number of Dof') 2623428b40fSMatthew G Knepley ylabel('Time (s)') 2633428b40fSMatthew G Knepley legend(arches, 'upper left', shadow = True) 2643428b40fSMatthew G Knepley show() 2653428b40fSMatthew G Knepley # Common event time 2663428b40fSMatthew G Knepley # We could make a stacked plot like Rio uses here 2673428b40fSMatthew G Knepley if showEventTime: 268df494a56SMatthew G Knepley bs = events[arches[0]].keys()[0] 2693428b40fSMatthew G Knepley data = [] 2703428b40fSMatthew G Knepley names = [] 271df494a56SMatthew G Knepley for event, color in zip(eventNames, ['b', 'g', 'r', 'y']): 2723428b40fSMatthew G Knepley for arch, style in zip(arches, ['-', ':']): 273df494a56SMatthew G Knepley if event in events[arch][bs]: 274df494a56SMatthew G Knepley names.append(arch+'-'+str(bs)+' '+event) 275df494a56SMatthew G Knepley data.append(sizes[arch][bs]) 276df494a56SMatthew G Knepley data.append(np.array(events[arch][bs][event])[:,0]) 2773428b40fSMatthew G Knepley data.append(color+style) 278df494a56SMatthew G Knepley else: 279df494a56SMatthew G Knepley print 'Could not find %s in %s-%d events' % (event, arch, bs) 280df494a56SMatthew G Knepley print data 2813428b40fSMatthew G Knepley plot(*data) 2823428b40fSMatthew G Knepley title('Performance on '+library+' Example '+str(num)) 2833428b40fSMatthew G Knepley xlabel('Number of Dof') 2843428b40fSMatthew G Knepley ylabel('Time (s)') 2853428b40fSMatthew G Knepley legend(names, 'upper left', shadow = True) 2863428b40fSMatthew G Knepley show() 2873428b40fSMatthew G Knepley # Common event flops 2883428b40fSMatthew G Knepley # We could make a stacked plot like Rio uses here 2893428b40fSMatthew G Knepley if showEventFlops: 290df494a56SMatthew G Knepley bs = events[arches[0]].keys()[0] 2913428b40fSMatthew G Knepley data = [] 2923428b40fSMatthew G Knepley names = [] 293df494a56SMatthew G Knepley for event, color in zip(eventNames, ['b', 'g', 'r', 'y']): 2943428b40fSMatthew G Knepley for arch, style in zip(arches, ['-', ':']): 295df494a56SMatthew G Knepley if event in events[arch][bs]: 296df494a56SMatthew G Knepley names.append(arch+'-'+str(bs)+' '+event) 297df494a56SMatthew G Knepley data.append(sizes[arch][bs]) 298df494a56SMatthew G Knepley data.append(np.array(events[arch][bs][event])[:,1]) 2993428b40fSMatthew G Knepley data.append(color+style) 300df494a56SMatthew G Knepley else: 301df494a56SMatthew G Knepley print 'Could not find %s in %s-%d events' % (event, arch, bs) 3023428b40fSMatthew G Knepley plot(*data) 3033428b40fSMatthew G Knepley title('Performance on '+library+' Example '+str(num)) 3043428b40fSMatthew G Knepley xlabel('Number of Dof') 3053428b40fSMatthew G Knepley ylabel('Computation Rate (MF/s)') 3063428b40fSMatthew G Knepley legend(names, 'upper left', shadow = True) 3073428b40fSMatthew G Knepley show() 3083428b40fSMatthew G Knepley return 3093428b40fSMatthew G Knepley 310303b7b21SMatthew G Knepleydef plotSummaryBar(library, num, eventNames, sizes, times, events): 311e3da8a91SMatthew G Knepley import numpy as np 312e3da8a91SMatthew G Knepley import matplotlib.pyplot as plt 313e3da8a91SMatthew G Knepley 314303b7b21SMatthew G Knepley eventColors = ['b', 'g', 'r', 'y'] 315e3da8a91SMatthew G Knepley arches = sizes.keys() 316e3da8a91SMatthew G Knepley names = [] 317e3da8a91SMatthew G Knepley N = len(sizes[arches[0]]) 318e3da8a91SMatthew G Knepley width = 0.2 319e3da8a91SMatthew G Knepley ind = np.arange(N) - 0.25 320e3da8a91SMatthew G Knepley bars = {} 321e3da8a91SMatthew G Knepley for arch in arches: 322e3da8a91SMatthew G Knepley bars[arch] = [] 323e3da8a91SMatthew G Knepley bottom = np.zeros(N) 324e3da8a91SMatthew G Knepley for event, color in zip(eventNames, eventColors): 325e3da8a91SMatthew G Knepley names.append(arch+' '+event) 326e3da8a91SMatthew G Knepley times = np.array(events[arch][event])[:,0] 327e3da8a91SMatthew G Knepley bars[arch].append(plt.bar(ind, times, width, color=color, bottom=bottom)) 328e3da8a91SMatthew G Knepley bottom += times 329e3da8a91SMatthew G Knepley ind += 0.3 330e3da8a91SMatthew G Knepley 331e3da8a91SMatthew G Knepley plt.xlabel('Number of Dof') 332e3da8a91SMatthew G Knepley plt.ylabel('Time (s)') 333e3da8a91SMatthew G Knepley plt.title('GPU vs. CPU Performance on '+library+' Example '+str(num)) 334e3da8a91SMatthew G Knepley plt.xticks(np.arange(N), map(str, sizes[arches[0]])) 335e3da8a91SMatthew G Knepley #plt.yticks(np.arange(0,81,10)) 336e3da8a91SMatthew G Knepley #plt.legend( (p1[0], p2[0]), ('Men', 'Women') ) 337e3da8a91SMatthew G Knepley plt.legend([bar[0] for bar in bars[arches[0]]], eventNames, 'upper right', shadow = True) 338e3da8a91SMatthew G Knepley 339e3da8a91SMatthew G Knepley plt.show() 340e3da8a91SMatthew G Knepley return 341e3da8a91SMatthew G Knepley 342df494a56SMatthew G Knepleydef getDMComplexSize(dim, out): 3430a2738abSAndy R. Terrel '''Retrieves the number of cells from -dm_view output''' 344683aebbfSMatthew G Knepley size = 0 345683aebbfSMatthew G Knepley for line in out.split('\n'): 346683aebbfSMatthew G Knepley if line.strip().startswith(str(dim)+'-cells: '): 3470a2738abSAndy R. Terrel sizes = line.strip()[9:].split() 3480a2738abSAndy R. Terrel size = sum(map(int, sizes)) 349683aebbfSMatthew G Knepley break 350683aebbfSMatthew G Knepley return size 351683aebbfSMatthew G Knepley 352d006b754SMatthew G Knepleydef run_DMDA(ex, name, opts, args, sizes, times, events, log=True): 353683aebbfSMatthew G Knepley for n in map(int, args.size): 354d006b754SMatthew G Knepley ex.run(log=log, da_grid_x=n, da_grid_y=n, **opts) 355683aebbfSMatthew G Knepley sizes[name].append(n*n * args.comp) 356683aebbfSMatthew G Knepley processSummary('summary', args.stage, args.events, times[name], events[name]) 357683aebbfSMatthew G Knepley return 358683aebbfSMatthew G Knepley 359d006b754SMatthew G Knepleydef run_DMComplex(ex, name, opts, args, sizes, times, events, log=True): 360683aebbfSMatthew G Knepley # This should eventually be replaced by a direct FFC/Ignition interface 361683aebbfSMatthew G Knepley if args.operator == 'laplacian': 362683aebbfSMatthew G Knepley numComp = 1 363683aebbfSMatthew G Knepley elif args.operator == 'elasticity': 364683aebbfSMatthew G Knepley numComp = args.dim 365683aebbfSMatthew G Knepley else: 366683aebbfSMatthew G Knepley raise RuntimeError('Unknown operator: %s' % args.operator) 367683aebbfSMatthew G Knepley 368683aebbfSMatthew G Knepley for numBlock in [2**i for i in map(int, args.blockExp)]: 369683aebbfSMatthew G Knepley opts['gpu_blocks'] = numBlock 370683aebbfSMatthew G Knepley args.files = ['['+','.join(source)+']'] 371683aebbfSMatthew G Knepley buildExample(args) 372683aebbfSMatthew G Knepley sizes[name][numBlock] = [] 373683aebbfSMatthew G Knepley times[name][numBlock] = [] 374683aebbfSMatthew G Knepley events[name][numBlock] = {} 375683aebbfSMatthew G Knepley for r in map(float, args.refine): 376d006b754SMatthew G Knepley out = ex.run(log=log, refinement_limit=r, **opts) 377df494a56SMatthew G Knepley sizes[name][numBlock].append(getDMComplexSize(args.dim, out)) 378683aebbfSMatthew G Knepley processSummary('summary', args.stage, args.events, times[name][numBlock], events[name][numBlock]) 379683aebbfSMatthew G Knepley return 380683aebbfSMatthew G Knepley 381d006b754SMatthew G Knepleydef outputData(sizes, times, events, name = 'output.py'): 382d006b754SMatthew G Knepley if os.path.exists(name): 383d006b754SMatthew G Knepley base, ext = os.path.splitext(name) 384d006b754SMatthew G Knepley num = 1 385d006b754SMatthew G Knepley while os.path.exists(base+str(num)+ext): 386d006b754SMatthew G Knepley num += 1 387d006b754SMatthew G Knepley name = base+str(num)+ext 388d006b754SMatthew G Knepley with file(name, 'w') as f: 389d006b754SMatthew G Knepley f.write('#PETSC_ARCH='+os.environ['PETSC_ARCH']+' '+' '.join(sys.argv)+'\n') 390d006b754SMatthew G Knepley f.write('sizes = '+repr(sizes)+'\n') 391d006b754SMatthew G Knepley f.write('times = '+repr(times)+'\n') 392d006b754SMatthew G Knepley f.write('events = '+repr(events)+'\n') 393d006b754SMatthew G Knepley return 394d006b754SMatthew G Knepley 3953428b40fSMatthew G Knepleyif __name__ == '__main__': 396eda8839fSMatthew G Knepley import argparse 397eda8839fSMatthew G Knepley 398eda8839fSMatthew G Knepley parser = argparse.ArgumentParser(description = 'PETSc Benchmarking', 399eda8839fSMatthew G Knepley epilog = 'This script runs src/<library>/examples/tutorials/ex<num>, For more information, visit http://www.mcs.anl.gov/petsc', 400eda8839fSMatthew G Knepley formatter_class = argparse.ArgumentDefaultsHelpFormatter) 401eda8839fSMatthew G Knepley parser.add_argument('--library', default='SNES', help='The PETSc library used in this example') 402eda8839fSMatthew G Knepley parser.add_argument('--num', type = int, default='5', help='The example number') 403eda8839fSMatthew G Knepley parser.add_argument('--module', default='summary', help='The module for timing output') 404eda8839fSMatthew G Knepley parser.add_argument('--stage', default='Main_Stage', help='The default logging stage') 405eda8839fSMatthew G Knepley parser.add_argument('--events', nargs='+', help='Events to process') 406eda8839fSMatthew G Knepley parser.add_argument('--batch', action='store_true', default=False, help='Generate batch files for the runs instead') 407d006b754SMatthew G Knepley parser.add_argument('--daemon', action='store_true', default=False, help='Run as a daemon') 4083973d8daSKarl Rupp parser.add_argument('--gpulang', default='OpenCL', help='GPU Language to use: Either CUDA or OpenCL (default)') 409683aebbfSMatthew G Knepley subparsers = parser.add_subparsers(help='DM types') 410eda8839fSMatthew G Knepley 411683aebbfSMatthew G Knepley parser_dmda = subparsers.add_parser('DMDA', help='Use a DMDA for the problem geometry') 412683aebbfSMatthew G Knepley parser_dmda.add_argument('--size', nargs='+', default=['10'], help='Grid size (implementation dependent)') 413683aebbfSMatthew G Knepley parser_dmda.add_argument('--comp', type = int, default='1', help='Number of field components') 414683aebbfSMatthew G Knepley parser_dmda.add_argument('runs', nargs='*', help='Run descriptions: <name>=<args>') 415683aebbfSMatthew G Knepley 416df494a56SMatthew G Knepley parser_dmmesh = subparsers.add_parser('DMComplex', help='Use a DMComplex for the problem geometry') 417683aebbfSMatthew G Knepley parser_dmmesh.add_argument('--dim', type = int, default='2', help='Spatial dimension') 418683aebbfSMatthew G Knepley parser_dmmesh.add_argument('--refine', nargs='+', default=['0.0'], help='List of refinement limits') 419683aebbfSMatthew G Knepley parser_dmmesh.add_argument('--order', type = int, default='1', help='Order of the finite element') 420683aebbfSMatthew G Knepley parser_dmmesh.add_argument('--operator', default='laplacian', help='The operator name') 421683aebbfSMatthew G Knepley parser_dmmesh.add_argument('--blockExp', nargs='+', default=range(0, 5), help='List of block exponents j, block size is 2^j') 422683aebbfSMatthew G Knepley parser_dmmesh.add_argument('runs', nargs='*', help='Run descriptions: <name>=<args>') 423eda8839fSMatthew G Knepley 424eda8839fSMatthew G Knepley args = parser.parse_args() 425eda8839fSMatthew G Knepley print(args) 426683aebbfSMatthew G Knepley if hasattr(args, 'comp'): 427683aebbfSMatthew G Knepley args.dmType = 'DMDA' 428683aebbfSMatthew G Knepley else: 429df494a56SMatthew G Knepley args.dmType = 'DMComplex' 430683aebbfSMatthew G Knepley 431eda8839fSMatthew G Knepley ex = PETScExample(args.library, args.num, log_summary='summary.dat', log_summary_python = None if args.batch else args.module+'.py', preload='off') 4323973d8daSKarl Rupp if args.gpulang == 'CUDA': 4333973d8daSKarl Rupp source = ex.petsc.source(args.library, args.num, '.cu') 4343973d8daSKarl Rupp else: 4353973d8daSKarl Rupp source = ex.petsc.source(args.library, args.num, 'OpenCL.c') # Using the convention of OpenCL code residing in source files ending in 'OpenCL.c' (at least for snes/ex52) 4363428b40fSMatthew G Knepley sizes = {} 4373428b40fSMatthew G Knepley times = {} 4383428b40fSMatthew G Knepley events = {} 439d006b754SMatthew G Knepley log = not args.daemon 440d006b754SMatthew G Knepley 441d006b754SMatthew G Knepley if args.daemon: 442d006b754SMatthew G Knepley import daemon 443d006b754SMatthew G Knepley print 'Starting daemon' 444d006b754SMatthew G Knepley daemon.createDaemon('.') 445683aebbfSMatthew G Knepley 446eda8839fSMatthew G Knepley for run in args.runs: 447eda8839fSMatthew G Knepley name, stropts = run.split('=', 1) 448eda8839fSMatthew G Knepley opts = dict([t if len(t) == 2 else (t[0], None) for t in [arg.split('=', 1) for arg in stropts.split(' ')]]) 449683aebbfSMatthew G Knepley if args.dmType == 'DMDA': 4503428b40fSMatthew G Knepley sizes[name] = [] 4513428b40fSMatthew G Knepley times[name] = [] 4523428b40fSMatthew G Knepley events[name] = {} 453d006b754SMatthew G Knepley run_DMDA(ex, name, opts, args, sizes, times, events, log=log) 454df494a56SMatthew G Knepley elif args.dmType == 'DMComplex': 455683aebbfSMatthew G Knepley sizes[name] = {} 456683aebbfSMatthew G Knepley times[name] = {} 457683aebbfSMatthew G Knepley events[name] = {} 458d006b754SMatthew G Knepley run_DMComplex(ex, name, opts, args, sizes, times, events, log=log) 459d006b754SMatthew G Knepley outputData(sizes, times, events) 460d006b754SMatthew G Knepley if not args.batch and log: plotSummaryLine(args.library, args.num, args.events, sizes, times, events) 461683aebbfSMatthew G Knepley# Benchmark for ex50 462683aebbfSMatthew G Knepley# ./src/benchmarks/benchmarkExample.py --events VecMDot VecMAXPY KSPGMRESOrthog MatMult VecCUSPCopyTo VecCUSPCopyFrom MatCUSPCopyTo --num 50 DMDA --size 10 20 50 100 --comp 4 CPU='pc_type=none mat_no_inode dm_vec_type=seq dm_mat_type=seqaij' GPU='pc_type=none mat_no_inode dm_vec_type=seqcusp dm_mat_type=seqaijcusp cusp_synchronize' 463683aebbfSMatthew G Knepley# Benchmark for ex52 464fd49fd63SMatthew G Knepley# ./src/benchmarks/benchmarkExample.py --events IntegBatchCPU IntegBatchGPU IntegGPUOnly --num 52 DMComplex --refine 0.0625 0.00625 0.000625 0.0000625 --blockExp 4 --order=1 CPU='dm_view show_residual=0 compute_function batch' GPU='dm_view show_residual=0 compute_function batch gpu gpu_batches=8' 465fd49fd63SMatthew G Knepley# ./src/benchmarks/benchmarkExample.py --events IntegBatchCPU IntegBatchGPU IntegGPUOnly --num 52 DMComplex --refine 0.0625 0.00625 0.000625 0.0000625 --blockExp 4 --order=1 --operator=elasticity CPU='dm_view op_type=elasticity show_residual=0 compute_function batch' GPU='dm_view op_type=elasticity show_residual=0 compute_function batch gpu gpu_batches=8' 466fd49fd63SMatthew G Knepley# ./src/benchmarks/benchmarkExample.py --events IntegBatchCPU IntegBatchGPU IntegGPUOnly --num 52 DMComplex --dim=3 --refine 0.0625 0.00625 0.000625 0.0000625 --blockExp 4 --order=1 CPU='dim=3 dm_view show_residual=0 compute_function batch' GPU='dim=3 dm_view show_residual=0 compute_function batch gpu gpu_batches=8' 467