Skip to content
Snippets Groups Projects
Commit f93688c9 authored by Martin Bauer's avatar Martin Bauer
Browse files

Kerncraft support

parent b3827807
Branches
Tags
No related merge requests found
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)
from .kernel import PyStencilsKerncraftKernel, KerncraftParameters from .kerncraft_interface import EcmAnalysis, BenchmarkAnalysis
\ No newline at end of file
...@@ -7,6 +7,7 @@ benchmarkTemplate = Template(""" ...@@ -7,6 +7,7 @@ benchmarkTemplate = Template("""
#include "kerncraft.h" #include "kerncraft.h"
#include <stdlib.h> #include <stdlib.h>
#include <stdint.h> #include <stdint.h>
#include <stdbool.h>
#include <math.h> #include <math.h>
{%- if likwid %} {%- if likwid %}
#include <likwid.h> #include <likwid.h>
......
from tempfile import TemporaryDirectory, TemporaryFile, NamedTemporaryFile from tempfile import TemporaryDirectory
import sympy as sp import sympy as sp
import os import os
from collections import defaultdict from collections import defaultdict
import subprocess import subprocess
import kerncraft.kernel
import kerncraft 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.kerncraft.generate_benchmark import generateBenchmark
from pystencils.astnodes import LoopOverCoordinate, SympyAssignment, ResolvedFieldAccess from pystencils.astnodes import LoopOverCoordinate, SympyAssignment, ResolvedFieldAccess
from pystencils.field import getLayoutFromStrides from pystencils.field import getLayoutFromStrides
...@@ -108,7 +110,7 @@ class PyStencilsKerncraftKernel(kerncraft.kernel.Kernel): ...@@ -108,7 +110,7 @@ class PyStencilsKerncraftKernel(kerncraft.kernel.Kernel):
subprocess.check_output(compilerCmd + [srcFile, '-S', '-o', asmFile]) subprocess.check_output(compilerCmd + [srcFile, '-S', '-o', asmFile])
subprocess.check_output(compilerCmd + [dummySrcFile, '-S', '-o', dummyAsmFile]) subprocess.check_output(compilerCmd + [dummySrcFile, '-S', '-o', dummyAsmFile])
instrumentedAsmBlock = iaca_instrumentation(asmFile, pointer_increment='auto') instrumentedAsmBlock = iaca_instrumentation(asmFile,)
# assemble asm files to executable # assemble asm files to executable
subprocess.check_output(compilerCmd + [asmFile, dummyAsmFile, '-o', binaryFile]) subprocess.check_output(compilerCmd + [asmFile, dummyAsmFile, '-o', binaryFile])
...@@ -151,6 +153,43 @@ class KerncraftParameters(DotDict): ...@@ -151,6 +153,43 @@ class KerncraftParameters(DotDict):
self['verbose'] = 0 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 --------------------------------------------------------- # ------------------------------------------- Helper functions ---------------------------------------------------------
......
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment