1 """Just-in-time compiling backend."""
2
3 from __future__ import division
4
5 __copyright__ = "Copyright (C) 2008 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 hedge.discretization
26 import hedge.optemplate
27 from pytools import memoize_method
28 from hedge.compiler import OperatorCompilerBase, FluxBatchAssign, \
29 Assign
36 __slots__ = ["toolchain"]
37
40
41 comment = "compiled"
42
43 @memoize_method
45 discr = executor.discr
46
47 if self.flop_count() > 500:
48
49 if "jit_dont_optimize_large_exprs" in discr.debug:
50 toolchain = discr.toolchain.with_optimization_level(0)
51 else:
52 toolchain = discr.toolchain.with_optimization_level(1)
53 else:
54 toolchain = discr.toolchain
55
56 from hedge.backends.vector_expr import \
57 VectorExpressionInfo, simple_result_dtype_getter
58 from hedge.backends.jit.vector_expr import CompiledVectorExpression
59 return CompiledVectorExpression(
60 [VectorExpressionInfo(
61 name=name,
62 expr=expr,
63 do_not_return=dnr)
64 for name, expr, dnr in zip(
65 self.names, self.exprs, self.do_not_return)],
66 result_dtype_getter=simple_result_dtype_getter,
67 toolchain=toolchain,
68 wait_on_error="jit_wait_on_compile_error" in discr.debug)
69
73
74
75 @memoize_method
92
93 @memoize_method
95 from hedge.backends.jit.flux import \
96 get_interior_flux_mod, \
97 get_boundary_flux_mod
98
99 if not self.is_boundary:
100 mod = get_interior_flux_mod(
101 self.fluxes, self.flux_var_info,
102 discr, dtype)
103
104 if discr.instrumented:
105 from hedge.tools import time_count_flop, gather_flops
106 mod.gather_flux = \
107 time_count_flop(
108 mod.gather_flux,
109 discr.gather_timer,
110 discr.gather_counter,
111 discr.gather_flop_counter,
112 len(self.fluxes)
113 * gather_flops(discr)
114 * len(self.flux_var_info.arg_names))
115
116 else:
117 mod = get_boundary_flux_mod(
118 self.fluxes, self.flux_var_info, discr, dtype)
119
120 if discr.instrumented:
121 from pytools.log import time_and_count_function
122 mod.gather_flux = time_and_count_function(
123 mod.gather_flux, discr.gather_timer)
124
125 return mod
126
134 return hash(self.__class__)
135
138
140 return (other.__class__ == self.__class__)
141
145
147 return "boundary(%s)" % self.tag
148
150 return hash((self.__class__, self.tag))
151
153 return (other.__class__ == self.__class__
154 and other.tag == self.tag)
155
164
174
175 def get_flux_deps(op_binding):
176 if isinstance(op_binding.field, BoundaryPair):
177 bpair = op_binding.field
178 return get_deps(bpair.field) | get_deps(bpair.bfield)
179 else:
180 return get_deps(op_binding.field)
181
182 def get_flux_kind(op_binding):
183 if isinstance(op_binding.field, BoundaryPair):
184 return BoundaryFluxKind(op_binding.field.tag)
185 else:
186 return InteriorFluxKind()
187
188 return [self.FluxRecord(
189 flux_expr=flux_binding,
190 kind=get_flux_kind(flux_binding),
191 dependencies=get_flux_deps(flux_binding))
192 for flux_binding in FluxCollector()(expr)]
193
197
204
205
213
220
227
228
234