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