Package hedge :: Package backends :: Module exec_common
[hide private]
[frames] | no frames]

Source Code for Module hedge.backends.exec_common

  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   
31 -class CPUExecutorBase(object):
32 - def instrument(self):
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):
73 from hedge._internal import lift_flux 74 from pytools import to_uncomplex_dtype 75 lift_flux(fgroup, 76 matrix.astype(to_uncomplex_dtype(field.dtype)), 77 scaling, field, out)
78
79 - def diff_rst(self, op, rst_axis, field):
80 result = self.discr.volume_zeros(dtype=field.dtype) 81 82 from hedge._internal import perform_elwise_operator 83 for eg in self.discr.element_groups: 84 perform_elwise_operator(eg.ranges, eg.ranges, 85 op.matrices(eg)[rst_axis].astype(field.dtype), 86 field, result) 87 88 return result
89
90 - def diff_rst_to_xyz(self, op, rst, result=None):
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):
105 for eg in self.discr.element_groups: 106 from hedge._internal import perform_elwise_scaled_operator 107 perform_elwise_scaled_operator(eg.ranges, eg.ranges, 108 op.coefficients(eg), numpy.asarray(op.matrix(eg), dtype=field.dtype), 109 field, out)
110 111 112 113
114 -class ExecutionMapperBase(hedge.optemplate.Evaluator, 115 hedge.optemplate.BoundOpMapperMixin, 116 hedge.optemplate.LocalOpReducerMixin):
117 - def __init__(self, context, executor):
118 hedge.optemplate.Evaluator.__init__(self, context) 119 self.discr = executor.discr 120 self.executor = executor
121
122 - def map_normal_component(self, expr):
123 return self.discr.boundary_normals(expr.tag)[expr.axis]
124
125 - def map_boundarize(self, op, field_expr):
126 return self.discr.boundarize_volume_field( 127 self.rec(field_expr), tag=op.tag)
128
129 - def map_scalar_parameter(self, expr):
130 return self.context[expr.name]
131 132 133 134 135
136 -class CPUExecutionMapperBase(ExecutionMapperBase):
137 - def map_diff_base(self, op, field_expr):
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
144 - def map_mass_base(self, op, field_expr):
145 field = self.rec(field_expr) 146 147 if isinstance(field, (float, int)) and field == 0: 148 return 0 149 150 out = self.discr.volume_zeros() 151 self.executor.do_mass(op, field, out) 152 return out
153
154 - def map_elementwise_max(self, op, field_expr):
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
164 - def map_call(self, expr):
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