xref: /petsc/src/benchmarks/benchmarkAssembly.py (revision f748bf6bfc83f133d5068e6a5445afd45844ada1)
1*1b37a2a7SPierre Jolivet#!/usr/bin/env python3
25b6bfdb9SJed Brownfrom __future__ import print_function
3c87d2d20SMatthew G Knepleyimport os
4c87d2d20SMatthew G Knepleyfrom benchmarkExample import PETScExample
5c87d2d20SMatthew G Knepley
65ec3c338SMatthew G KnepleysavedTiming = {'baconost': {'ElemAssembly': [(0.040919999999999998, 0.0), (0.1242, 0.0), (0.24410000000000001, 0.0), (0.374, 0.0), (0.56259999999999999, 0.0), (0.79049999999999998, 0.0), (1.0880000000000001, 0.0), (1.351, 0.0), (1.6930000000000001, 0.0), (2.0609999999999999, 0.0), (2.4820000000000002, 0.0), (3.0640000000000001, 0.0)],
75ec3c338SMatthew G Knepley                            'MatCUSPSetValBch': [(0.0123, 0.0), (0.023429999999999999, 0.0), (0.043540000000000002, 0.0), (0.06608, 0.0), (0.09579, 0.0), (0.12920000000000001, 0.0), (0.17169999999999999, 0.0), (0.2172, 0.0), (0.27179999999999999, 0.0), (0.48309999999999997, 0.0), (0.44180000000000003, 0.0), (0.51529999999999998, 0.0)]}
85ec3c338SMatthew G Knepley               }
95ec3c338SMatthew G Knepley
106cbfa02cSMatthew G Knepleydef calculateNonzeros(n):
116cbfa02cSMatthew G Knepley  num = 0
126cbfa02cSMatthew G Knepley  # corners
136cbfa02cSMatthew G Knepley  num += 2*3 + 2*4
146cbfa02cSMatthew G Knepley  # edges
156cbfa02cSMatthew G Knepley  num += 4*(n-2)*5
166cbfa02cSMatthew G Knepley  # interior
176cbfa02cSMatthew G Knepley  num += (n-2)*(n-2)*7
186cbfa02cSMatthew G Knepley  return num
196cbfa02cSMatthew G Knepley
20c87d2d20SMatthew G Knepleydef processSummary(moduleName, times, events):
21c87d2d20SMatthew G Knepley  '''Process the Python log summary into plot data'''
22c87d2d20SMatthew G Knepley  m = __import__(moduleName)
23c87d2d20SMatthew G Knepley  reload(m)
24c87d2d20SMatthew G Knepley  # Total Time
25c87d2d20SMatthew G Knepley  times.append(m.Time[0])
26c87d2d20SMatthew G Knepley  # Common events
27c87d2d20SMatthew G Knepley  #   Add the time and flop rate
280cfd297dSMatthew G Knepley  for stageName, eventName in [('GPU_Stage','MatCUSPSetValBch'), ('CPU_Stage','ElemAssembly')]:
290cfd297dSMatthew G Knepley    s = getattr(m, stageName)
300cfd297dSMatthew G Knepley    if not eventName in events:
310cfd297dSMatthew G Knepley      events[eventName] = []
320cfd297dSMatthew G Knepley    events[eventName].append((s.event[eventName].Time[0], s.event[eventName].Flops[0]/(s.event[eventName].Time[0] * 1e6)))
33c87d2d20SMatthew G Knepley  return
34c87d2d20SMatthew G Knepley
356cbfa02cSMatthew G Knepleydef plotSummary(library, num, sizes, nonzeros, times, events):
366cbfa02cSMatthew G Knepley  from pylab import legend, plot, show, title, xlabel, ylabel, ylim
37c87d2d20SMatthew G Knepley  import numpy as np
38194dd558SMatthew G Knepley  showEventTime      = True
396cbfa02cSMatthew G Knepley  showTimePerRow     = False
406cbfa02cSMatthew G Knepley  showTimePerNonzero = True
415b6bfdb9SJed Brown  print(events)
42c87d2d20SMatthew G Knepley  if showEventTime:
43c87d2d20SMatthew G Knepley    data  = []
44c87d2d20SMatthew G Knepley    names = []
45c87d2d20SMatthew G Knepley    for event, style in [('MatCUSPSetValBch', 'b-'), ('ElemAssembly', 'b:')]:
46c87d2d20SMatthew G Knepley      names.append(event)
47c87d2d20SMatthew G Knepley      data.append(sizes)
48c87d2d20SMatthew G Knepley      data.append(np.array(events[event])[:,0])
49c87d2d20SMatthew G Knepley      data.append(style)
50c87d2d20SMatthew G Knepley    plot(*data)
51c87d2d20SMatthew G Knepley    title('Performance on '+library+' Example '+str(num))
52c87d2d20SMatthew G Knepley    xlabel('Number of Dof')
53c87d2d20SMatthew G Knepley    ylabel('Time (s)')
54c87d2d20SMatthew G Knepley    legend(names, 'upper left', shadow = True)
55c87d2d20SMatthew G Knepley    show()
566cbfa02cSMatthew G Knepley  if showTimePerRow:
576cbfa02cSMatthew G Knepley    data  = []
586cbfa02cSMatthew G Knepley    names = []
596cbfa02cSMatthew G Knepley    for event, style in [('MatCUSPSetValBch', 'b-'), ('ElemAssembly', 'b:')]:
606cbfa02cSMatthew G Knepley      names.append(event)
616cbfa02cSMatthew G Knepley      data.append(sizes)
626cbfa02cSMatthew G Knepley      rows = np.sqrt(sizes)
636cbfa02cSMatthew G Knepley      data.append(np.array(events[event])[:,0]/rows/3)
646cbfa02cSMatthew G Knepley      data.append(style)
656cbfa02cSMatthew G Knepley    plot(*data)
666cbfa02cSMatthew G Knepley    title('Performance on '+library+' Example '+str(num))
676cbfa02cSMatthew G Knepley    xlabel('Number of Dof')
686cbfa02cSMatthew G Knepley    ylabel('Time/Row (s)')
696cbfa02cSMatthew G Knepley    legend(names, 'upper left', shadow = True)
706cbfa02cSMatthew G Knepley    show()
716cbfa02cSMatthew G Knepley  if showTimePerNonzero:
726cbfa02cSMatthew G Knepley    data  = []
736cbfa02cSMatthew G Knepley    names = []
746cbfa02cSMatthew G Knepley    for event, style in [('MatCUSPSetValBch', 'b-'), ('ElemAssembly', 'b:')]:
756cbfa02cSMatthew G Knepley      names.append(event)
766cbfa02cSMatthew G Knepley      data.append(sizes)
776cbfa02cSMatthew G Knepley      data.append(np.array(events[event])[:,0]/nonzeros * 10**9)
786cbfa02cSMatthew G Knepley      data.append(style)
796cbfa02cSMatthew G Knepley    plot(*data)
806cbfa02cSMatthew G Knepley    title('Performance on '+library+' Example '+str(num))
816cbfa02cSMatthew G Knepley    xlabel('Number of Dof')
826cbfa02cSMatthew G Knepley    ylabel('Time/Nonzero (ns)')
836cbfa02cSMatthew G Knepley    legend(names, 'center right', shadow = True)
846cbfa02cSMatthew G Knepley    show()
85c87d2d20SMatthew G Knepley  return
86c87d2d20SMatthew G Knepley
87c87d2d20SMatthew G Knepleyif __name__ == '__main__':
885ec3c338SMatthew G Knepley  import argparse
895ec3c338SMatthew G Knepley
905ec3c338SMatthew G Knepley  parser = argparse.ArgumentParser(description     = 'PETSc Benchmarking',
91a17b96a8SKyle Gerard Felker                                   epilog          = 'This script runs src/<library>/tutorials/ex<num>, For more information, visit https://petsc.org/',
925ec3c338SMatthew G Knepley                                   formatter_class = argparse.ArgumentDefaultsHelpFormatter)
93eda8839fSMatthew G Knepley  parser.add_argument('--library', default='SNES',          help='The PETSc library used in this example')
94eda8839fSMatthew G Knepley  parser.add_argument('--num',     type = int, default='5', help='The example number')
955ec3c338SMatthew G Knepley  parser.add_argument('--module',  default='summary',       help='The module for timing output')
965ec3c338SMatthew G Knepley  parser.add_argument('--saved',                            help='Name of saved data')
9719d5f70aSMatthew G Knepley  parser.add_argument('--scaling',                          help='Run parallel scaling test')
98194dd558SMatthew G Knepley  parser.add_argument('--small',   action='store_true', default=False, help='Use small sizes')
9919d5f70aSMatthew G Knepley  parser.add_argument('--batch',   action='store_true', default=False, help='Generate batch files for the runs instead')
1005ec3c338SMatthew G Knepley
1015ec3c338SMatthew G Knepley  args = parser.parse_args()
1025ec3c338SMatthew G Knepley  print(args)
103375e53f0SMatthew G Knepley  ex       = PETScExample(args.library, args.num, log_summary_python = None if args.batch else args.module+'.py', preload='off')
104c87d2d20SMatthew G Knepley  sizes    = []
1056cbfa02cSMatthew G Knepley  nonzeros = []
106c87d2d20SMatthew G Knepley  times    = []
1075ec3c338SMatthew G Knepley  if args.saved is None:
108c87d2d20SMatthew G Knepley    events   = {}
10919d5f70aSMatthew G Knepley    if args.scaling == 'strong':
11019d5f70aSMatthew G Knepley      procs  = [1, 2, 4, 8]
11119d5f70aSMatthew G Knepley      if args.small:
11219d5f70aSMatthew G Knepley        grid = [10]*len(procs)
11319d5f70aSMatthew G Knepley      else:
11419d5f70aSMatthew G Knepley        grid = [1250]*len(procs)
11519d5f70aSMatthew G Knepley    else:
116194dd558SMatthew G Knepley      if args.small:
117194dd558SMatthew G Knepley        grid = [100, 150, 200, 250, 300]
118194dd558SMatthew G Knepley      else:
119194dd558SMatthew G Knepley        grid = range(150, 1350, 100)
12019d5f70aSMatthew G Knepley      procs  = [1]*len(grid)
12119d5f70aSMatthew G Knepley    for n, p in zip(grid, procs):
12219d5f70aSMatthew G Knepley      ex.run(p, da_grid_x=n, da_grid_y=n, cusp_synchronize=1, batch=args.batch)
123c87d2d20SMatthew G Knepley      sizes.append(n*n)
1246cbfa02cSMatthew G Knepley      nonzeros.append(calculateNonzeros(n))
1256a9c5db9SMatthew G Knepley      if not args.batch:
1266a9c5db9SMatthew G Knepley        processSummary(args.module, times, events)
1276a9c5db9SMatthew G Knepley        os.remove(args.module+'.pyc')
12821c1d55bSMatthew G Knepley  else:
1293849a283SMatthew G Knepley    if args.batch: raise RuntimeException('Cannot use batch option with saved data')
1309d3211cbSMatthew G Knepley    if args.saved in savedTiming:
1315ec3c338SMatthew G Knepley      events = savedTiming[args.saved]
1329d3211cbSMatthew G Knepley    else:
1339d3211cbSMatthew G Knepley      # Process output to produce module
1349d3211cbSMatthew G Knepley      events       = {}
1359d3211cbSMatthew G Knepley      filenameBase = args.saved[:-7]
1369d3211cbSMatthew G Knepley      jobnumBase   = int(args.saved[-7:])
1379d3211cbSMatthew G Knepley      for i, n in enumerate(range(150, 1350, 100)):
1389d3211cbSMatthew G Knepley        filename = filenameBase+str(jobnumBase+i)
1395b6bfdb9SJed Brown        print('Processing',filename)
1409d3211cbSMatthew G Knepley        headerSeen = False
1419d3211cbSMatthew G Knepley        with file(filename) as f, file(args.module+'.py', 'w') as o:
1429d3211cbSMatthew G Knepley          for line in f.readlines():
1439d3211cbSMatthew G Knepley            if not headerSeen:
1449d3211cbSMatthew G Knepley              if not line[0] == '#': continue
1459d3211cbSMatthew G Knepley              headerSeen = True
1469d3211cbSMatthew G Knepley            if line[0] == '#' and line[-6:] == '=====\n': break
1479d3211cbSMatthew G Knepley            o.write(line)
1489d3211cbSMatthew G Knepley            #print line
1499d3211cbSMatthew G Knepley        processSummary(args.module, times, events)
1509d3211cbSMatthew G Knepley        # I can't believe that this is necessary
1519d3211cbSMatthew G Knepley        os.remove(args.module+'.pyc')
15221c1d55bSMatthew G Knepley    for n in range(150, 1350, 100):
15321c1d55bSMatthew G Knepley      sizes.append(n*n)
1546cbfa02cSMatthew G Knepley      nonzeros.append(calculateNonzeros(n))
1553849a283SMatthew G Knepley  if not args.batch: plotSummary(args.library, args.num, sizes, nonzeros, times, events)
156