xref: /libCEED/benchmarks/postprocess_base.py (revision fc0f7cc68128f3536a834f19d72828f4c59a4439)
1#!/usr/bin/env python3
2
3# Copyright (c) 2017-2024, 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