def simple_result_dtype_getter(vector_dtype_map, scalar_dtype_map, const_dtypes): from pytools import common_dtype, match_precision result = common_dtype(vector_dtype_map.values()) scalar_dtypes = scalar_dtype_map.values() + const_dtypes if scalar_dtypes: prec_matched_scalar_dtype = match_precision( common_dtype(scalar_dtypes), dtype_to_match=result) result = common_dtype([result, prec_matched_scalar_dtype]) return result
def exec_flux_batch_assign(self, insn): from pymbolic.primitives import is_zero class ZeroSpec: pass class BoundaryZeros(ZeroSpec): pass class VolumeZeros(ZeroSpec): pass def eval_arg(arg_spec): arg_expr, is_int = arg_spec arg = self.rec(arg_expr) if is_zero(arg): if insn.is_boundary and not is_int: return BoundaryZeros() else: return VolumeZeros() else: return arg args = [ eval_arg(arg_expr) for arg_expr in insn.flux_var_info.arg_specs ] from pytools import common_dtype max_dtype = common_dtype( [a.dtype for a in args if not isinstance(a, ZeroSpec)], self.discr.default_scalar_type) def cast_arg(arg): if isinstance(arg, BoundaryZeros): return self.discr.boundary_zeros(insn.repr_op.boundary_tag, dtype=max_dtype) elif isinstance(arg, VolumeZeros): return self.discr.volume_zeros(dtype=max_dtype) elif isinstance(arg, np.ndarray): return np.asarray(arg, dtype=max_dtype) else: return arg args = [cast_arg(arg) for arg in args] if insn.quadrature_tag is None: if insn.is_boundary: face_groups = self.discr.get_boundary(insn.repr_op.boundary_tag)\ .face_groups else: face_groups = self.discr.face_groups else: if insn.is_boundary: face_groups = self.discr.get_boundary(insn.repr_op.boundary_tag)\ .get_quadrature_info(insn.quadrature_tag).face_groups else: face_groups = self.discr.get_quadrature_info(insn.quadrature_tag) \ .face_groups result = [] for fg in face_groups: # grab module module = insn.get_module(self.discr, max_dtype) func = module.gather_flux # set up argument structure arg_struct = module.ArgStruct() for arg_name, arg in zip(insn.flux_var_info.arg_names, args): setattr(arg_struct, arg_name, arg) for arg_num, scalar_arg_expr in enumerate( insn.flux_var_info.scalar_parameters): setattr(arg_struct, "_scalar_arg_%d" % arg_num, self.rec(scalar_arg_expr)) fof_shape = (fg.face_count * fg.face_length() * fg.element_count(), ) all_fluxes_on_faces = [ np.zeros(fof_shape, dtype=max_dtype) for f in insn.expressions ] for i, fof in enumerate(all_fluxes_on_faces): setattr(arg_struct, "flux%d_on_faces" % i, fof) # make sure everything ended up in Boost.Python attributes # (i.e. empty __dict__) assert not arg_struct.__dict__, arg_struct.__dict__.keys() # perform gather func(fg, arg_struct) # do lift, produce output for name, flux_bdg, fluxes_on_faces in zip(insn.names, insn.expressions, all_fluxes_on_faces): if insn.quadrature_tag is None: if flux_bdg.op.is_lift: mat = fg.ldis_loc.lifting_matrix() scaling = fg.local_el_inverse_jacobians else: mat = fg.ldis_loc.multi_face_mass_matrix() scaling = None else: assert not flux_bdg.op.is_lift mat = fg.ldis_loc_quad_info.multi_face_mass_matrix() scaling = None out = self.discr.volume_zeros(dtype=fluxes_on_faces.dtype) self.executor.lift_flux(fg, mat, scaling, fluxes_on_faces, out) if self.discr.instrumented: from hedge.tools import lift_flops # correct for quadrature, too. self.discr.lift_flop_counter.add(lift_flops(fg)) result.append((name, out)) if not face_groups: # No face groups? Still assign context variables. for name, flux_bdg in zip(insn.names, insn.expressions): result.append((name, self.discr.volume_zeros())) return result, []
def make_linear_comb_kernel(scalar_dtypes, vector_dtypes): from pytools import common_dtype result_dtype = common_dtype(scalar_dtypes+vector_dtypes) return make_linear_comb_kernel_with_result_dtype( result_dtype, scalar_dtypes, vector_dtypes), result_dtype
def exec_flux_batch_assign(self, insn): from pymbolic.primitives import is_zero class ZeroSpec: pass class BoundaryZeros(ZeroSpec): pass class VolumeZeros(ZeroSpec): pass def eval_arg(arg_spec): arg_expr, is_int = arg_spec arg = self.rec(arg_expr) if is_zero(arg): if insn.is_boundary and not is_int: return BoundaryZeros() else: return VolumeZeros() else: return arg args = [eval_arg(arg_expr) for arg_expr in insn.flux_var_info.arg_specs] from pytools import common_dtype max_dtype = common_dtype( [a.dtype for a in args if not isinstance(a, ZeroSpec)], self.discr.default_scalar_type) def cast_arg(arg): if isinstance(arg, BoundaryZeros): return self.discr.boundary_zeros( insn.repr_op.boundary_tag, dtype=max_dtype) elif isinstance(arg, VolumeZeros): return self.discr.volume_zeros( dtype=max_dtype) elif isinstance(arg, np.ndarray): return np.asarray(arg, dtype=max_dtype) else: return arg args = [cast_arg(arg) for arg in args] if insn.quadrature_tag is None: if insn.is_boundary: face_groups = self.discr.get_boundary(insn.repr_op.boundary_tag)\ .face_groups else: face_groups = self.discr.face_groups else: if insn.is_boundary: face_groups = self.discr.get_boundary(insn.repr_op.boundary_tag)\ .get_quadrature_info(insn.quadrature_tag).face_groups else: face_groups = self.discr.get_quadrature_info(insn.quadrature_tag) \ .face_groups result = [] for fg in face_groups: # grab module module = insn.get_module(self.discr, max_dtype) func = module.gather_flux # set up argument structure arg_struct = module.ArgStruct() for arg_name, arg in zip(insn.flux_var_info.arg_names, args): setattr(arg_struct, arg_name, arg) for arg_num, scalar_arg_expr in enumerate( insn.flux_var_info.scalar_parameters): setattr(arg_struct, "_scalar_arg_%d" % arg_num, self.rec(scalar_arg_expr)) fof_shape = (fg.face_count*fg.face_length()*fg.element_count(),) all_fluxes_on_faces = [ np.zeros(fof_shape, dtype=max_dtype) for f in insn.expressions] for i, fof in enumerate(all_fluxes_on_faces): setattr(arg_struct, "flux%d_on_faces" % i, fof) # make sure everything ended up in Boost.Python attributes # (i.e. empty __dict__) assert not arg_struct.__dict__, arg_struct.__dict__.keys() # perform gather func(fg, arg_struct) # do lift, produce output for name, flux_bdg, fluxes_on_faces in zip(insn.names, insn.expressions, all_fluxes_on_faces): if insn.quadrature_tag is None: if flux_bdg.op.is_lift: mat = fg.ldis_loc.lifting_matrix() scaling = fg.local_el_inverse_jacobians else: mat = fg.ldis_loc.multi_face_mass_matrix() scaling = None else: assert not flux_bdg.op.is_lift mat = fg.ldis_loc_quad_info.multi_face_mass_matrix() scaling = None out = self.discr.volume_zeros(dtype=fluxes_on_faces.dtype) self.executor.lift_flux(fg, mat, scaling, fluxes_on_faces, out) if self.discr.instrumented: from hedge.tools import lift_flops # correct for quadrature, too. self.discr.lift_flop_counter.add(lift_flops(fg)) result.append((name, out)) if not face_groups: # No face groups? Still assign context variables. for name, flux_bdg in zip(insn.names, insn.expressions): result.append((name, self.discr.volume_zeros())) return result, []
def make_linear_comb_kernel(scalar_dtypes, vector_dtypes): from pytools import common_dtype result_dtype = common_dtype(scalar_dtypes + vector_dtypes) return make_linear_comb_kernel_with_result_dtype( result_dtype, scalar_dtypes, vector_dtypes), result_dtype