From 7f8d6873ee200f8b8453cf93b673d531ead94515 Mon Sep 17 00:00:00 2001 From: Martin Bauer <martin.bauer@fau.de> Date: Mon, 5 Feb 2018 12:42:52 +0100 Subject: [PATCH] Bugfixes in LBM phase field code - 3 phase model works now with step sytem --- cpu/kernelcreation.py | 2 +- datahandling/datahandling_interface.py | 9 +++------ datahandling/parallel_datahandling.py | 11 ++++++----- datahandling/serial_datahandling.py | 17 +++++++++++------ gpucuda/kernelcreation.py | 2 ++ timeloop.py | 14 +++++++++----- 6 files changed, 32 insertions(+), 23 deletions(-) diff --git a/cpu/kernelcreation.py b/cpu/kernelcreation.py index f290942ce..af2ddae9c 100644 --- a/cpu/kernelcreation.py +++ b/cpu/kernelcreation.py @@ -136,7 +136,7 @@ def createIndexedKernel(listOfEquations, indexFields, functionName="kernel", typ loopBody.append(assignment) functionBody = Block([loopNode]) - ast = KernelFunction(functionBody, "cpu", functionName=functionName) + ast = KernelFunction(functionBody, backend="cpu", functionName=functionName) fixedCoordinateMapping = {f.name: coordinateTypedSymbols for f in nonIndexFields} resolveFieldAccesses(ast, set(['indexField']), fieldToFixedCoordinates=fixedCoordinateMapping) diff --git a/datahandling/datahandling_interface.py b/datahandling/datahandling_interface.py index 3d1ad21be..d4d1f428c 100644 --- a/datahandling/datahandling_interface.py +++ b/datahandling/datahandling_interface.py @@ -181,22 +181,19 @@ class DataHandling(ABC): # ------------------------------- Communication -------------------------------------------------------------------- - def synchronizationFunctionCPU(self, names, stencil=None, **kwargs): + @abstractmethod + def synchronizationFunction(self, names, stencil, target, **kwargs): """ Synchronizes ghost layers for distributed arrays - for serial scenario this has to be called for correct periodicity handling :param names: what data to synchronize: name of array or sequence of names :param stencil: stencil as string defining which neighbors are synchronized e.g. 'D2Q9', 'D3Q19' if None, a full synchronization (i.e. D2Q9 or D3Q27) is done + :param target: either 'cpu' or 'gpu :param kwargs: implementation specific, optional optimization parameters for communication :return: function object to run the communication """ - def synchronizationFunctionGPU(self, names, stencil=None, **kwargs): - """ - Synchronization of GPU fields, for documentation see CPU version above - """ - def reduceFloatSequence(self, sequence, operation, allReduce=False): """Takes a sequence of floating point values on each process and reduces it element wise to all processes (allReduce=True) or only to the root process (allReduce=False). diff --git a/datahandling/parallel_datahandling.py b/datahandling/parallel_datahandling.py index d35dbd3b0..2b1007434 100644 --- a/datahandling/parallel_datahandling.py +++ b/datahandling/parallel_datahandling.py @@ -205,7 +205,7 @@ class ParallelDataHandling(DataHandling): nameMap = self._fieldNameToCpuDataName toArray = wlb.field.toArray dataUsedInKernel = [(nameMap[p.fieldName], self.fields[p.fieldName]) - for p in kernelFunc.parameters if p.isFieldPtrArgument] + for p in kernelFunc.parameters if p.isFieldPtrArgument and p.fieldName not in kwargs] for block in self.blocks: fieldArgs = {} for dataName, f in dataUsedInKernel: @@ -229,10 +229,11 @@ class ParallelDataHandling(DataHandling): for block in self.blocks: transferFunc(block[self.GPU_DATA_PREFIX + name], block[name]) else: + print("trying to transfer ", self.GPU_DATA_PREFIX + name) wlb.cuda.copyFieldToGpu(self.blocks, self.GPU_DATA_PREFIX + name, name) def isOnGpu(self, name): - return name, self.GPU_DATA_PREFIX + name in self._cpuGpuPairs + return (name, self.GPU_DATA_PREFIX + name) in self._cpuGpuPairs def allToCpu(self): for cpuName, gpuName in self._cpuGpuPairs: @@ -247,12 +248,12 @@ class ParallelDataHandling(DataHandling): self.toGpu(name) def synchronizationFunctionCPU(self, names, stencil=None, buffered=True, **kwargs): - return self._synchronizationFunction(names, stencil, buffered, 'cpu') + return self.synchronizationFunction(names, stencil, 'cpu', buffered,) def synchronizationFunctionGPU(self, names, stencil=None, buffered=True, **kwargs): - return self._synchronizationFunction(names, stencil, buffered, 'gpu') + return self.synchronizationFunction(names, stencil, 'gpu', buffered) - def _synchronizationFunction(self, names, stencil, buffered, target): + def synchronizationFunction(self, names, stencil=None, target='cpu', buffered=True): if stencil is None: stencil = 'D3Q27' if self.dim == 3 else 'D2Q9' diff --git a/datahandling/serial_datahandling.py b/datahandling/serial_datahandling.py index caf446719..a70b48de1 100644 --- a/datahandling/serial_datahandling.py +++ b/datahandling/serial_datahandling.py @@ -1,11 +1,13 @@ -import numpy as np import itertools + +import numpy as np + from pystencils import Field +from pystencils.datahandling.datahandling_interface import DataHandling from pystencils.field import layoutStringToTuple, spatialLayoutStringToTuple, createNumpyArrayWithLayout from pystencils.parallel.blockiteration import SerialBlock from pystencils.slicing import normalizeSlice, removeGhostLayers from pystencils.utils import DotDict -from pystencils.datahandling.datahandling_interface import DataHandling try: import pycuda.gpuarray as gpuarray @@ -96,6 +98,8 @@ class SerialDataHandling(DataHandling): # cpuArr is always created - since there is no createPycudaArrayWithLayout() cpuArr = createNumpyArrayWithLayout(layout=layoutTuple, **kwargs) + cpuArr.fill(np.inf) + if cpu: if name in self.cpuArrays: raise ValueError("CPU Field with this name already exists") @@ -195,7 +199,7 @@ class SerialDataHandling(DataHandling): def runKernel(self, kernelFunc, *args, **kwargs): dataUsedInKernel = [self._fieldLatexNameToDataName[p.fieldName] - for p in kernelFunc.parameters if p.isFieldPtrArgument] + for p in kernelFunc.parameters if p.isFieldPtrArgument and p.fieldName not in kwargs] arrays = self.gpuArrays if kernelFunc.ast.backend == 'gpucuda' else self.cpuArrays arrayParams = {name: arrays[name] for name in dataUsedInKernel} arrayParams.update(kwargs) @@ -219,12 +223,12 @@ class SerialDataHandling(DataHandling): return name in self.gpuArrays def synchronizationFunctionCPU(self, names, stencilName=None, **kwargs): - return self._synchronizationFunctor(names, stencilName, 'cpu') + return self.synchronizationFunction(names, stencilName, 'cpu') def synchronizationFunctionGPU(self, names, stencilName=None, **kwargs): - return self._synchronizationFunctor(names, stencilName, 'gpu') + return self.synchronizationFunction(names, stencilName, 'gpu') - def _synchronizationFunctor(self, names, stencil, target): + def synchronizationFunction(self, names, stencil=None, target='cpu'): assert target in ('cpu', 'gpu') if not hasattr(names, '__len__') or type(names) is str: names = [names] @@ -337,3 +341,4 @@ class SerialDataHandling(DataHandling): indDims = 1 if self._fieldInformation[name]['fSize'] > 1 else 0 return removeGhostLayers(self.cpuArrays[name], indDims, glToRemove) + diff --git a/gpucuda/kernelcreation.py b/gpucuda/kernelcreation.py index 7797b46a3..2c25243d3 100644 --- a/gpucuda/kernelcreation.py +++ b/gpucuda/kernelcreation.py @@ -136,3 +136,5 @@ def createdIndexedCUDAKernel(listOfEquations, indexFields, functionName="kernel" ast.indexing = indexing ast.compile = partial(makePythonFunction, ast) return ast + + diff --git a/timeloop.py b/timeloop.py index b6f3cfd51..c5c88a04f 100644 --- a/timeloop.py +++ b/timeloop.py @@ -6,6 +6,7 @@ class TimeLoop: self._preRunFunctions = [] self._postRunFunctions = [] self._timeStepFunctions = [] + self._functionNames = [] self.timeStepsRun = 0 def addStep(self, stepObj): @@ -13,13 +14,16 @@ class TimeLoop: self.addPreRunFunction(stepObj.preRun) if hasattr(stepObj, 'postRun'): self.addPostRunFunction(stepObj.postRun) - self.add(stepObj.timeStep) + self.add(stepObj.timeStep, stepObj.name) - def add(self, timeStepFunction): + def add(self, timeStepFunction, name=None): + if name is None: + name = str(timeStepFunction) self._timeStepFunctions.append(timeStepFunction) + self._functionNames.append(name) - def addKernel(self, dataHandling, kernelFunc): - self._timeStepFunctions.append(lambda: dataHandling.runKernel(kernelFunc)) + def addKernel(self, dataHandling, kernelFunc, name=None): + self.add(lambda: dataHandling.runKernel(kernelFunc), name) def addPreRunFunction(self, f): self._preRunFunctions.append(f) @@ -27,7 +31,7 @@ class TimeLoop: def addPostRunFunction(self, f): self._postRunFunctions.append(f) - def run(self, timeSteps=0): + def run(self, timeSteps=1): self.preRun() try: -- GitLab