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