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)
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
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
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
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