1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185
|
# Copyright (C) 2018 Michal Habera
#
# This file is part of DOLFINx (https://www.fenicsproject.org)
#
# SPDX-License-Identifier: LGPL-3.0-or-later
"""General tools for timing and configuration."""
import datetime
import functools
from dolfinx import cpp as _cpp
from dolfinx.cpp.common import (
IndexMap,
git_commit_hash,
has_adios2,
has_complex_ufcx_kernels,
has_debug,
has_kahip,
has_parmetis,
has_petsc,
has_petsc4py,
has_ptscotch,
has_slepc,
ufcx_signature,
)
__all__ = [
"IndexMap",
"Reduction",
"Timer",
"git_commit_hash",
"has_adios2",
"has_complex_ufcx_kernels",
"has_debug",
"has_kahip",
"has_parmetis",
"has_petsc",
"has_petsc4py",
"has_ptscotch",
"has_slepc",
"list_timings",
"timed",
"timing",
"ufcx_signature",
]
Reduction = _cpp.common.Reduction
def timing(task: str) -> tuple[int, datetime.timedelta]:
"""Return the logged elapsed time.
Timing data is for the calling process.
Arguments:
task: The task name using when logging the time.
Returns:
(number of times logged, total wall time)
"""
return _cpp.common.timing(task)
def list_timings(comm, reduction=Reduction.max):
"""Print out a summary of all Timer measurements.
When used in parallel, a reduction is applied across all processes.
By default, the maximum time is shown.
"""
_cpp.common.list_timings(comm, reduction)
class Timer:
"""A timer for timing section of code.
The recommended usage is with a context manager.
Example:
With a context manager, the timer is started when entering
and stopped at exit. With a named :class:`Timer`::
with Timer(\"Some costly operation\"):
costly_call_1()
costly_call_2()
delta = timing(\"Some costly operation\")
print(delta)
or with an un-named :class:`Timer`::
with Timer() as t:
costly_call_1()
costly_call_2()
print(f\"Elapsed time: {t.elapsed()}\")
Example:
It is possible to start and stop a timer explicitly::
t = Timer(\"Some costly operation\")
costly_call()
delta = t.stop()
and retrieve timing data using::
delta = t.elapsed()
To flush the timing data for a named :class:`Timer` to the logger,
the timer should be stopped and flushed::
t.stop()
t.flush()
Timings are stored globally (if task name is given) and once flushed
(if used without a context manager) may be printed using functions
:func:`timing` and :func:`list_timings`, e.g.::
list_timings(comm)
"""
_cpp_object: _cpp.common.Timer
def __init__(self, name: str | None = None):
"""Create timer.
Args:
name: Identifier to use when storing elapsed time in logger.
"""
self._cpp_object = _cpp.common.Timer(name)
def __enter__(self):
self._cpp_object.start()
return self
def __exit__(self, *args):
self._cpp_object.stop()
self._cpp_object.flush()
def start(self) -> None:
"""Reset elapsed time and (re-)start timer."""
self._cpp_object.start()
def stop(self) -> datetime.timedelta:
"""Stop timer and return elapsed time.
Returns:
Elapsed time.
"""
return self._cpp_object.stop()
def resume(self) -> None:
"""Resume timer."""
self._cpp_object.resume()
def elapsed(self) -> datetime.timedelta:
"""Return elapsed time.
Returns:
Elapsed time.
"""
return self._cpp_object.elapsed()
def flush(self) -> None:
"""Flush timer duration to the logger.
Note:
Timer must have been stopped before flushing.
Timer can be flushed only once. Subsequent calls will have
no effect.
"""
self._cpp_object.flush()
def timed(task: str):
"""Decorator for timing functions."""
def decorator(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
with Timer(task):
return func(*args, **kwargs)
return wrapper
return decorator
|