Coverage for pySDC/helpers/stats_helper.py: 100%
35 statements
« prev ^ index » next coverage.py v7.5.0, created at 2024-04-29 09:02 +0000
« prev ^ index » next coverage.py v7.5.0, created at 2024-04-29 09:02 +0000
1import numpy as np
4def filter_stats(stats, comm=None, recomputed=None, **kwargs):
5 """
6 Helper function to extract data from the dictionary of statistics. Please supply metadata as keyword arguments.
8 Args:
9 stats (dict): raw statistics from a controller run
10 recomputed (bool): filter recomputed values from stats if set to anything other than None
11 comm (mpi4py.MPI.Intracomm): Communicator (or None if not applicable)
13 Returns:
14 dict: dictionary containing only the entries corresponding to the filter
15 """
16 result = {}
17 for k, v in stats.items():
18 if all([k._asdict().get(k2, None) == v2 for k2, v2 in kwargs.items() if v2 is not None] + [True]):
19 result[k] = v
21 if comm is not None:
22 # gather the results across all ranks
23 result = {key: value for sub_result in comm.allgather(result) for key, value in sub_result.items()}
25 if recomputed is not None:
26 # delete values that have been recorded and superseded by similar, but not identical keys
27 times_restarted = np.unique([me.time for me in result.keys() if me.num_restarts > 0])
28 for t in times_restarted:
29 restarts = {}
30 for me in filter_stats(result, time=t).keys():
31 restarts[me.type] = max([restarts.get(me.type, 0), me.num_restarts])
33 [
34 [
35 [result.pop(you, None) for you in filter_stats(result, time=t, type=type_, num_restarts=i).keys()]
36 for i in range(num_restarts_)
37 ]
38 for type_, num_restarts_ in restarts.items()
39 ]
41 # delete values that were recorded at times that shouldn't be recorded because we performed a different step after the restart
42 if kwargs.get('type', None) != '_recomputed':
43 other_restarted_steps = [
44 key for key, val in filter_stats(stats, type='_recomputed', recomputed=False, comm=comm).items() if val
45 ]
46 for step in other_restarted_steps:
47 [result.pop(me) for me in filter_stats(result, time=step.time).keys()]
49 return result
52def sort_stats(stats, sortby):
53 """
54 Helper function to transform stats dictionary to sorted list of tuples
56 Args:
57 stats (dict): dictionary of statistics
58 sortby (str): string to specify which key to use for sorting
60 Returns:
61 list: list of tuples containing the sortby item and the value
62 """
64 result = []
65 for k, v in stats.items():
66 # convert string to attribute and append key + value to result as tuple
67 item = getattr(k, sortby)
68 result.append((item, v))
70 # sort by first element of the tuple (which is the sortby key) and return
71 sorted_data = sorted(result, key=lambda tup: tup[0])
73 return sorted_data
76def get_list_of_types(stats):
77 """
78 Helper function to get list of types registered in stats
80 Args:
81 stats (dict): dictionary with statistics
83 Returns:
84 list: list of types registered
86 """
88 type_list = []
89 for k, _ in stats.items():
90 if k.type not in type_list:
91 type_list.append(k.type)
92 return type_list
95def get_sorted(stats, sortby='time', **kwargs):
96 """
97 Utility for filtering and sorting stats in a single call. Pass a communicator if using MPI.
98 Keyword arguments are passed to `filter_stats` for filtering.
100 stats (dict): raw statistics from a controller run
101 sortby (str): string to specify which key to use for sorting
103 Returns:
104 list: list of tuples containing the sortby item and the value
105 """
107 return sort_stats(
108 filter_stats(stats, **kwargs),
109 sortby=sortby,
110 )