Commit 0b6b1589 by Martin Bauer

### Initial work on close kerncraft integration

parent 8d278092
 ... ... @@ -354,6 +354,13 @@ def extractCommonSubexpressions(equations): return equations def getLayoutFromStrides(strides, indexDimensionIds=[]): coordinates = list(range(len(strides))) relevantStrides = [stride for i, stride in enumerate(strides) if i not in indexDimensionIds] result = [x for (y, x) in sorted(zip(relevantStrides, coordinates), key=lambda pair: pair[0], reverse=True)] return normalizeLayout(result) def getLayoutOfArray(arr, indexDimensionIds=[]): """ Returns a list indicating the memory layout (linearization order) of the numpy array. ... ... @@ -368,10 +375,7 @@ def getLayoutOfArray(arr, indexDimensionIds=[]): The indexDimensionIds parameter leaves specifies which coordinates should not be """ coordinates = list(range(len(arr.shape))) relevantStrides = [stride for i, stride in enumerate(arr.strides) if i not in indexDimensionIds] result = [x for (y, x) in sorted(zip(relevantStrides, coordinates), key=lambda pair: pair[0], reverse=True)] return normalizeLayout(result) return getLayoutFromStrides(arr.strides, indexDimensionIds) def createNumpyArrayWithLayout(shape, layout): ... ...
 #include #define M 512*512 #define N 512*512 void twodfivept(double s, int n, double a[M][n], double b[M][n]) { for (int j = 1; j < (M - 1); ++j) for (int i = 1; i < (n - 1); ++i) b[j][i] = (a[j][i-1] + a[j][i+1] + a[j-1][i] + a[j+1][i]) * (s ? a[j][i-1] > 0 : 1.0); } int main(int argc, char **argv) { double a[M][N]; double b[M][N]; for(int i=0; i
 general: analysis: tool: LLVM (3.9.0svn) build: Apr 19 2016 (14:38:27) kernel: file: 2d-5pt.c_compilable.c function: twodfivept scop number: 0 arrays: a: type: double dimension: [*, n] b: type: double dimension: [*, n] loops: - index: i start: 0 stop: 262142 step: 1 - index: j start: 0 stop: (-2+n) step: 1 data sources: a: - [1+i, j] - [1+i, 2+j] - [i, 1+j] - [2+i, 1+j] data destinations: b: - [1+i, 1+j] flops: "+": 3 "*": 1 "f+": 4 "f*": 2
 arrays: a: type: double dimension: [30, 50] b: type: double dimension: [30, 50] loops: - index: i start: 0 stop: 262142 step: 1 - index: j start: 0 stop: (-2+20) step: 1 data sources: a: - [1+i, j] - [1+i, 2+j] - [i, 1+j] - [2+i, 1+j] data destinations: b: - [1+i, 1+j] flops: "+": 3 "*": 1
 import kerncraft from kerncraft.kernel import KernelCode from kernel import KernelDescription from pystencils.astnodes import LoopOverCoordinate from pystencils.cpu import createKernel from pystencils.field import getLayoutFromStrides from pystencils.sympyextensions import countNumberOfOperations from pystencils.transformations import typeAllEquations from pystencils import Field from collections import defaultdict class PyStencilsKerncraftKernel(kerncraft.kernel.Kernel): def __init__(self, listOfEquations, typeForSymbol=None): super(PyStencilsKerncraftKernel, self).__init__() pystencilsAst = createKernel(listOfEquations, typeForSymbol=typeForSymbol) self.ast = pystencilsAst fieldsRead, fieldsWritten, assignments = typeAllEquations(listOfEquations, typeForSymbol) allFields = fieldsRead.union(fieldsWritten) # Loops innerLoops = [l for l in pystencilsAst.atoms(LoopOverCoordinate) if l.isInnermostLoop] if len(innerLoops) == 0: raise ValueError("No loop found in pystencils AST") elif len(innerLoops) > 1: raise ValueError("pystencils AST contains multiple inner loops - only one can be analyzed") else: innerLoop = innerLoops[0] self._loop_stack = [] curNode = innerLoop while curNode is not None: if isinstance(curNode, LoopOverCoordinate): loopInfo = (curNode.loopCounterSymbol.name, curNode.start, curNode.stop, curNode.step) self._loop_stack.append(loopInfo) curNode = curNode.parent self._loop_stack = list(reversed(self._loop_stack)) # Data sources & destinations self._sources = defaultdict(list) self._destinations = defaultdict(list) for eq in listOfEquations: for accessesDict, expr in [(self._destinations, eq.lhs), (self._sources, eq.rhs)]: for fa in expr.atoms(Field.Access): coord = [sp.Symbol(LoopOverCoordinate.getLoopCounterName(i)) + off for i, off in enumerate(fa.offsets)] coord += list(fa.index) layout = getLayoutFromStrides(fa.field.strides) permutedCoord = [coord[i] for i in layout] accessesDict[fa.field.name].append(permutedCoord) # Variables (arrays) for field in allFields: layout = getLayoutFromStrides(field.strides) permutedShape = list(field.shape[i] for i in layout) self.set_variable(field.name, str(field.dtype), permutedShape) for param in pystencilsAst.parameters: if not param.isFieldArgument: self.set_variable(param.name, str(param.dtype), None) self._sources[param.name] = [None] # Datatype self.datatype = list(self.variables.values())[0][0] # Flops operationCount = countNumberOfOperations(listOfEquations) self._flops = { '+': operationCount['adds'], '*': operationCount['muls'], '/': operationCount['divs'], } self.check() from kerncraft.iaca_marker import find_asm_blocks, userselect_block, select_best_block from kerncraft.models import ECM, ECMData from kerncraft.machinemodel import MachineModel from ruamel import yaml if __name__ == "__main__": from pystencils import Field import sympy as sp import numpy as np from pystencils.cpu import generateC arr = np.zeros([80, 40], order='c') #arr = np.zeros([40, 80, 3], order='f') a = Field.createFromNumpyArray('a', arr, indexDimensions=0) b = Field.createFromNumpyArray('b', arr, indexDimensions=0) s = sp.Symbol("s") rhs = a[0, -1](0) + a[0, 1] + a[-1, 0] + a[1, 0] updateRule = sp.Eq(b[0, 0], s*rhs) k = PyStencilsKerncraftKernel([updateRule]) print(generateC(k.ast)) kernelFile = "2d-5pt.c" #k = KernelCode(open("/home/martin/dev/kerncraft/examples/kernels/" + kernelFile).read())] descr = yaml.load(open("/home/martin/dev/pystencils/pystencils/kerncraft/2d-5pt.yml").read()) k = KernelDescription(descr) k.print_kernel_info() k.print_variables_info() offsets = list(k.compile_global_offsets(1000)) print(offsets) machineFilePath = "/home/martin/dev/kerncraft/examples/machine-files/emmy.yaml" machine = MachineModel(path_to_yaml=machineFilePath) #exit(0) from kerncraft.kerncraft import create_parser parser = create_parser() parserArgs = parser.parse_args(["-m", machineFilePath, "-p", "ECMData", machineFilePath]) model = ECMData(k, machine, parserArgs) model.analyze() model.report() #blocks = find_asm_blocks(open("/home/martin/dev/kerncraft/2d-5pt.c_compilable.s").readlines()) #userselect_block(blocks) ##select_ #bestBlock = select_best_block(blocks) #print(bestBlock)
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!