From a12d57700787657659c543962b4ec9211115a07f Mon Sep 17 00:00:00 2001
From: Keck Jean-Baptiste <jean-baptiste.keck@imag.fr>
Date: Tue, 6 Jun 2017 21:36:21 +0200
Subject: [PATCH] fixed topologies

---
 .../device/codegen/functions/advection_rhs.py | 14 +++---
 .../device/codegen/functions/apply_stencil.py |  8 ++--
 .../device/codegen/functions/cache_load.py    |  8 ++--
 .../device/codegen/functions/compute_index.py |  2 +-
 .../codegen/functions/stretching_rhs.py       | 16 +++----
 .../codegen/kernels/directional_advection.py  | 45 +++++++------------
 .../codegen/kernels/directional_stretching.py | 14 +++---
 .../tests/test_directional_advection.py       | 25 +++++++----
 .../tests/test_directional_stretching.py      | 14 +++---
 .../device/opencl/opencl_array_backend.py     | 18 ++++++--
 .../operator/directional/advection_dir.py     | 18 +++++---
 .../host/fortran/operator/diffusion.py        |  8 +++-
 .../host/fortran/operator/fortran_fftw.py     | 20 +++++----
 .../backend/host/fortran/operator/poisson.py  | 14 +++---
 hysop/backend/host/host_allocator.py          |  3 +-
 hysop/backend/host/host_array_backend.py      |  2 +-
 hysop/core/arrays/array_backend.py            | 14 ++++++
 hysop/core/graph/computational_graph.py       | 11 ++++-
 hysop/core/graph/computational_node.py        | 31 +++++++++++--
 hysop/core/graph/computational_operator.py    | 14 ++++++
 hysop/core/memory/mempool.py                  |  2 +-
 hysop/core/mpi/redistribute.py                |  1 +
 hysop/core/mpi/topology.py                    |  4 +-
 hysop/deps.py                                 |  2 +-
 24 files changed, 198 insertions(+), 110 deletions(-)

diff --git a/hysop/backend/device/codegen/functions/advection_rhs.py b/hysop/backend/device/codegen/functions/advection_rhs.py
index da083a708..23cc392a3 100644
--- a/hysop/backend/device/codegen/functions/advection_rhs.py
+++ b/hysop/backend/device/codegen/functions/advection_rhs.py
@@ -18,7 +18,7 @@ from hysop.numerics.stencil.stencil import Stencil
 class DirectionalAdvectionRhsFunction(OpenClFunctionCodeGenerator):
 
     def __init__(self, typegen, ftype, work_dim, nparticles, is_cached, boundary,
-            restrict=True, 
+            ptr_restrict=True, 
             itype='int', 
             known_args=None):
         
@@ -36,10 +36,10 @@ class DirectionalAdvectionRhsFunction(OpenClFunctionCodeGenerator):
         vtype = typegen.vtype(ftype,nparticles)
 
         (args,basename) = self.build_prototype(typegen,work_dim,itype,ftype,vtype,
-                nparticles,restrict,storage,is_cached, is_periodic)
+                nparticles,ptr_restrict,storage,is_cached, is_periodic)
 
         reqs = self.build_requirements(typegen,work_dim,itype,ftype,vtype,
-                nparticles,restrict,storage,is_cached, is_periodic)
+                nparticles,ptr_restrict,storage,is_cached, is_periodic)
         
         super(DirectionalAdvectionRhsFunction,self).__init__(basename=basename,
                 output=vtype,typegen=typegen,inline=True,
@@ -61,19 +61,19 @@ class DirectionalAdvectionRhsFunction(OpenClFunctionCodeGenerator):
         self.gencode()
 
     def build_prototype(self,typegen,work_dim,itype,ftype,vtype,
-            nparticles,restrict,storage,is_cached, is_periodic):
+            nparticles,ptr_restrict,storage,is_cached, is_periodic):
 
         args = ArgDict()
         
         args['line_velocity'] = CodegenVariable('line_velocity', ftype, typegen, const=True, add_impl_const=True, 
-                storage=storage, ptr=True, restrict=restrict, nl=True)
+                storage=storage, ptr=True, ptr_restrict=ptr_restrict, nl=True)
         args['X'] = CodegenVectorClBuiltin('X', ftype, nparticles, typegen, add_impl_const=True, nl=True)
         
         if is_periodic and (not is_cached):
             args['line_width']   = CodegenVariable('line_width',   itype, typegen, add_impl_const=True)
         args['line_offset']   = CodegenVariable('line_offset',  itype, typegen, add_impl_const=True,nl=True)
 
-        args['rk_step'] = CodegenVariable('rk_step', itype, typegen, add_impl_const=True)
+        args['rk_step'] = CodegenVariable('rk_step', itype, typegen)
         args['inv_dx'] = CodegenVariable('inv_dx', ftype, typegen, add_impl_const=True, nl=True)
         # args['active'] = CodegenVariable('active','bool',typegen, add_impl_const=True)
         
@@ -83,7 +83,7 @@ class DirectionalAdvectionRhsFunction(OpenClFunctionCodeGenerator):
         return (args,basename)
 
     def build_requirements(self,typegen,work_dim,itype,ftype,vtype,
-            nparticles,restrict,storage,is_cached, is_periodic):
+            nparticles,ptr_restrict,storage,is_cached, is_periodic):
         reqs = WriteOnceDict()
         return reqs
 
diff --git a/hysop/backend/device/codegen/functions/apply_stencil.py b/hysop/backend/device/codegen/functions/apply_stencil.py
index 682e7c269..1fdd04e1f 100644
--- a/hysop/backend/device/codegen/functions/apply_stencil.py
+++ b/hysop/backend/device/codegen/functions/apply_stencil.py
@@ -21,7 +21,7 @@ class ApplyStencilFunction(OpenClFunctionCodeGenerator):
             op='{vinput0}[id]',
             custom_id=None,
             vector_suffixes=None,
-            data_storage='__local', restrict=True,
+            data_storage='__local', ptr_restrict=True,
             multipliers={},
             itype='int', 
             known_args=None):
@@ -48,17 +48,17 @@ class ApplyStencilFunction(OpenClFunctionCodeGenerator):
             if vectorize:
                 name = iname
                 args[name] = CodegenVariable(name, vtype, typegen, const=True, 
-                    add_impl_const=True, storage=data_storage, ptr=True, restrict=restrict)
+                    add_impl_const=True, storage=data_storage, ptr=True, ptr_restrict=ptr_restrict)
             else:
                 for i in xrange(components):
                     name = '{}{}'.format(iname,vector_suffixes[i])
                     args[name] = CodegenVariable(name, ftype, typegen, 
                             const=True, add_impl_const=True, storage=data_storage, 
-                            ptr=True, restrict=restrict)
+                            ptr=True, ptr_restrict=ptr_restrict)
         for iname in scalar_inputs:
             name = iname
             args[name] = CodegenVariable(name, ftype, typegen, const=True, 
-                    add_impl_const=True, storage=data_storage, ptr=True, restrict=restrict)
+                    add_impl_const=True, storage=data_storage, ptr=True, ptr_restrict=ptr_restrict)
         for arg in extra_inputs:
             args[arg.name] = arg
         
diff --git a/hysop/backend/device/codegen/functions/cache_load.py b/hysop/backend/device/codegen/functions/cache_load.py
index 29782fa47..852d8eb28 100644
--- a/hysop/backend/device/codegen/functions/cache_load.py
+++ b/hysop/backend/device/codegen/functions/cache_load.py
@@ -48,20 +48,20 @@ class CacheLoadFunction(OpenClFunctionCodeGenerator):
         args = ArgDict()
         if src_vectorize:
             args['src'] = CodegenVariable('src', vtype, typegen=tg, ptr=True, const=True,  
-                    storage='__global', nl=True, restrict=True)
+                    storage='__global', nl=True, ptr_restrict=True)
         else:
             for i in xrange(components):
                 src = 'src{}'.format(i)
                 args[src] = CodegenVariable(src, ftype, typegen=tg, ptr=True, const=True, 
-                        storage='__global', nl=True, restrict=True)
+                        storage='__global', nl=True, ptr_restrict=True)
         if dst_vectorize:
             args['dst'] = CodegenVariable('dst', vtype, typegen=tg, ptr=True, const=False, 
-                    storage='__local' , nl=True, restrict=True)
+                    storage='__local' , nl=True, ptr_restrict=True)
         else:
             for i in xrange(components):
                 dst = 'dst{}'.format(i)
                 args[dst] = CodegenVariable(dst, ftype, typegen=tg, ptr=True, const=False, 
-                        storage='__local' , nl=True, restrict=True)
+                        storage='__local' , nl=True, ptr_restrict=True)
 
         args['global_id']  = CodegenVectorClBuiltin('gid',itype,work_dim,typegen,
                 add_impl_const=False)
diff --git a/hysop/backend/device/codegen/functions/compute_index.py b/hysop/backend/device/codegen/functions/compute_index.py
index 2a92a6c30..2208ac321 100644
--- a/hysop/backend/device/codegen/functions/compute_index.py
+++ b/hysop/backend/device/codegen/functions/compute_index.py
@@ -12,7 +12,7 @@ class ComputeIndexFunction(OpenClFunctionCodeGenerator):
     def __init__(self,typegen,dim,wrap=None,itype='int'):
         assert dim>0
         args = ArgDict()
-        args['idx']  = CodegenVectorClBuiltin('idx', 'int', dim, typegen, add_impl_const=(wrap==False))
+        args['idx']  = CodegenVectorClBuiltin('idx', 'int', dim, typegen, add_impl_const=bool(wrap==False))
         args['size'] = CodegenVectorClBuiltin('size', itype, dim, typegen, add_impl_const=True)
         args['wrap'] = CodegenVariable('wrap', 'bool',typegen, add_impl_const=True, value=wrap)
 
diff --git a/hysop/backend/device/codegen/functions/stretching_rhs.py b/hysop/backend/device/codegen/functions/stretching_rhs.py
index fcb9f2bcb..5cda6360b 100644
--- a/hysop/backend/device/codegen/functions/stretching_rhs.py
+++ b/hysop/backend/device/codegen/functions/stretching_rhs.py
@@ -27,7 +27,7 @@ class DirectionalStretchingRhsFunction(OpenClFunctionCodeGenerator):
     }
     
     def __init__(self, typegen, dim, ftype, order, direction, formulation, cached, boundary,
-            restrict=True, vectorize_u=False,
+            ptr_restrict=True, vectorize_u=False,
             itype='int', 
             used_variables = _default_used_variables,
             known_args=None):
@@ -50,11 +50,11 @@ class DirectionalStretchingRhsFunction(OpenClFunctionCodeGenerator):
         vtype = typegen.vtype(ftype,dim)
 
         (args,basename) = self.build_prototype(typegen,dim,itype,ftype,vtype,order,
-                direction,cached,restrict,storage,vectorize_u,used_variables,
+                direction,cached,ptr_restrict,storage,vectorize_u,used_variables,
                 formulation,is_conservative,is_periodic)
 
         reqs = self.build_requirements(typegen,dim,itype,ftype,vtype,order,direction,
-                boundary,cached,restrict,storage,vectorize_u,used_variables,
+                boundary,cached,ptr_restrict,storage,vectorize_u,used_variables,
                 is_conservative,is_periodic,args)
         
         super(DirectionalStretchingRhsFunction,self).__init__(basename=basename,
@@ -82,7 +82,7 @@ class DirectionalStretchingRhsFunction(OpenClFunctionCodeGenerator):
         self.gencode()
 
     def build_prototype(self,typegen,dim,itype,ftype,vtype,order,direction,cached,
-            restrict,storage, vectorize_u,used_variables,formulation,is_conservative,is_periodic):
+            ptr_restrict,storage, vectorize_u,used_variables,formulation,is_conservative,is_periodic):
 
         U = used_variables['U']
         W = used_variables['W']
@@ -91,14 +91,14 @@ class DirectionalStretchingRhsFunction(OpenClFunctionCodeGenerator):
         
         args = ArgDict()
         if vectorize_u:
-            args[U] = CodegenVariable(U, vtype, typegen, const=True, add_impl_const=True, storage=storage, ptr=True, restrict=restrict,nl=True)
+            args[U] = CodegenVariable(U, vtype, typegen, const=True, add_impl_const=True, storage=storage, ptr=True, ptr_restrict=ptr_restrict,nl=True)
         else:
             for i in xrange(dim):
                 Uxyz= '{}{}'.format(U,xyz[i])
-                args[Uxyz] = CodegenVariable(Uxyz, ftype, typegen, const=True, add_impl_const=True, storage=storage, ptr=True, restrict=restrict, nl=True)
+                args[Uxyz] = CodegenVariable(Uxyz, ftype, typegen, const=True, add_impl_const=True, storage=storage, ptr=True, ptr_restrict=ptr_restrict, nl=True)
         if is_conservative:
                 Wd= '{}{}'.format(W,xyz[direction])
-                args[Wd] = CodegenVariable(Wd, ftype, typegen, const=False, add_impl_const=True, storage=storage, ptr=True, restrict=restrict, nl=True)
+                args[Wd] = CodegenVariable(Wd, ftype, typegen, const=False, add_impl_const=True, storage=storage, ptr=True, ptr_restrict=ptr_restrict, nl=True)
                 
         args[W]        = CodegenVectorClBuiltin(W, ftype, dim, typegen, add_impl_const=True)
         args['inv_dx'] = CodegenVariable('inv_dx', ftype, typegen, add_impl_const=True, nl=True)
@@ -130,7 +130,7 @@ class DirectionalStretchingRhsFunction(OpenClFunctionCodeGenerator):
         return stencil
         
     def build_requirements(self, typegen,dim,itype,ftype,vtype,order,direction,boundary,cached,
-            restrict,storage,vectorize_u,used_variables,is_conservative,is_periodic,args):
+            ptr_restrict,storage,vectorize_u,used_variables,is_conservative,is_periodic,args):
 
         reqs = WriteOnceDict()
 
diff --git a/hysop/backend/device/codegen/kernels/directional_advection.py b/hysop/backend/device/codegen/kernels/directional_advection.py
index d22ec82ba..283ad06fc 100644
--- a/hysop/backend/device/codegen/kernels/directional_advection.py
+++ b/hysop/backend/device/codegen/kernels/directional_advection.py
@@ -230,7 +230,7 @@ class DirectionalAdvectionKernel(KernelCodeGenerator):
         advection_rhs = DirectionalAdvectionRhsFunction(typegen=typegen, work_dim=work_dim, 
                 ftype=ftype, is_cached=is_cached,
                 boundary=vboundary[0], nparticles=nparticles,
-                restrict=True,
+                ptr_restrict=True,
                 itype=itype)
    
         used_vars = RungeKuttaFunction._default_used_vars.copy()
@@ -253,22 +253,22 @@ class DirectionalAdvectionKernel(KernelCodeGenerator):
                 add_impl_const=True,nl=True)
 
         kargs['velocity_base'] = CodegenVariable(storage=self._global,name='velocity_base',
-                ctype=ftype, typegen=typegen, restrict=True,ptr=True,const=True,
+                ctype=ftype, typegen=typegen, ptr_restrict=True,ptr=True,const=True,
                 add_impl_const=True, nl=False)
         kargs['velocity_offset'] = CodegenVariable(ctype='unsigned long',name='velocity_offset',
                 typegen=typegen, add_impl_const=True,nl=True)
 
         kargs['position_base'] = CodegenVariable(storage=self._global,name='position_base',
-                ctype=ftype, typegen=typegen, restrict=True, ptr=True,const=False,
+                ctype=ftype, typegen=typegen, ptr_restrict=True, ptr=True,const=False,
                 add_impl_const=True, nl=False)
         kargs['position_offset'] = CodegenVariable(ctype='unsigned long',name='position_offset',
                 typegen=typegen,add_impl_const=True,nl=True)
         
         if debug_mode:
             kargs['dbg0'] = CodegenVariable(storage=self._global,name='dbg0',ctype=itype,
-                    typegen=typegen, restrict=True,ptr=True,const=False,add_impl_const=True)
+                    typegen=typegen, ptr_restrict=True,ptr=True,const=False,add_impl_const=True)
             kargs['dbg1'] = CodegenVariable(storage=self._global,name='dbg1',ctype=itype,
-                    typegen=typegen, restrict=True,ptr=True,const=False,add_impl_const=True)
+                    typegen=typegen, ptr_restrict=True,ptr=True,const=False,add_impl_const=True)
 
         kargs['velocity_mesh_info'] = requirements['MeshInfoStruct'].build_codegen_variable(
                 const=True, name='velocity_mesh_info')
@@ -277,7 +277,7 @@ class DirectionalAdvectionKernel(KernelCodeGenerator):
 
         if is_cached and not local_size_known:
              kargs['Vc'] = CodegenVariable(storage=_local,ctype=ftype, add_impl_const=True,
-                     name='Vc', ptr=True, restrict=True, typegen=typegen, nl=False)
+                     name='Vc', ptr=True, ptr_restrict=True, typegen=typegen, nl=False)
 
         return kargs
     
@@ -321,10 +321,10 @@ class DirectionalAdvectionKernel(KernelCodeGenerator):
         position_offset = s.vars['position_offset']
 
         velocity = CodegenVariable(storage=s._global,name='velocity',
-                ctype=ftype, typegen=tg, restrict=True, ptr=True, const=True,
+                ctype=ftype, typegen=tg, ptr_restrict=True, ptr=True, const=True,
                 add_impl_const=True)
         position = CodegenVariable(storage=s._global,name='position',
-                ctype=ftype, typegen=tg, restrict=True, ptr=True, const=False)
+                ctype=ftype, typegen=tg, ptr_restrict=True, ptr=True, const=False)
         
         grid_size           = position_mesh_info['local_mesh']['resolution'].view(
                                             'grid_size', slice(None,work_dim))
@@ -347,7 +347,7 @@ class DirectionalAdvectionKernel(KernelCodeGenerator):
         line_index    = CodegenVariable(name='line_index', ctype=itype, typegen=tg)
         line_offset   = CodegenVariable(name='line_offset', ctype=itype, typegen=tg,const=True)
         line_velocity = CodegenVariable(name='line_velocity', ctype=ftype, ptr=True, 
-                storage='__global', restrict=True, const=True, add_impl_const=True, typegen=tg)
+                storage='__global', ptr_restrict=True, const=True, add_impl_const=True, typegen=tg)
 
         X           = CodegenVectorClBuiltin('X',       ftype, nparticles, typegen=tg)
         pid         = CodegenVectorClBuiltin('pid',     itype, nparticles, typegen=tg, 
@@ -588,36 +588,25 @@ class DirectionalAdvectionKernel(KernelCodeGenerator):
             p_ghosts     = position_mesh_info['ghosts'].value[:dim]
             p_dx         = position_mesh_info['dx'].value[:dim]
 
-            vboundary = (v_lboundary[dir], v_rboundary[dir])
+            vboundary = (v_lboundary[0], v_rboundary[0])
 
             min_v_ghosts = int(math.ceil(cfl))
-            min_p_ghosts = int(math.ceil(cfl*v_dx[direction]/p_dx[direction]))
+            min_p_ghosts = 0
             assert (min_v_ghosts>=1)
-            assert (min_p_ghosts>=1)
 
             if not cl_env.is_multi_device: 
-                if v_lboundary[dir] == BoundaryCondition.PERIODIC:
-                    assert v_rboundary[dir] == BoundaryCondition.PERIODIC
+                if v_lboundary[0] == BoundaryCondition.PERIODIC:
+                    assert v_rboundary[0] == BoundaryCondition.PERIODIC
                     min_v_ghosts = 0
-                if p_lboundary[dir] == BoundaryCondition.PERIODIC:
-                    assert p_rboundary[dir] == BoundaryCondition.PERIODIC
-                    min_p_ghosts = 0
 
-            if (v_ghosts[dir] < min_v_ghosts):
-                msg= 'Given boundary condition implies minimum ghosts numbers to be at least {}'
+            if (v_ghosts[0] < min_v_ghosts):
+                msg= 'Given boundary condition implies minimum ghosts numbers to be at least {} '
                 msg+='in current direction for velocity but only {} ghosts '
                 msg+='are present in the grid.'
-                msg=msg.format(min_v_ghosts, v_ghosts[dir])
+                msg=msg.format(min_v_ghosts, v_ghosts[0])
                 raise ValueError(msg)
             
-            if (p_ghosts[dir] < min_p_ghosts):
-                msg= 'Given boundary condition implies minimum ghosts numbers to be at least {}'
-                msg+='in current direction for position but only {} ghosts '
-                msg+='are present in the grid.'
-                msg=msg.format(min_p_ghosts, p_ghosts[dir])
-                raise ValueError(msg)
-
-            is_multi_scale = (v_resolution[dir] != p_resolution[dir])
+            is_multi_scale = (v_resolution[0] != p_resolution[0])
             if is_multi_scale:
                 msg='Compute_resolution mismatch between velocity and particles, '
                 msg+='got {} and {} and multiscale has not been implemented yet.'
diff --git a/hysop/backend/device/codegen/kernels/directional_stretching.py b/hysop/backend/device/codegen/kernels/directional_stretching.py
index 76b621a26..96363a696 100644
--- a/hysop/backend/device/codegen/kernels/directional_stretching.py
+++ b/hysop/backend/device/codegen/kernels/directional_stretching.py
@@ -261,7 +261,7 @@ class DirectionalStretchingKernel(KernelCodeGenerator):
                 ftype=ftype, cached=is_cached,
                 order=order, direction=direction, boundary=boundary,
                 formulation=formulation,
-                restrict=True, vectorize_u=False,
+                ptr_restrict=True, vectorize_u=False,
                 itype='int')
    
         used_vars = RungeKuttaFunction._default_used_vars.copy()
@@ -292,17 +292,17 @@ class DirectionalStretchingKernel(KernelCodeGenerator):
         for i in xrange(work_dim):
             name = svelocity+xyz[i]
             kargs[name] = CodegenVariable(storage=_global,name=name,typegen=typegen,
-                ctype=ftype,ptr=True,restrict=True,const=True,add_impl_const=True)
+                ctype=ftype,ptr=True,ptr_restrict=True,const=True,add_impl_const=True)
 
         for i in xrange(work_dim):
             name = svorticity+xyz[i]+'_in'
             kargs[name] = CodegenVariable(storage=_global,name=name,typegen=typegen,
-              ctype=ftype,ptr=True,restrict=(not is_inplace),const=True,add_impl_const=True)
+              ctype=ftype,ptr=True,ptr_restrict=(not is_inplace),const=True,add_impl_const=True)
         
         for i in xrange(work_dim):
             name = svorticity+xyz[i]+'_out'
             kargs[name] = CodegenVariable(storage=_global,name=name,typegen=typegen,
-              ctype=ftype,ptr=True,restrict=(not is_inplace),const=False,add_impl_const=True)
+              ctype=ftype,ptr=True,ptr_restrict=(not is_inplace),const=False,add_impl_const=True)
 
         kargs['velocity_mesh_info'] = \
                 requirements['MeshInfoStruct'].build_codegen_variable(const=True,
@@ -313,7 +313,7 @@ class DirectionalStretchingKernel(KernelCodeGenerator):
 
         if is_cached and not local_size_known:
              kargs['buffer'] = CodegenVariable(storage=_local,ctype=ftype, 
-                     add_impl_const=True, name='buffer', ptr=True, restrict=True, 
+                     add_impl_const=True, name='buffer', ptr=True, ptr_restrict=True, 
                      typegen=typegen, nl=False)
 
         self.svorticity = svorticity
@@ -393,7 +393,7 @@ class DirectionalStretchingKernel(KernelCodeGenerator):
                     buf = s.vars['buffer']
                     init = '{} + {}*{}'.format(buf(), i, local_size[0])
                     Vic = CodegenVariable(storage=storage,name=Vi+'c',ctype=ftype,typegen=tg,
-                                const=True, restrict=True,ptr=True,init=init)
+                                const=True, ptr_restrict=True,ptr=True,init=init)
                 cached_vars[Vi] = Vic 
             
             if is_conservative:
@@ -405,7 +405,7 @@ class DirectionalStretchingKernel(KernelCodeGenerator):
                     buf = s.vars['buffer']
                     init = '{} + {}*{}'.format(buf(), work_dim, local_size[0])
                     Wic = CodegenVariable(storage=storage,name=Wi+'c',ctype=ftype,typegen=tg,
-                                    const=True, restrict=True,ptr=True,init=init)
+                                    const=True, ptr_restrict=True,ptr=True,init=init)
                 cached_vars[Wi] = Wic 
 
         _U   = self.svelocity
diff --git a/hysop/backend/device/codegen/kernels/tests/test_directional_advection.py b/hysop/backend/device/codegen/kernels/tests/test_directional_advection.py
index 0ef8ad42a..5c9d905df 100644
--- a/hysop/backend/device/codegen/kernels/tests/test_directional_advection.py
+++ b/hysop/backend/device/codegen/kernels/tests/test_directional_advection.py
@@ -22,7 +22,8 @@ class TestDirectionalAdvection(object):
         ctx = typegen.context
 
         grid_size = np.asarray([64,64,1])
-        (A,grid_mesh_info) = _test_mesh_info(typegen,3,0,grid_size)
+        (A,grid_mesh_info) = _test_mesh_info('velocity_mesh_info',typegen,3,0,grid_size)
+        (_,position_mesh_info) = _test_mesh_info('position_mesh_info',typegen,3,0,grid_size)
         
         dx     = A['dx'][0][0]
         inv_dx = A['inv_dx'][0][0]
@@ -30,14 +31,14 @@ class TestDirectionalAdvection(object):
         
         umax = 1.0
         min_ghosts = int(math.ceil(dt*umax/float(dx)))
-        ghosts = min_ghosts + 0
+        ghosts = min_ghosts
 
         print 'min ghosts are: {}'.format(min_ghosts)
         print 'actual ghosts are: {}'.format(ghosts)
         
         compute_grid_ghosts = np.asarray([ghosts,0,0])
         compute_grid_size   = grid_size + 2*compute_grid_ghosts
-        (B,compute_grid_mesh_info) = _test_mesh_info(typegen,3,compute_grid_ghosts,compute_grid_size)
+        (B,compute_grid_mesh_info) = _test_mesh_info('velocity_mesh_info',typegen,3,compute_grid_ghosts,compute_grid_size)
         
         grid_shape         = grid_size[::-1]
         compute_grid_shape = compute_grid_size[::-1]
@@ -101,6 +102,7 @@ class TestDirectionalAdvection(object):
 
         cls.grid_mesh_info         = grid_mesh_info
         cls.compute_grid_mesh_info = compute_grid_mesh_info
+        cls.position_mesh_info     = position_mesh_info
 
         cls.compute_grid_ghosts = compute_grid_ghosts
         cls.compute_grid_size   = compute_grid_size
@@ -243,15 +245,16 @@ class TestDirectionalAdvection(object):
         assert grid_size[0] % nparticles == 0
 
         kernel_args = [dt]
+        position_mesh_info = self.position_mesh_info
         if boundary   == BoundaryCondition.PERIODIC:
             target = 'no_ghosts'
-            mesh_info = self.grid_mesh_info
+            velocity_mesh_info = self.grid_mesh_info
             view = [slice(0,grid_size[2]),
                     slice(0,grid_size[1]),
                     slice(0,grid_size[0])]
         elif boundary == BoundaryCondition.NONE:
             target = 'with_ghosts'
-            mesh_info = self.compute_grid_mesh_info
+            velocity_mesh_info = self.compute_grid_mesh_info
             view = [slice(ghosts[2],grid_size[2]+ghosts[2]),
                     slice(ghosts[1],grid_size[1]+ghosts[1]),
                     slice(ghosts[0],grid_size[0]+ghosts[0])]
@@ -271,7 +274,8 @@ class TestDirectionalAdvection(object):
 
         known_vars = {
             'local_size': local_work_size,
-            'mesh_info': mesh_info
+            'velocity_mesh_info': velocity_mesh_info,
+            'position_mesh_info': position_mesh_info
         }
         
         host_init_buffers      = self.host_buffers_init[target] 
@@ -285,7 +289,7 @@ class TestDirectionalAdvection(object):
             work_dim=work_dim, 
             rk_scheme=rk_scheme,
             is_cached=cached,
-            boundary=boundary,
+            vboundary=(boundary, boundary),
             nparticles = nparticles,
             min_ghosts=min_ghosts,
             symbolic_mode=False,
@@ -299,7 +303,10 @@ class TestDirectionalAdvection(object):
         
         variables = ['u','pos']
         debug     = ['dbg0', 'dbg1']
-        for varname in variables+debug:
+        for varname in variables:
+            kernel_args.append(device_buffers[varname])
+            kernel_args.append(np.uint64(0))  
+        for varname in debug:
             kernel_args.append(device_buffers[varname])
         if (dynamic_shared_bytes != 0):
             shared_buffer = cl.LocalMemory(dynamic_shared_bytes)
@@ -428,7 +435,7 @@ class TestDirectionalAdvection(object):
         self._check_kernels(rk_scheme=rk_scheme)
 
 if __name__ == '__main__':
-    TestDirectionalAdvection.setup_class(enable_extra_tests=True, enable_error_plots=True)
+    TestDirectionalAdvection.setup_class(enable_extra_tests=False, enable_error_plots=True)
     test = TestDirectionalAdvection()
     
     test.test_advection_Euler()
diff --git a/hysop/backend/device/codegen/kernels/tests/test_directional_stretching.py b/hysop/backend/device/codegen/kernels/tests/test_directional_stretching.py
index d216a7cac..ef41f9b03 100644
--- a/hysop/backend/device/codegen/kernels/tests/test_directional_stretching.py
+++ b/hysop/backend/device/codegen/kernels/tests/test_directional_stretching.py
@@ -26,8 +26,8 @@ class TestDirectionalStretching(object):
         compute_grid_ghosts = np.asarray([3*4,0,0])
         compute_grid_size   = grid_size + 2*compute_grid_ghosts
 
-        (A,grid_mesh_info)         = _test_mesh_info(typegen,3,0,grid_size)
-        (B,compute_grid_mesh_info) = _test_mesh_info(typegen,3,compute_grid_ghosts,compute_grid_size)
+        (A,grid_mesh_info)         = _test_mesh_info('grid_mesh_info', typegen,3,0,grid_size)
+        (B,compute_grid_mesh_info) = _test_mesh_info('compute_grid_mesh_info', typegen,3,compute_grid_ghosts,compute_grid_size)
         
         grid_shape         = grid_size[::-1]
         compute_grid_shape = compute_grid_size[::-1]
@@ -356,14 +356,15 @@ class TestDirectionalStretching(object):
 
         dsk = DirectionalStretchingKernel(
             typegen=self.typegen, 
-            ftype=self.typegen.fbtype,
             dim=3, 
+            ftype=self.typegen.fbtype,
             order=order, 
             direction=direction, 
-            formulation=formulation,
-            rk_scheme=rk_scheme,
             is_cached=cached,
-            boundary=boundary,
+            is_inplace=True,
+            boundary=(boundary, boundary),
+            formulation=formulation,
+            time_integrator=rk_scheme,
             symbolic_mode=False,
             known_vars=known_vars)
 
@@ -381,6 +382,7 @@ class TestDirectionalStretching(object):
             kernel_args.append(shared_buffer)
     
         print '\tGenerating and compiling Kernel...'
+        dsk.edit()
         source = dsk.__str__()
         prg = cl.Program(self.typegen.context, source)
         prg.build(devices=[self.typegen.device])
diff --git a/hysop/backend/device/opencl/opencl_array_backend.py b/hysop/backend/device/opencl/opencl_array_backend.py
index e0fe9fc1b..981cb7ec6 100644
--- a/hysop/backend/device/opencl/opencl_array_backend.py
+++ b/hysop/backend/device/opencl/opencl_array_backend.py
@@ -218,14 +218,26 @@ class OpenClArrayBackend(ArrayBackend):
     
     def short_description(self):
         return ':OpenClBackend:  id={}, ctx={}, allocator={}[{}], queue={}, HostBackend[id={}, allocator={}[{}]]'.format(
-                hash_id(self),
+                self.identifier(),
                 hash_id(self._context),
                 self._allocator.__class__.__name__, hash_id(self._allocator), 
                 hash_id(self._default_queue), 
-                hash_id(self.host_array_backend), 
+                self.host_array_backend.identifier(),
                 self.host_array_backend.allocator.__class__.__name__,
                 hash_id(self.host_array_backend.allocator))
-
+    
+    def __eq__(self, other):
+        if not other.__class__ == self.__class__:
+            return NotImplemented
+        eq  = (self._context           is other._context)
+        eq &= (self._default_queue     is other._default_queue)
+        eq &= (self._allocator         is other._allocator)
+        eq &= (self.host_array_backend is other.host_array_backend)
+        return eq
+    def __ne__(self):
+        return not (self == other)
+    def __hash__(self):
+        return id(self._context) ^ id(self._default_queue) ^ id(self.allocator) ^ id(self.host_array_backend)
 
     def __init__(self, cl_env=None, queue=None, allocator=None,
             host_array_backend=None): 
diff --git a/hysop/backend/device/opencl/operator/directional/advection_dir.py b/hysop/backend/device/opencl/operator/directional/advection_dir.py
index 4ce3c22aa..04ad728fe 100644
--- a/hysop/backend/device/opencl/operator/directional/advection_dir.py
+++ b/hysop/backend/device/opencl/operator/directional/advection_dir.py
@@ -124,10 +124,11 @@ class OpenClDirectionalAdvection(OpenClDirectionalOperator):
         
         vdx = velocity_mesh_info[1].value['dx'][0]
         advection_ghosts = int(npw.ceil(self.cfl * vdx))
+        assert (advection_ghosts >= 1)
 
-        advected_fields_in  = {field: self.input_discrete_fields[field] 
+        dadvected_fields_in  = {field: self.input_discrete_fields[field] 
                 for field in self.advected_fields_in}
-        advected_fields_out = {field: self.output_discrete_fields[field] 
+        dadvected_fields_out = {field: self.output_discrete_fields[field] 
                 for field in self.advected_fields_out}
         
         fields_in_mesh_info = [ self.input_mesh_info[field] 
@@ -140,8 +141,15 @@ class OpenClDirectionalAdvection(OpenClDirectionalOperator):
         for field in fields_in_mesh_info + fields_out_mesh_info:
             assert field[1].vars['dx'][0] == fdx
             assert field[1].vars['global_mesh'].vars['xmin'][0] == xmin
-        
-        assert (advection_ghosts >= 1)
+
+        self.dvelocity            = dvelocity
+        self.dadvected_fields_in  = dadvected_fields_in
+        self.dadvected_fields_out = dadvected_fields_out
+
+        self.velocity_mesh_info   = velocity_mesh_info
+        self.fields_in_mesh_info  = fields_in_mesh_info
+        self.fields_out_mesh_info = fields_out_mesh_info
+
         self.advection_ghosts = advection_ghosts
 
     @debug
@@ -149,7 +157,7 @@ class OpenClDirectionalAdvection(OpenClDirectionalOperator):
         requests  = super(OpenClDirectionalAdvection,self).get_work_properties()
         precision = self.cl_env.precision
 
-        request, mesh = MemoryRequest.dfield_like(a=advected_fields_in.values()[0],
+        request, mesh = MemoryRequest.dfield_like(a=self.dadvected_fields_in.values()[0],
                 dtype=precision, ghosts=None, ncomponents=1)
         requests.push_mem_request('position', request)
         
diff --git a/hysop/backend/host/fortran/operator/diffusion.py b/hysop/backend/host/fortran/operator/diffusion.py
index 0d9e4cc31..891c19dc6 100644
--- a/hysop/backend/host/fortran/operator/diffusion.py
+++ b/hysop/backend/host/fortran/operator/diffusion.py
@@ -48,7 +48,10 @@ class DiffusionFFTW(FortranFFTWOperator):
         self.input_field   = input_field
         self.output_field  = output_field
         self.viscosity     = viscosity
-        
+    
+
+    def initialize(self, **kwds):
+        super(DiffusionFFTW,self).initialize(**kwds)
         dim = self.dim
         if (dim==2):
             self._solve = self._solve_2d
@@ -57,6 +60,7 @@ class DiffusionFFTW(FortranFFTWOperator):
         else:
             raise AttributeError(dim + "D case not yet implemented.")
 
+        
     @debug
     def discretize(self):
         if self.discretized:
@@ -82,7 +86,7 @@ class DiffusionFFTW(FortranFFTWOperator):
         """ Solve 3D diffusion problem
         """
         dt = simulation.time_step
-        ghosts = self.topology.ghosts()
+        ghosts = self.topology.ghosts
         self.dout.data = \
             fftw2py.solve_diffusion_3d(self.viscosity * dt,
                                        self.din.data[0],
diff --git a/hysop/backend/host/fortran/operator/fortran_fftw.py b/hysop/backend/host/fortran/operator/fortran_fftw.py
index 1f197df40..b2aa556ef 100644
--- a/hysop/backend/host/fortran/operator/fortran_fftw.py
+++ b/hysop/backend/host/fortran/operator/fortran_fftw.py
@@ -25,20 +25,21 @@ class FortranFFTWOperator(ComputationalGraphOperator):
         check_instance(output_vars, dict, keys=Field, values=CartesianDescriptors)
         
         domain   = self.input_vars.keys()[0].domain
+        self.dim      = domain.dimension
+        self.domain   = domain
+        
+    def handle_topologies(self):
+        super(FortranFFTWOperator,self).handle_topologies()
+        
         topology = self.input_vars.values()[0]
-        for (field,topo) in input_vars.iteritems():
+        domain = self.domain
+        for (field,topo) in self.input_vars.iteritems():
             assert topo is topology, 'topology mismatch'
             assert field.domain is domain, 'domain mismatch'
-        for (field,topo) in output_vars.iteritems():
+        for (field,topo) in self.output_vars.iteritems():
             assert topo is topology, 'topology mismatch'
             assert field.domain is domain, 'domain mismatch'
-        
-        self.dim      = domain.dimension
-        self.domain   = domain
         self.topology = topology
-
-    def initialize(self, **kwds):
-        super(FortranFFTWOperator,self).initialize(**kwds)
     
     @debug
     def get_field_requirements(self):
@@ -60,6 +61,7 @@ class FortranFFTWOperator(ComputationalGraphOperator):
         if self.discretized:
             return
         super(FortranFFTWOperator,self).discretize()
+        
         self._fftw_discretize()
     
     @debug
@@ -105,7 +107,7 @@ class FortranFFTWOperator(ComputationalGraphOperator):
         assert (topo.mesh.resolution == localres).all(), 'Local resolution mismatch.'
         assert (topo.mesh.start()    == global_start).all(), 'Global start mismatch.'
         msg = 'Ghosts points not yet implemented for fortran fftw operators.'
-        assert (topo.ghosts() == 0).all(), msg
+        assert (topo.ghosts == 0).all(), msg
 
     @classmethod
     def supports_multiple_topologies(cls):
diff --git a/hysop/backend/host/fortran/operator/poisson.py b/hysop/backend/host/fortran/operator/poisson.py
index a4439a9f9..a583f0fa5 100644
--- a/hysop/backend/host/fortran/operator/poisson.py
+++ b/hysop/backend/host/fortran/operator/poisson.py
@@ -55,11 +55,16 @@ class PoissonFFTW(FortranFFTWOperator):
         self.velocity  = velocity
         self.vorticity = vorticity
         
-        dim = velocity.domain.dimension
+    def initialize(self, **kwds):
+        super(PoissonFFTW,self).initialize(**kwds)
+        dim = self.dim
         if (dim==2):
             self._solve = self._solve_2d
         elif (dim==3):
             self._solve = self._solve_3d
+        
+        if (dim!=3) and (self.projection!=FieldProjection.NONE):
+            raise ValueError('Velocity reprojection only available in 3D.')
                
     def available_methods(self):
         return PoissonFFTW.__available_methods
@@ -70,8 +75,6 @@ class PoissonFFTW(FortranFFTWOperator):
     def handle_method(self, method):
         super(PoissonFFTW,self).handle_method(method)
         projection = method.pop(FieldProjection)
-        if (self.dim!=3) and (projection!=FieldProjection.NONE):
-            raise ValueError('Velocity reprojection only available in 3D.')
 
         if projection == FieldProjection.NONE:
             self._do_project = lambda simu: False
@@ -81,6 +84,7 @@ class PoissonFFTW(FortranFFTWOperator):
             freq = projection
             assert freq>=1
             self._do_project = lambda simu: ((simu.current_iteration % freq)==0)
+        self.projection = projection
         assert not method, 'Unused method keywords {}.'.format(method.keys())
 
     @debug
@@ -113,8 +117,8 @@ class PoissonFFTW(FortranFFTWOperator):
         """ Solve 3D poisson problem, no projection, no correction
         """
         # Solves Poisson equation using usual dvorticity
-        ghosts_v = self.output_vars[self.velocity].ghosts()
-        ghosts_w = self.input_vars[self.vorticity].ghosts()
+        ghosts_v = self.output_vars[self.velocity].ghosts
+        ghosts_w = self.input_vars[self.vorticity].ghosts
         self.dvelocity.data =\
             fftw2py.solve_poisson_3d(self.dvorticity.data[0],
                                      self.dvorticity.data[1],
diff --git a/hysop/backend/host/host_allocator.py b/hysop/backend/host/host_allocator.py
index 1ed0935dd..3a7630962 100644
--- a/hysop/backend/host/host_allocator.py
+++ b/hysop/backend/host/host_allocator.py
@@ -1,4 +1,5 @@
 
+from hysop.deps import cpuinfo
 from hysop.constants                import default_order
 from hysop.core.memory.allocator import AllocatorBase
 from hysop.backend.host.host_buffer import HostBuffer
@@ -28,4 +29,4 @@ class HostAllocator(AllocatorBase):
         return HostMemoryPool(allocator=self, name=name, **kwds) 
 
 default_host_allocator = HostAllocator()
-default_host_mempool = default_host_allocator.memory_pool(name='default host pool')
+default_host_mempool = default_host_allocator.memory_pool(name=cpuinfo.cpuinfo.get_cpu_info()['brand'])
diff --git a/hysop/backend/host/host_array_backend.py b/hysop/backend/host/host_array_backend.py
index b40b34c14..604ae3076 100644
--- a/hysop/backend/host/host_array_backend.py
+++ b/hysop/backend/host/host_array_backend.py
@@ -80,7 +80,7 @@ class HostArrayBackend(ArrayBackend):
     
     def short_description(self):
         return ':HostBackend:  id={}, allocator={}[{}]'.format(
-                hash_id(self), self.allocator.__class__.__name__, hash_id(self.allocator))
+                self.identifier(), self.allocator.__class__.__name__, hash_id(self.allocator))
 
 
 ############################
diff --git a/hysop/core/arrays/array_backend.py b/hysop/core/arrays/array_backend.py
index 6ee18fac8..08a9248cd 100644
--- a/hysop/core/arrays/array_backend.py
+++ b/hysop/core/arrays/array_backend.py
@@ -149,6 +149,17 @@ class ArrayBackend(object):
         check_instance(allocator, AllocatorBase)
         super(ArrayBackend,self).__init__(**kwds)
         self._allocator = allocator
+
+
+    def __eq__(self, other):
+        if not other.__class__ == self.__class__:
+            return NotImplemented
+        eq = (self._allocator is other._allocator)
+        return eq
+    def __ne__(self):
+        return not (self == other)
+    def __hash__(self):
+        return id(self._allocator)
     
     @abstractmethod
     def get_host_array_backend(self):
@@ -160,6 +171,9 @@ class ArrayBackend(object):
     def short_description(self):
         pass
 
+    def identifier(self):
+        return str(hex(hash(self)))[2:6]
+
     def get_allocator(self):
         """
         Get the allocated associated to this backend.
diff --git a/hysop/core/graph/computational_graph.py b/hysop/core/graph/computational_graph.py
index 3ea638fe0..9f7cffc2e 100644
--- a/hysop/core/graph/computational_graph.py
+++ b/hysop/core/graph/computational_graph.py
@@ -113,8 +113,7 @@ class ComputationalGraph(ComputationalGraphNode):
                     topologies[backend] = set()
                 topologies[backend].update(topos)
         return topologies
-
-
+    
     @debug
     @not_initialized
     def push_nodes(self, *args):
@@ -171,6 +170,7 @@ class ComputationalGraph(ComputationalGraphNode):
         if is_root:
             field_requirements = self.get_field_requirements()
             field_requirements.build_topologies()
+            self.handle_topologies()
             self._build_graph(outputs_are_inputs=outputs_are_inputs, current_level=0)
         
         self.initialized=True
@@ -189,6 +189,13 @@ class ComputationalGraph(ComputationalGraphNode):
         if (self.is_root and __VERBOSE__) or __DEBUG__:
             print self.field_requirements_report(requirements)
         return requirements
+    
+    @debug
+    def handle_topologies(self):
+        super(ComputationalGraph, self).handle_topologies()
+        for node in self.nodes:
+            node.handle_topologies()
+
 
     @staticmethod
     def _op_info(op, jmp=False):
diff --git a/hysop/core/graph/computational_node.py b/hysop/core/graph/computational_node.py
index 8ca467606..a933f8213 100644
--- a/hysop/core/graph/computational_node.py
+++ b/hysop/core/graph/computational_node.py
@@ -27,6 +27,19 @@ def base_initialized(f):
         return f(*args,**kargs)
     return _check
 
+def topology_handled(f):
+    assert callable(f)
+    @wraps(f)
+    def _check(*args,**kargs):
+        self = args[0]
+        msg = 'Cannot call {}.{}() on node \'{}\' because {}'\
+                .format(self.__class__.__name__,f.__name__,self.name,'{}')
+        if not self.topology_handled:
+            reason='this self.handle_topologies() has not been called yet.'
+            raise RuntimeError(msg.format(reason))
+        return f(*args,**kargs)
+    return _check
+
 class ComputationalGraphNode(OperatorBase):
     """
     Interface of an abstract computational graph node.
@@ -126,9 +139,10 @@ class ComputationalGraphNode(OperatorBase):
         self.output_vars = output_vars
         self.base_method = method
         
-        self.initialized = False
-        self.discretized = False
-        self.ready       = False
+        self.initialized      = False
+        self.topology_handled = False
+        self.discretized      = False
+        self.ready            = False
         
         self._base_initialized = False
         if (input_vars or output_vars):
@@ -353,6 +367,15 @@ class ComputationalGraphNode(OperatorBase):
         """
         self.method = copy.deepcopy(method)
     
+    @debug
+    def handle_topologies(self):
+        """
+        Called after all topologies have been set up.
+        Topologies are available as values of self.input_vars 
+        and self.output_vars and are mapped by continuous Field.
+        """
+        self.topology_handled = True
+    
     @abstractmethod
     def get_field_requirements(self):
         """
@@ -465,7 +488,7 @@ class ComputationalGraphNode(OperatorBase):
         return method
 
     @debug
-    @initialized
+    @topology_handled
     def discretize(self):
         """
         Discretize this operator.
diff --git a/hysop/core/graph/computational_operator.py b/hysop/core/graph/computational_operator.py
index 89e862c72..e0df05d35 100644
--- a/hysop/core/graph/computational_operator.py
+++ b/hysop/core/graph/computational_operator.py
@@ -196,6 +196,20 @@ class ComputationalGraphOperator(ComputationalGraphNode):
         and self.output_discrete_fields, which contains input and output
         dicretised fields.
         """
+        if not self.topology_handled:
+            import warnings
+            msg= '\nTopologies in operator {} has not been handled yet.'
+            msg+='\nThis may be the case if this operator was not embedded into '
+            msg+='a ComputationalGraph.'
+            msg=msg.format(self.name)
+            print
+            warnings.warn(msg)
+            print
+
+            requirements = self.get_field_requirements()
+            requirements.build_topologies()
+            self.handle_topologies()
+
         super(ComputationalGraphOperator,self).discretize()
         for field,topology in self.input_vars.iteritems():
             self.input_discrete_fields[field] = field.discretize(topology)
diff --git a/hysop/core/memory/mempool.py b/hysop/core/memory/mempool.py
index 615743e50..836d9bfb3 100644
--- a/hysop/core/memory/mempool.py
+++ b/hysop/core/memory/mempool.py
@@ -32,7 +32,7 @@ class MemoryPool(object):
     __metaclass__ = ABCMeta   
 
     def __init__(self, name, allocator, max_alloc_bytes=None,
-                mantissa_bits=2, verbose=None, **kwds):
+                mantissa_bits=4, verbose=None, **kwds):
         """
         Builds a MemoryPool from an allocator.
         Provides an allocator like interface.
diff --git a/hysop/core/mpi/redistribute.py b/hysop/core/mpi/redistribute.py
index f0db60394..20c2985a6 100644
--- a/hysop/core/mpi/redistribute.py
+++ b/hysop/core/mpi/redistribute.py
@@ -186,6 +186,7 @@ class RedistributeOperator(ComputationalGraphOperator):
         super(RedistributeOperator,self).initialize(topgraph_method)
     @debug
     def discretize(self):
+        self.handle_topologies()
         super(RedistributeOperator,self).discretize()
         # Dictionnary of discrete fields to be sent and received
         v = self.variable
diff --git a/hysop/core/mpi/topology.py b/hysop/core/mpi/topology.py
index eb5eadf8f..afe862db5 100644
--- a/hysop/core/mpi/topology.py
+++ b/hysop/core/mpi/topology.py
@@ -83,8 +83,8 @@ class Topology(object):
         check_instance(backend, Backend)
         if backend == Backend.HOST:
             from hysop.core.arrays.all import HostArrayBackend
-            from hysop.backend.host.host_allocator import HostAllocator
-            allocator = allocator or HostAllocator()
+            from hysop.backend.host.host_allocator import default_host_mempool
+            allocator = allocator or default_host_mempool
             backend = HostArrayBackend(allocator)
         elif backend == Backend.OPENCL:
             from hysop.backend.device.opencl.opencl_tools import get_or_create_opencl_env
diff --git a/hysop/deps.py b/hysop/deps.py
index 342a42e5c..7abbe217d 100644
--- a/hysop/deps.py
+++ b/hysop/deps.py
@@ -21,7 +21,7 @@ except ImportError as e:
     print(msg)
 
 import sys, os, subprocess, platform
-import resource, psutil, tempfile
+import resource, psutil, tempfile, cpuinfo
 import inspect, functools, operator
 import hashlib, gzip, copy, types, string
 import math, re, contextlib
-- 
GitLab