xref: /libCEED/benchmarks/postprocess_base.py (revision d99fa3c5cd91a1690aedf0679cbf290d44fec74c)
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
18import pandas as pd
19import fileinput
20import pprint
21
22# Read all input files specified on the command line, or stdin and parse
23# the content, storing it as a pandas dataframe
24
25
26def read_logs(files=None):
27    """Read all input files and return pandas DataFrame"""
28    data_default = dict(
29        file='unknown',
30        backend='unknown',
31        backend_memtype='unknown',
32        hostname='unknown',
33        test='unknown',
34        num_procs=0,
35        num_procs_node=0,
36        degree=0,
37        quadrature_pts=0,
38        code='libCEED',
39    )
40    data = data_default.copy()
41
42    runs = []
43    for line in fileinput.input(files):
44        # Legacy header contains number of MPI tasks
45        if 'Running the tests using a total of' in line:
46            data = data_default.copy()
47            data['num_procs'] = int(
48                line.split(
49                    'a total of ',
50                    1)[1].split(
51                    None,
52                    1)[0])
53        # MPI tasks per node
54        elif 'tasks per node' in line:
55            data['num_procs_node'] = int(
56                line.split(
57                    ' tasks per',
58                    1)[0].rsplit(
59                    None,
60                    1)[1])
61        # New Benchmark Problem
62        elif "CEED Benchmark Problem" in line:
63            # Starting a new block
64            data = data.copy()
65            runs.append(data)
66            data['file'] = fileinput.filename()
67            data['test'] = line.split()[-2] + " " + line.split('-- ')[1]
68            data['bp'] = data['test'].rsplit()[-1]
69            data['case'] = 'scalar' if (('Problem 1' in line) or ('Problem 3' in line)
70                                        or ('Problem 5' in line)) else 'vector'
71        elif "Hostname" in line:
72            data['hostname'] = line.split(':')[1].strip()
73        elif "Total ranks" in line:
74            data['num_procs'] = int(line.split(':')[1].strip())
75        elif "Ranks per compute node" in line:
76            data['num_procs_node'] = int(line.split(':')[1].strip())
77        # Backend
78        elif 'libCEED Backend MemType' in line:
79            data['backend_memtype'] = line.split(':')[1].strip()
80        elif 'libCEED Backend' in line:
81            data['backend'] = line.split(':')[1].strip()
82        # P
83        elif 'Basis Nodes' in line:
84            data['degree'] = int(line.split(':')[1]) - 1
85        # Q
86        elif 'Quadrature Points' in line:
87            data['quadrature_pts'] = int(line.split(':')[1])
88        # Total DOFs
89        elif 'Global nodes' in line:
90            data['num_unknowns'] = int(line.split(':')[1])
91            if data['case'] == 'vector':
92                data['num_unknowns'] *= 3
93        elif 'Global DOFs' in line:  # Legacy
94            data['num_unknowns'] = int(line.split(':')[1])
95        # Number of elements
96        elif 'Local Elements' in line:
97            data['num_elem'] = int(
98                line.split(':')[1].split()[0]) * data['num_procs']
99        elif 'DoF per node' in line:
100            data['dof_per_node'] = int(line.split(':')[1])
101        # CG Solve Time
102        elif 'Total KSP Iterations' in line:
103            data['ksp_its'] = int(line.split(':')[1].split()[0])
104        elif 'CG Solve Time' in line:
105            data['time_per_it'] = float(
106                line.split(':')[1].split()[0]) / data['ksp_its']
107        # CG DOFs/Sec
108        elif 'DoFs/Sec in CG' in line or 'DOFs/Sec in CG' in line:
109            data['cg_iteration_dps'] = 1e6 * \
110                float(line.split(':')[1].split()[0])
111        # End of output
112
113    return pd.DataFrame(runs)
114
115
116if __name__ == "__main__":
117    runs = read_logs()
118    print(runs)         # Print summary (about 10 lines)
119    print('First entry:\n', runs.iloc[0])
120    print('Last entry:\n', runs.iloc[-1])
121