From 92249115dcf9d45512738ea7af5ec95aa42f529a Mon Sep 17 00:00:00 2001
From: Jean-Baptiste Keck <Jean-Baptiste.Keck@imag.fr>
Date: Fri, 29 Sep 2017 16:09:54 +0200
Subject: [PATCH] fix unaligned subbuffer offsets, closes #1

---
 examples/scalar_advection/scalar_advection.py     |  6 +++---
 hysop/__init__.py                                 |  6 +++---
 .../codegen/functions/directional_remesh.py       |  7 ++++---
 hysop/backend/device/opencl/opencl_array.py       |  6 ------
 hysop/core/memory/memory_request.py               | 15 ++++++---------
 .../operator/tests/test_directional_advection.py  |  4 ++++
 6 files changed, 20 insertions(+), 24 deletions(-)

diff --git a/examples/scalar_advection/scalar_advection.py b/examples/scalar_advection/scalar_advection.py
index 9850f8220..ee713dfa1 100644
--- a/examples/scalar_advection/scalar_advection.py
+++ b/examples/scalar_advection/scalar_advection.py
@@ -31,12 +31,12 @@ def init_scalar(data, coords):
         data[0][...] *= cos(x)
 
 def run(npts=64+1, cfl=0.5):
-    dim = 2
+    dim = 3
     d3d=(npts,)*dim
     box = Box(length=(2*pi,)*dim)
     
-    impl = Implementation.PYTHON
-    #impl = Implementation.OPENCL_CODEGEN
+    # impl = Implementation.PYTHON
+    impl = Implementation.OPENCL_CODEGEN
 
     if impl is Implementation.OPENCL_CODEGEN:
         autotuner_config = OpenClKernelAutotunerConfig(
diff --git a/hysop/__init__.py b/hysop/__init__.py
index de2e02cf7..279e86abe 100644
--- a/hysop/__init__.py
+++ b/hysop/__init__.py
@@ -16,11 +16,11 @@ __FFTW_ENABLED__   = "ON"   is "ON"
 __SCALES_ENABLED__ = "ON" is "ON"
 __OPTIMIZE__       = not __debug__
 
-__VERBOSE__        = "ON"   in ["1", "3"]
-__DEBUG__          = "ON"   in ["2", "3"]
+__VERBOSE__        = False
+__DEBUG__          = False
 __TRACE__          = False
 __TRACE_WARNINGS__ = False
-__KERNEL_DEBUG__   = False
+__KERNEL_DEBUG__   = True
 __PROFILE__        = True
 
 __ENABLE_LONG_TESTS__ = "OFF" is "ON"
diff --git a/hysop/backend/device/codegen/functions/directional_remesh.py b/hysop/backend/device/codegen/functions/directional_remesh.py
index d91f23aa3..3cdb73085 100644
--- a/hysop/backend/device/codegen/functions/directional_remesh.py
+++ b/hysop/backend/device/codegen/functions/directional_remesh.py
@@ -229,6 +229,7 @@ class DirectionalRemeshFunction(OpenClFunctionCodeGenerator):
         y    = CodegenVectorClBuiltin(name='y',    btype=ftype, dim=nparticles, typegen=tg)
         ind  = CodegenVectorClBuiltin(name='ind',  btype=itype, dim=nparticles, typegen=tg)
         find = CodegenVectorClBuiltin(name='find', btype=ftype, dim=nparticles, typegen=tg)
+        vone = CodegenVectorClBuiltin(name='one', btype=ftype, dim=nparticles, typegen=tg)
         
         if poly_splitted:
             wl = CodegenVectorClBuiltin(name='Wl', btype=ftype, dim=nparticles, typegen=tg)
@@ -245,15 +246,15 @@ class DirectionalRemeshFunction(OpenClFunctionCodeGenerator):
                 eps.declare(s)
             s.jumpline()
             
-            s.decl_aligned_vars(find, ind, y)
+            s.decl_aligned_vars(find, ind, y, vone)
             s.decl_vars(*weights)
             s.jumpline()
             
             with if_thread_active():
                 code='{} = fract({}*{}, &{});'.format(y, pos, inv_dx, find)
                 s.append(code)
-
-                s.append('y = (1.0-y);') # the real MVP
+                
+                s.append('{} = ({}-{});'.format(y,vone,y)) # the real MVP
 
                 code = '{} = convert_{}_rtn({});'.format(ind, ivtype, find)
                 s.append(code)
diff --git a/hysop/backend/device/opencl/opencl_array.py b/hysop/backend/device/opencl/opencl_array.py
index 7b4fc690d..38094150d 100644
--- a/hysop/backend/device/opencl/opencl_array.py
+++ b/hysop/backend/device/opencl/opencl_array.py
@@ -52,17 +52,11 @@ class OpenClArray(Array):
             return self._handle.data
         except clArray.ArrayHasOffsetError:
              offset = self.offset
-             bdata  = self.base_data
              alignment = self.backend.device.mem_base_addr_align
-             print 'INT_PTR', bdata.int_ptr, bdata.int_ptr % alignment
-             print 'OFFSET', offset
-             print 'ALIGNMENT', alignment
-             print 'INT_PTR+OFFSET % ALIGNMENT', (bdata.int_ptr+offset)%alignment
              if (offset % alignment) == 0:
                  # try to return a subbuffer
                  buf = self.base_data.buf[offset:]
                  buf.__parent = self.base_data
-                 assert buf.int_ptr == self.int_ptr + offset
                  return buf
              else:
                  raise
diff --git a/hysop/core/memory/memory_request.py b/hysop/core/memory/memory_request.py
index 64f9b6d70..3e510e3b6 100644
--- a/hysop/core/memory/memory_request.py
+++ b/hysop/core/memory/memory_request.py
@@ -281,13 +281,13 @@ class MultipleOperatorMemoryRequests(object):
         for op,requests in op_requests.iteritems():
             check_instance(requests, list, values=MemoryRequest)
             start_idx, end_idx = 0, 0
-            ptr = data.int_ptr
             for req in requests:
-                # assert data.int_ptr % req.alignment == 0, '{}%{} = {}'.format(data.int_ptr, req.alignment, data.int_ptr % req.alignment)
                 req_views = []
                 size = req.data_bytes_per_component()
                 for i in xrange(req.nb_components):
-                    align_offset = (-ptr % req.alignment)
+                    # align on offset and not on pointer anymore (see issue #1)
+                    align_offset = (-start_idx % req.alignment)
+
                     start_idx += align_offset 
                     end_idx    = start_idx + size
                     
@@ -306,15 +306,12 @@ class MultipleOperatorMemoryRequests(object):
                         msg=msg.format(data.int_ptr+start_idx, view.int_ptr)
                         raise RuntimeError(msg)
 
-                    if (view.int_ptr % req.alignment) != 0:
-                        msg='FATAL ERROR: Could not provide requested alignment.'
-                        msg+=' Expected: {}B'
-                        msg+=' Actual:   {}B'
-                        msg=msg.format(req.alignment, view.int_ptr % req.alignment)
+                    if ((view.int_ptr-data.int_ptr) % req.alignment) != 0:
+                        msg='FATAL ERROR: Could not provide requested offset alignment.'
+                        msg=msg.format(req.alignment)
                         raise RuntimeError(msg)
 
                     start_idx = end_idx
-                    ptr += (align_offset + size)
                 if (op not in views):
                     views[op] = {}
                 if req.nb_components>=1:
diff --git a/hysop/operator/tests/test_directional_advection.py b/hysop/operator/tests/test_directional_advection.py
index 23bad1b5f..75182d6a8 100644
--- a/hysop/operator/tests/test_directional_advection.py
+++ b/hysop/operator/tests/test_directional_advection.py
@@ -167,10 +167,14 @@ class TestDirectionalAdvectionOperator(object):
                         dvin.initialize(self.__velocity_init, axes=axes)
                         dsin.initialize(self.__scalar_init)
                         S0 = dsin.integrate()
+                        print '\nVi = {}'.format(Vi)
+                        dvin.print_with_ghosts()
+                        dsin.print_with_ghosts()
 
                         simu.initialize()
                         while not simu.is_over:
                             split.apply(simulation=simu)
+                            dsout.print_with_ghosts()
                             Si = dsout.integrate()
                             if (np.abs(Si-S0)>1e-4).any():
                                 msg='Scalar was not conserved on iteration {}, expected {} but got {}.'
-- 
GitLab