diff --git a/cpu/kerncraft.py b/cpu/kerncraft.py deleted file mode 100644 index 3c00c167c8904fa8406c1ee794349d95fbe41a2b..0000000000000000000000000000000000000000 --- a/cpu/kerncraft.py +++ /dev/null @@ -1,70 +0,0 @@ -from pystencils.transformations import makeLoopOverDomain, typingFromSympyInspection, \ - typeAllEquations, moveConstantsBeforeLoop, getOptimalLoopOrdering -import pystencils.astnodes as ast -from pystencils.backends.cbackend import CBackend, CustomSympyPrinter -from pystencils import TypedSymbol - - -def createKerncraftCode(listOfEquations, typeForSymbol=None, ghostLayers=None): - """ - Creates an abstract syntax tree for a kernel function, by taking a list of update rules. - - Loops are created according to the field accesses in the equations. - - :param listOfEquations: list of sympy equations, containing accesses to :class:`pystencils.field.Field`. - Defining the update rules of the kernel - :param typeForSymbol: a map from symbol name to a C type specifier. If not specified all symbols are assumed to - be of type 'double' except symbols which occur on the left hand side of equations where the - right hand side is a sympy Boolean which are assumed to be 'bool' . - :param ghostLayers: a sequence of pairs for each coordinate with lower and upper nr of ghost layers - if None, the number of ghost layers is determined automatically and assumed to be equal for a - all dimensions - - :return: :class:`pystencils.ast.KernelFunction` node - """ - if not typeForSymbol: - typeForSymbol = typingFromSympyInspection(listOfEquations, "double") - - fieldsRead, fieldsWritten, assignments = typeAllEquations(listOfEquations, typeForSymbol) - allFields = fieldsRead.union(fieldsWritten) - - optimalLoopOrder = getOptimalLoopOrdering(allFields) - cstyleLoopOrder = list(range(len(optimalLoopOrder))) - - body = ast.Block(assignments) - code = makeLoopOverDomain(body, "kerncraft", ghostLayers=ghostLayers, loopOrder=cstyleLoopOrder) - moveConstantsBeforeLoop(code) - loopBody = code.body - - printer = CBackend(sympyPrinter=ArraySympyPrinter()) - - FIXED_SIZES = ("XS", "YS", "ZS", "E1S", "E2S") - - result = "" - for field in allFields: - sizesPermutation = [FIXED_SIZES[i] for i in field.layout] - suffix = "".join("[%s]" % (size,) for size in sizesPermutation) - result += "%s%s;\n" % (field.name, suffix) - - # add parameter definitions - for s in loopBody.undefinedSymbols: - if isinstance(s, TypedSymbol): - result += "%s %s;\n" % (s.dtype, s.name) - - for element in loopBody.args: - result += printer(element) - result += "\n" - return result - - -class ArraySympyPrinter(CustomSympyPrinter): - - def _print_Access(self, fieldAccess): - """""" - Loop = ast.LoopOverCoordinate - coordinateValues = [Loop.getLoopCounterSymbol(i) + offset for i, offset in enumerate(fieldAccess.offsets)] - coordinateValues += list(fieldAccess.index) - permutedCoordinates = [coordinateValues[i] for i in fieldAccess.field.layout] - - suffix = "".join("[%s]" % (self._print(a)) for a in permutedCoordinates) - return "%s%s" % (self._print(fieldAccess.field.name), suffix) diff --git a/kerncraft/__init__.py b/kerncraft/__init__.py index d5a970aaf1fb0c206832f29b8705cd3b0c4d5305..0a3c2b60ff8d6e6020de1bd2fa35634accc32f18 100644 --- a/kerncraft/__init__.py +++ b/kerncraft/__init__.py @@ -1 +1 @@ -from .kernel import PyStencilsKerncraftKernel, KerncraftParameters +from .kerncraft_interface import EcmAnalysis, BenchmarkAnalysis \ No newline at end of file diff --git a/kerncraft/generate_benchmark.py b/kerncraft/generate_benchmark.py index a200352a19f3e2c22e47ca5e386dd27b98e713c7..12c3401de28446270044675093b2c8360a481e43 100644 --- a/kerncraft/generate_benchmark.py +++ b/kerncraft/generate_benchmark.py @@ -7,6 +7,7 @@ benchmarkTemplate = Template(""" #include "kerncraft.h" #include <stdlib.h> #include <stdint.h> +#include <stdbool.h> #include <math.h> {%- if likwid %} #include <likwid.h> diff --git a/kerncraft/kernel.py b/kerncraft/kerncraft_interface.py similarity index 82% rename from kerncraft/kernel.py rename to kerncraft/kerncraft_interface.py index bfc6eaa20c6e8447401a9f68656768c6198b736d..60c1743b4fd16d7aea00bd69586f916fe893dc77 100644 --- a/kerncraft/kernel.py +++ b/kerncraft/kerncraft_interface.py @@ -1,12 +1,14 @@ -from tempfile import TemporaryDirectory, TemporaryFile, NamedTemporaryFile +from tempfile import TemporaryDirectory import sympy as sp import os from collections import defaultdict import subprocess -import kerncraft.kernel import kerncraft -from iaca_marker import iaca_analyse_instrumented_binary, iaca_instrumentation +import kerncraft.kernel +from kerncraft.machinemodel import MachineModel +from kerncraft.models import ECM, Benchmark +from kerncraft.iaca_marker import iaca_analyse_instrumented_binary, iaca_instrumentation from pystencils.kerncraft.generate_benchmark import generateBenchmark from pystencils.astnodes import LoopOverCoordinate, SympyAssignment, ResolvedFieldAccess from pystencils.field import getLayoutFromStrides @@ -108,7 +110,7 @@ class PyStencilsKerncraftKernel(kerncraft.kernel.Kernel): subprocess.check_output(compilerCmd + [srcFile, '-S', '-o', asmFile]) subprocess.check_output(compilerCmd + [dummySrcFile, '-S', '-o', dummyAsmFile]) - instrumentedAsmBlock = iaca_instrumentation(asmFile, pointer_increment='auto') + instrumentedAsmBlock = iaca_instrumentation(asmFile,) # assemble asm files to executable subprocess.check_output(compilerCmd + [asmFile, dummyAsmFile, '-o', binaryFile]) @@ -151,6 +153,43 @@ class KerncraftParameters(DotDict): self['verbose'] = 0 +class Analysis(object): + def __init__(self, ast, kerncraftMachineModel, AnalysisClass, args): + self.ast = ast + + if not isinstance(kerncraftMachineModel, MachineModel): + kerncraftMachineModel = MachineModel(kerncraftMachineModel) + + self.analysis = AnalysisClass(PyStencilsKerncraftKernel(self.ast), + kerncraftMachineModel, + args=args) + self.analysis.analyze() + + @property + def results(self): + return self.analysis.results + + +class EcmAnalysis(Analysis): + + def __init__(self, ast, kerncraftMachineModel, cachePredictor='SIM'): + args = KerncraftParameters() + args['cache_predictor'] = cachePredictor + super(EcmAnalysis, self).__init__(ast, kerncraftMachineModel, ECM, args) + + def _repr_html(self): + pass + + +class BenchmarkAnalysis(Analysis): + + def __init__(self, ast, kerncraftMachineModel): + super(EcmAnalysis, self).__init__(ast, kerncraftMachineModel, Benchmark, KerncraftParameters()) + + def _repr_html(self): + pass + + # ------------------------------------------- Helper functions ---------------------------------------------------------