diff --git a/python/dune/perftool/pdelab/localoperator.py b/python/dune/perftool/pdelab/localoperator.py index abddb94c11ffae3affa41c694d9b4d27c0818a4f..c3dbd024c86ee41a795989b9df4f95812c838752 100644 --- a/python/dune/perftool/pdelab/localoperator.py +++ b/python/dune/perftool/pdelab/localoperator.py @@ -192,10 +192,26 @@ def assembler_routine_name(): return "{}_{}".format(part1, part2) -def assembly_routine_signature(formdata): +def kernel_name(): + arn = assembler_routine_name() + facedir_s = get_global_context_value("facedir_s", None) + facedir_n = get_global_context_value("facedir_n", None) + facemod_s = get_global_context_value("facemod_s", None) + facemod_n = get_global_context_value("facemod_n", None) + suffix = "{}{}{}{}".format("_facedirs{}".format(facedir_s) if facedir_s is not None else "", + "_facedirn{}".format(facedir_n) if facedir_n is not None else "", + "_facemods{}".format(facemod_s) if facemod_s is not None else "", + "_facemodn{}".format(facemod_n) if facemod_n is not None else "", + ) + + return "{}{}".format(arn, suffix) + + +def assembly_routine_signature(): from dune.perftool.generation import get_global_context_value integral_type = get_global_context_value("integral_type") form_type = get_global_context_value("form_type") + formdata = get_global_context_value("formdata") # Check if form is linear from dune.perftool.pdelab.driver import is_linear @@ -204,46 +220,46 @@ def assembly_routine_signature(formdata): if form_type == 'residual': if integral_type == 'cell': from dune.perftool.pdelab.signatures import alpha_volume_signature - return alpha_volume_signature() + return alpha_volume_signature(kernel_name()) if integral_type == 'exterior_facet': from dune.perftool.pdelab.signatures import alpha_boundary_signature - return alpha_boundary_signature() + return alpha_boundary_signature(kernel_name()) if integral_type == 'interior_facet': from dune.perftool.pdelab.signatures import alpha_skeleton_signature - return alpha_skeleton_signature() + return alpha_skeleton_signature(kernel_name()) if form_type == 'jacobian': if integral_type == 'cell': from dune.perftool.pdelab.signatures import jacobian_volume_signature - return jacobian_volume_signature() + return jacobian_volume_signature(kernel_name()) if integral_type == 'exterior_facet': from dune.perftool.pdelab.signatures import jacobian_boundary_signature - return jacobian_boundary_signature() + return jacobian_boundary_signature(kernel_name()) if integral_type == 'interior_facet': from dune.perftool.pdelab.signatures import jacobian_skeleton_signature - return jacobian_skeleton_signature() + return jacobian_skeleton_signature(kernel_name()) if form_type == 'jacobian_apply': if linear: if integral_type == 'cell': from dune.perftool.pdelab.signatures import jacobian_apply_volume_signature - return jacobian_apply_volume_signature() + return jacobian_apply_volume_signature(kernel_name()) if integral_type == 'exterior_facet': from dune.perftool.pdelab.signatures import jacobian_apply_boundary_signature - return jacobian_apply_boundary_signature() + return jacobian_apply_boundary_signature(kernel_name()) if integral_type == 'interior_facet': from dune.perftool.pdelab.signatures import jacobian_apply_skeleton_signature - return jacobian_apply_skeleton_signature() + return jacobian_apply_skeleton_signature(kernel_name()) else: if integral_type == 'cell': from dune.perftool.pdelab.signatures import nonlinear_jacobian_apply_volume_signature - return nonlinear_jacobian_apply_volume_signature() + return nonlinear_jacobian_apply_volume_signature(kernel_name()) if integral_type == 'exterior_facet': from dune.perftool.pdelab.signatures import nonlinear_jacobian_apply_boundary_signature - return nonlinear_jacobian_apply_boundary_signature() + return nonlinear_jacobian_apply_boundary_signature(kernel_name()) if integral_type == 'interior_facet': from dune.perftool.pdelab.signatures import nonlinear_jacobian_apply_skeleton_signature - return nonlinear_jacobian_apply_skeleton_signature() + return nonlinear_jacobian_apply_skeleton_signature(kernel_name()) assert False @@ -501,7 +517,12 @@ def generate_kernel(integrals): return knl -def extract_kernel_from_cache(tag): +@backend(interface="generate_kernels_per_integral") +def generate_kernels_per_integral(integrals): + yield generate_kernel(integrals) + + +def extract_kernel_from_cache(tag, wrap_in_cgen=True): # Now extract regular loopy kernel components from dune.perftool.loopy.target import DuneTarget domains = [i for i in retrieve_cache_items("{} and domain".format(tag))] @@ -555,6 +576,11 @@ def extract_kernel_from_cache(tag): # Do the loopy preprocessing! kernel = preprocess_kernel(kernel) + if wrap_in_cgen: + # Wrap the kernel in something which can generate code + signature = assembly_routine_signature() + kernel = LoopyKernelMethod(signature, kernel) + return kernel @@ -662,7 +688,7 @@ def cgen_class_from_cache(tag, members=[]): tparams = [i for i in retrieve_cache_items('{} and template_param'.format(tag))] # Construct the constructor - constructor_knl = extract_kernel_from_cache(tag) + constructor_knl = extract_kernel_from_cache(tag, wrap_in_cgen=False) from dune.perftool.loopy.target import DuneTarget constructor_knl = constructor_knl.copy(target=DuneTarget(declare_temporaries=False)) signature = "{}({})".format(basename, ", ".join(next(iter(p.generate(with_semicolon=False))) for p in constructor_params)) @@ -740,7 +766,7 @@ def generate_localoperator_kernels(formdata, data): pattern_baseclass() enum_alpha() with global_context(kernel=assembler_routine_name()): - kernel = generate_kernel(form.integrals_by_type(measure)) + kernel = [k for k in get_backend(interface="generate_kernels_per_integral")(form.integrals_by_type(measure))] # Maybe add numerical differentiation if get_option("numerical_jacobian"): @@ -796,7 +822,7 @@ def generate_localoperator_kernels(formdata, data): for measure in set(i.integral_type() for i in jacform.integrals()): with global_context(integral_type=measure): with global_context(kernel=assembler_routine_name()): - kernel = generate_kernel(jacform.integrals_by_type(measure)) + kernel = [k for k in get_backend(interface="generate_kernels_per_integral")(jacform.integrals_by_type(measure))] operator_kernels[(measure, 'jacobian')] = kernel # Generate dummy functions for those kernels, that vanished in the differentiation process @@ -822,7 +848,7 @@ def generate_localoperator_kernels(formdata, data): for measure in set(i.integral_type() for i in jac_apply_form.integrals()): with global_context(integral_type=measure): with global_context(kernel=assembler_routine_name()): - kernel = generate_kernel(jac_apply_form.integrals_by_type(measure)) + kernel = [k for k in get_backend(interface="generate_kernels_per_integral")(jac_apply_form.integrals_by_type(measure))] operator_kernels[(measure, 'jacobian_apply')] = kernel # Generate dummy functions for those kernels, that vanished in the differentiation process @@ -839,13 +865,8 @@ def generate_localoperator_kernels(formdata, data): def generate_localoperator_file(formdata, kernels, filename): operator_methods = [] - - # Make generables from the given kernels - for method, kernel in kernels.items(): - it, ft = method - with global_context(integral_type=it, form_type=ft): - signature = assembly_routine_signature(formdata) - operator_methods.append(LoopyKernelMethod(signature, kernel)) + for k in kernels.values(): + operator_methods.extend(k) if get_option('timer'): include_file('dune/perftool/common/timer.hh', filetag='operatorfile') diff --git a/python/dune/perftool/pdelab/signatures.py b/python/dune/perftool/pdelab/signatures.py index b329245d2d6d2c5e04f60cc4ebcdca1439df9666..cc11184ed8657b11093a6e4e0c4fe8718b29c2da 100644 --- a/python/dune/perftool/pdelab/signatures.py +++ b/python/dune/perftool/pdelab/signatures.py @@ -17,7 +17,7 @@ from dune.perftool.pdelab.spaces import (name_testfunctionspace, ) -def alpha_volume_signature(): +def alpha_volume_signature(name): geot = type_geometry_wrapper() geo = name_geometry_wrapper() lfsut = type_trialfunctionspace() @@ -28,27 +28,30 @@ def alpha_volume_signature(): cc = name_coefficientcontainer(Restriction.NONE) avt = type_accumulation_variable() av = name_accumulation_variable((Restriction.NONE,)) - return ['template<typename {}, typename {}, typename {}, typename {}, typename {}>'.format(geot, - lfsut, - cct, - lfsvt, - avt, - ), - 'void alpha_volume(const {}& {}, const {}& {}, const {}& {}, const {}& {}, {}& {}) const'.format(geot, - geo, - lfsut, - lfsu, - cct, - cc, - lfsvt, - lfsv, - avt, - av, - ) + return ['template<typename {}, typename {}, typename {}, typename {}, typename {}>'.format( + geot, + lfsut, + cct, + lfsvt, + avt, + ), + 'void {}(const {}& {}, const {}& {}, const {}& {}, const {}& {}, {}& {}) const'.format( + name, + geot, + geo, + lfsut, + lfsu, + cct, + cc, + lfsvt, + lfsv, + avt, + av, + ) ] -def alpha_boundary_signature(): +def alpha_boundary_signature(name): geot = type_geometry_wrapper() geo = name_geometry_wrapper() lfsut = type_trialfunctionspace() @@ -59,27 +62,30 @@ def alpha_boundary_signature(): cc = name_coefficientcontainer(Restriction.NEGATIVE) avt = type_accumulation_variable() av = name_accumulation_variable((Restriction.NEGATIVE,)) - return ['template<typename {}, typename {}, typename {}, typename {}, typename {}>'.format(geot, - lfsut, - cct, - lfsvt, - avt, - ), - 'void alpha_boundary(const {}& {}, const {}& {}, const {}& {}, const {}& {}, {}& {}) const'.format(geot, - geo, - lfsut, - lfsu, - cct, - cc, - lfsvt, - lfsv, - avt, - av, - ) + return ['template<typename {}, typename {}, typename {}, typename {}, typename {}>'.format( + geot, + lfsut, + cct, + lfsvt, + avt, + ), + 'void {}(const {}& {}, const {}& {}, const {}& {}, const {}& {}, {}& {}) const'.format( + name, + geot, + geo, + lfsut, + lfsu, + cct, + cc, + lfsvt, + lfsv, + avt, + av, + ) ] -def alpha_skeleton_signature(): +def alpha_skeleton_signature(name): geot = type_geometry_wrapper() geo = name_geometry_wrapper() lfsut = type_trialfunctionspace() @@ -94,35 +100,38 @@ def alpha_skeleton_signature(): avt = type_accumulation_variable() av_s = name_accumulation_variable((Restriction.NEGATIVE,)) av_n = name_accumulation_variable((Restriction.POSITIVE,)) - return ['template<typename {}, typename {}, typename {}, typename {}, typename {}>'.format(geot, - lfsut, - cct, - lfsvt, - avt, - ), - 'void alpha_skeleton(const {}& {}, const {}& {}, const {}& {}, const {}& {}, const {}& {}, const {}& {}, const {}& {}, {}& {}, {}& {}) const'.format(geot, - geo, - lfsut, - lfsu_s, - cct, - cc_s, - lfsvt, - lfsv_s, - lfsut, - lfsu_n, - cct, - cc_n, - lfsvt, - lfsv_n, - avt, - av_s, - avt, - av_n, - ) + return ['template<typename {}, typename {}, typename {}, typename {}, typename {}>'.format( + geot, + lfsut, + cct, + lfsvt, + avt, + ), + 'void {}(const {}& {}, const {}& {}, const {}& {}, const {}& {}, const {}& {}, const {}& {}, const {}& {}, {}& {}, {}& {}) const'.format( + name, + geot, + geo, + lfsut, + lfsu_s, + cct, + cc_s, + lfsvt, + lfsv_s, + lfsut, + lfsu_n, + cct, + cc_n, + lfsvt, + lfsv_n, + avt, + av_s, + avt, + av_n, + ) ] -def jacobian_volume_signature(): +def jacobian_volume_signature(name): geot = type_geometry_wrapper() geo = name_geometry_wrapper() lfsut = type_trialfunctionspace() @@ -133,27 +142,30 @@ def jacobian_volume_signature(): cc = name_coefficientcontainer(Restriction.NONE) avt = type_accumulation_variable() av = name_accumulation_variable((Restriction.NONE, Restriction.NONE)) - return ['template<typename {}, typename {}, typename {}, typename {}, typename {}>'.format(geot, - lfsut, - cct, - lfsvt, - avt, - ), - 'void jacobian_volume(const {}& {}, const {}& {}, const {}& {}, const {}& {}, {}& {}) const'.format(geot, - geo, - lfsut, - lfsu, - cct, - cc, - lfsvt, - lfsv, - avt, - av, - ) + return ['template<typename {}, typename {}, typename {}, typename {}, typename {}>'.format( + geot, + lfsut, + cct, + lfsvt, + avt, + ), + 'void {}(const {}& {}, const {}& {}, const {}& {}, const {}& {}, {}& {}) const'.format( + name, + geot, + geo, + lfsut, + lfsu, + cct, + cc, + lfsvt, + lfsv, + avt, + av, + ) ] -def jacobian_boundary_signature(): +def jacobian_boundary_signature(name): geot = type_geometry_wrapper() geo = name_geometry_wrapper() lfsut = type_trialfunctionspace() @@ -164,27 +176,30 @@ def jacobian_boundary_signature(): cc = name_coefficientcontainer(Restriction.NEGATIVE) avt = type_accumulation_variable() av = name_accumulation_variable((Restriction.NEGATIVE, Restriction.NEGATIVE)) - return ['template<typename {}, typename {}, typename {}, typename {}, typename {}>'.format(geot, - lfsut, - cct, - lfsvt, - avt, - ), - 'void jacobian_boundary(const {}& {}, const {}& {}, const {}& {}, const {}& {}, {}& {}) const'.format(geot, - geo, - lfsut, - lfsu, - cct, - cc, - lfsvt, - lfsv, - avt, - av, - ) + return ['template<typename {}, typename {}, typename {}, typename {}, typename {}>'.format( + geot, + lfsut, + cct, + lfsvt, + avt, + ), + 'void {}(const {}& {}, const {}& {}, const {}& {}, const {}& {}, {}& {}) const'.format( + name, + geot, + geo, + lfsut, + lfsu, + cct, + cc, + lfsvt, + lfsv, + avt, + av, + ) ] -def jacobian_skeleton_signature(): +def jacobian_skeleton_signature(name): geot = type_geometry_wrapper() geo = name_geometry_wrapper() lfsut = type_trialfunctionspace() @@ -201,39 +216,42 @@ def jacobian_skeleton_signature(): av_sn = name_accumulation_variable((Restriction.NEGATIVE, Restriction.POSITIVE)) av_ns = name_accumulation_variable((Restriction.POSITIVE, Restriction.NEGATIVE)) av_nn = name_accumulation_variable((Restriction.POSITIVE, Restriction.POSITIVE)) - return ['template<typename {}, typename {}, typename {}, typename {}, typename {}>'.format(geot, - lfsut, - cct, - lfsvt, - avt, - ), - 'void jacobian_skeleton(const {}& {}, const {}& {}, const {}& {}, const {}& {}, const {}& {}, const {}& {}, const {}& {}, {}& {}, {}& {}, {}& {}, {}& {}) const'.format(geot, - geo, - lfsut, - lfsu_s, - cct, - cc_s, - lfsvt, - lfsv_s, - lfsut, - lfsu_n, - cct, - cc_n, - lfsvt, - lfsv_n, - avt, - av_ss, - avt, - av_sn, - avt, - av_ns, - avt, - av_nn, - ) + return ['template<typename {}, typename {}, typename {}, typename {}, typename {}>'.format( + geot, + lfsut, + cct, + lfsvt, + avt, + ), + 'void {}(const {}& {}, const {}& {}, const {}& {}, const {}& {}, const {}& {}, const {}& {}, const {}& {}, {}& {}, {}& {}, {}& {}, {}& {}) const'.format( + name, + geot, + geo, + lfsut, + lfsu_s, + cct, + cc_s, + lfsvt, + lfsv_s, + lfsut, + lfsu_n, + cct, + cc_n, + lfsvt, + lfsv_n, + avt, + av_ss, + avt, + av_sn, + avt, + av_ns, + avt, + av_nn, + ) ] -def jacobian_apply_volume_signature(): +def jacobian_apply_volume_signature(name): geot = type_geometry_wrapper() geo = name_geometry_wrapper() lfsut = type_trialfunctionspace() @@ -244,13 +262,15 @@ def jacobian_apply_volume_signature(): ac = name_applycontainer(Restriction.NONE) avt = type_accumulation_variable() av = name_accumulation_variable((Restriction.NONE,)) - return ['template<typename {}, typename {}, typename {}, typename {}, typename {}>'.format(geot, - lfsut, - cct, - lfsvt, - avt, - ), - 'void jacobian_apply_volume(const {}& {}, const {}& {}, const {}& {}, const {}& {}, {}& {}) const'.format( + return ['template<typename {}, typename {}, typename {}, typename {}, typename {}>'.format( + geot, + lfsut, + cct, + lfsvt, + avt, + ), + 'void {}(const {}& {}, const {}& {}, const {}& {}, const {}& {}, {}& {}) const'.format( + name, geot, geo, lfsut, @@ -264,7 +284,7 @@ def jacobian_apply_volume_signature(): ] -def jacobian_apply_boundary_signature(): +def jacobian_apply_boundary_signature(name): geot = type_geometry_wrapper() geo = name_geometry_wrapper() lfsut = type_trialfunctionspace() @@ -275,13 +295,15 @@ def jacobian_apply_boundary_signature(): ac = name_applycontainer(Restriction.NEGATIVE) avt = type_accumulation_variable() av = name_accumulation_variable((Restriction.NEGATIVE,)) - return ['template<typename {}, typename {}, typename {}, typename {}, typename {}>'.format(geot, - lfsut, - cct, - lfsvt, - avt, - ), - 'void jacobian_apply_boundary(const {}& {}, const {}& {}, const {}& {}, const {}& {}, {}& {}) const'.format( + return ['template<typename {}, typename {}, typename {}, typename {}, typename {}>'.format( + geot, + lfsut, + cct, + lfsvt, + avt, + ), + 'void {}(const {}& {}, const {}& {}, const {}& {}, const {}& {}, {}& {}) const'.format( + name, geot, geo, lfsut, @@ -295,7 +317,7 @@ def jacobian_apply_boundary_signature(): ] -def jacobian_apply_skeleton_signature(): +def jacobian_apply_skeleton_signature(name): geot = type_geometry_wrapper() geo = name_geometry_wrapper() lfsut = type_trialfunctionspace() @@ -310,13 +332,15 @@ def jacobian_apply_skeleton_signature(): avt = type_accumulation_variable() av_s = name_accumulation_variable((Restriction.NEGATIVE,)) av_n = name_accumulation_variable((Restriction.POSITIVE,)) - return ['template<typename {}, typename {}, typename {}, typename {}, typename {}>'.format(geot, - lfsut, - cct, - lfsvt, - avt, - ), - 'void jacobian_apply_skeleton(const {}& {}, const {}& {}, const {}& {}, const {}& {}, const {}& {}, const {}& {}, const {}& {}, {}& {}, {}& {}) const'.format( + return ['template<typename {}, typename {}, typename {}, typename {}, typename {}>'.format( + geot, + lfsut, + cct, + lfsvt, + avt, + ), + 'void {}(const {}& {}, const {}& {}, const {}& {}, const {}& {}, const {}& {}, const {}& {}, const {}& {}, {}& {}, {}& {}) const'.format( + name, geot, geo, lfsut, @@ -338,7 +362,7 @@ def jacobian_apply_skeleton_signature(): ] -def nonlinear_jacobian_apply_volume_signature(): +def nonlinear_jacobian_apply_volume_signature(name): geot = type_geometry_wrapper() geo = name_geometry_wrapper() lfsut = type_trialfunctionspace() @@ -350,13 +374,15 @@ def nonlinear_jacobian_apply_volume_signature(): ac = name_applycontainer(Restriction.NONE) avt = type_accumulation_variable() av = name_accumulation_variable((Restriction.NONE,)) - return ['template<typename {}, typename {}, typename {}, typename {}, typename {}>'.format(geot, - lfsut, - cct, - lfsvt, - avt, - ), - 'void jacobian_apply_volume(const {}& {}, const {}& {}, const {}& {}, const {}& {}, const {}& {}, {}& {}) const'.format( + return ['template<typename {}, typename {}, typename {}, typename {}, typename {}>'.format( + geot, + lfsut, + cct, + lfsvt, + avt, + ), + 'void {}(const {}& {}, const {}& {}, const {}& {}, const {}& {}, const {}& {}, {}& {}) const'.format( + name, geot, geo, lfsut, @@ -372,7 +398,7 @@ def nonlinear_jacobian_apply_volume_signature(): ] -def nonlinear_jacobian_apply_boundary_signature(): +def nonlinear_jacobian_apply_boundary_signature(name): geot = type_geometry_wrapper() geo = name_geometry_wrapper() lfsut = type_trialfunctionspace() @@ -384,13 +410,15 @@ def nonlinear_jacobian_apply_boundary_signature(): ac = name_applycontainer(Restriction.NEGATIVE) avt = type_accumulation_variable() av = name_accumulation_variable((Restriction.NEGATIVE,)) - return ['template<typename {}, typename {}, typename {}, typename {}, typename {}>'.format(geot, - lfsut, - cct, - lfsvt, - avt, - ), - 'void jacobian_apply_boundary(const {}& {}, const {}& {}, const {}& {}, const {}& {}, const {}& {}, {}& {}) const'.format( + return ['template<typename {}, typename {}, typename {}, typename {}, typename {}>'.format( + geot, + lfsut, + cct, + lfsvt, + avt, + ), + 'void {}(const {}& {}, const {}& {}, const {}& {}, const {}& {}, const {}& {}, {}& {}) const'.format( + name, geot, geo, lfsut, @@ -406,7 +434,7 @@ def nonlinear_jacobian_apply_boundary_signature(): ] -def nonlinear_jacobian_apply_skeleton_signature(): +def nonlinear_jacobian_apply_skeleton_signature(name): geot = type_geometry_wrapper() geo = name_geometry_wrapper() lfsut = type_trialfunctionspace() @@ -423,13 +451,15 @@ def nonlinear_jacobian_apply_skeleton_signature(): avt = type_accumulation_variable() av_s = name_accumulation_variable((Restriction.NEGATIVE,)) av_n = name_accumulation_variable((Restriction.POSITIVE,)) - return ['template<typename {}, typename {}, typename {}, typename {}, typename {}>'.format(geot, - lfsut, - cct, - lfsvt, - avt, - ), - 'void jacobian_apply_skeleton(const {}& {}, const {}& {}, const {}& {}, const {}& {}, const {}& {}, const {}& {}, const {}& {}, const {}& {}, const {}& {}, {}& {}, {}& {}) const'.format( + return ['template<typename {}, typename {}, typename {}, typename {}, typename {}>'.format( + geot, + lfsut, + cct, + lfsvt, + avt, + ), + 'void {}(const {}& {}, const {}& {}, const {}& {}, const {}& {}, const {}& {}, const {}& {}, const {}& {}, const {}& {}, const {}& {}, {}& {}, {}& {}) const'.format( + name, geot, geo, lfsut,