From 3cdcef4d9bf6dea15a67770c287c13be88a6e553 Mon Sep 17 00:00:00 2001
From: Martin Bauer <martin.bauer@fau.de>
Date: Thu, 11 Jan 2018 16:53:57 +0100
Subject: [PATCH] Python: accessing GPU fields from python - ghost layer info

---
 python/waLBerla/cuda_extension.py  | 14 ++++++++---
 python/waLBerla/field_extension.py | 40 ++++++++++++++++--------------
 2 files changed, 33 insertions(+), 21 deletions(-)

diff --git a/python/waLBerla/cuda_extension.py b/python/waLBerla/cuda_extension.py
index be218d116..aecd783cd 100644
--- a/python/waLBerla/cuda_extension.py
+++ b/python/waLBerla/cuda_extension.py
@@ -1,14 +1,22 @@
 from pycuda.gpuarray import GPUArray
 import numpy as np
+from .field_extension import normalizeGhostlayerInfo
 
-def toGpuArray(f):
+
+def toGpuArray(f, withGhostLayers=True):
     """Converts a waLBerla GPUField to a pycuda GPUArray"""
     if not f:
         return None
     dtype = np.dtype(f.dtypeStr)
     strides = [dtype.itemsize*a for a in f.strides]
-    return GPUArray(f.sizeWithGhostLayers, dtype, gpudata=f.ptr, strides=strides)
-
+    res = GPUArray(f.sizeWithGhostLayers, dtype, gpudata=f.ptr, strides=strides)
+    ghostLayers = normalizeGhostlayerInfo(f, withGhostLayers)
+    glCutoff = [ f.nrOfGhostLayers - gl for gl in ghostLayers ]
+    res = res[ glCutoff[0]:-glCutoff[0] if glCutoff[0] > 0 else None,
+               glCutoff[1]:-glCutoff[1] if glCutoff[1] > 0 else None,
+               glCutoff[2]:-glCutoff[2] if glCutoff[2] > 0 else None,
+               : ]
+    return res
 
 def extend(cppCudaModule):
     cppCudaModule.toGpuArray = toGpuArray
diff --git a/python/waLBerla/field_extension.py b/python/waLBerla/field_extension.py
index 7856c4ed9..3ec291da6 100644
--- a/python/waLBerla/field_extension.py
+++ b/python/waLBerla/field_extension.py
@@ -7,6 +7,25 @@ except ImportError:
 
 # ----------------------------- Python functions to extend the C++ field module ---------------------------------
 
+def normalizeGhostlayerInfo( field, withGhostLayers):
+    """Takes one ghost layer parameter and returns an integer:
+        True -> all ghost layers, False->no ghost layers"""
+
+    def normalizeComponent(gl):
+        if gl == False:
+            return 0
+        if gl == True:
+            return field.nrOfGhostLayers
+        if gl > field.nrOfGhostLayers:
+            raise ValueError("Field only has %d ghost layers (requested %d)" % ( field.nrOfGhostLayers, gl ) )
+        return gl
+
+    if hasattr( withGhostLayers, "__len__") and len(withGhostLayers) == 3:
+        ghostLayers = [ normalizeComponent(gl) for gl in withGhostLayers ]
+    else:
+        ghostLayers = [ normalizeComponent(withGhostLayers) ] * 3
+    return ghostLayers
+
 def npArrayFromWaLBerlaField(field, withGhostLayers=False):
     """ Creates a numpy array view on the waLBerla field data
         @field: the waLBerla field
@@ -19,24 +38,9 @@ def npArrayFromWaLBerlaField(field, withGhostLayers=False):
     
     if not field:
         return None
-    
-    def normalizeGhostlayerInfo( field, gl ):
-        """Takes one ghost layer parameter and returns an integer:
-            True -> all ghost layers, False->no ghost layers"""
-        if gl == False:
-            return 0
-        if gl == True:
-            return field.nrOfGhostLayers
-        if gl > field.nrOfGhostLayers:
-            raise ValueError("Field only has %d ghost layers (requested %d)" % ( field.nrOfGhostLayers, gl ) )     
-        return gl
-    
-    if hasattr( withGhostLayers, "__len__") and len(withGhostLayers) == 3:
-        ghostLayers = [ normalizeGhostlayerInfo(field, gl) for gl in withGhostLayers ]
-    else:
-        ghostLayers = [ normalizeGhostlayerInfo(field, withGhostLayers) ] * 3
-    
-    
+
+    ghostLayers = normalizeGhostlayerInfo(field, withGhostLayers)
+
     if not hasattr(field, 'buffer'): # Field adaptor -> create field with adapted values
         field = field.copyToField()
     
-- 
GitLab