code: def convolve_sep2(data, hx, hy, res_g=None, sub_blocks=None):
      
  
      if isinstance(data, np.ndarray):
          data = np.ascontiguousarray(data)
  
          if sub_blocks == (1, 1) or sub_blocks is None:
              return _convolve_sep2_numpy(data, hx, hy)
          else:
              # cut the image into tile and operate on every of them
              N_sub = [int(np.ceil(1. * n / s)) for n, s in zip(data.shape, sub_blocks)]
              Npads = [int(len(_h) / 2) for _h in [hy, hx]]
              res = np.empty(data.shape, np.float32)
              for data_tile, data_s_src, data_s_dest \
                      in tile_iterator(data, blocksize=N_sub,
                                       padsize=Npads,
                                       mode="constant"):
                  res_tile = _convolve_sep2_numpy(data_tile.copy(),
                                                  hx, hy)
                  res[data_s_src] = res_tile[data_s_dest]
              return res
      elif isinstance(data, OCLArray):
          if not sub_blocks is None:
              raise NotImplementedError()
          return _convolve_sep2_gpu(data, hx, hy, res_g=res_g)
      else:
          raise TypeError("array argument (1) has bad type: %s" % type(data))
docs: convolves 2d data with kernel h = outer(hx,hy)
      boundary conditions are clamping to edge.
  
      data is either np array or a gpu buffer (OCLArray)