Coverage for pySDC/helpers/stats_helper.py: 100%
36 statements
« prev ^ index » next coverage.py v7.6.9, created at 2024-12-20 14:51 +0000
« prev ^ index » next coverage.py v7.6.9, created at 2024-12-20 14:51 +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 stats_now = filter_stats(result, time=t)
31 for me in stats_now.keys():
32 restarts[me.type] = max([restarts.get(me.type, 0), me.num_restarts])
34 [
35 [
36 [result.pop(you, None) for you in filter_stats(stats_now, type=type_, num_restarts=i).keys()]
37 for i in range(num_restarts_)
38 ]
39 for type_, num_restarts_ in restarts.items()
40 ]
42 # delete values that were recorded at times that shouldn't be recorded because we performed a different step after the restart
43 if kwargs.get('type', None) != '_recomputed':
44 other_restarted_steps = [
45 key for key, val in filter_stats(stats, type='_recomputed', recomputed=False, comm=comm).items() if val
46 ]
47 for step in other_restarted_steps:
48 [result.pop(me) for me in filter_stats(result, time=step.time).keys()]
50 return result
53def sort_stats(stats, sortby):
54 """
55 Helper function to transform stats dictionary to sorted list of tuples
57 Args:
58 stats (dict): dictionary of statistics
59 sortby (str): string to specify which key to use for sorting
61 Returns:
62 list: list of tuples containing the sortby item and the value
63 """
65 result = []
66 for k, v in stats.items():
67 # convert string to attribute and append key + value to result as tuple
68 item = getattr(k, sortby)
69 result.append((item, v))
71 # sort by first element of the tuple (which is the sortby key) and return
72 sorted_data = sorted(result, key=lambda tup: tup[0])
74 return sorted_data
77def get_list_of_types(stats):
78 """
79 Helper function to get list of types registered in stats
81 Args:
82 stats (dict): dictionary with statistics
84 Returns:
85 list: list of types registered
87 """
89 type_list = []
90 for k, _ in stats.items():
91 if k.type not in type_list:
92 type_list.append(k.type)
93 return type_list
96def get_sorted(stats, sortby='time', **kwargs):
97 """
98 Utility for filtering and sorting stats in a single call. Pass a communicator if using MPI.
99 Keyword arguments are passed to `filter_stats` for filtering.
101 stats (dict): raw statistics from a controller run
102 sortby (str): string to specify which key to use for sorting
104 Returns:
105 list: list of tuples containing the sortby item and the value
106 """
108 return sort_stats(
109 filter_stats(stats, **kwargs),
110 sortby=sortby,
111 )