1*d13e9b48SJed Brown#!/usr/bin/env python3 2*d13e9b48SJed Brown# Copyright (c) 2017-2018, Lawrence Livermore National Security, LLC. 3*d13e9b48SJed Brown# Produced at the Lawrence Livermore National Laboratory. LLNL-CODE-734707. 4*d13e9b48SJed Brown# All Rights reserved. See files LICENSE and NOTICE for details. 5*d13e9b48SJed Brown# 6*d13e9b48SJed Brown# This file is part of CEED, a collection of benchmarks, miniapps, software 7*d13e9b48SJed Brown# libraries and APIs for efficient high-order finite element and spectral 8*d13e9b48SJed Brown# element discretizations for exascale applications. For more information and 9*d13e9b48SJed Brown# source code availability see http://github.com/ceed. 10*d13e9b48SJed Brown# 11*d13e9b48SJed Brown# The CEED research is supported by the Exascale Computing Project 17-SC-20-SC, 12*d13e9b48SJed Brown# a collaborative effort of two U.S. Department of Energy organizations (Office 13*d13e9b48SJed Brown# of Science and the National Nuclear Security Administration) responsible for 14*d13e9b48SJed Brown# the planning and preparation of a capable exascale ecosystem, including 15*d13e9b48SJed Brown# software, applications, hardware, advanced system engineering and early 16*d13e9b48SJed Brown# testbed platforms, in support of the nation's exascale computing imperative. 17*d13e9b48SJed Brown 18*d13e9b48SJed Brown 19*d13e9b48SJed Brown##### Adjustable plot parameters: 20*d13e9b48SJed Brownlog_y=0 # use log scale on the y-axis? 21*d13e9b48SJed Brownx_range=(1e1,4e6) # plot range for the x-axis; comment out for auto 22*d13e9b48SJed Browny_range=(0,2e9) # plot range for the y-axis; comment out for auto 23*d13e9b48SJed Browndraw_iter_lines=0 # draw the "iter/s" lines? 24*d13e9b48SJed Brownymin_iter_lines=3e5 # minimal y value for the "iter/s" lines 25*d13e9b48SJed Brownymax_iter_lines=8e8 # maximal y value for the "iter/s" lines 26*d13e9b48SJed Brownlegend_ncol=(2 if log_y else 1) # number of columns in the legend 27*d13e9b48SJed Brownwrite_figures=1 # save the figures to files? 28*d13e9b48SJed Brownshow_figures=1 # display the figures on the screen? 29*d13e9b48SJed Brown 30*d13e9b48SJed Brown 31*d13e9b48SJed Brown##### Load the data 32*d13e9b48SJed Brownimport pandas as pd 33*d13e9b48SJed Brownfrom postprocess_base import read_logs 34*d13e9b48SJed Brown 35*d13e9b48SJed Brownruns = read_logs() 36*d13e9b48SJed Brown 37*d13e9b48SJed Brown##### Sample plot output 38*d13e9b48SJed Brownfrom matplotlib import use 39*d13e9b48SJed Brownif not show_figures: 40*d13e9b48SJed Brown use('pdf') 41*d13e9b48SJed Brownfrom pylab import * 42*d13e9b48SJed Brown 43*d13e9b48SJed BrownrcParams['font.sans-serif'].insert(0,'Noto Sans') 44*d13e9b48SJed BrownrcParams['font.sans-serif'].insert(1,'Open Sans') 45*d13e9b48SJed BrownrcParams['figure.figsize']=[10, 8] # default: 8 x 6 46*d13e9b48SJed Brown 47*d13e9b48SJed Browncm_size=16 48*d13e9b48SJed Browncolors=['dimgrey','black','saddlebrown','firebrick','red','orange', 49*d13e9b48SJed Brown 'gold','lightgreen','green','cyan','teal','blue','navy', 50*d13e9b48SJed Brown 'purple','magenta','pink'] 51*d13e9b48SJed Brown 52*d13e9b48SJed Brown##### Get test names 53*d13e9b48SJed Brownsel_runs=runs 54*d13e9b48SJed Browntests=list(sel_runs.test.unique()) 55*d13e9b48SJed Browntest=tests[0] 56*d13e9b48SJed Brown 57*d13e9b48SJed Brown##### Run information 58*d13e9b48SJed Brownprint('Using test:', test) 59*d13e9b48SJed Brown 60*d13e9b48SJed Brownif 'CEED Benchmark Problem' in test: 61*d13e9b48SJed Brown test_short = test.strip().split()[0] + ' BP' + test.strip().split()[-1] 62*d13e9b48SJed Brown 63*d13e9b48SJed Brown##### Plot same BP 64*d13e9b48SJed Brownsel_runs=sel_runs.loc[sel_runs['test'] == test] 65*d13e9b48SJed Brown 66*d13e9b48SJed Brown##### Plot same case (scalar vs vector) 67*d13e9b48SJed Browncases=list(sel_runs.case.unique()) 68*d13e9b48SJed Browncase=cases[0] 69*d13e9b48SJed Brownvdim=1 if case=='scalar' else 3 70*d13e9b48SJed Brownprint('Using case:', case) 71*d13e9b48SJed Brownsel_runs=sel_runs.loc[sel_runs['case'] == case] 72*d13e9b48SJed Brown 73*d13e9b48SJed Brown##### Plot same 'code' 74*d13e9b48SJed Browncodes = list(sel_runs.code.unique()) 75*d13e9b48SJed Browncode = codes[0] 76*d13e9b48SJed Brownsel_runs=sel_runs.loc[sel_runs['code'] == code] 77*d13e9b48SJed Brown 78*d13e9b48SJed Brown##### Group plots by backend and number of processes 79*d13e9b48SJed Brownpl_set=sel_runs[['backend', 'backend_memtype', 'num_procs', 'num_procs_node']] 80*d13e9b48SJed Brownpl_set=pl_set.drop_duplicates() 81*d13e9b48SJed Brown 82*d13e9b48SJed Brown##### Plotting 83*d13e9b48SJed Brownfor index, row in pl_set.iterrows(): 84*d13e9b48SJed Brown backend=row['backend'] 85*d13e9b48SJed Brown backend_memtype=row['backend_memtype'] 86*d13e9b48SJed Brown num_procs=float(row['num_procs']) 87*d13e9b48SJed Brown num_procs_node=float(row['num_procs_node']) 88*d13e9b48SJed Brown num_nodes=num_procs/num_procs_node 89*d13e9b48SJed Brown pl_runs=sel_runs[(sel_runs.backend==backend) | 90*d13e9b48SJed Brown (sel_runs.num_procs==num_procs) | 91*d13e9b48SJed Brown (sel_runs.num_procs_node==num_procs_node)] 92*d13e9b48SJed Brown if len(pl_runs.index)==0: 93*d13e9b48SJed Brown continue 94*d13e9b48SJed Brown 95*d13e9b48SJed Brown print('backend: %s, compute nodes: %i, number of MPI tasks = %i'%( 96*d13e9b48SJed Brown backend,num_nodes,num_procs)) 97*d13e9b48SJed Brown 98*d13e9b48SJed Brown figure() 99*d13e9b48SJed Brown i=0 100*d13e9b48SJed Brown sol_p_set=sel_runs['degree'].drop_duplicates() 101*d13e9b48SJed Brown sol_p_set=sol_p_set.sort_values() 102*d13e9b48SJed Brown ##### Iterate over P 103*d13e9b48SJed Brown for sol_p in sol_p_set: 104*d13e9b48SJed Brown qpts=sel_runs['quadrature_pts'].loc[pl_runs['degree']==sol_p] 105*d13e9b48SJed Brown qpts=qpts.drop_duplicates().sort_values(ascending=False) 106*d13e9b48SJed Brown qpts=qpts.reset_index(drop=True) 107*d13e9b48SJed Brown print('Degree: %i, quadrature points:'%sol_p, qpts[0]) 108*d13e9b48SJed Brown # Generate plot data 109*d13e9b48SJed Brown d=[[run['degree'],run['num_elem'],1.*run['num_unknowns']/num_nodes/vdim, 110*d13e9b48SJed Brown run['cg_iteration_dps']/num_nodes] 111*d13e9b48SJed Brown for index, run in 112*d13e9b48SJed Brown pl_runs.loc[(pl_runs['degree']==sol_p) | 113*d13e9b48SJed Brown (pl_runs['quadrature_pts']==qpts[0])].iterrows()] 114*d13e9b48SJed Brown d=[[e[2],e[3]] for e in d if e[0]==sol_p] 115*d13e9b48SJed Brown # (DOFs/[sec/iter]/node)/(DOFs/node) = iter/sec 116*d13e9b48SJed Brown d=[[nun, 117*d13e9b48SJed Brown min([e[1] for e in d if e[0]==nun]), 118*d13e9b48SJed Brown max([e[1] for e in d if e[0]==nun])] 119*d13e9b48SJed Brown for nun in set([e[0] for e in d])] 120*d13e9b48SJed Brown d=asarray(sorted(d)) 121*d13e9b48SJed Brown # Plot 122*d13e9b48SJed Brown plot(d[:,0],d[:,2],'o-',color=colors[i%cm_size], 123*d13e9b48SJed Brown label='p=%i'%sol_p) 124*d13e9b48SJed Brown if list(d[:,1]) != list(d[:,2]): 125*d13e9b48SJed Brown plot(d[:,0],d[:,1],'o-',color=colors[i]) 126*d13e9b48SJed Brown fill_between(d[:,0],d[:,1],d[:,2],facecolor=colors[i],alpha=0.2) 127*d13e9b48SJed Brown # Continue if only 1 set of qpts 128*d13e9b48SJed Brown if len(qpts)==1: 129*d13e9b48SJed Brown i=i+1 130*d13e9b48SJed Brown continue 131*d13e9b48SJed Brown # Second set of qpts 132*d13e9b48SJed Brown d=[[run['degree'],run['num_elem'],1.*run['num_unknowns']/num_nodes/vdim, 133*d13e9b48SJed Brown run['cg_iteration_dps']/num_nodes] 134*d13e9b48SJed Brown for index, run in 135*d13e9b48SJed Brown pl_runs.loc[(pl_runs['degree']==sol_p) | 136*d13e9b48SJed Brown (pl_runs['quadrature_pts']==qpts[1])].iterrows()] 137*d13e9b48SJed Brown d=[[e[2],e[3]] for e in d if e[0]==sol_p] 138*d13e9b48SJed Brown if len(d)==0: 139*d13e9b48SJed Brown i=i+1 140*d13e9b48SJed Brown continue 141*d13e9b48SJed Brown d=[[nun, 142*d13e9b48SJed Brown min([e[1] for e in d if e[0]==nun]), 143*d13e9b48SJed Brown max([e[1] for e in d if e[0]==nun])] 144*d13e9b48SJed Brown for nun in set([e[0] for e in d])] 145*d13e9b48SJed Brown d=asarray(sorted(d)) 146*d13e9b48SJed Brown plot(d[:,0],d[:,2],'s--',color=colors[i], 147*d13e9b48SJed Brown label='p=%i'%sol_p) 148*d13e9b48SJed Brown if list(d[:,1]) != list(d[:,2]): 149*d13e9b48SJed Brown plot(d[:,0],d[:,1],'s--',color=colors[i]) 150*d13e9b48SJed Brown ## 151*d13e9b48SJed Brown i=i+1 152*d13e9b48SJed Brown ## 153*d13e9b48SJed Brown if draw_iter_lines: 154*d13e9b48SJed Brown y0,y1=ymin_iter_lines,ymax_iter_lines 155*d13e9b48SJed Brown y=asarray([y0,y1]) if log_y else exp(linspace(log(y0), log(y1))) 156*d13e9b48SJed Brown slope1=600. 157*d13e9b48SJed Brown slope2=6000. 158*d13e9b48SJed Brown plot(y/slope1,y,'k--',label='%g iter/s'%(slope1/vdim)) 159*d13e9b48SJed Brown plot(y/slope2,y,'k-',label='%g iter/s'%(slope2/vdim)) 160*d13e9b48SJed Brown 161*d13e9b48SJed Brown # Plot information 162*d13e9b48SJed Brown title(r'%i node%s $\times$ %i ranks, %s, %s, %s'%( 163*d13e9b48SJed Brown num_nodes,'' if num_nodes==1 else 's', 164*d13e9b48SJed Brown num_procs_node,backend,backend_memtype,test_short),fontsize=16) 165*d13e9b48SJed Brown xscale('log') # subsx=[2,4,6,8] 166*d13e9b48SJed Brown if log_y: 167*d13e9b48SJed Brown yscale('log') 168*d13e9b48SJed Brown if 'x_range' in vars() and len(x_range)==2: 169*d13e9b48SJed Brown xlim(x_range) 170*d13e9b48SJed Brown if 'y_range' in vars() and len(y_range)==2: 171*d13e9b48SJed Brown ylim(y_range) 172*d13e9b48SJed Brown grid('on', color='gray', ls='dotted') 173*d13e9b48SJed Brown grid('on', axis='both', which='minor', color='gray', ls='dotted') 174*d13e9b48SJed Brown plt.tick_params(labelsize=14) 175*d13e9b48SJed Brown exptext = gca().yaxis.get_offset_text() 176*d13e9b48SJed Brown exptext.set_size(14) 177*d13e9b48SJed Brown gca().set_axisbelow(True) 178*d13e9b48SJed Brown xlabel('Points per compute node',fontsize=14) 179*d13e9b48SJed Brown ylabel('[DOFs x CG iterations] / [compute nodes x seconds]',fontsize=14) 180*d13e9b48SJed Brown legend(ncol=legend_ncol, loc='best',fontsize=13) 181*d13e9b48SJed Brown 182*d13e9b48SJed Brown # Write 183*d13e9b48SJed Brown if write_figures: # write .pdf file? 184*d13e9b48SJed Brown short_backend=backend.replace('/','') 185*d13e9b48SJed Brown test_short_save=test_short.replace(' ','') 186*d13e9b48SJed Brown pdf_file='plot_%s_%s_%s_%s_N%03i_pn%i.pdf'%( 187*d13e9b48SJed Brown code,test_short_save,short_backend,backend_memtype,num_nodes,num_procs_node) 188*d13e9b48SJed Brown print('\nsaving figure --> %s'%pdf_file) 189*d13e9b48SJed Brown savefig(pdf_file, format='pdf', bbox_inches='tight') 190*d13e9b48SJed Brown 191*d13e9b48SJed Brownif show_figures: # show the figures? 192*d13e9b48SJed Brown print('\nShowing figures ...') 193*d13e9b48SJed Brown show() 194