Skip to content

Commit

Permalink
Feature: Add a Python library for log parsing (#499)
Browse files Browse the repository at this point in the history
Add initial log parsing Python library

---------

Co-authored-by: Daniel R. Reynolds <[email protected]>
Co-authored-by: David J. Gardner <[email protected]>
  • Loading branch information
3 people authored Jun 10, 2024
1 parent a995c04 commit 3807ca7
Show file tree
Hide file tree
Showing 15 changed files with 211 additions and 38 deletions.
1 change: 1 addition & 0 deletions doc/developers
1 change: 1 addition & 0 deletions doc/superbuild/source/developers/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ meant for SUNDIALS developers.
pull_requests/index
releases/index
packages/index
sundialsdev/index
appendix/index

.. only:: html
Expand Down
18 changes: 18 additions & 0 deletions doc/superbuild/source/developers/style_guide/SourceCode.rst
Original file line number Diff line number Diff line change
Expand Up @@ -338,6 +338,24 @@ Coding Conventions and Rules
x;`` to ``return(x);``. Note, however, lots of older SUNDIALS source code
uses ``return(x);``.

#. ``SUNLogger`` statements must be in the format:

.. code-block:: c
[log level][rank][scope][label] key1 = value, key2 = value
or if the payload (the part after the label) is a vector/array:

.. code-block:: c
[log level][rank][scope][label] key(:) =
value1
value2
Note that the ``(:)`` is needed for the ``scripts/sundialsdev/logs.py`` Python
utility to understand that the payload is an array.

.. code-block:: c
.. _Style.Formatting:

Expand Down
23 changes: 23 additions & 0 deletions doc/superbuild/source/developers/sundialsdev/index.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
..
-----------------------------------------------------------------------------
SUNDIALS Copyright Start
Copyright (c) 2002-2024, Lawrence Livermore National Security
and Southern Methodist University.
All rights reserved.
See the top-level LICENSE and NOTICE files for details.

SPDX-License-Identifier: BSD-3-Clause
SUNDIALS Copyright End
-----------------------------------------------------------------------------

.. _SUNDIALS_DEV:

sundialsdev Python Library
==========================

This is a Python library of utilities SUNDIALS developer may find useful.
Right now it consists of the following modules:

- ``logs``: this module has functions for parsing logs produced by `SUNLogger`.

8 changes: 8 additions & 0 deletions scripts/sundialsdev/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@

"""
This is a Python library of utilities SUNDIALS developer may find useful.
Right now it consists of the following modules:
- `logs`: this module has functions for parsing logs produced by `SUNLogger`.
"""
120 changes: 120 additions & 0 deletions scripts/sundialsdev/logs.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
#!/usr/bin/env python3
# -----------------------------------------------------------------------------
# Programmer(s): Cody Balos @ LLNL
# -----------------------------------------------------------------------------
# SUNDIALS Copyright Start
# Copyright (c) 2002-2024, Lawrence Livermore National Security
# and Southern Methodist University.
# All rights reserved.
#
# See the top-level LICENSE and NOTICE files for details.
#
# SPDX-License-Identifier: BSD-3-Clause
# SUNDIALS Copyright End
# -----------------------------------------------------------------------------
# Module of Python functions that may be useful to SUNDIALS developers writing
# scripts to parse logs produced by SUNLogger.
# -----------------------------------------------------------------------------

import re
import numpy as np


def parse_logfile_payload(payload, line_number, all_lines, array_indicator="(:)"):
"""
This function parses the payload of in a SUNDIALS log file line
into a dictionary. The payload of a SUNDIALS log file line
is the part after all the [ ] brackets.
"""
kvpstrs = payload.split(",")
kvp_dict = {}
for kvpstr in kvpstrs:
kvp = kvpstr.split("=")
if len(kvp) == 1:
kvp_dict[kvp[0].strip()] = ""
else:
key, value = kvp
values = []
if array_indicator in key:
for line in all_lines[line_number + 1 :]:
if line.startswith("["):
break
values.append(np.double(line))
kvp_dict[key.strip()] = values
else:
kvp_dict[key.strip()] = value.strip()
return kvp_dict


def parse_logfile_line(line, line_number, all_lines):
"""
This function takes a line from a SUNDIALS log file and parses it into a dictionary.
A log file line has the form:
[loglvl][rank][scope][label] key1 = value, key2 = value
Log file payloads can be multiline if they are an array/vector with one value per line.
I.e.
[loglvl][rank][scope][label] y(:)
y_1
y_2
...
"""
pattern = re.compile(r"\[(\w+)\]\[(rank \d+)\]\[(.*)\]\[(.*)\](.*)")
matches = pattern.findall(line)
line_dict = {}
if matches:
line_dict["loglvl"] = matches[0][0]
line_dict["rank"] = matches[0][1]
line_dict["scope"] = matches[0][2]
line_dict["label"] = matches[0][3]
line_dict["payload"] = parse_logfile_payload(
matches[0][4], line_number, all_lines
)
return line_dict


def log_file_to_list(filename, step_scope_txt):
"""
This function takes a debug log file from a SUNDIALS log file and creates a list where
each list element represents an integrator step attempt.
E.g.,
[
[
{
"loglvl": "DEBUG",
"rank": "rank 0",
"scope": "<step_scope_txt>",
"label": "enter-step-attempt-loop",
"payload": {"step": "0", "h": "1e-06", "q": "1", "t_n": "0"},
}, ...
], ...
]
"""
with open(filename, "r") as logfile:
log = []
lines_for_this_step = None
all_lines = logfile.readlines()
for line_number, line in enumerate(all_lines):
line_dict = parse_logfile_line(line.rstrip(), line_number, all_lines)
if not line_dict:
continue
if (
line_dict["scope"] == step_scope_txt
and line_dict["label"] == "enter-step-attempt-loop"
):
if lines_for_this_step is None:
lines_for_this_step = [line_dict]
else:
log.append(lines_for_this_step)
lines_for_this_step = [line_dict]
else:
lines_for_this_step.append(line_dict)
return log


def cvode_debug_file_to_list(filename):
"""
This function takes a debug log file from CVODE and creates a list where
each list entry is a step attempt. See log_file_to_list.
"""
return log_file_to_list(filename, "CVODE::cvStep")
26 changes: 14 additions & 12 deletions src/arkode/arkode_arkstep.c
Original file line number Diff line number Diff line change
Expand Up @@ -1838,20 +1838,20 @@ int arkStep_TakeStep_Z(ARKodeMem ark_mem, sunrealtype* dsmPtr, int* nflagPtr)
#ifdef SUNDIALS_LOGGING_EXTRA_DEBUG
SUNLogger_QueueMsg(ARK_LOGGER, SUN_LOGLEVEL_DEBUG,
"ARKODE::arkStep_TakeStep_Z", "explicit stage",
"z[%i] =", 0);
"z_%i(:) =", 0);
N_VPrintFile(ark_mem->ycur, ARK_LOGGER->debug_fp);
if (step_mem->implicit)
{
SUNLogger_QueueMsg(ARK_LOGGER, SUN_LOGLEVEL_DEBUG,
"ARKODE::arkStep_TakeStep_Z", "implicit RHS",
"Fi[%i] =", 0);
"Fi_%i(:) =", 0);
N_VPrintFile(step_mem->Fi[0], ARK_LOGGER->debug_fp);
}
if (step_mem->explicit)
{
SUNLogger_QueueMsg(ARK_LOGGER, SUN_LOGLEVEL_DEBUG,
"ARKODE::arkStep_TakeStep_Z", "explicit RHS",
"Fe[%i] =", 0);
"Fe_%i(:) =", 0);
N_VPrintFile(step_mem->Fe[0], ARK_LOGGER->debug_fp);
}
#endif
Expand Down Expand Up @@ -1919,7 +1919,8 @@ int arkStep_TakeStep_Z(ARKodeMem ark_mem, sunrealtype* dsmPtr, int* nflagPtr)

#ifdef SUNDIALS_LOGGING_EXTRA_DEBUG
SUNLogger_QueueMsg(ARK_LOGGER, SUN_LOGLEVEL_DEBUG,
"ARKODE::arkStep_TakeStep_Z", "predictor", "zpred =", "");
"ARKODE::arkStep_TakeStep_Z", "predictor",
"zpred(:) =", "");
N_VPrintFile(step_mem->zpred, ARK_LOGGER->debug_fp);
#endif

Expand All @@ -1929,7 +1930,8 @@ int arkStep_TakeStep_Z(ARKodeMem ark_mem, sunrealtype* dsmPtr, int* nflagPtr)

#ifdef SUNDIALS_LOGGING_EXTRA_DEBUG
SUNLogger_QueueMsg(ARK_LOGGER, SUN_LOGLEVEL_DEBUG,
"ARKODE::arkStep_TakeStep_Z", "rhs data", "sdata =", "");
"ARKODE::arkStep_TakeStep_Z", "rhs data",
"sdata(:) =", "");
N_VPrintFile(step_mem->sdata, ARK_LOGGER->debug_fp);
#endif

Expand All @@ -1944,7 +1946,7 @@ int arkStep_TakeStep_Z(ARKodeMem ark_mem, sunrealtype* dsmPtr, int* nflagPtr)
#ifdef SUNDIALS_LOGGING_EXTRA_DEBUG
SUNLogger_QueueMsg(ARK_LOGGER, SUN_LOGLEVEL_DEBUG,
"ARKODE::arkStep_TakeStep_Z", "implicit stage",
"z[%i] =", is);
"z_%i(:) =", is);
N_VPrintFile(ark_mem->ycur, ARK_LOGGER->debug_fp);
#endif

Expand All @@ -1968,7 +1970,7 @@ int arkStep_TakeStep_Z(ARKodeMem ark_mem, sunrealtype* dsmPtr, int* nflagPtr)
#ifdef SUNDIALS_LOGGING_EXTRA_DEBUG
SUNLogger_QueueMsg(ARK_LOGGER, SUN_LOGLEVEL_DEBUG,
"ARKODE::arkStep_TakeStep_Z", "explicit stage",
"z[%i] =", is);
"z_%i(:) =", is);
N_VPrintFile(ark_mem->ycur, ARK_LOGGER->debug_fp);
#endif
}
Expand Down Expand Up @@ -2013,7 +2015,7 @@ int arkStep_TakeStep_Z(ARKodeMem ark_mem, sunrealtype* dsmPtr, int* nflagPtr)
#ifdef SUNDIALS_LOGGING_EXTRA_DEBUG
SUNLogger_QueueMsg(ARK_LOGGER, SUN_LOGLEVEL_DEBUG,
"ARKODE::arkStep_TakeStep_Z", "implicit RHS",
"Fi[%i] =", is);
"Fi_%i(:) =", is);
N_VPrintFile(step_mem->Fi[is], ARK_LOGGER->debug_fp);
#endif

Expand All @@ -2031,7 +2033,7 @@ int arkStep_TakeStep_Z(ARKodeMem ark_mem, sunrealtype* dsmPtr, int* nflagPtr)
#ifdef SUNDIALS_LOGGING_EXTRA_DEBUG
SUNLogger_QueueMsg(ARK_LOGGER, SUN_LOGLEVEL_DEBUG,
"ARKODE::arkStep_TakeStep_Z", "explicit RHS",
"Fe[%i] =", is);
"Fe_%i(:) =", is);
N_VPrintFile(step_mem->Fe[is], ARK_LOGGER->debug_fp);
#endif

Expand All @@ -2050,7 +2052,7 @@ int arkStep_TakeStep_Z(ARKodeMem ark_mem, sunrealtype* dsmPtr, int* nflagPtr)
#ifdef SUNDIALS_LOGGING_EXTRA_DEBUG
SUNLogger_QueueMsg(ARK_LOGGER, SUN_LOGLEVEL_DEBUG,
"ARKODE::arkStep_TakeStep_Z", "M^{-1} implicit RHS",
"Fi[%i] =", is);
"Fi_%i(:) =", is);
N_VPrintFile(step_mem->Fi[is], ARK_LOGGER->debug_fp);
#endif
if (*nflagPtr != ARK_SUCCESS) { return (TRY_AGAIN); }
Expand All @@ -2062,7 +2064,7 @@ int arkStep_TakeStep_Z(ARKodeMem ark_mem, sunrealtype* dsmPtr, int* nflagPtr)
#ifdef SUNDIALS_LOGGING_EXTRA_DEBUG
SUNLogger_QueueMsg(ARK_LOGGER, SUN_LOGLEVEL_DEBUG,
"ARKODE::arkStep_TakeStep_Z", "M^{-1} explicit RHS",
"Fe[%i] =", is);
"Fe_%i(:) =", is);
N_VPrintFile(step_mem->Fe[is], ARK_LOGGER->debug_fp);
#endif
if (*nflagPtr != ARK_SUCCESS) { return (TRY_AGAIN); }
Expand All @@ -2084,7 +2086,7 @@ int arkStep_TakeStep_Z(ARKodeMem ark_mem, sunrealtype* dsmPtr, int* nflagPtr)

#ifdef SUNDIALS_LOGGING_EXTRA_DEBUG
SUNLogger_QueueMsg(ARK_LOGGER, SUN_LOGLEVEL_DEBUG, "ARKODE::arkStep_TakeStep_Z",
"updated solution", "ycur =", "");
"updated solution", "ycur(:) =", "");
N_VPrintFile(ark_mem->ycur, ARK_LOGGER->debug_fp);
#endif

Expand Down
2 changes: 1 addition & 1 deletion src/arkode/arkode_arkstep_nls.c
Original file line number Diff line number Diff line change
Expand Up @@ -425,7 +425,7 @@ int arkStep_Nls(ARKodeMem ark_mem, int nflag)

#ifdef SUNDIALS_LOGGING_EXTRA_DEBUG
SUNLogger_QueueMsg(ARK_LOGGER, SUN_LOGLEVEL_DEBUG, "ARKODE::arkStep_Nls",
"correction", "zcor =", "");
"correction", "zcor(:) =", "");
N_VPrintFile(step_mem->zcor, ARK_LOGGER->debug_fp);
#endif

Expand Down
8 changes: 4 additions & 4 deletions src/arkode/arkode_erkstep.c
Original file line number Diff line number Diff line change
Expand Up @@ -635,10 +635,10 @@ int erkStep_TakeStep(ARKodeMem ark_mem, sunrealtype* dsmPtr, int* nflagPtr)

#ifdef SUNDIALS_LOGGING_EXTRA_DEBUG
SUNLogger_QueueMsg(ARK_LOGGER, SUN_LOGLEVEL_DEBUG, "ARKODE::erkStep_TakeStep",
"stage", "z[0] =", "");
"stage", "z_0(:) =", "");
N_VPrintFile(ark_mem->ycur, ARK_LOGGER->debug_fp);
SUNLogger_QueueMsg(ARK_LOGGER, SUN_LOGLEVEL_DEBUG, "ARKODE::erkStep_TakeStep",
"stage RHS", "F[0] =", "");
"stage RHS", "F_0(:) =", "");
N_VPrintFile(step_mem->F[0], ARK_LOGGER->debug_fp);
#endif

Expand Down Expand Up @@ -704,7 +704,7 @@ int erkStep_TakeStep(ARKodeMem ark_mem, sunrealtype* dsmPtr, int* nflagPtr)

#ifdef SUNDIALS_LOGGING_EXTRA_DEBUG
SUNLogger_QueueMsg(ARK_LOGGER, SUN_LOGLEVEL_DEBUG,
"ARKODE::erkStep_TakeStep", "stage RHS", "F[%i] =", is);
"ARKODE::erkStep_TakeStep", "stage RHS", "F_%i(:) =", is);
N_VPrintFile(step_mem->F[is], ARK_LOGGER->debug_fp);
#endif

Expand All @@ -716,7 +716,7 @@ int erkStep_TakeStep(ARKodeMem ark_mem, sunrealtype* dsmPtr, int* nflagPtr)

#ifdef SUNDIALS_LOGGING_EXTRA_DEBUG
SUNLogger_QueueMsg(ARK_LOGGER, SUN_LOGLEVEL_DEBUG, "ARKODE::erkStep_TakeStep",
"updated solution", "ycur =", "");
"updated solution", "ycur(:) =", "");
N_VPrintFile(ark_mem->ycur, ARK_LOGGER->debug_fp);
#endif

Expand Down
Loading

0 comments on commit 3807ca7

Please sign in to comment.