Exemple #1
0
    def instrument(self):
        discr = self.discr
        assert discr.instrumented

        from pytools.log import time_and_count_function
        from hedge.tools import time_count_flop

        from hedge.tools import diff_rst_flops, mass_flops

        if discr.quad_min_degrees:
            from warnings import warn
            warn("flop counts for quadrature may be wrong")

        self.diff_rst = \
                time_count_flop(
                        self.diff_rst,
                        discr.diff_timer,
                        discr.diff_counter,
                        discr.diff_flop_counter,
                        diff_rst_flops(discr))

        self.do_elementwise_linear = \
                time_count_flop(
                        self.do_elementwise_linear,
                        discr.el_local_timer,
                        discr.el_local_counter,
                        discr.el_local_flop_counter,
                        mass_flops(discr))

        self.lift_flux = \
                time_and_count_function(
                        self.lift_flux,
                        discr.lift_timer,
                        discr.lift_counter)
Exemple #2
0
    def instrument(self):
        discr = self.discr
        assert discr.instrumented

        from pytools.log import time_and_count_function
        from hedge.tools import time_count_flop

        from hedge.tools import diff_rst_flops, mass_flops

        if discr.quad_min_degrees:
            from warnings import warn
            warn("flop counts for quadrature may be wrong")

        self.diff_rst = \
                time_count_flop(
                        self.diff_rst,
                        discr.diff_timer,
                        discr.diff_counter,
                        discr.diff_flop_counter,
                        diff_rst_flops(discr))

        self.do_elementwise_linear = \
                time_count_flop(
                        self.do_elementwise_linear,
                        discr.el_local_timer,
                        discr.el_local_counter,
                        discr.el_local_flop_counter,
                        mass_flops(discr))

        self.lift_flux = \
                time_and_count_function(
                        self.lift_flux,
                        discr.lift_timer,
                        discr.lift_counter)
Exemple #3
0
    def get_module(self, discr, dtype):
        from hedge.backends.jit.flux import get_interior_flux_mod, get_boundary_flux_mod

        if not self.is_boundary:
            mod = get_interior_flux_mod(self.expressions, self.flux_var_info, discr, dtype)

            if discr.instrumented:
                from hedge.tools import time_count_flop, gather_flops

                mod.gather_flux = time_count_flop(
                    mod.gather_flux,
                    discr.gather_timer,
                    discr.gather_counter,
                    discr.gather_flop_counter,
                    len(self.expressions)
                    * gather_flops(discr, self.quadrature_tag)
                    * len(self.flux_var_info.arg_names),
                )

        else:
            mod = get_boundary_flux_mod(self.expressions, self.flux_var_info, discr, dtype)

            if discr.instrumented:
                from pytools.log import time_and_count_function

                mod.gather_flux = time_and_count_function(mod.gather_flux, discr.gather_timer)

        return mod
Exemple #4
0
    def get_module(self, discr, dtype):
        from hedge.backends.jit.flux import \
                get_interior_flux_mod, \
                get_boundary_flux_mod

        if not self.is_boundary:
            mod = get_interior_flux_mod(self.expressions, self.flux_var_info,
                                        discr, dtype)

            if discr.instrumented:
                from hedge.tools import time_count_flop, gather_flops
                mod.gather_flux = \
                        time_count_flop(
                                mod.gather_flux,
                                discr.gather_timer,
                                discr.gather_counter,
                                discr.gather_flop_counter,
                                len(self.expressions)
                                * gather_flops(discr, self.quadrature_tag)
                                * len(self.flux_var_info.arg_names))

        else:
            mod = get_boundary_flux_mod(self.expressions, self.flux_var_info,
                                        discr, dtype)

            if discr.instrumented:
                from pytools.log import time_and_count_function
                mod.gather_flux = time_and_count_function(
                    mod.gather_flux, discr.gather_timer)

        return mod
Exemple #5
0
    def make_diff(self, elgroup, dtype, shape):
        """
        :param shape: If non-square, the resulting code takes two element_ranges
          arguments and supports non-square matrices.
        """
        from hedge._internal import UniformElementRanges

        assert isinstance(elgroup.ranges, UniformElementRanges)

        ldis = elgroup.local_discretization
        discr = self.discr
        from cgen import (
            FunctionDeclaration,
            FunctionBody,
            Typedef,
            Const,
            Reference,
            Value,
            POD,
            Statement,
            Include,
            Line,
            Block,
            Initializer,
            Assign,
            For,
            If,
            Define,
        )

        from pytools import to_uncomplex_dtype

        from codepy.bpl import BoostPythonModule

        mod = BoostPythonModule()

        # {{{ preamble
        S = Statement
        mod.add_to_preamble([Include("hedge/volume_operators.hpp"), Include("boost/foreach.hpp")])

        mod.add_to_module(
            [
                S("namespace ublas = boost::numeric::ublas"),
                S("using namespace hedge"),
                S("using namespace pyublas"),
                Line(),
                Define("ROW_COUNT", shape[0]),
                Define("COL_COUNT", shape[1]),
                Define("DIMENSIONS", discr.dimensions),
                Line(),
                Typedef(POD(dtype, "value_type")),
                Typedef(POD(to_uncomplex_dtype(dtype), "uncomplex_type")),
            ]
        )

        fdecl = FunctionDeclaration(
            Value("void", "diff"),
            [
                Const(Reference(Value("uniform_element_ranges", "from_ers"))),
                Const(Reference(Value("uniform_element_ranges", "to_ers"))),
                Value("numpy_array<value_type>", "field"),
            ]
            + [Value("ublas::matrix<uncomplex_type>", "diffmat_rst%d" % rst) for rst in range(discr.dimensions)]
            + [Value("numpy_array<value_type>", "result%d" % i) for i in range(discr.dimensions)],
        )
        # }}}

        # {{{ set-up
        def make_it(name, is_const=True, tpname="value_type"):
            if is_const:
                const = "const_"
            else:
                const = ""

            return Initializer(
                Value("numpy_array<%s>::%siterator" % (tpname, const), name + "_it"), "%s.begin()" % name
            )

        fbody = Block(
            [
                If("ROW_COUNT != diffmat_rst%d.size1()" % i, S('throw(std::runtime_error("unexpected matrix size"))'))
                for i in range(discr.dimensions)
            ]
            + [
                If("COL_COUNT != diffmat_rst%d.size2()" % i, S('throw(std::runtime_error("unexpected matrix size"))'))
                for i in range(discr.dimensions)
            ]
            + [
                If("ROW_COUNT != to_ers.el_size()", S('throw(std::runtime_error("unsupported image element size"))')),
                If(
                    "COL_COUNT != from_ers.el_size()",
                    S('throw(std::runtime_error("unsupported preimage element size"))'),
                ),
                If(
                    "from_ers.size() != to_ers.size()",
                    S(
                        'throw(std::runtime_error("image and preimage element groups '
                        'do nothave the same element count"))'
                    ),
                ),
                Line(),
                make_it("field"),
            ]
            + [make_it("result%d" % i, is_const=False) for i in range(discr.dimensions)]
            + [
                Line(),
                # }}}
                # {{{ computation
                For(
                    "element_number_t eg_el_nr = 0",
                    "eg_el_nr < to_ers.size()",
                    "++eg_el_nr",
                    Block(
                        [
                            Initializer(
                                Value("node_number_t", "from_el_base"), "from_ers.start() + eg_el_nr*COL_COUNT"
                            ),
                            Initializer(Value("node_number_t", "to_el_base"), "to_ers.start() + eg_el_nr*ROW_COUNT"),
                            Line(),
                            For(
                                "unsigned i = 0",
                                "i < ROW_COUNT",
                                "++i",
                                Block(
                                    [
                                        Initializer(Value("value_type", "drst_%d" % rst), 0)
                                        for rst in range(discr.dimensions)
                                    ]
                                    + [Line()]
                                    + [
                                        For(
                                            "unsigned j = 0",
                                            "j < COL_COUNT",
                                            "++j",
                                            Block(
                                                [
                                                    S(
                                                        "drst_%(rst)d += "
                                                        "diffmat_rst%(rst)d(i, j)*field_it[from_el_base+j]"
                                                        % {"rst": rst}
                                                    )
                                                    for rst in range(discr.dimensions)
                                                ]
                                            ),
                                        ),
                                        Line(),
                                    ]
                                    + [
                                        Assign("result%d_it[to_el_base+i]" % rst, "drst_%d" % rst)
                                        for rst in range(discr.dimensions)
                                    ]
                                ),
                            ),
                        ]
                    ),
                ),
            ]
        )
        # }}}

        # {{{ compilation
        mod.add_function(FunctionBody(fdecl, fbody))

        # print "----------------------------------------------------------------"
        # print mod.generate()
        # raw_input()

        compiled_func = mod.compile(self.discr.toolchain).diff

        if self.discr.instrumented:
            from hedge.tools import time_count_flop

            compiled_func = time_count_flop(
                compiled_func,
                discr.diff_timer,
                discr.diff_counter,
                discr.diff_flop_counter,
                flops=discr.dimensions
                * (
                    2 * ldis.node_count() * len(elgroup.members) * ldis.node_count()  # mul+add
                    + 2 * discr.dimensions * len(elgroup.members) * ldis.node_count()
                ),
                increment=discr.dimensions,
            )

        return compiled_func
Exemple #6
0
    def make_diff(self, elgroup, dtype, shape):
        """
        :param shape: If non-square, the resulting code takes two element_ranges
          arguments and supports non-square matrices.
        """
        from hedge._internal import UniformElementRanges
        assert isinstance(elgroup.ranges, UniformElementRanges)

        ldis = elgroup.local_discretization
        discr = self.discr
        from cgen import (
                FunctionDeclaration, FunctionBody, Typedef,
                Const, Reference, Value, POD,
                Statement, Include, Line, Block, Initializer, Assign,
                For, If,
                Define)

        from pytools import to_uncomplex_dtype

        from codepy.bpl import BoostPythonModule
        mod = BoostPythonModule()

        # {{{ preamble
        S = Statement
        mod.add_to_preamble([
            Include("hedge/volume_operators.hpp"),
            Include("boost/foreach.hpp"),
            ])

        mod.add_to_module([
            S("namespace ublas = boost::numeric::ublas"),
            S("using namespace hedge"),
            S("using namespace pyublas"),
            Line(),
            Define("ROW_COUNT", shape[0]),
            Define("COL_COUNT", shape[1]),
            Define("DIMENSIONS", discr.dimensions),
            Line(),
            Typedef(POD(dtype, "value_type")),
            Typedef(POD(to_uncomplex_dtype(dtype), "uncomplex_type")),
            ])

        fdecl = FunctionDeclaration(
                    Value("void", "diff"),
                    [
                    Const(Reference(Value("uniform_element_ranges", "from_ers"))),
                    Const(Reference(Value("uniform_element_ranges", "to_ers"))),
                    Value("numpy_array<value_type>", "field")
                    ]+[
                    Value("ublas::matrix<uncomplex_type>", "diffmat_rst%d" % rst)
                    for rst in range(discr.dimensions)
                    ]+[
                    Value("numpy_array<value_type>", "result%d" % i)
                    for i in range(discr.dimensions)
                    ]
                    )
        # }}}

        # {{{ set-up
        def make_it(name, is_const=True, tpname="value_type"):
            if is_const:
                const = "const_"
            else:
                const = ""

            return Initializer(
                Value("numpy_array<%s>::%siterator" % (tpname, const), name+"_it"),
                "%s.begin()" % name)

        fbody = Block([
            If("ROW_COUNT != diffmat_rst%d.size1()" % i,
                S('throw(std::runtime_error("unexpected matrix size"))'))
            for i in range(discr.dimensions)
            ] + [
            If("COL_COUNT != diffmat_rst%d.size2()" % i,
                S('throw(std::runtime_error("unexpected matrix size"))'))
            for i in range(discr.dimensions) 
            ]+[
            If("ROW_COUNT != to_ers.el_size()",
                S('throw(std::runtime_error("unsupported image element size"))')),
            If("COL_COUNT != from_ers.el_size()",
                S('throw(std::runtime_error("unsupported preimage element size"))')),
            If("from_ers.size() != to_ers.size()",
                S('throw(std::runtime_error("image and preimage element groups '
                    'do nothave the same element count"))')),
            Line(),
            make_it("field"),
            ]+[
            make_it("result%d" % i, is_const=False)
            for i in range(discr.dimensions)
            ]+[
            Line(),
        # }}}

        # {{{ computation
            For("element_number_t eg_el_nr = 0",
                "eg_el_nr < to_ers.size()",
                "++eg_el_nr",
                Block([
                    Initializer(
                        Value("node_number_t", "from_el_base"),
                        "from_ers.start() + eg_el_nr*COL_COUNT"),
                    Initializer(
                        Value("node_number_t", "to_el_base"),
                        "to_ers.start() + eg_el_nr*ROW_COUNT"),
                    Line(),
                    For("unsigned i = 0",
                        "i < ROW_COUNT",
                        "++i",
                        Block([
                            Initializer(Value("value_type", "drst_%d" % rst), 0)
                            for rst in range(discr.dimensions)
                            ]+[
                            Line(),
                            ]+[
                            For("unsigned j = 0",
                                "j < COL_COUNT",
                                "++j",
                                Block([
                                    S("drst_%(rst)d += "
                                        "diffmat_rst%(rst)d(i, j)*field_it[from_el_base+j]"
                                        % {"rst":rst})
                                    for rst in range(discr.dimensions)
                                    ])
                                ),
                            Line(),
                            ]+[
                            Assign("result%d_it[to_el_base+i]" % rst,
                                "drst_%d" % rst)
                            for rst in range(discr.dimensions)
                            ])
                        )
                    ])
                )
            ])
        # }}}

        # {{{ compilation
        mod.add_function(FunctionBody(fdecl, fbody))

        #print "----------------------------------------------------------------"
        #print mod.generate()
        #raw_input()

        compiled_func = mod.compile(self.discr.toolchain).diff

        if self.discr.instrumented:
            from hedge.tools import time_count_flop

            compiled_func = time_count_flop(compiled_func,
                    discr.diff_timer, discr.diff_counter,
                    discr.diff_flop_counter,
                    flops=discr.dimensions*(
                        2 # mul+add
                        * ldis.node_count() * len(elgroup.members)
                        * ldis.node_count()
                        +
                        2 * discr.dimensions
                        * len(elgroup.members) * ldis.node_count()),
                    increment=discr.dimensions)

        return compiled_func