Skip to content

Commit 31d83a2

Browse files
Implemented hook for measuring GPU times (#502)
1 parent ca01ecf commit 31d83a2

File tree

3 files changed

+343
-252
lines changed

3 files changed

+343
-252
lines changed

pySDC/core/controller.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
from pySDC.helpers.pysdc_helper import FrozenClass
88
from pySDC.implementations.convergence_controller_classes.check_convergence import CheckConvergence
99
from pySDC.implementations.hooks.default_hook import DefaultHooks
10+
from pySDC.implementations.hooks.log_timings import CPUTimings
1011

1112

1213
# short helper class to add params as attributes
@@ -43,7 +44,7 @@ def __init__(self, controller_params, description, useMPI=None):
4344

4445
# check if we have a hook on this list. If not, use default class.
4546
self.__hooks = []
46-
hook_classes = [DefaultHooks]
47+
hook_classes = [DefaultHooks, CPUTimings]
4748
user_hooks = controller_params.get('hook_class', [])
4849
hook_classes += user_hooks if type(user_hooks) == list else [user_hooks]
4950
[self.add_hook(hook) for hook in hook_classes]

pySDC/implementations/hooks/default_hook.py

Lines changed: 0 additions & 251 deletions
Original file line numberDiff line numberDiff line change
@@ -5,155 +5,8 @@
55
class DefaultHooks(Hooks):
66
"""
77
Hook class to contain the functions called during the controller runs (e.g. for calling user-routines)
8-
9-
Attributes:
10-
__t0_setup (float): private variable to get starting time of setup
11-
__t0_run (float): private variable to get starting time of the run
12-
__t0_predict (float): private variable to get starting time of the predictor
13-
__t0_step (float): private variable to get starting time of the step
14-
__t0_iteration (float): private variable to get starting time of the iteration
15-
__t0_sweep (float): private variable to get starting time of the sweep
16-
__t0_comm (list): private variable to get starting time of the communication
17-
__t1_run (float): private variable to get end time of the run
18-
__t1_predict (float): private variable to get end time of the predictor
19-
__t1_step (float): private variable to get end time of the step
20-
__t1_iteration (float): private variable to get end time of the iteration
21-
__t1_sweep (float): private variable to get end time of the sweep
22-
__t1_setup (float): private variable to get end time of setup
23-
__t1_comm (list): private variable to hold timing of the communication (!)
248
"""
259

26-
def __init__(self):
27-
super().__init__()
28-
self.__t0_setup = None
29-
self.__t0_run = None
30-
self.__t0_predict = None
31-
self.__t0_step = None
32-
self.__t0_iteration = None
33-
self.__t0_sweep = None
34-
self.__t0_comm = []
35-
self.__t1_run = None
36-
self.__t1_predict = None
37-
self.__t1_step = None
38-
self.__t1_iteration = None
39-
self.__t1_sweep = None
40-
self.__t1_setup = None
41-
self.__t1_comm = []
42-
43-
def pre_setup(self, step, level_number):
44-
"""
45-
Default routine called before setup starts
46-
47-
Args:
48-
step (pySDC.Step.step): the current step
49-
level_number (int): the current level number
50-
"""
51-
super().pre_setup(step, level_number)
52-
self.__t0_setup = time.perf_counter()
53-
54-
def pre_run(self, step, level_number):
55-
"""
56-
Default routine called before time-loop starts
57-
58-
Args:
59-
step (pySDC.Step.step): the current step
60-
level_number (int): the current level number
61-
"""
62-
super().pre_run(step, level_number)
63-
self.__t0_run = time.perf_counter()
64-
65-
def pre_predict(self, step, level_number):
66-
"""
67-
Default routine called before predictor starts
68-
69-
Args:
70-
step (pySDC.Step.step): the current step
71-
level_number (int): the current level number
72-
"""
73-
super().pre_predict(step, level_number)
74-
self.__t0_predict = time.perf_counter()
75-
76-
def pre_step(self, step, level_number):
77-
"""
78-
Hook called before each step
79-
80-
Args:
81-
step (pySDC.Step.step): the current step
82-
level_number (int): the current level number
83-
"""
84-
super().pre_step(step, level_number)
85-
self.__t0_step = time.perf_counter()
86-
87-
def pre_iteration(self, step, level_number):
88-
"""
89-
Default routine called before iteration starts
90-
91-
Args:
92-
step (pySDC.Step.step): the current step
93-
level_number (int): the current level number
94-
"""
95-
super().pre_iteration(step, level_number)
96-
self.__t0_iteration = time.perf_counter()
97-
98-
def pre_sweep(self, step, level_number):
99-
"""
100-
Default routine called before sweep starts
101-
102-
Args:
103-
step (pySDC.Step.step): the current step
104-
level_number (int): the current level number
105-
"""
106-
super().pre_sweep(step, level_number)
107-
self.__t0_sweep = time.perf_counter()
108-
109-
def pre_comm(self, step, level_number):
110-
"""
111-
Default routine called before communication starts
112-
113-
Args:
114-
step (pySDC.Step.step): the current step
115-
level_number (int): the current level number
116-
"""
117-
super().pre_comm(step, level_number)
118-
if len(self.__t0_comm) >= level_number + 1:
119-
self.__t0_comm[level_number] = time.perf_counter()
120-
else:
121-
while len(self.__t0_comm) < level_number:
122-
self.__t0_comm.append(None)
123-
self.__t0_comm.append(time.perf_counter())
124-
while len(self.__t1_comm) <= level_number:
125-
self.__t1_comm.append(0.0)
126-
assert len(self.__t0_comm) == level_number + 1
127-
assert len(self.__t1_comm) == level_number + 1
128-
129-
def post_comm(self, step, level_number, add_to_stats=False):
130-
"""
131-
Default routine called after each communication
132-
133-
Args:
134-
step (pySDC.Step.step): the current step
135-
level_number (int): the current level number
136-
add_to_stats (bool): set if result should go to stats object
137-
"""
138-
super().post_comm(step, level_number)
139-
assert len(self.__t1_comm) >= level_number + 1
140-
self.__t1_comm[level_number] += time.perf_counter() - self.__t0_comm[level_number]
141-
142-
if add_to_stats:
143-
L = step.levels[level_number]
144-
145-
self.add_to_stats(
146-
process=step.status.slot,
147-
process_sweeper=L.sweep.rank,
148-
time=L.time,
149-
level=L.level_index,
150-
iter=step.status.iter,
151-
sweep=L.status.sweep,
152-
type='timing_comm',
153-
value=self.__t1_comm[level_number],
154-
)
155-
self.__t1_comm[level_number] = 0.0
156-
15710
def post_sweep(self, step, level_number):
15811
"""
15912
Default routine called after each sweep
@@ -163,7 +16,6 @@ def post_sweep(self, step, level_number):
16316
level_number (int): the current level number
16417
"""
16518
super().post_sweep(step, level_number)
166-
self.__t1_sweep = time.perf_counter()
16719

16820
L = step.levels[level_number]
16921

@@ -188,16 +40,6 @@ def post_sweep(self, step, level_number):
18840
type='residual_post_sweep',
18941
value=L.status.residual,
19042
)
191-
self.add_to_stats(
192-
process=step.status.slot,
193-
process_sweeper=L.sweep.rank,
194-
time=L.time,
195-
level=L.level_index,
196-
iter=step.status.iter,
197-
sweep=L.status.sweep,
198-
type='timing_sweep',
199-
value=self.__t1_sweep - self.__t0_sweep,
200-
)
20143

20244
def post_iteration(self, step, level_number):
20345
"""
@@ -208,7 +50,6 @@ def post_iteration(self, step, level_number):
20850
level_number (int): the current level number
20951
"""
21052
super().post_iteration(step, level_number)
211-
self.__t1_iteration = time.perf_counter()
21253

21354
L = step.levels[level_number]
21455

@@ -222,16 +63,6 @@ def post_iteration(self, step, level_number):
22263
type='residual_post_iteration',
22364
value=L.status.residual,
22465
)
225-
self.add_to_stats(
226-
process=step.status.slot,
227-
process_sweeper=L.sweep.rank,
228-
time=L.time,
229-
level=L.level_index,
230-
iter=step.status.iter,
231-
sweep=L.status.sweep,
232-
type='timing_iteration',
233-
value=self.__t1_iteration - self.__t0_iteration,
234-
)
23566

23667
def post_step(self, step, level_number):
23768
"""
@@ -242,20 +73,9 @@ def post_step(self, step, level_number):
24273
level_number (int): the current level number
24374
"""
24475
super().post_step(step, level_number)
245-
self.__t1_step = time.perf_counter()
24676

24777
L = step.levels[level_number]
24878

249-
self.add_to_stats(
250-
process=step.status.slot,
251-
process_sweeper=L.sweep.rank,
252-
time=L.time,
253-
level=L.level_index,
254-
iter=step.status.iter,
255-
sweep=L.status.sweep,
256-
type='timing_step',
257-
value=self.__t1_step - self.__t0_step,
258-
)
25979
self.add_to_stats(
26080
process=step.status.slot,
26181
process_sweeper=L.sweep.rank,
@@ -289,74 +109,3 @@ def post_step(self, step, level_number):
289109
value=step.status.get('restart'),
290110
process_sweeper=-1,
291111
)
292-
293-
def post_predict(self, step, level_number):
294-
"""
295-
Default routine called after each predictor
296-
297-
Args:
298-
step (pySDC.Step.step): the current step
299-
level_number (int): the current level number
300-
"""
301-
super().post_predict(step, level_number)
302-
self.__t1_predict = time.perf_counter()
303-
304-
L = step.levels[level_number]
305-
306-
self.add_to_stats(
307-
process=step.status.slot,
308-
process_sweeper=L.sweep.rank,
309-
time=L.time,
310-
level=L.level_index,
311-
iter=step.status.iter,
312-
sweep=L.status.sweep,
313-
type='timing_predictor',
314-
value=self.__t1_predict - self.__t0_predict,
315-
)
316-
317-
def post_run(self, step, level_number):
318-
"""
319-
Default routine called after each run
320-
321-
Args:
322-
step (pySDC.Step.step): the current step
323-
level_number (int): the current level number
324-
"""
325-
super().post_run(step, level_number)
326-
self.__t1_run = time.perf_counter()
327-
328-
L = step.levels[level_number]
329-
330-
self.add_to_stats(
331-
process=step.status.slot,
332-
process_sweeper=L.sweep.rank,
333-
time=L.time,
334-
level=L.level_index,
335-
iter=step.status.iter,
336-
sweep=L.status.sweep,
337-
type='timing_run',
338-
value=self.__t1_run - self.__t0_run,
339-
)
340-
self.logger.info(f'Finished run after {self.__t1_run - self.__t0_run:.2f}s')
341-
342-
def post_setup(self, step, level_number):
343-
"""
344-
Default routine called after setup
345-
346-
Args:
347-
step (pySDC.Step.step): the current step
348-
level_number (int): the current level number
349-
"""
350-
super().post_setup(step, level_number)
351-
self.__t1_setup = time.perf_counter()
352-
353-
self.add_to_stats(
354-
process=-1,
355-
process_sweeper=-1,
356-
time=-1,
357-
level=-1,
358-
iter=-1,
359-
sweep=-1,
360-
type='timing_setup',
361-
value=self.__t1_setup - self.__t0_setup,
362-
)

0 commit comments

Comments
 (0)