code: def fftshift(arr_obj, axes = None, res_g = None, return_buffer = False):
      
  
      if axes is None:
          axes = list(range(arr_obj.ndim))
  
  
      if isinstance(arr_obj, OCLArray):
          if not arr_obj.dtype.type in DTYPE_KERNEL_NAMES:
              raise NotImplementedError("only works for float32 or complex64")
      elif isinstance(arr_obj, np.ndarray):
          if np.iscomplexobj(arr_obj):
              arr_obj = OCLArray.from_array(arr_obj.astype(np.complex64,copy = False))
          else:
              arr_obj = OCLArray.from_array(arr_obj.astype(np.float32,copy = False))
      else:
          raise ValueError("unknown type (%s)"%(type(arr_obj)))
  
      if not np.all([arr_obj.shape[a]%2==0 for a in axes]):
          raise NotImplementedError("only works on axes of even dimensions")
  
      if res_g is None:
          res_g = OCLArray.empty_like(arr_obj)
  
  
      # iterate over all axes
      # FIXME: this is still rather inefficient
      in_g = arr_obj
      for ax in axes:
          _fftshift_single(in_g, res_g, ax)
          in_g = res_g
  
      if return_buffer:
          return res_g
      else:
          return res_g.get()
docs: gpu version of fftshift for numpy arrays or OCLArrays
  
      Parameters
      ----------
      arr_obj: numpy array or OCLArray (float32/complex64)
          the array to be fftshifted
      axes: list or None
          the axes over which to shift (like np.fft.fftshift)
          if None, all axes are taken
      res_g:
          if given, fills it with the result (has to be same shape and dtype as arr_obj)
          else internally creates a new one
      Returns
      -------
          if return_buffer, returns the result as (well :) OCLArray
          else returns the result as numpy array