예제 #1
0
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
예제 #2
0
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
예제 #3
0
    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, []
예제 #4
0
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
예제 #5
0
    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, []
예제 #6
0
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