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