1 """Code for operator execution shared among multiple backends."""
2
3 from __future__ import division
4
5 __copyright__ = "Copyright (C) 2007 Andreas Kloeckner"
6
7 __license__ = """
8 This program is free software: you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation, either version 3 of the License, or
11 (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see U{http://www.gnu.org/licenses/}.
20 """
21
22
23
24
25 import numpy
26 import hedge.optemplate
27
28
29
30
33 discr = self.discr
34 assert discr.instrumented
35
36 from pytools.log import time_and_count_function
37 from hedge.tools import time_count_flop
38
39 from hedge.tools import \
40 diff_rst_flops, diff_rescale_one_flops, mass_flops
41
42 self.diff_rst = \
43 time_count_flop(
44 self.diff_rst,
45 discr.diff_timer,
46 discr.diff_counter,
47 discr.diff_flop_counter,
48 diff_rst_flops(discr))
49
50 self.diff_rst_to_xyz = \
51 time_count_flop(
52 self.diff_rst_to_xyz,
53 discr.diff_timer,
54 discr.diff_counter,
55 discr.diff_flop_counter,
56 diff_rescale_one_flops(discr))
57
58 self.do_mass = \
59 time_count_flop(
60 self.do_mass,
61 discr.mass_timer,
62 discr.mass_counter,
63 discr.mass_flop_counter,
64 mass_flops(discr))
65
66 self.lift_flux = \
67 time_and_count_function(
68 self.lift_flux,
69 discr.lift_timer,
70 discr.lift_counter)
71
72 - def lift_flux(self, fgroup, matrix, scaling, field, out):
78
79 - def diff_rst(self, op, rst_axis, field):
89
91 from hedge._internal import perform_elwise_scale
92
93 if result is None:
94 result = self.discr.volume_zeros(dtype=rst[0].dtype)
95
96 for rst_axis in range(self.discr.dimensions):
97 for eg in self.discr.element_groups:
98 perform_elwise_scale(eg.ranges,
99 op.coefficients(eg)[op.xyz_axis][rst_axis],
100 rst[rst_axis], result)
101
102 return result
103
104 - def do_mass(self, op, field, out):
110
111
112
113
114 -class ExecutionMapperBase(hedge.optemplate.Evaluator,
115 hedge.optemplate.BoundOpMapperMixin,
116 hedge.optemplate.LocalOpReducerMixin):
131
132
133
134
135
138 field = self.rec(field_expr)
139
140 out = self.discr.volume_zeros()
141 self.executor.diff_xyz(self, op, field_expr, field, out)
142 return out
143
153
155 from hedge._internal import perform_elwise_max
156 field = self.rec(field_expr)
157
158 out = self.discr.volume_zeros()
159 for eg in self.discr.element_groups:
160 perform_elwise_max(eg.ranges, field, out)
161
162 return out
163
165 from pymbolic.primitives import Variable
166 assert isinstance(expr.function, Variable)
167 func_name = expr.function.name
168
169 try:
170 func = self.discr.exec_functions[func_name]
171 except KeyError:
172 func = getattr(numpy, expr.function.name)
173
174 return func(*[self.rec(p) for p in expr.parameters])
175