| Home | Trees | Indices | Help |
|---|
|
|
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
30
31
32
33
34 # compiler stuff --------------------------------------------------------------
35 -class VectorExprAssign(Assign):
36 __slots__ = ["toolchain"]
37
39 return executor.exec_vector_expr_assign
40
41 comment = "compiled"
42
43 @memoize_method
45 discr = executor.discr
46
47 if self.flop_count() > 500:
48 # reduce optimization level for complicated expressions
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 # members: compiled_func, arg_specs, is_boundary
74
75 @memoize_method
77 deps = set()
78
79 from hedge.tools import setify_field as setify
80 from hedge.optemplate import OperatorBinding, BoundaryPair
81 for f in self.fluxes:
82 assert isinstance(f, OperatorBinding)
83 if isinstance(f.field, BoundaryPair):
84 deps |= setify(f.field.field) | setify(f.field.bfield)
85 else:
86 deps |= setify(f.field)
87
88 dep_mapper = self.dep_mapper_factory()
89
90 from pytools import flatten
91 return set(flatten(dep_mapper(dep) for dep in deps))
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
127
128
129
130
131 # flux kinds ------------------------------------------------------------------
132 -class InteriorFluxKind(object):
141
155
164
166 from hedge.optemplate import FluxCollector, BoundaryPair
167 from hedge.tools import is_obj_array
168
169 def get_deps(field):
170 if is_obj_array(field):
171 return set(field)
172 else:
173 return set([field])
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
195 from hedge.optemplate import IdentityMapper
196 return IdentityMapper.map_operator_binding(self, flux_bind)
197
199 from hedge.optemplate import FluxOperatorBase
200 if isinstance(expr.op, FluxOperatorBase):
201 return self.map_planned_flux(expr)
202 else:
203 return OperatorCompilerBase.map_operator_binding(self, expr)
204
205 # flux compilation --------------------------------------------------------
207 if isinstance(kind, BoundaryFluxKind):
208 return self.make_boundary_flux_batch_assign(names, fluxes, kind)
209 elif isinstance(kind, InteriorFluxKind):
210 return self.make_interior_flux_batch_assign(names, fluxes, kind)
211 else:
212 raise ValueError("invalid flux batch kind: %s" % kind)
213
215 from hedge.backends.jit.flux import get_flux_var_info
216 return CompiledFluxBatchAssign(is_boundary=False,
217 names=names, fluxes=fluxes, kind=kind,
218 flux_var_info=get_flux_var_info(fluxes),
219 dep_mapper_factory=self.dep_mapper_factory)
220
222 from hedge.backends.jit.flux import get_flux_var_info
223 return CompiledFluxBatchAssign(is_boundary=True,
224 names=names, fluxes=fluxes, kind=kind,
225 flux_var_info=get_flux_var_info(fluxes),
226 dep_mapper_factory=self.dep_mapper_factory)
227
228 # vector math -------------------------------------------------------------
230 return VectorExprAssign(names=names, exprs=exprs,
231 do_not_return=do_not_return,
232 dep_mapper_factory=self.dep_mapper_factory,
233 priority=priority)
234
| Home | Trees | Indices | Help |
|---|
| Generated by Epydoc 3.0.1 on Sat Aug 29 14:33:50 2009 | http://epydoc.sourceforge.net |