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

Initial work on close kerncraft integration

parent 8d278092
Branches
Tags
No related merge requests found
...@@ -354,6 +354,13 @@ def extractCommonSubexpressions(equations): ...@@ -354,6 +354,13 @@ def extractCommonSubexpressions(equations):
return 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=[]): def getLayoutOfArray(arr, indexDimensionIds=[]):
""" """
Returns a list indicating the memory layout (linearization order) of the numpy array. Returns a list indicating the memory layout (linearization order) of the numpy array.
...@@ -368,10 +375,7 @@ def getLayoutOfArray(arr, indexDimensionIds=[]): ...@@ -368,10 +375,7 @@ def getLayoutOfArray(arr, indexDimensionIds=[]):
The indexDimensionIds parameter leaves specifies which coordinates should not be The indexDimensionIds parameter leaves specifies which coordinates should not be
""" """
coordinates = list(range(len(arr.shape))) return getLayoutFromStrides(arr.strides, indexDimensionIds)
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)
def createNumpyArrayWithLayout(shape, layout): def createNumpyArrayWithLayout(shape, layout):
......
#include <stdlib.h>
#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<M; ++i)
for(int j=0; j<N; ++j)
a[i][j] = b[i][j] = 42.0;
twodfivept(0.23, N, a, b);
return 0;
}
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)
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