From 2f5f6ad6a30eb1757f2f4b711454c7f37a1dfffd Mon Sep 17 00:00:00 2001 From: Julian Hammer <julian.hammer@fau.de> Date: Fri, 15 Mar 2019 13:23:19 +0100 Subject: [PATCH] Worked on kerncraft interface --- kerncraft_coupling/kerncraft_interface.py | 34 +++++++++++++++++++---- sympyextensions.py | 5 ++++ 2 files changed, 34 insertions(+), 5 deletions(-) diff --git a/kerncraft_coupling/kerncraft_interface.py b/kerncraft_coupling/kerncraft_interface.py index dace67b7a..b8d3e5e4e 100644 --- a/kerncraft_coupling/kerncraft_interface.py +++ b/kerncraft_coupling/kerncraft_interface.py @@ -6,9 +6,12 @@ from collections import defaultdict import subprocess import kerncraft import kerncraft.kernel +from typing import Optional from kerncraft.iaca import iaca_analyse_instrumented_binary, iaca_instrumentation +from kerncraft.machinemodel import MachineModel + from pystencils.kerncraft_coupling.generate_benchmark import generate_benchmark -from pystencils.astnodes import LoopOverCoordinate, SympyAssignment, ResolvedFieldAccess +from pystencils.astnodes import LoopOverCoordinate, SympyAssignment, ResolvedFieldAccess, KernelFunction from pystencils.field import get_layout_from_strides from pystencils.sympyextensions import count_operations_in_ast from pystencils.utils import DotDict @@ -21,7 +24,16 @@ class PyStencilsKerncraftKernel(kerncraft.kernel.Kernel): """ LIKWID_BASE = '/usr/local/likwid' - def __init__(self, ast, machine=None): + def __init__(self, ast: KernelFunction, machine: Optional[MachineModel] = None, assumed_layout='SoA'): + """Create a kerncraft kernel using a pystencils AST + + Args: + ast: pystencils ast + machine: kerncraft machine model - specify this if kernel needs to be compiled + assumed_layout: either 'SoA' or 'AoS' - if fields have symbolic sizes the layout of the index coordinates is not + known. In this case either a structures of array (SoA) or array of structures (AoS) layout + is assumed + """ super(PyStencilsKerncraftKernel, self).__init__(machine) self.ast = ast @@ -50,20 +62,29 @@ class PyStencilsKerncraftKernel(kerncraft.kernel.Kernel): self.sources = defaultdict(list) self.destinations = defaultdict(list) + def get_layout_tuple(f): + if f.has_fixed_shape: + return get_layout_from_strides(f.strides) + else: + layout_list = list(f.layout) + for _ in range(f.index_dimensions): + layout_list.insert(0 if assumed_layout == 'SoA' else -1, max(layout_list) + 1) + return layout_list + reads, writes = search_resolved_field_accesses_in_ast(inner_loop) for accesses, target_dict in [(reads, self.sources), (writes, self.destinations)]: for fa in accesses: coord = [sp.Symbol(LoopOverCoordinate.get_loop_counter_name(i), positive=True, integer=True) + off for i, off in enumerate(fa.offsets)] coord += list(fa.idx_coordinate_values) - layout = get_layout_from_strides(fa.field.strides) - permuted_coord = [coord[i] for i in layout] + layout = get_layout_tuple(fa.field) + permuted_coord = [sp.sympify(coord[i]) for i in layout] target_dict[fa.field.name].append(permuted_coord) # Variables (arrays) fields_accessed = ast.fields_accessed for field in fields_accessed: - layout = get_layout_from_strides(field.strides) + layout = get_layout_tuple(field) permuted_shape = list(field.shape[i] for i in layout) self.set_variable(field.name, str(field.dtype), tuple(permuted_shape)) @@ -76,6 +97,7 @@ class PyStencilsKerncraftKernel(kerncraft.kernel.Kernel): self.datatype = list(self.variables.values())[0][0] # flops + # FIXME operation_count operation_count = count_operations_in_ast(inner_loop) self._flops = { '+': operation_count['adds'], @@ -155,6 +177,8 @@ class KerncraftParameters(DotDict): self['verbose'] = 0 self['pointer_increment'] = 'auto' self['iterations'] = 10 + self['unit'] = 'cy/CL' + self['ignore_warnings'] = True # ------------------------------------------- Helper functions --------------------------------------------------------- diff --git a/sympyextensions.py b/sympyextensions.py index 24c14c5f8..1be095058 100644 --- a/sympyextensions.py +++ b/sympyextensions.py @@ -439,6 +439,9 @@ def count_operations(term: Union[sp.Expr, List[sp.Expr]], elif isinstance(term, Assignment): term = term.rhs + if not hasattr(term, 'evalf'): + return result + term = term.evalf() def check_type(e): @@ -460,6 +463,8 @@ def count_operations(term: Union[sp.Expr, List[sp.Expr]], if t.func is sp.Add: if check_type(t): result['adds'] += len(t.args) - 1 + elif t.func in [sp.Or, sp.And]: + pass elif t.func is sp.Mul: if check_type(t): result['muls'] += len(t.args) - 1 -- GitLab