From f719152295d6066dfeeba51ead8a684e3d522e2d Mon Sep 17 00:00:00 2001 From: Dominic Kempf <dominic.kempf@iwr.uni-heidelberg.de> Date: Thu, 24 Nov 2016 14:03:18 +0100 Subject: [PATCH] Make sumfact data structure loopy-controlled --- python/dune/perftool/cgen/clazz.py | 2 +- python/dune/perftool/generation/__init__.py | 1 + python/dune/perftool/generation/loopy.py | 14 +++++++++++++ python/dune/perftool/loopy/target.py | 9 ++++++++- python/dune/perftool/pdelab/localoperator.py | 20 ++++++++++++++++++- python/dune/perftool/sumfact/amatrix.py | 21 ++++++++++---------- 6 files changed, 54 insertions(+), 13 deletions(-) diff --git a/python/dune/perftool/cgen/clazz.py b/python/dune/perftool/cgen/clazz.py index f265638e..dca212ec 100644 --- a/python/dune/perftool/cgen/clazz.py +++ b/python/dune/perftool/cgen/clazz.py @@ -72,7 +72,7 @@ class Class(Generable): for bc in base_classes: assert isinstance(bc, BaseClass) for mem in members: - assert isinstance(mem, ClassMember) + assert isinstance(mem, Generable) def generate(self): # define the class header diff --git a/python/dune/perftool/generation/__init__.py b/python/dune/perftool/generation/__init__.py index 72fad902..89a98fd7 100644 --- a/python/dune/perftool/generation/__init__.py +++ b/python/dune/perftool/generation/__init__.py @@ -36,6 +36,7 @@ from dune.perftool.generation.loopy import (barrier, globalarg, iname, instruction, + loopy_class_member, kernel_cached, noop_instruction, silenced_warning, diff --git a/python/dune/perftool/generation/loopy.py b/python/dune/perftool/generation/loopy.py index c61fec6a..16c9d4f5 100644 --- a/python/dune/perftool/generation/loopy.py +++ b/python/dune/perftool/generation/loopy.py @@ -164,3 +164,17 @@ def barrier(**kwargs): name = 'barrier_{}'.format(get_counter('barrier')) _barrier(id=name, **kwargs) return name + + +def loopy_class_member(name, classtag=None, **kwargs): + """ A class member is based on loopy! It is an + * temporary variable of the constructor kernel + * A globalarg of the requesting kernel (to make things pass) + """ + assert classtag + temporary_variable(name, kernel=classtag, **kwargs) + silenced_warning("read_no_write({})".format(name), kernel=classtag) + + kwargs.pop("decl_method", None) + # TODO I guess some filtering has to be applied here. + globalarg(name, **kwargs) \ No newline at end of file diff --git a/python/dune/perftool/loopy/target.py b/python/dune/perftool/loopy/target.py index 57ff1d23..f3b7d3e3 100644 --- a/python/dune/perftool/loopy/target.py +++ b/python/dune/perftool/loopy/target.py @@ -115,11 +115,18 @@ class DuneASTBuilder(CASTBuilder): post_include("#define BARRIER asm volatile(\"\": : :\"memory\")", filetag="operatorfile") return cgen.Line("BARRIER;") + def get_temporary_decls(self, codegen_state, schedule_index): + if self.target.declare_temporaries: + return CASTBuilder.get_temporary_decls(self, codegen_state, schedule_index) + else: + return [] + class DuneTarget(TargetBase): - def __init__(self): + def __init__(self, declare_temporaries=True): # Set fortran_abi to allow reusing CASTBuilder for the moment self.fortran_abi = False + self.declare_temporaries = declare_temporaries def split_kernel_at_global_barriers(self): return False diff --git a/python/dune/perftool/pdelab/localoperator.py b/python/dune/perftool/pdelab/localoperator.py index 0234b422..30454153 100644 --- a/python/dune/perftool/pdelab/localoperator.py +++ b/python/dune/perftool/pdelab/localoperator.py @@ -644,11 +644,29 @@ def cgen_class_from_cache(tag, members=[]): # Construct the constructor constructor_knl = extract_kernel_from_cache(tag) + 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)) constructor = LoopyKernelMethod([signature], constructor_knl, add_timings=False, initializer_list=il) + # Take any temporary declarations from the kernel and make them class members + target = DuneTarget() + from loopy.codegen import CodeGenerationState + codegen_state = CodeGenerationState(kernel=constructor_knl, + implemented_data_info=None, + implemented_domain=None, + implemented_predicates=frozenset(), + seen_dtypes=frozenset(), + seen_functions=frozenset(), + seen_atomic_dtypes=frozenset(), + var_subst_map={}, + allow_complex=False, + is_generating_device_code=True, + ) + decls = target.get_device_ast_builder().get_temporary_decls(codegen_state, 0) + from dune.perftool.cgen import Class - return Class(basename, base_classes=base_classes, members=[constructor] + members + pm, tparam_decls=tparams) + return Class(basename, base_classes=base_classes, members=[constructor] + members + pm + decls, tparam_decls=tparams) def generate_localoperator_kernels(formdata, data): diff --git a/python/dune/perftool/sumfact/amatrix.py b/python/dune/perftool/sumfact/amatrix.py index 387fb400..e919951b 100644 --- a/python/dune/perftool/sumfact/amatrix.py +++ b/python/dune/perftool/sumfact/amatrix.py @@ -13,6 +13,7 @@ from dune.perftool.generation import (class_member, include_file, initializer_list, instruction, + loopy_class_member, preamble, silenced_warning, temporary_variable, @@ -93,30 +94,30 @@ def basis_functions_per_direction(): return polynomial_degree() + 1 -@class_member(classtag="operator") def define_oned_quadrature_weights(name): - range_field = lop_template_range_field() - number_qp = quadrature_points_per_direction() - return "{} {}[{}];".format(range_field, name, number_qp) + loopy_class_member(name, + dtype=numpy.float64, + classtag="operator", + shape=(quadrature_points_per_direction(),), + ) def name_oned_quadrature_weights(): name = "qw" - globalarg(name, shape=(quadrature_points_per_direction(),), dtype=NumpyType(numpy.float64)) define_oned_quadrature_weights(name) return name -@class_member(classtag="operator") def define_oned_quadrature_points(name): - range_field = lop_template_range_field() - number_qp = quadrature_points_per_direction() - return "{} {}[{}];".format(range_field, name, number_qp) + loopy_class_member(name, + dtype=numpy.float64, + classtag="operator", + shape=(quadrature_points_per_direction(),), + ) def name_oned_quadrature_points(): name = "qp" - globalarg(name, shape=(quadrature_points_per_direction(),), dtype=NumpyType(numpy.float64)) define_oned_quadrature_points(name) return name -- GitLab