xref: /petsc/src/benchmarks/benchmarkExample.py (revision fd49fd63e21d7adee9456d0fefc2a5e1815277af)
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'))
4683aebbfSMatthew G Knepleyfrom builder2 import buildExample
519d5f70aSMatthew G Knepleyfrom benchmarkBatch import generateBatchScript
63428b40fSMatthew G Knepley
73428b40fSMatthew G Knepleyclass PETSc(object):
83428b40fSMatthew G Knepley  def __init__(self):
93428b40fSMatthew G Knepley    return
103428b40fSMatthew G Knepley
113428b40fSMatthew G Knepley  def dir(self):
123428b40fSMatthew G Knepley    '''Return the root directory for the PETSc tree (usually $PETSC_DIR)'''
133428b40fSMatthew G Knepley    # This should search for a valid PETSc
143428b40fSMatthew G Knepley    return os.environ['PETSC_DIR']
153428b40fSMatthew G Knepley
163428b40fSMatthew G Knepley  def arch(self):
173428b40fSMatthew G Knepley    '''Return the PETSc build label (usually $PETSC_ARCH)'''
183428b40fSMatthew G Knepley    # This should be configurable
193428b40fSMatthew G Knepley    return os.environ['PETSC_ARCH']
203428b40fSMatthew G Knepley
213428b40fSMatthew G Knepley  def mpiexec(self):
223428b40fSMatthew G Knepley    '''Return the path for the mpi launch executable'''
23e3da8a91SMatthew G Knepley    mpiexec = os.path.join(self.dir(), self.arch(), 'bin', 'mpiexec')
246cbfa02cSMatthew G Knepley    if not os.path.isfile(mpiexec):
25e3da8a91SMatthew G Knepley      return None
26e3da8a91SMatthew G Knepley    return mpiexec
273428b40fSMatthew G Knepley
283428b40fSMatthew G Knepley  def example(self, num):
293428b40fSMatthew G Knepley    '''Return the path to the executable for a given example number'''
303428b40fSMatthew G Knepley    return os.path.join(self.dir(), self.arch(), 'lib', 'ex'+str(num)+'-obj', 'ex'+str(num))
313428b40fSMatthew G Knepley
320790b1abSMatthew G Knepley  def source(self, library, num):
330790b1abSMatthew G Knepley    '''Return the path to the sources for a given example number'''
340790b1abSMatthew G Knepley    d = os.path.join(self.dir(), 'src', library.lower(), 'examples', 'tutorials')
350790b1abSMatthew G Knepley    name = 'ex'+str(num)
360790b1abSMatthew G Knepley    sources = []
370790b1abSMatthew G Knepley    for f in os.listdir(d):
380790b1abSMatthew G Knepley      if f == name+'.c':
392642ea08SMatthew G Knepley        sources.insert(0, f)
400790b1abSMatthew G Knepley      elif f.startswith(name) and f.endswith('.cu'):
410790b1abSMatthew G Knepley        sources.append(f)
420790b1abSMatthew G Knepley    return map(lambda f: os.path.join(d, f), sources)
430790b1abSMatthew G Knepley
443428b40fSMatthew G Knepleyclass PETScExample(object):
453428b40fSMatthew G Knepley  def __init__(self, library, num, **defaultOptions):
463428b40fSMatthew G Knepley    self.petsc   = PETSc()
473428b40fSMatthew G Knepley    self.library = library
483428b40fSMatthew G Knepley    self.num     = num
493428b40fSMatthew G Knepley    self.opts    = defaultOptions
503428b40fSMatthew G Knepley    return
513428b40fSMatthew G Knepley
523428b40fSMatthew G Knepley  @staticmethod
533428b40fSMatthew G Knepley  def runShellCommand(command, cwd = None):
543428b40fSMatthew G Knepley    import subprocess
553428b40fSMatthew G Knepley
563428b40fSMatthew G Knepley    Popen = subprocess.Popen
573428b40fSMatthew G Knepley    PIPE  = subprocess.PIPE
583428b40fSMatthew G Knepley    print 'Executing: %s\n' % (command,)
593428b40fSMatthew G Knepley    pipe = Popen(command, cwd=cwd, stdin=None, stdout=PIPE, stderr=PIPE, bufsize=-1, shell=True, universal_newlines=True)
603428b40fSMatthew G Knepley    (out, err) = pipe.communicate()
613428b40fSMatthew G Knepley    ret = pipe.returncode
623428b40fSMatthew G Knepley    return (out, err, ret)
633428b40fSMatthew G Knepley
643428b40fSMatthew G Knepley  def optionsToString(self, **opts):
653428b40fSMatthew G Knepley    '''Convert a dictionary of options to a command line argument string'''
663428b40fSMatthew G Knepley    a = []
673428b40fSMatthew G Knepley    for key,value in opts.iteritems():
683428b40fSMatthew G Knepley      if value is None:
693428b40fSMatthew G Knepley        a.append('-'+key)
703428b40fSMatthew G Knepley      else:
713428b40fSMatthew G Knepley        a.append('-'+key+' '+str(value))
723428b40fSMatthew G Knepley    return ' '.join(a)
733428b40fSMatthew G Knepley
7419d5f70aSMatthew G Knepley  def run(self, numProcs = 1, **opts):
75e3da8a91SMatthew G Knepley    if self.petsc.mpiexec() is None:
76e3da8a91SMatthew G Knepley      cmd = self.petsc.example(self.num)
77e3da8a91SMatthew G Knepley    else:
7819d5f70aSMatthew G Knepley      cmd = ' '.join([self.petsc.mpiexec(), '-n', str(numProcs), self.petsc.example(self.num)])
79e3da8a91SMatthew G Knepley    cmd += ' '+self.optionsToString(**self.opts)+' '+self.optionsToString(**opts)
8019d5f70aSMatthew G Knepley    if 'batch' in opts and opts['batch']:
8119d5f70aSMatthew G Knepley      del opts['batch']
823849a283SMatthew G Knepley      filename = generateBatchScript(self.num, numProcs, 120, ' '+self.optionsToString(**self.opts)+' '+self.optionsToString(**opts))
833849a283SMatthew G Knepley      # Submit job
843849a283SMatthew G Knepley      out, err, ret = self.runShellCommand('qsub -q gpu '+filename)
853849a283SMatthew G Knepley      if ret:
863849a283SMatthew G Knepley        print err
873849a283SMatthew G Knepley        print out
8819d5f70aSMatthew G Knepley    else:
893428b40fSMatthew G Knepley      out, err, ret = self.runShellCommand(cmd)
903428b40fSMatthew G Knepley      if ret:
913428b40fSMatthew G Knepley        print err
923428b40fSMatthew G Knepley        print out
930790b1abSMatthew G Knepley    return out
943428b40fSMatthew G Knepley
95eda8839fSMatthew G Knepleydef processSummary(moduleName, defaultStage, eventNames, times, events):
963428b40fSMatthew G Knepley  '''Process the Python log summary into plot data'''
973428b40fSMatthew G Knepley  m = __import__(moduleName)
983428b40fSMatthew G Knepley  reload(m)
993428b40fSMatthew G Knepley  # Total Time
1003428b40fSMatthew G Knepley  times.append(m.Time[0])
1013428b40fSMatthew G Knepley  # Particular events
102eda8839fSMatthew G Knepley  for name in eventNames:
103eda8839fSMatthew G Knepley    if name.find(':') >= 0:
104eda8839fSMatthew G Knepley      stageName, name = name.split(':', 1)
105eda8839fSMatthew G Knepley      stage = getattr(m, stageName)
106eda8839fSMatthew G Knepley    else:
107eda8839fSMatthew G Knepley      stage = getattr(m, defaultStage)
108eda8839fSMatthew G Knepley    if name in stage.event:
1093428b40fSMatthew G Knepley      if not name in events:
1103428b40fSMatthew G Knepley        events[name] = []
111df494a56SMatthew G Knepley      try:
112eda8839fSMatthew G Knepley        events[name].append((stage.event[name].Time[0], stage.event[name].Flops[0]/(stage.event[name].Time[0] * 1e6)))
113df494a56SMatthew G Knepley      except ZeroDivisionError:
114df494a56SMatthew G Knepley        events[name].append((stage.event[name].Time[0], 0))
1153428b40fSMatthew G Knepley  return
1163428b40fSMatthew G Knepley
1176e25a272SMatthew G Knepleydef plotTime(library, num, eventNames, sizes, times, events):
1186e25a272SMatthew G Knepley  from pylab import legend, plot, show, title, xlabel, ylabel
1196e25a272SMatthew G Knepley  import numpy as np
1206e25a272SMatthew G Knepley
1216e25a272SMatthew G Knepley  arches = sizes.keys()
1226e25a272SMatthew G Knepley  data   = []
1236e25a272SMatthew G Knepley  for arch in arches:
1246e25a272SMatthew G Knepley    data.append(sizes[arch])
1256e25a272SMatthew G Knepley    data.append(times[arch])
1266e25a272SMatthew G Knepley  plot(*data)
1276e25a272SMatthew G Knepley  title('Performance on '+library+' Example '+str(num))
1286e25a272SMatthew G Knepley  xlabel('Number of Dof')
1296e25a272SMatthew G Knepley  ylabel('Time (s)')
1306e25a272SMatthew G Knepley  legend(arches, 'upper left', shadow = True)
1316e25a272SMatthew G Knepley  show()
1326e25a272SMatthew G Knepley  return
1336e25a272SMatthew G Knepley
1346e25a272SMatthew G Knepleydef plotEventTime(library, num, eventNames, sizes, times, events, filename = None):
1356e25a272SMatthew G Knepley  from pylab import close, legend, plot, savefig, show, title, xlabel, ylabel
1366e25a272SMatthew G Knepley  import numpy as np
1376e25a272SMatthew G Knepley
1386e25a272SMatthew G Knepley  close()
1396e25a272SMatthew G Knepley  arches = sizes.keys()
1406e25a272SMatthew G Knepley  bs     = events[arches[0]].keys()[0]
1416e25a272SMatthew G Knepley  data   = []
1426e25a272SMatthew G Knepley  names  = []
1436e25a272SMatthew G Knepley  for event, color in zip(eventNames, ['b', 'g', 'r', 'y']):
1446e25a272SMatthew G Knepley    for arch, style in zip(arches, ['-', ':']):
1456e25a272SMatthew G Knepley      if event in events[arch][bs]:
1466e25a272SMatthew G Knepley        names.append(arch+'-'+str(bs)+' '+event)
1476e25a272SMatthew G Knepley        data.append(sizes[arch][bs])
1486e25a272SMatthew G Knepley        data.append(np.array(events[arch][bs][event])[:,0])
1496e25a272SMatthew G Knepley        data.append(color+style)
1506e25a272SMatthew G Knepley      else:
1516e25a272SMatthew G Knepley        print 'Could not find %s in %s-%d events' % (event, arch, bs)
1526e25a272SMatthew G Knepley  print data
1536e25a272SMatthew G Knepley  plot(*data)
1546e25a272SMatthew G Knepley  title('Performance on '+library+' Example '+str(num))
1556e25a272SMatthew G Knepley  xlabel('Number of Dof')
1566e25a272SMatthew G Knepley  ylabel('Time (s)')
1576e25a272SMatthew G Knepley  legend(names, 'upper left', shadow = True)
1586e25a272SMatthew G Knepley  if filename is None:
1596e25a272SMatthew G Knepley    show()
1606e25a272SMatthew G Knepley  else:
1616e25a272SMatthew G Knepley    savefig(filename)
1626e25a272SMatthew G Knepley  return
1636e25a272SMatthew G Knepley
1646e25a272SMatthew G Knepleydef plotEventFlop(library, num, eventNames, sizes, times, events, filename = None):
1656e25a272SMatthew G Knepley  from pylab import legend, plot, savefig, semilogy, show, title, xlabel, ylabel
1666e25a272SMatthew G Knepley  import numpy as np
1676e25a272SMatthew G Knepley
1686e25a272SMatthew G Knepley  arches = sizes.keys()
1696e25a272SMatthew G Knepley  bs     = events[arches[0]].keys()[0]
1706e25a272SMatthew G Knepley  data   = []
1716e25a272SMatthew G Knepley  names  = []
1726e25a272SMatthew G Knepley  for event, color in zip(eventNames, ['b', 'g', 'r', 'y']):
1736e25a272SMatthew G Knepley    for arch, style in zip(arches, ['-', ':']):
1746e25a272SMatthew G Knepley      if event in events[arch][bs]:
1756e25a272SMatthew G Knepley        names.append(arch+'-'+str(bs)+' '+event)
1766e25a272SMatthew G Knepley        data.append(sizes[arch][bs])
1776e25a272SMatthew G Knepley        data.append(1e-3*np.array(events[arch][bs][event])[:,1])
1786e25a272SMatthew G Knepley        data.append(color+style)
1796e25a272SMatthew G Knepley      else:
1806e25a272SMatthew G Knepley        print 'Could not find %s in %s-%d events' % (event, arch, bs)
1816e25a272SMatthew G Knepley  semilogy(*data)
1826e25a272SMatthew G Knepley  title('Performance on '+library+' Example '+str(num))
1836e25a272SMatthew G Knepley  xlabel('Number of Dof')
1846e25a272SMatthew G Knepley  ylabel('Computation Rate (GF/s)')
1856e25a272SMatthew G Knepley  legend(names, 'upper left', shadow = True)
1866e25a272SMatthew G Knepley  if filename is None:
1876e25a272SMatthew G Knepley    show()
1886e25a272SMatthew G Knepley  else:
1896e25a272SMatthew G Knepley    savefig(filename)
1906e25a272SMatthew G Knepley  return
1916e25a272SMatthew G Knepley
192303b7b21SMatthew G Knepleydef plotSummaryLine(library, num, eventNames, sizes, times, events):
1933428b40fSMatthew G Knepley  from pylab import legend, plot, show, title, xlabel, ylabel
1943428b40fSMatthew G Knepley  import numpy as np
1953428b40fSMatthew G Knepley  showTime       = False
1963428b40fSMatthew G Knepley  showEventTime  = True
1973428b40fSMatthew G Knepley  showEventFlops = True
1983428b40fSMatthew G Knepley  arches         = sizes.keys()
1993428b40fSMatthew G Knepley  # Time
2003428b40fSMatthew G Knepley  if showTime:
2013428b40fSMatthew G Knepley    data = []
2023428b40fSMatthew G Knepley    for arch in arches:
2033428b40fSMatthew G Knepley      data.append(sizes[arch])
2043428b40fSMatthew G Knepley      data.append(times[arch])
2053428b40fSMatthew G Knepley    plot(*data)
2063428b40fSMatthew G Knepley    title('Performance on '+library+' Example '+str(num))
2073428b40fSMatthew G Knepley    xlabel('Number of Dof')
2083428b40fSMatthew G Knepley    ylabel('Time (s)')
2093428b40fSMatthew G Knepley    legend(arches, 'upper left', shadow = True)
2103428b40fSMatthew G Knepley    show()
2113428b40fSMatthew G Knepley  # Common event time
2123428b40fSMatthew G Knepley  #   We could make a stacked plot like Rio uses here
2133428b40fSMatthew G Knepley  if showEventTime:
214df494a56SMatthew G Knepley    bs    = events[arches[0]].keys()[0]
2153428b40fSMatthew G Knepley    data  = []
2163428b40fSMatthew G Knepley    names = []
217df494a56SMatthew G Knepley    for event, color in zip(eventNames, ['b', 'g', 'r', 'y']):
2183428b40fSMatthew G Knepley      for arch, style in zip(arches, ['-', ':']):
219df494a56SMatthew G Knepley        if event in events[arch][bs]:
220df494a56SMatthew G Knepley          names.append(arch+'-'+str(bs)+' '+event)
221df494a56SMatthew G Knepley          data.append(sizes[arch][bs])
222df494a56SMatthew G Knepley          data.append(np.array(events[arch][bs][event])[:,0])
2233428b40fSMatthew G Knepley          data.append(color+style)
224df494a56SMatthew G Knepley        else:
225df494a56SMatthew G Knepley          print 'Could not find %s in %s-%d events' % (event, arch, bs)
226df494a56SMatthew G Knepley    print data
2273428b40fSMatthew G Knepley    plot(*data)
2283428b40fSMatthew G Knepley    title('Performance on '+library+' Example '+str(num))
2293428b40fSMatthew G Knepley    xlabel('Number of Dof')
2303428b40fSMatthew G Knepley    ylabel('Time (s)')
2313428b40fSMatthew G Knepley    legend(names, 'upper left', shadow = True)
2323428b40fSMatthew G Knepley    show()
2333428b40fSMatthew G Knepley  # Common event flops
2343428b40fSMatthew G Knepley  #   We could make a stacked plot like Rio uses here
2353428b40fSMatthew G Knepley  if showEventFlops:
236df494a56SMatthew G Knepley    bs    = events[arches[0]].keys()[0]
2373428b40fSMatthew G Knepley    data  = []
2383428b40fSMatthew G Knepley    names = []
239df494a56SMatthew G Knepley    for event, color in zip(eventNames, ['b', 'g', 'r', 'y']):
2403428b40fSMatthew G Knepley      for arch, style in zip(arches, ['-', ':']):
241df494a56SMatthew G Knepley        if event in events[arch][bs]:
242df494a56SMatthew G Knepley          names.append(arch+'-'+str(bs)+' '+event)
243df494a56SMatthew G Knepley          data.append(sizes[arch][bs])
244df494a56SMatthew G Knepley          data.append(np.array(events[arch][bs][event])[:,1])
2453428b40fSMatthew G Knepley          data.append(color+style)
246df494a56SMatthew G Knepley        else:
247df494a56SMatthew G Knepley          print 'Could not find %s in %s-%d events' % (event, arch, bs)
2483428b40fSMatthew G Knepley    plot(*data)
2493428b40fSMatthew G Knepley    title('Performance on '+library+' Example '+str(num))
2503428b40fSMatthew G Knepley    xlabel('Number of Dof')
2513428b40fSMatthew G Knepley    ylabel('Computation Rate (MF/s)')
2523428b40fSMatthew G Knepley    legend(names, 'upper left', shadow = True)
2533428b40fSMatthew G Knepley    show()
2543428b40fSMatthew G Knepley  return
2553428b40fSMatthew G Knepley
256303b7b21SMatthew G Knepleydef plotSummaryBar(library, num, eventNames, sizes, times, events):
257e3da8a91SMatthew G Knepley  import numpy as np
258e3da8a91SMatthew G Knepley  import matplotlib.pyplot as plt
259e3da8a91SMatthew G Knepley
260303b7b21SMatthew G Knepley  eventColors = ['b', 'g', 'r', 'y']
261e3da8a91SMatthew G Knepley  arches = sizes.keys()
262e3da8a91SMatthew G Knepley  names  = []
263e3da8a91SMatthew G Knepley  N      = len(sizes[arches[0]])
264e3da8a91SMatthew G Knepley  width  = 0.2
265e3da8a91SMatthew G Knepley  ind    = np.arange(N) - 0.25
266e3da8a91SMatthew G Knepley  bars   = {}
267e3da8a91SMatthew G Knepley  for arch in arches:
268e3da8a91SMatthew G Knepley    bars[arch] = []
269e3da8a91SMatthew G Knepley    bottom = np.zeros(N)
270e3da8a91SMatthew G Knepley    for event, color in zip(eventNames, eventColors):
271e3da8a91SMatthew G Knepley      names.append(arch+' '+event)
272e3da8a91SMatthew G Knepley      times = np.array(events[arch][event])[:,0]
273e3da8a91SMatthew G Knepley      bars[arch].append(plt.bar(ind, times, width, color=color, bottom=bottom))
274e3da8a91SMatthew G Knepley      bottom += times
275e3da8a91SMatthew G Knepley    ind += 0.3
276e3da8a91SMatthew G Knepley
277e3da8a91SMatthew G Knepley  plt.xlabel('Number of Dof')
278e3da8a91SMatthew G Knepley  plt.ylabel('Time (s)')
279e3da8a91SMatthew G Knepley  plt.title('GPU vs. CPU Performance on '+library+' Example '+str(num))
280e3da8a91SMatthew G Knepley  plt.xticks(np.arange(N), map(str, sizes[arches[0]]))
281e3da8a91SMatthew G Knepley  #plt.yticks(np.arange(0,81,10))
282e3da8a91SMatthew G Knepley  #plt.legend( (p1[0], p2[0]), ('Men', 'Women') )
283e3da8a91SMatthew G Knepley  plt.legend([bar[0] for bar in bars[arches[0]]], eventNames, 'upper right', shadow = True)
284e3da8a91SMatthew G Knepley
285e3da8a91SMatthew G Knepley  plt.show()
286e3da8a91SMatthew G Knepley  return
287e3da8a91SMatthew G Knepley
288df494a56SMatthew G Knepleydef getDMComplexSize(dim, out):
289683aebbfSMatthew G Knepley  '''Retrieves the number of cells from '''
290683aebbfSMatthew G Knepley  size = 0
291683aebbfSMatthew G Knepley  for line in out.split('\n'):
292683aebbfSMatthew G Knepley    if line.strip().startswith(str(dim)+'-cells: '):
293683aebbfSMatthew G Knepley      size = int(line.strip()[9:])
294683aebbfSMatthew G Knepley      break
295683aebbfSMatthew G Knepley  return size
296683aebbfSMatthew G Knepley
297683aebbfSMatthew G Knepleydef run_DMDA(ex, name, opts, args, sizes, times, events):
298683aebbfSMatthew G Knepley  for n in map(int, args.size):
299683aebbfSMatthew G Knepley    ex.run(da_grid_x=n, da_grid_y=n, **opts)
300683aebbfSMatthew G Knepley    sizes[name].append(n*n * args.comp)
301683aebbfSMatthew G Knepley    processSummary('summary', args.stage, args.events, times[name], events[name])
302683aebbfSMatthew G Knepley  return
303683aebbfSMatthew G Knepley
304df494a56SMatthew G Knepleydef run_DMComplex(ex, name, opts, args, sizes, times, events):
305683aebbfSMatthew G Knepley  # This should eventually be replaced by a direct FFC/Ignition interface
306683aebbfSMatthew G Knepley  if args.operator == 'laplacian':
307683aebbfSMatthew G Knepley    numComp  = 1
308683aebbfSMatthew G Knepley  elif args.operator == 'elasticity':
309683aebbfSMatthew G Knepley    numComp  = args.dim
310683aebbfSMatthew G Knepley  else:
311683aebbfSMatthew G Knepley    raise RuntimeError('Unknown operator: %s' % args.operator)
312683aebbfSMatthew G Knepley
313683aebbfSMatthew G Knepley  for numBlock in [2**i for i in map(int, args.blockExp)]:
314683aebbfSMatthew G Knepley    opts['gpu_blocks'] = numBlock
315683aebbfSMatthew G Knepley    # Generate new block size
316683aebbfSMatthew G Knepley    cmd = './bin/pythonscripts/PetscGenerateFEMQuadrature.py %d %d %d %d %s %s.h' % (args.dim, args.order, numComp, numBlock, args.operator, os.path.splitext(source[0])[0])
317683aebbfSMatthew G Knepley    print(cmd)
318683aebbfSMatthew G Knepley    ret = os.system('python '+cmd)
319683aebbfSMatthew G Knepley    args.files = ['['+','.join(source)+']']
320683aebbfSMatthew G Knepley    buildExample(args)
321683aebbfSMatthew G Knepley    sizes[name][numBlock]  = []
322683aebbfSMatthew G Knepley    times[name][numBlock]  = []
323683aebbfSMatthew G Knepley    events[name][numBlock] = {}
324683aebbfSMatthew G Knepley    for r in map(float, args.refine):
325683aebbfSMatthew G Knepley      out = ex.run(refinement_limit=r, **opts)
326df494a56SMatthew G Knepley      sizes[name][numBlock].append(getDMComplexSize(args.dim, out))
327683aebbfSMatthew G Knepley      processSummary('summary', args.stage, args.events, times[name][numBlock], events[name][numBlock])
328683aebbfSMatthew G Knepley  return
329683aebbfSMatthew G Knepley
3303428b40fSMatthew G Knepleyif __name__ == '__main__':
331eda8839fSMatthew G Knepley  import argparse
332eda8839fSMatthew G Knepley
333eda8839fSMatthew G Knepley  parser = argparse.ArgumentParser(description     = 'PETSc Benchmarking',
334eda8839fSMatthew G Knepley                                   epilog          = 'This script runs src/<library>/examples/tutorials/ex<num>, For more information, visit http://www.mcs.anl.gov/petsc',
335eda8839fSMatthew G Knepley                                   formatter_class = argparse.ArgumentDefaultsHelpFormatter)
336eda8839fSMatthew G Knepley  parser.add_argument('--library', default='SNES',                     help='The PETSc library used in this example')
337eda8839fSMatthew G Knepley  parser.add_argument('--num',     type = int, default='5',            help='The example number')
338eda8839fSMatthew G Knepley  parser.add_argument('--module',  default='summary',                  help='The module for timing output')
339eda8839fSMatthew G Knepley  parser.add_argument('--stage',   default='Main_Stage',               help='The default logging stage')
340eda8839fSMatthew G Knepley  parser.add_argument('--events',  nargs='+',                          help='Events to process')
341eda8839fSMatthew G Knepley  parser.add_argument('--batch',   action='store_true', default=False, help='Generate batch files for the runs instead')
342683aebbfSMatthew G Knepley  subparsers = parser.add_subparsers(help='DM types')
343eda8839fSMatthew G Knepley
344683aebbfSMatthew G Knepley  parser_dmda = subparsers.add_parser('DMDA', help='Use a DMDA for the problem geometry')
345683aebbfSMatthew G Knepley  parser_dmda.add_argument('--size', nargs='+',  default=['10'], help='Grid size (implementation dependent)')
346683aebbfSMatthew G Knepley  parser_dmda.add_argument('--comp', type = int, default='1',    help='Number of field components')
347683aebbfSMatthew G Knepley  parser_dmda.add_argument('runs',   nargs='*',                  help='Run descriptions: <name>=<args>')
348683aebbfSMatthew G Knepley
349df494a56SMatthew G Knepley  parser_dmmesh = subparsers.add_parser('DMComplex', help='Use a DMComplex for the problem geometry')
350683aebbfSMatthew G Knepley  parser_dmmesh.add_argument('--dim',      type = int, default='2',        help='Spatial dimension')
351683aebbfSMatthew G Knepley  parser_dmmesh.add_argument('--refine',   nargs='+',  default=['0.0'],    help='List of refinement limits')
352683aebbfSMatthew G Knepley  parser_dmmesh.add_argument('--order',    type = int, default='1',        help='Order of the finite element')
353683aebbfSMatthew G Knepley  parser_dmmesh.add_argument('--operator', default='laplacian',            help='The operator name')
354683aebbfSMatthew G Knepley  parser_dmmesh.add_argument('--blockExp', nargs='+', default=range(0, 5), help='List of block exponents j, block size is 2^j')
355683aebbfSMatthew G Knepley  parser_dmmesh.add_argument('runs',       nargs='*',                      help='Run descriptions: <name>=<args>')
356eda8839fSMatthew G Knepley
357eda8839fSMatthew G Knepley  args = parser.parse_args()
358eda8839fSMatthew G Knepley  print(args)
359683aebbfSMatthew G Knepley  if hasattr(args, 'comp'):
360683aebbfSMatthew G Knepley    args.dmType = 'DMDA'
361683aebbfSMatthew G Knepley  else:
362df494a56SMatthew G Knepley    args.dmType = 'DMComplex'
363683aebbfSMatthew G Knepley
364eda8839fSMatthew 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')
365683aebbfSMatthew G Knepley  source = ex.petsc.source(args.library, args.num)
3663428b40fSMatthew G Knepley  sizes  = {}
3673428b40fSMatthew G Knepley  times  = {}
3683428b40fSMatthew G Knepley  events = {}
369683aebbfSMatthew G Knepley
370eda8839fSMatthew G Knepley  for run in args.runs:
371eda8839fSMatthew G Knepley    name, stropts = run.split('=', 1)
372eda8839fSMatthew G Knepley    opts = dict([t if len(t) == 2 else (t[0], None) for t in [arg.split('=', 1) for arg in stropts.split(' ')]])
373683aebbfSMatthew G Knepley    if args.dmType == 'DMDA':
3743428b40fSMatthew G Knepley      sizes[name]  = []
3753428b40fSMatthew G Knepley      times[name]  = []
3763428b40fSMatthew G Knepley      events[name] = {}
377683aebbfSMatthew G Knepley      run_DMDA(ex, name, opts, args, sizes, times, events)
378df494a56SMatthew G Knepley    elif args.dmType == 'DMComplex':
379683aebbfSMatthew G Knepley      sizes[name]  = {}
380683aebbfSMatthew G Knepley      times[name]  = {}
381683aebbfSMatthew G Knepley      events[name] = {}
382df494a56SMatthew G Knepley      run_DMComplex(ex, name, opts, args, sizes, times, events)
383683aebbfSMatthew G Knepley  print('sizes',sizes)
384683aebbfSMatthew G Knepley  print('times',times)
385683aebbfSMatthew G Knepley  print('events',events)
386303b7b21SMatthew G Knepley  if not args.batch: plotSummaryLine(args.library, args.num, args.events, sizes, times, events)
387683aebbfSMatthew G Knepley# Benchmark for ex50
388683aebbfSMatthew 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'
389683aebbfSMatthew G Knepley# Benchmark for ex52
390*fd49fd63SMatthew 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'
391*fd49fd63SMatthew 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'
392*fd49fd63SMatthew 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'
393