1d13e9b48SJed Brown#!/usr/bin/env python3 2*5cd6c1fbSSebastian Grimberg 3d13e9b48SJed Brown# Copyright (c) 2017-2018, Lawrence Livermore National Security, LLC. 4d13e9b48SJed Brown# Produced at the Lawrence Livermore National Laboratory. LLNL-CODE-734707. 5d13e9b48SJed Brown# All Rights reserved. See files LICENSE and NOTICE for details. 6d13e9b48SJed Brown# 7d13e9b48SJed Brown# This file is part of CEED, a collection of benchmarks, miniapps, software 8d13e9b48SJed Brown# libraries and APIs for efficient high-order finite element and spectral 9d13e9b48SJed Brown# element discretizations for exascale applications. For more information and 103d8e8822SJeremy L Thompson# source code availability see http://github.com/ceed 11d13e9b48SJed Brown# 12d13e9b48SJed Brown# The CEED research is supported by the Exascale Computing Project 17-SC-20-SC, 13d13e9b48SJed Brown# a collaborative effort of two U.S. Department of Energy organizations (Office 14d13e9b48SJed Brown# of Science and the National Nuclear Security Administration) responsible for 15d13e9b48SJed Brown# the planning and preparation of a capable exascale ecosystem, including 16d13e9b48SJed Brown# software, applications, hardware, advanced system engineering and early 17d13e9b48SJed Brown# testbed platforms, in support of the nation's exascale computing imperative. 18d13e9b48SJed Brown 19*5cd6c1fbSSebastian Grimberg# Read all input files specified on the command line, or stdin and parse 20*5cd6c1fbSSebastian Grimberg# the content, storing it as a pandas dataframe 21*5cd6c1fbSSebastian Grimberg 22d13e9b48SJed Brownimport pandas as pd 23d13e9b48SJed Brownimport fileinput 24d13e9b48SJed Brownimport pprint 25d13e9b48SJed Brown 26dec49e00SJed Brown 27d13e9b48SJed Browndef read_logs(files=None): 28aa2aa0aeSJed Brown """Read all input files and return pandas DataFrame""" 29aa2aa0aeSJed Brown data_default = dict( 30dd839fb7SJed Brown file='unknown', 31dd839fb7SJed Brown backend='unknown', 32aa2aa0aeSJed Brown backend_memtype='unknown', 33aa2aa0aeSJed Brown hostname='unknown', 34dd839fb7SJed Brown test='unknown', 35dd839fb7SJed Brown num_procs=0, 36dd839fb7SJed Brown num_procs_node=0, 37dd839fb7SJed Brown degree=0, 38dd839fb7SJed Brown quadrature_pts=0, 39dd839fb7SJed Brown code='libCEED', 40dd839fb7SJed Brown ) 41aa2aa0aeSJed Brown data = data_default.copy() 42dd839fb7SJed Brown 43d13e9b48SJed Brown runs = [] 44aa2aa0aeSJed Brown for line in fileinput.input(files): 45dec49e00SJed Brown # Legacy header contains number of MPI tasks 46dd839fb7SJed Brown if 'Running the tests using a total of' in line: 47aa2aa0aeSJed Brown data = data_default.copy() 48dec49e00SJed Brown data['num_procs'] = int( 49dec49e00SJed Brown line.split( 50dec49e00SJed Brown 'a total of ', 51dec49e00SJed Brown 1)[1].split( 52dec49e00SJed Brown None, 53dec49e00SJed Brown 1)[0]) 54dec49e00SJed Brown # MPI tasks per node 55d13e9b48SJed Brown elif 'tasks per node' in line: 56dec49e00SJed Brown data['num_procs_node'] = int( 57dec49e00SJed Brown line.split( 58dec49e00SJed Brown ' tasks per', 59dec49e00SJed Brown 1)[0].rsplit( 60dec49e00SJed Brown None, 61dec49e00SJed Brown 1)[1]) 62dec49e00SJed Brown # New Benchmark Problem 63d13e9b48SJed Brown elif "CEED Benchmark Problem" in line: 64dd839fb7SJed Brown # Starting a new block 65dd839fb7SJed Brown data = data.copy() 66dd839fb7SJed Brown runs.append(data) 67dd839fb7SJed Brown data['file'] = fileinput.filename() 68d13e9b48SJed Brown data['test'] = line.split()[-2] + " " + line.split('-- ')[1] 69aa2aa0aeSJed Brown data['bp'] = data['test'].rsplit()[-1] 70d13e9b48SJed Brown data['case'] = 'scalar' if (('Problem 1' in line) or ('Problem 3' in line) 71d13e9b48SJed Brown or ('Problem 5' in line)) else 'vector' 72dd839fb7SJed Brown elif "Hostname" in line: 73dd839fb7SJed Brown data['hostname'] = line.split(':')[1].strip() 74dd839fb7SJed Brown elif "Total ranks" in line: 75dd839fb7SJed Brown data['num_procs'] = int(line.split(':')[1].strip()) 76aa2aa0aeSJed Brown elif "Ranks per compute node" in line: 77dd839fb7SJed Brown data['num_procs_node'] = int(line.split(':')[1].strip()) 78dec49e00SJed Brown # Backend 79d13e9b48SJed Brown elif 'libCEED Backend MemType' in line: 80d13e9b48SJed Brown data['backend_memtype'] = line.split(':')[1].strip() 81d13e9b48SJed Brown elif 'libCEED Backend' in line: 82d13e9b48SJed Brown data['backend'] = line.split(':')[1].strip() 83dec49e00SJed Brown # P 84d13e9b48SJed Brown elif 'Basis Nodes' in line: 85d13e9b48SJed Brown data['degree'] = int(line.split(':')[1]) - 1 86dec49e00SJed Brown # Q 87d13e9b48SJed Brown elif 'Quadrature Points' in line: 88aa2aa0aeSJed Brown data['quadrature_pts'] = int(line.split(':')[1]) 89dec49e00SJed Brown # Total DOFs 90d13e9b48SJed Brown elif 'Global nodes' in line: 91d13e9b48SJed Brown data['num_unknowns'] = int(line.split(':')[1]) 92d13e9b48SJed Brown if data['case'] == 'vector': 93d13e9b48SJed Brown data['num_unknowns'] *= 3 94aa2aa0aeSJed Brown elif 'Global DOFs' in line: # Legacy 95aa2aa0aeSJed Brown data['num_unknowns'] = int(line.split(':')[1]) 96dec49e00SJed Brown # Number of elements 97d13e9b48SJed Brown elif 'Local Elements' in line: 98dec49e00SJed Brown data['num_elem'] = int( 99dec49e00SJed Brown line.split(':')[1].split()[0]) * data['num_procs'] 100aa2aa0aeSJed Brown elif 'DoF per node' in line: 101aa2aa0aeSJed Brown data['dof_per_node'] = int(line.split(':')[1]) 102dec49e00SJed Brown # CG Solve Time 103d13e9b48SJed Brown elif 'Total KSP Iterations' in line: 104d13e9b48SJed Brown data['ksp_its'] = int(line.split(':')[1].split()[0]) 105d13e9b48SJed Brown elif 'CG Solve Time' in line: 106dec49e00SJed Brown data['time_per_it'] = float( 107dec49e00SJed Brown line.split(':')[1].split()[0]) / data['ksp_its'] 108dec49e00SJed Brown # CG DOFs/Sec 109aa2aa0aeSJed Brown elif 'DoFs/Sec in CG' in line or 'DOFs/Sec in CG' in line: 110dec49e00SJed Brown data['cg_iteration_dps'] = 1e6 * \ 111dec49e00SJed Brown float(line.split(':')[1].split()[0]) 112dec49e00SJed Brown # End of output 113d13e9b48SJed Brown 114d13e9b48SJed Brown return pd.DataFrame(runs) 115d13e9b48SJed Brown 116dec49e00SJed Brown 117d13e9b48SJed Brownif __name__ == "__main__": 118d13e9b48SJed Brown runs = read_logs() 119aa2aa0aeSJed Brown print(runs) # Print summary (about 10 lines) 120aa2aa0aeSJed Brown print('First entry:\n', runs.iloc[0]) 121aa2aa0aeSJed Brown print('Last entry:\n', runs.iloc[-1]) 122