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