1#!/usr/bin/env python3 2 3# Copyright (c) 2017-2026, Lawrence Livermore National Security, LLC and other CEED contributors. 4# All Rights Reserved. See the top-level LICENSE and NOTICE files for details. 5# 6# SPDX-License-Identifier: BSD-2-Clause 7# 8# This file is part of CEED: http://github.com/ceed 9 10# Read all input files specified on the command line, or stdin and parse 11# the content, storing it as a pandas dataframe 12 13import pandas as pd 14import fileinput 15import pprint 16 17 18def read_logs(files=None): 19 """Read all input files and return pandas DataFrame""" 20 data_default = dict( 21 file='unknown', 22 backend='unknown', 23 backend_memtype='unknown', 24 hostname='unknown', 25 test='unknown', 26 num_procs=0, 27 num_procs_node=0, 28 degree=0, 29 quadrature_pts=0, 30 code='libCEED', 31 ) 32 data = data_default.copy() 33 34 runs = [] 35 for line in fileinput.input(files): 36 # Legacy header contains number of MPI tasks 37 if 'Running the tests using a total of' in line: 38 data = data_default.copy() 39 data['num_procs'] = int( 40 line.split( 41 'a total of ', 42 1)[1].split( 43 None, 44 1)[0]) 45 # MPI tasks per node 46 elif 'tasks per node' in line: 47 data['num_procs_node'] = int( 48 line.split( 49 ' tasks per', 50 1)[0].rsplit( 51 None, 52 1)[1]) 53 # New Benchmark Problem 54 elif "CEED Benchmark Problem" in line: 55 # Starting a new block 56 data = data.copy() 57 runs.append(data) 58 data['file'] = fileinput.filename() 59 data['test'] = line.split()[-2] + " " + line.split('-- ')[1] 60 data['bp'] = data['test'].rsplit()[-1] 61 data['case'] = 'scalar' if (('Problem 1' in line) or ('Problem 3' in line) 62 or ('Problem 5' in line)) else 'vector' 63 elif "Hostname" in line: 64 data['hostname'] = line.split(':')[1].strip() 65 elif "Total ranks" in line: 66 data['num_procs'] = int(line.split(':')[1].strip()) 67 elif "Ranks per compute node" in line: 68 data['num_procs_node'] = int(line.split(':')[1].strip()) 69 # Backend 70 elif 'libCEED Backend MemType' in line: 71 data['backend_memtype'] = line.split(':')[1].strip() 72 elif 'libCEED Backend' in line: 73 data['backend'] = line.split(':')[1].strip() 74 # P 75 elif 'Basis Nodes' in line: 76 data['degree'] = int(line.split(':')[1]) - 1 77 # Q 78 elif 'Quadrature Points' in line: 79 data['quadrature_pts'] = int(line.split(':')[1]) 80 # Total DOFs 81 elif 'Global nodes' in line: 82 data['num_unknowns'] = int(line.split(':')[1]) 83 if data['case'] == 'vector': 84 data['num_unknowns'] *= 3 85 elif 'Global DOFs' in line: # Legacy 86 data['num_unknowns'] = int(line.split(':')[1]) 87 # Number of elements 88 elif 'Local Elements' in line: 89 data['num_elem'] = int( 90 line.split(':')[1].split()[0]) * data['num_procs'] 91 elif 'DoF per node' in line: 92 data['dof_per_node'] = int(line.split(':')[1]) 93 # CG Solve Time 94 elif 'Total KSP Iterations' in line: 95 data['ksp_its'] = int(line.split(':')[1].split()[0]) 96 elif 'CG Solve Time' in line: 97 data['time_per_it'] = float( 98 line.split(':')[1].split()[0]) / data['ksp_its'] 99 # CG DOFs/Sec 100 elif 'DoFs/Sec in CG' in line or 'DOFs/Sec in CG' in line: 101 data['cg_iteration_dps'] = 1e6 * \ 102 float(line.split(':')[1].split()[0]) 103 # End of output 104 105 return pd.DataFrame(runs) 106 107 108if __name__ == "__main__": 109 runs = read_logs() 110 print(runs) # Print summary (about 10 lines) 111 print('First entry:\n', runs.iloc[0]) 112 print('Last entry:\n', runs.iloc[-1]) 113