Coverage for pySDC/core/hooks.py: 98%
54 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 logging
2from collections import namedtuple
5# metadata with defaults
6meta_data = {
7 'process': None,
8 'process_sweeper': None,
9 'time': None,
10 'level': None,
11 'iter': None,
12 'sweep': None,
13 'type': None,
14 'num_restarts': None,
15}
16Entry = namedtuple('Entry', meta_data.keys())
19# noinspection PyUnusedLocal,PyShadowingBuiltins,PyShadowingNames
20class Hooks(object):
21 """
22 Hook class to contain the functions called during the controller runs (e.g. for calling user-routines)
24 When deriving a custom hook from this class make sure to always call the parent method using e.g.
25 `super().post_step(step, level_number)`. Otherwise bugs may arise when using `filer_recomputed` from the stats
26 helper for post processing.
28 Attributes:
29 logger: logger instance for output
30 __num_restarts (int): number of restarts of the current step
31 __stats (dict): dictionary for gathering the statistics of a run
32 entry (namedtuple): statistics entry containing all information to identify the value
33 """
35 entry = Entry
36 meta_data = meta_data
38 def __init__(self):
39 """
40 Initialization routine
41 """
42 self.__num_restarts = 0
44 self.logger = logging.getLogger('hooks')
46 # create statistics and entry elements
47 self.__stats = {}
49 def add_to_stats(self, value, **kwargs):
50 """
51 Routine to add data to the statistics dict. Please supply the metadata as keyword arguments in accordance with
52 the entry class.
54 Args:
55 value: the actual data
56 """
57 # create named tuple for the key and add to dict
58 meta = {
59 **self.meta_data,
60 **kwargs,
61 'num_restarts': self.__num_restarts,
62 }
63 self.__stats[self.entry(**meta)] = value
65 def increment_stats(self, value, initialize=None, **kwargs):
66 """
67 Routine to increment data to the statistics dict. If the data is not yet created, it will be initialized to
68 initialize if applicable and to value otherwise. Please supply metadata as keyword arguments in accordance with
69 the entry class.
71 Args:
72 value: the actual data
73 initialize: if supplied and data does not exist already, this will be used over value
74 """
75 meta = {
76 **meta_data,
77 **kwargs,
78 'num_restarts': self.__num_restarts,
79 }
80 key = self.entry(**meta)
81 if key in self.__stats.keys():
82 self.__stats[key] += value
83 elif initialize is not None:
84 self.__stats[key] = initialize
85 else:
86 self.__stats[key] = value
88 def return_stats(self):
89 """
90 Getter for the stats
92 Returns:
93 dict: stats
94 """
95 return self.__stats
97 def reset_stats(self):
98 """
99 Function to reset the stats for multiple runs
100 """
101 self.__stats = {}
103 def pre_setup(self, step, level_number):
104 """
105 Default routine called before setup starts
107 Args:
108 step (pySDC.Step.step): the current step
109 level_number (int): the current level number
110 """
111 self.__num_restarts = step.status.get('restarts_in_a_row') if step is not None else 0
113 def pre_run(self, step, level_number):
114 """
115 Default routine called before time-loop starts
117 Args:
118 step (pySDC.Step.step): the current step
119 level_number (int): the current level number
120 """
121 self.__num_restarts = step.status.get('restarts_in_a_row') if step is not None else 0
123 def pre_predict(self, step, level_number):
124 """
125 Default routine called before predictor starts
127 Args:
128 step (pySDC.Step.step): the current step
129 level_number (int): the current level number
130 """
131 self.__num_restarts = step.status.get('restarts_in_a_row') if step is not None else 0
133 def pre_step(self, step, level_number):
134 """
135 Hook called before each step
137 Args:
138 step (pySDC.Step.step): the current step
139 level_number (int): the current level number
140 """
141 self.__num_restarts = step.status.get('restarts_in_a_row') if step is not None else 0
143 def pre_iteration(self, step, level_number):
144 """
145 Default routine called before iteration starts
147 Args:
148 step (pySDC.Step.step): the current step
149 level_number (int): the current level number
150 """
151 self.__num_restarts = step.status.get('restarts_in_a_row') if step is not None else 0
153 def pre_sweep(self, step, level_number):
154 """
155 Default routine called before sweep starts
157 Args:
158 step (pySDC.Step.step): the current step
159 level_number (int): the current level number
160 """
161 self.__num_restarts = step.status.get('restarts_in_a_row') if step is not None else 0
163 def pre_comm(self, step, level_number):
164 """
165 Default routine called before communication starts
167 Args:
168 step (pySDC.Step.step): the current step
169 level_number (int): the current level number
170 """
171 self.__num_restarts = step.status.get('restarts_in_a_row') if step is not None else 0
173 def post_comm(self, step, level_number, add_to_stats=False):
174 """
175 Default routine called after each communication
177 Args:
178 step (pySDC.Step.step): the current step
179 level_number (int): the current level number
180 add_to_stats (bool): set if result should go to stats object
181 """
182 self.__num_restarts = step.status.get('restarts_in_a_row') if step is not None else 0
184 def post_sweep(self, step, level_number):
185 """
186 Default routine called after each sweep
188 Args:
189 step (pySDC.Step.step): the current step
190 level_number (int): the current level number
191 """
192 self.__num_restarts = step.status.get('restarts_in_a_row') if step is not None else 0
194 def post_iteration(self, step, level_number):
195 """
196 Default routine called after each iteration
198 Args:
199 step (pySDC.Step.step): the current step
200 level_number (int): the current level number
201 """
202 self.__num_restarts = step.status.get('restarts_in_a_row') if step is not None else 0
204 def post_step(self, step, level_number):
205 """
206 Default routine called after each step or block
208 Args:
209 step (pySDC.Step.step): the current step
210 level_number (int): the current level number
211 """
212 self.__num_restarts = step.status.get('restarts_in_a_row') if step is not None else 0
214 def post_predict(self, step, level_number):
215 """
216 Default routine called after each predictor
218 Args:
219 step (pySDC.Step.step): the current step
220 level_number (int): the current level number
221 """
222 self.__num_restarts = step.status.get('restarts_in_a_row') if step is not None else 0
224 def post_run(self, step, level_number):
225 """
226 Default routine called after each run
228 Args:
229 step (pySDC.Step.step): the current step
230 level_number (int): the current level number
231 """
232 self.__num_restarts = step.status.get('restarts_in_a_row') if step is not None else 0
234 def post_setup(self, step, level_number):
235 """
236 Default routine called after setup
238 Args:
239 step (pySDC.Step.step): the current step
240 level_number (int): the current level number
241 """
242 self.__num_restarts = step.status.get('restarts_in_a_row') if step is not None else 0