Repository: vincefn/pyvkfft (language: python)

Issue:
Cannot import pyvkfft.fft.fftn without OpenCL backends
I tried install pyvkfft with only cuda backends using `VKFFT_BACKEND=CUDA CUDAHOME=/usr/local/cuda pip install pyvkfft`

This runs and builds the wheel for pyvkfft without errors. After running, I can import and use the cuda pyvkfft planner without error
```
$ python
Python 3.9.10 (main, Sep  1 2022, 19:43:27) 
[GCC 8.5.0 20210514 (Red Hat 8.5.0-10)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from pyvkfft.cuda import VkFFTApp
>>> 
```

But if I try to import `pyvkfft.fft.fftn` I get an `OSError`
```
$ python
Python 3.9.10 (main, Sep  1 2022, 19:43:27) 
[GCC 8.5.0 20210514 (Red Hat 8.5.0-10)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from pyvkfft.fft import fftn
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File ".../venv/lib/python3.9/site-packages/pyvkfft/fft.py", line 28, in <module>
    from .opencl import VkFFTApp as VkFFTApp_cl, cla, vkfft_version
  File ".../venv/lib/python3.9/site-packages/pyvkfft/opencl.py", line 15, in <module>
    _vkfft_opencl = load_library("_vkfft_opencl")
  File ".../venv/lib/python3.9/site-packages/pyvkfft/base.py", line 117, in load_library
    return ctypes.cdll.LoadLibrary(os.path.join(os.path.dirname(__file__) or os.path.curdir, basename + ext))
  File ".../Python-3.9.10/Lib/ctypes/__init__.py", line 452, in LoadLibrary
    return self._dlltype(name)
  File ".../Python-3.9.10/Lib/ctypes/__init__.py", line 374, in __init__
    self._handle = _dlopen(self._name, mode)
OSError: .../venv/lib/python3.9/site-packages/pyvkfft/_vkfft_opencl.cpython-39-x86_64-linux-gnu.so: cannot open shared object file: No such file or directory
```

Looking at the code for `pyvkfft.fft` it looks like it tries to handle the case where the `OpenCL` backend isn't installed 
https://github.com/vincefn/pyvkfft/blob/d75c620d9d1fdd91d06454439a7d731f7166de70/pyvkfft/fft.py#L27-L33
only I get an `OSError` not `ImportError`.

If I install `pyvkfft` with both OpenCL and cuda backends using `CUDAHOME=/usr/local/cuda pip install pyvkfft` things work
```
$ python
Python 3.9.10 (main, Sep  1 2022, 19:43:27) 
[GCC 8.5.0 20210514 (Red Hat 8.5.0-10)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from pyvkfft.fft import fftn
>>> 
```
but I'd like to use `pyvkfft` with only the Cuda backends installed. 
All R2C test that have ndim=2 fails [numpy], because the fast axis is not always the last one
```
pyopencl  R2C         (30+2) axes=      None ndim=   1    float32 lut=None inplace=1  norm=   0   FFT: n2=1.09e-07 ninf=1.18e-07 < 2.74e-06 (0.043) 0 iFFT: n2=1.06e-07 ninf=1.28e-07 < 2.74e-06 (0.047) 0   OK
pyopencl  R2C         (30+2) axes=      None ndim=   1    float32 lut=None inplace=1  norm=   1   FFT: n2=1.09e-07 ninf=1.18e-07 < 2.74e-06 (0.043) 0 iFFT: n2=9.92e-08 ninf=1.36e-07 < 2.74e-06 (0.049) 0   OK
pyopencl  R2C          (30,) axes=      None ndim=   1    float32 lut=None inplace=0  norm=   0   FFT: n2=1.09e-07 ninf=1.18e-07 < 2.74e-06 (0.043) 1 iFFT: n2=1.06e-07 ninf=1.28e-07 < 2.74e-06 (0.047) 1   OK
pyopencl  R2C          (30,) axes=      None ndim=   1    float32 lut=None inplace=0  norm=   1   FFT: n2=1.09e-07 ninf=1.18e-07 < 2.74e-06 (0.043) 1 iFFT: n2=9.92e-08 ninf=1.36e-07 < 2.74e-06 (0.049) 1   OK
pyopencl  R2C         (30+2) axes=      None ndim=   1    float32 lut=True inplace=1  norm=   0   FFT: n2=8.12e-08 ninf=8.93e-08 < 2.74e-06 (0.033) 0 iFFT: n2=7.62e-08 ninf=7.70e-08 < 2.74e-06 (0.028) 0   OK
pyopencl  R2C         (30+2) axes=      None ndim=   1    float32 lut=True inplace=1  norm=   1   FFT: n2=8.12e-08 ninf=8.93e-08 < 2.74e-06 (0.033) 0 iFFT: n2=1.31e-07 ninf=1.35e-07 < 2.74e-06 (0.049) 0   OK
pyopencl  R2C          (30,) axes=      None ndim=   1    float32 lut=True inplace=0  norm=   0   FFT: n2=8.12e-08 ninf=8.93e-08 < 2.74e-06 (0.033) 1 iFFT: n2=7.62e-08 ninf=7.70e-08 < 2.74e-06 (0.028) 1   OK
pyopencl  R2C          (30,) axes=      None ndim=   1    float32 lut=True inplace=0  norm=   1   FFT: n2=8.12e-08 ninf=8.93e-08 < 2.74e-06 (0.033) 1 iFFT: n2=1.31e-07 ninf=1.35e-07 < 2.74e-06 (0.049) 1   OK
pyopencl  R2C         (30+2) axes=      None ndim=   1    float64 lut=None inplace=1  norm=   0   FFT: n2=2.93e-16 ninf=3.16e-16 < 5.74e-15 (0.055) 0 iFFT: n2=3.70e-16 ninf=4.57e-16 < 5.74e-15 (0.080) 0   OK
pyopencl  R2C         (30+2) axes=      None ndim=   1    float64 lut=None inplace=1  norm=   1   FFT: n2=2.93e-16 ninf=3.16e-16 < 5.74e-15 (0.055) 0 iFFT: n2=2.13e-16 ninf=3.43e-16 < 5.74e-15 (0.060) 0   OK
pyopencl  R2C          (30,) axes=      None ndim=   1    float64 lut=None inplace=0  norm=   0   FFT: n2=2.62e-16 ninf=3.16e-16 < 5.74e-15 (0.055) 1 iFFT: n2=2.61e-16 ninf=3.43e-16 < 5.74e-15 (0.060) 1   OK
pyopencl  R2C          (30,) axes=      None ndim=   1    float64 lut=None inplace=0  norm=   1   FFT: n2=2.62e-16 ninf=3.16e-16 < 5.74e-15 (0.055) 1 iFFT: n2=2.63e-16 ninf=3.43e-16 < 5.74e-15 (0.060) 1   OK
pyopencl  R2C       (2,30+2) axes=      None ndim=   1    float32 lut=None inplace=1  norm=   0   FFT: n2=1.37e-07 ninf=1.27e-07 < 2.74e-06 (0.047) 0 iFFT: n2=1.38e-07 ninf=2.24e-07 < 2.74e-06 (0.082) 0   OK
pyopencl  R2C       (2,30+2) axes=      None ndim=   1    float32 lut=None inplace=1  norm=   1   FFT: n2=1.37e-07 ninf=1.27e-07 < 2.74e-06 (0.047) 0 iFFT: n2=1.22e-07 ninf=1.96e-07 < 2.74e-06 (0.071) 0   OK
pyopencl  R2C         (2,30) axes=      None ndim=   1    float32 lut=None inplace=0  norm=   0   FFT: n2=1.37e-07 ninf=1.27e-07 < 2.74e-06 (0.047) 1 iFFT: n2=1.38e-07 ninf=2.24e-07 < 2.74e-06 (0.082) 1   OK
pyopencl  R2C         (2,30) axes=      None ndim=   1    float32 lut=None inplace=0  norm=   1   FFT: n2=1.37e-07 ninf=1.27e-07 < 2.74e-06 (0.047) 1 iFFT: n2=1.22e-07 ninf=1.96e-07 < 2.74e-06 (0.071) 1   OK
pyopencl  R2C       (2,30+2) axes=      None ndim=   1    float32 lut=True inplace=1  norm=   0   FFT: n2=8.20e-08 ninf=6.13e-08 < 2.74e-06 (0.022) 0 iFFT: n2=1.01e-07 ninf=1.30e-07 < 2.74e-06 (0.047) 0   OK
pyopencl  R2C       (2,30+2) axes=      None ndim=   1    float32 lut=True inplace=1  norm=   1   FFT: n2=8.20e-08 ninf=6.13e-08 < 2.74e-06 (0.022) 0 iFFT: n2=1.32e-07 ninf=2.33e-07 < 2.74e-06 (0.085) 0   OK
pyopencl  R2C         (2,30) axes=      None ndim=   1    float32 lut=True inplace=0  norm=   0   FFT: n2=8.20e-08 ninf=6.13e-08 < 2.74e-06 (0.022) 1 iFFT: n2=1.01e-07 ninf=1.30e-07 < 2.74e-06 (0.047) 1   OK
pyopencl  R2C         (2,30) axes=      None ndim=   1    float32 lut=True inplace=0  norm=   1   FFT: n2=8.20e-08 ninf=6.13e-08 < 2.74e-06 (0.022) 1 iFFT: n2=1.32e-07 ninf=2.33e-07 < 2.74e-06 (0.085) 1   OK
pyopencl  R2C       (2,30+2) axes=      None ndim=   1    float64 lut=None inplace=1  norm=   0   FFT: n2=2.25e-16 ninf=3.30e-16 < 5.74e-15 (0.057) 0 iFFT: n2=5.44e-16 ninf=7.78e-16 < 5.74e-15 (0.136) 0   OK
pyopencl  R2C       (2,30+2) axes=      None ndim=   1    float64 lut=None inplace=1  norm=   1   FFT: n2=2.25e-16 ninf=3.30e-16 < 5.74e-15 (0.057) 0 iFFT: n2=2.97e-16 ninf=5.56e-16 < 5.74e-15 (0.097) 0   OK
pyopencl  R2C         (2,30) axes=      None ndim=   1    float64 lut=None inplace=0  norm=   0   FFT: n2=2.30e-16 ninf=3.76e-16 < 5.74e-15 (0.066) 1 iFFT: n2=2.62e-16 ninf=4.45e-16 < 5.74e-15 (0.077) 1   OK
pyopencl  R2C         (2,30) axes=      None ndim=   1    float64 lut=None inplace=0  norm=   1   FFT: n2=2.30e-16 ninf=3.76e-16 < 5.74e-15 (0.066) 1 iFFT: n2=2.76e-16 ninf=3.47e-16 < 5.74e-15 (0.061) 1   OK
pyopencl  R2C        (30,30) axes=      None ndim=   2    float32 lut=None inplace=0  norm=   0   FFT: n2=1.79e-07 ninf=2.24e-07 < 3.48e-06 (0.064) 1 iFFT: n2=1.43e+00 ninf=2.52e+00 < 3.48e-06 (723527.389) 0 FAIL
pyopencl  R2C        (30,30) axes=      None ndim=   2    float32 lut=None inplace=0  norm=   1   FFT: n2=1.79e-07 ninf=2.24e-07 < 3.48e-06 (0.064) 1 iFFT: n2=1.43e+00 ninf=2.52e+00 < 3.48e-06 (723527.355) 0 FAIL
pyopencl  R2C        (30,30) axes=      None ndim=   2    float32 lut=True inplace=0  norm=   0   FFT: n2=1.43e-07 ninf=1.81e-07 < 3.48e-06 (0.052) 1 iFFT: n2=1.43e+00 ninf=2.52e+00 < 3.48e-06 (723527.423) 0 FAIL
pyopencl  R2C        (30,30) axes=      None ndim=   2    float32 lut=True inplace=0  norm=   1   FFT: n2=1.43e-07 ninf=1.81e-07 < 3.48e-06 (0.052) 1 iFFT: n2=1.43e+00 ninf=2.52e+00 < 3.48e-06 (723527.423) 0 FAIL
pyopencl  R2C        (30,30) axes=      None ndim=   2    float64 lut=None inplace=0  norm=   0   FFT: n2=3.85e-16 ninf=4.70e-16 < 6.48e-15 (0.073) 1 iFFT: n2=1.43e+00 ninf=2.38e+00 < 6.48e-15 (367908337750424.188) 0 FAIL
pyopencl  R2C        (30,30) axes=      None ndim=   2    float64 lut=None inplace=0  norm=   1   FFT: n2=3.85e-16 ninf=4.70e-16 < 6.48e-15 (0.073) 1 iFFT: n2=1.43e+00 ninf=2.38e+00 < 6.48e-15 (367908337750424.188) 0 FAIL
pyopencl  R2C     (2,2,30+2) axes=      None ndim=   1    float32 lut=None inplace=1  norm=   0   FFT: n2=1.45e-07 ninf=2.15e-07 < 2.74e-06 (0.078) 0 iFFT: n2=1.31e-07 ninf=2.21e-07 < 2.74e-06 (0.081) 0   OK
pyopencl  R2C     (2,2,30+2) axes=      None ndim=   1    float32 lut=None inplace=1  norm=   1   FFT: n2=1.45e-07 ninf=2.15e-07 < 2.74e-06 (0.078) 0 iFFT: n2=1.43e-07 ninf=2.25e-07 < 2.74e-06 (0.082) 0   OK
pyopencl  R2C       (2,2,30) axes=      None ndim=   1    float32 lut=None inplace=0  norm=   0   FFT: n2=1.45e-07 ninf=2.15e-07 < 2.74e-06 (0.078) 1 iFFT: n2=1.31e-07 ninf=2.21e-07 < 2.74e-06 (0.081) 1   OK
pyopencl  R2C       (2,2,30) axes=      None ndim=   1    float32 lut=None inplace=0  norm=   1   FFT: n2=1.45e-07 ninf=2.15e-07 < 2.74e-06 (0.078) 1 iFFT: n2=1.43e-07 ninf=2.25e-07 < 2.74e-06 (0.082) 1   OK
pyopencl  R2C     (2,2,30+2) axes=      None ndim=   1    float32 lut=True inplace=1  norm=   0   FFT: n2=1.01e-07 ninf=1.28e-07 < 2.74e-06 (0.047) 0 iFFT: n2=9.53e-08 ninf=1.23e-07 < 2.74e-06 (0.045) 0   OK
pyopencl  R2C     (2,2,30+2) axes=      None ndim=   1    float32 lut=True inplace=1  norm=   1   FFT: n2=1.01e-07 ninf=1.28e-07 < 2.74e-06 (0.047) 0 iFFT: n2=1.37e-07 ninf=2.25e-07 < 2.74e-06 (0.082) 0   OK
pyopencl  R2C       (2,2,30) axes=      None ndim=   1    float32 lut=True inplace=0  norm=   0   FFT: n2=1.01e-07 ninf=1.28e-07 < 2.74e-06 (0.047) 1 iFFT: n2=9.53e-08 ninf=1.23e-07 < 2.74e-06 (0.045) 1   OK
pyopencl  R2C       (2,2,30) axes=      None ndim=   1    float32 lut=True inplace=0  norm=   1   FFT: n2=1.01e-07 ninf=1.28e-07 < 2.74e-06 (0.047) 1 iFFT: n2=1.37e-07 ninf=2.25e-07 < 2.74e-06 (0.082) 1   OK
pyopencl  R2C     (2,2,30+2) axes=      None ndim=   1    float64 lut=None inplace=1  norm=   0   FFT: n2=2.88e-16 ninf=3.14e-16 < 5.74e-15 (0.055) 0 iFFT: n2=4.60e-16 ninf=8.94e-16 < 5.74e-15 (0.156) 0   OK
pyopencl  R2C     (2,2,30+2) axes=      None ndim=   1    float64 lut=None inplace=1  norm=   1   FFT: n2=2.88e-16 ninf=3.14e-16 < 5.74e-15 (0.055) 0 iFFT: n2=2.65e-16 ninf=5.59e-16 < 5.74e-15 (0.097) 0   OK
pyopencl  R2C       (2,2,30) axes=      None ndim=   1    float64 lut=None inplace=0  norm=   0   FFT: n2=2.82e-16 ninf=3.14e-16 < 5.74e-15 (0.055) 1 iFFT: n2=2.87e-16 ninf=4.75e-16 < 5.74e-15 (0.083) 1   OK
pyopencl  R2C       (2,2,30) axes=      None ndim=   1    float64 lut=None inplace=0  norm=   1   FFT: n2=2.82e-16 ninf=3.14e-16 < 5.74e-15 (0.055) 1 iFFT: n2=2.72e-16 ninf=3.91e-16 < 5.74e-15 (0.068) 1   OK
pyopencl  R2C   (2,2,2,30+2) axes=      None ndim=   1    float32 lut=None inplace=1  norm=   0   FFT: n2=1.53e-07 ninf=2.01e-07 < 2.74e-06 (0.073) 0 iFFT: n2=1.43e-07 ninf=3.13e-07 < 2.74e-06 (0.114) 0   OK
pyopencl  R2C   (2,2,2,30+2) axes=      None ndim=   1    float32 lut=None inplace=1  norm=   1   FFT: n2=1.53e-07 ninf=2.01e-07 < 2.74e-06 (0.073) 0 iFFT: n2=1.48e-07 ninf=2.80e-07 < 2.74e-06 (0.102) 0   OK
pyopencl  R2C     (2,2,2,30) axes=      None ndim=   1    float32 lut=None inplace=0  norm=   0   FFT: n2=1.53e-07 ninf=2.01e-07 < 2.74e-06 (0.073) 1 iFFT: n2=1.43e-07 ninf=3.13e-07 < 2.74e-06 (0.114) 1   OK
pyopencl  R2C     (2,2,2,30) axes=      None ndim=   1    float32 lut=None inplace=0  norm=   1   FFT: n2=1.53e-07 ninf=2.01e-07 < 2.74e-06 (0.073) 1 iFFT: n2=1.48e-07 ninf=2.80e-07 < 2.74e-06 (0.102) 1   OK
pyopencl  R2C   (2,2,2,30+2) axes=      None ndim=   1    float32 lut=True inplace=1  norm=   0   FFT: n2=1.01e-07 ninf=1.18e-07 < 2.74e-06 (0.043) 0 iFFT: n2=1.08e-07 ninf=2.20e-07 < 2.74e-06 (0.080) 0   OK
pyopencl  R2C   (2,2,2,30+2) axes=      None ndim=   1    float32 lut=True inplace=1  norm=   1   FFT: n2=1.01e-07 ninf=1.18e-07 < 2.74e-06 (0.043) 0 iFFT: n2=1.37e-07 ninf=1.94e-07 < 2.74e-06 (0.071) 0   OK
pyopencl  R2C     (2,2,2,30) axes=      None ndim=   1    float32 lut=True inplace=0  norm=   0   FFT: n2=1.01e-07 ninf=1.18e-07 < 2.74e-06 (0.043) 1 iFFT: n2=1.08e-07 ninf=2.20e-07 < 2.74e-06 (0.080) 1   OK
pyopencl  R2C     (2,2,2,30) axes=      None ndim=   1    float32 lut=True inplace=0  norm=   1   FFT: n2=1.01e-07 ninf=1.18e-07 < 2.74e-06 (0.043) 1 iFFT: n2=1.37e-07 ninf=1.94e-07 < 2.74e-06 (0.071) 1   OK
pyopencl  R2C   (2,2,2,30+2) axes=      None ndim=   1    float64 lut=None inplace=1  norm=   0   FFT: n2=2.89e-16 ninf=3.35e-16 < 5.74e-15 (0.058) 0 iFFT: n2=4.58e-16 ninf=7.84e-16 < 5.74e-15 (0.137) 0   OK
pyopencl  R2C   (2,2,2,30+2) axes=      None ndim=   1    float64 lut=None inplace=1  norm=   1   FFT: n2=2.89e-16 ninf=3.35e-16 < 5.74e-15 (0.058) 0 iFFT: n2=3.03e-16 ninf=5.60e-16 < 5.74e-15 (0.098) 0   OK
pyopencl  R2C     (2,2,2,30) axes=      None ndim=   1    float64 lut=None inplace=0  norm=   0   FFT: n2=2.92e-16 ninf=3.35e-16 < 5.74e-15 (0.058) 1 iFFT: n2=3.06e-16 ninf=6.72e-16 < 5.74e-15 (0.117) 1   OK
pyopencl  R2C     (2,2,2,30) axes=      None ndim=   1    float64 lut=None inplace=0  norm=   1   FFT: n2=2.92e-16 ninf=3.35e-16 < 5.74e-15 (0.058) 1 iFFT: n2=3.27e-16 ninf=5.60e-16 < 5.74e-15 (0.098) 1   OK
pyopencl  R2C         (34+2) axes=      None ndim=   1    float32 lut=None inplace=1  norm=   0   FFT: n2=1.92e-07 ninf=1.58e-07 < 2.77e-06 (0.057) 0 iFFT: n2=1.88e-07 ninf=2.73e-07 < 2.77e-06 (0.099) 0   OK
pyopencl  R2C         (34+2) axes=      None ndim=   1    float32 lut=None inplace=1  norm=   1   FFT: n2=1.92e-07 ninf=1.58e-07 < 2.77e-06 (0.057) 0 iFFT: n2=1.72e-07 ninf=2.00e-07 < 2.77e-06 (0.072) 0   OK
pyopencl  R2C          (34,) axes=      None ndim=   1    float32 lut=None inplace=0  norm=   0   FFT: n2=1.92e-07 ninf=1.58e-07 < 5.53e-06 (0.028) 1 iFFT: n2=1.88e-07 ninf=2.73e-07 < 5.53e-06 (0.049) 1   OK
pyopencl  R2C          (34,) axes=      None ndim=   1    float32 lut=None inplace=0  norm=   1   FFT: n2=1.92e-07 ninf=1.58e-07 < 5.53e-06 (0.028) 1 iFFT: n2=1.72e-07 ninf=2.00e-07 < 5.53e-06 (0.036) 1   OK
pyopencl  R2C         (34+2) axes=      None ndim=   1    float32 lut=True inplace=1  norm=   0   FFT: n2=1.86e-07 ninf=1.78e-07 < 2.77e-06 (0.064) 0 iFFT: n2=1.64e-07 ninf=2.63e-07 < 2.77e-06 (0.095) 0   OK
pyopencl  R2C         (34+2) axes=      None ndim=   1    float32 lut=True inplace=1  norm=   1   FFT: n2=1.86e-07 ninf=1.78e-07 < 2.77e-06 (0.064) 0 iFFT: n2=1.71e-07 ninf=2.59e-07 < 2.77e-06 (0.094) 0   OK
pyopencl  R2C          (34,) axes=      None ndim=   1    float32 lut=True inplace=0  norm=   0   FFT: n2=1.86e-07 ninf=1.78e-07 < 5.53e-06 (0.032) 1 iFFT: n2=1.64e-07 ninf=2.63e-07 < 5.53e-06 (0.047) 1   OK
pyopencl  R2C          (34,) axes=      None ndim=   1    float32 lut=True inplace=0  norm=   1   FFT: n2=1.86e-07 ninf=1.78e-07 < 5.53e-06 (0.032) 1 iFFT: n2=1.71e-07 ninf=2.59e-07 < 5.53e-06 (0.047) 1   OK
pyopencl  R2C         (34+2) axes=      None ndim=   1    float64 lut=None inplace=1  norm=   0   FFT: n2=6.19e-16 ninf=7.44e-16 < 5.77e-15 (0.129) 0 iFFT: n2=3.26e-16 ninf=3.41e-16 < 5.77e-15 (0.059) 0   OK
pyopencl  R2C         (34+2) axes=      None ndim=   1    float64 lut=None inplace=1  norm=   1   FFT: n2=6.19e-16 ninf=7.44e-16 < 5.77e-15 (0.129) 0 iFFT: n2=3.07e-16 ninf=4.55e-16 < 5.77e-15 (0.079) 0   OK
pyopencl  R2C          (34,) axes=      None ndim=   1    float64 lut=None inplace=0  norm=   0   FFT: n2=6.19e-16 ninf=7.44e-16 < 1.15e-14 (0.064) 1 iFFT: n2=3.26e-16 ninf=3.41e-16 < 1.15e-14 (0.030) 1   OK
pyopencl  R2C          (34,) axes=      None ndim=   1    float64 lut=None inplace=0  norm=   1   FFT: n2=6.19e-16 ninf=7.44e-16 < 1.15e-14 (0.064) 1 iFFT: n2=3.07e-16 ninf=4.55e-16 < 1.15e-14 (0.039) 1   OK
pyopencl  R2C       (2,34+2) axes=      None ndim=   1    float32 lut=None inplace=1  norm=   0   FFT: n2=1.66e-07 ninf=1.91e-07 < 2.77e-06 (0.069) 0 iFFT: n2=2.20e-07 ninf=2.82e-07 < 2.77e-06 (0.102) 0   OK
pyopencl  R2C       (2,34+2) axes=      None ndim=   1    float32 lut=None inplace=1  norm=   1   FFT: n2=1.66e-07 ninf=1.91e-07 < 2.77e-06 (0.069) 0 iFFT: n2=2.38e-07 ninf=3.21e-07 < 2.77e-06 (0.116) 0   OK
pyopencl  R2C         (2,34) axes=      None ndim=   1    float32 lut=None inplace=0  norm=   0   FFT: n2=1.66e-07 ninf=1.91e-07 < 5.53e-06 (0.035) 1 iFFT: n2=2.20e-07 ninf=2.82e-07 < 5.53e-06 (0.051) 1   OK
pyopencl  R2C         (2,34) axes=      None ndim=   1    float32 lut=None inplace=0  norm=   1   FFT: n2=1.66e-07 ninf=1.91e-07 < 5.53e-06 (0.035) 1 iFFT: n2=2.38e-07 ninf=3.21e-07 < 5.53e-06 (0.058) 1   OK
pyopencl  R2C       (2,34+2) axes=      None ndim=   1    float32 lut=True inplace=1  norm=   0   FFT: n2=1.94e-07 ninf=2.01e-07 < 2.77e-06 (0.073) 0 iFFT: n2=2.05e-07 ninf=2.96e-07 < 2.77e-06 (0.107) 0   OK
pyopencl  R2C       (2,34+2) axes=      None ndim=   1    float32 lut=True inplace=1  norm=   1   FFT: n2=1.94e-07 ninf=2.01e-07 < 2.77e-06 (0.073) 0 iFFT: n2=2.16e-07 ninf=3.21e-07 < 2.77e-06 (0.116) 0   OK
pyopencl  R2C         (2,34) axes=      None ndim=   1    float32 lut=True inplace=0  norm=   0   FFT: n2=1.94e-07 ninf=2.01e-07 < 5.53e-06 (0.036) 1 iFFT: n2=2.05e-07 ninf=2.96e-07 < 5.53e-06 (0.054) 1   OK
pyopencl  R2C         (2,34) axes=      None ndim=   1    float32 lut=True inplace=0  norm=   1   FFT: n2=1.94e-07 ninf=2.01e-07 < 5.53e-06 (0.036) 1 iFFT: n2=2.16e-07 ninf=3.21e-07 < 5.53e-06 (0.058) 1   OK
pyopencl  R2C       (2,34+2) axes=      None ndim=   1    float64 lut=None inplace=1  norm=   0   FFT: n2=4.90e-16 ninf=5.49e-16 < 5.77e-15 (0.095) 0 iFFT: n2=5.86e-16 ninf=8.89e-16 < 5.77e-15 (0.154) 0   OK
pyopencl  R2C       (2,34+2) axes=      None ndim=   1    float64 lut=None inplace=1  norm=   1   FFT: n2=4.90e-16 ninf=5.49e-16 < 5.77e-15 (0.095) 0 iFFT: n2=5.30e-16 ninf=8.89e-16 < 5.77e-15 (0.154) 0   OK
pyopencl  R2C         (2,34) axes=      None ndim=   1    float64 lut=None inplace=0  norm=   0   FFT: n2=4.90e-16 ninf=5.49e-16 < 1.15e-14 (0.048) 1 iFFT: n2=5.86e-16 ninf=8.89e-16 < 1.15e-14 (0.077) 1   OK
pyopencl  R2C         (2,34) axes=      None ndim=   1    float64 lut=None inplace=0  norm=   1   FFT: n2=4.90e-16 ninf=5.49e-16 < 1.15e-14 (0.048) 1 iFFT: n2=5.30e-16 ninf=8.89e-16 < 1.15e-14 (0.077) 1   OK
pyopencl  R2C        (34,34) axes=      None ndim=   2    float32 lut=None inplace=0  norm=   0   FFT: n2=3.16e-07 ninf=3.05e-07 < 7.06e-06 (0.043) 1 iFFT: n2=1.39e+00 ninf=2.70e+00 < 7.06e-06 (382709.503) 0 FAIL
pyopencl  R2C        (34,34) axes=      None ndim=   2    float32 lut=None inplace=0  norm=   1   FFT: n2=3.16e-07 ninf=3.05e-07 < 7.06e-06 (0.043) 1 iFFT: n2=1.39e+00 ninf=2.70e+00 < 7.06e-06 (382709.486) 0 FAIL
pyopencl  R2C        (34,34) axes=      None ndim=   2    float32 lut=True inplace=0  norm=   0   FFT: n2=3.04e-07 ninf=3.78e-07 < 7.06e-06 (0.053) 1 iFFT: n2=1.39e+00 ninf=2.70e+00 < 7.06e-06 (382709.503) 0 FAIL
pyopencl  R2C        (34,34) axes=      None ndim=   2    float32 lut=True inplace=0  norm=   1   FFT: n2=3.04e-07 ninf=3.78e-07 < 7.06e-06 (0.053) 1 iFFT: n2=1.39e+00 ninf=2.70e+00 < 7.06e-06 (382709.469) 0 FAIL
pyopencl  R2C        (34,34) axes=      None ndim=   2    float64 lut=None inplace=0  norm=   0   FFT: n2=7.93e-16 ninf=1.04e-15 < 1.31e-14 (0.080) 1 iFFT: n2=1.43e+00 ninf=2.78e+00 < 1.31e-14 (212602327789630.625) 0 FAIL
pyopencl  R2C        (34,34) axes=      None ndim=   2    float64 lut=None inplace=0  norm=   1   FFT: n2=7.93e-16 ninf=1.04e-15 < 1.31e-14 (0.080) 1 iFFT: n2=1.43e+00 ninf=2.78e+00 < 1.31e-14 (212602327789630.625) 0 FAIL
pyopencl  R2C     (2,2,34+2) axes=      None ndim=   1    float32 lut=None inplace=1  norm=   0   FFT: n2=2.07e-07 ninf=2.35e-07 < 2.77e-06 (0.085) 0 iFFT: n2=2.13e-07 ninf=2.84e-07 < 2.77e-06 (0.103) 0   OK
pyopencl  R2C     (2,2,34+2) axes=      None ndim=   1    float32 lut=None inplace=1  norm=   1   FFT: n2=2.07e-07 ninf=2.35e-07 < 2.77e-06 (0.085) 0 iFFT: n2=2.30e-07 ninf=3.37e-07 < 2.77e-06 (0.122) 0   OK
pyopencl  R2C       (2,2,34) axes=      None ndim=   1    float32 lut=None inplace=0  norm=   0   FFT: n2=2.07e-07 ninf=2.35e-07 < 5.53e-06 (0.042) 1 iFFT: n2=2.13e-07 ninf=2.84e-07 < 5.53e-06 (0.051) 1   OK
pyopencl  R2C       (2,2,34) axes=      None ndim=   1    float32 lut=None inplace=0  norm=   1   FFT: n2=2.07e-07 ninf=2.35e-07 < 5.53e-06 (0.042) 1 iFFT: n2=2.30e-07 ninf=3.37e-07 < 5.53e-06 (0.061) 1   OK
pyopencl  R2C     (2,2,34+2) axes=      None ndim=   1    float32 lut=True inplace=1  norm=   0   FFT: n2=2.07e-07 ninf=2.72e-07 < 2.77e-06 (0.098) 0 iFFT: n2=2.05e-07 ninf=3.36e-07 < 2.77e-06 (0.121) 0   OK
pyopencl  R2C     (2,2,34+2) axes=      None ndim=   1    float32 lut=True inplace=1  norm=   1   FFT: n2=2.07e-07 ninf=2.72e-07 < 2.77e-06 (0.098) 0 iFFT: n2=2.00e-07 ninf=3.03e-07 < 2.77e-06 (0.110) 0   OK
pyopencl  R2C       (2,2,34) axes=      None ndim=   1    float32 lut=True inplace=0  norm=   0   FFT: n2=2.07e-07 ninf=2.72e-07 < 5.53e-06 (0.049) 1 iFFT: n2=2.05e-07 ninf=3.36e-07 < 5.53e-06 (0.061) 1   OK
pyopencl  R2C       (2,2,34) axes=      None ndim=   1    float32 lut=True inplace=0  norm=   1   FFT: n2=2.07e-07 ninf=2.72e-07 < 5.53e-06 (0.049) 1 iFFT: n2=2.00e-07 ninf=3.03e-07 < 5.53e-06 (0.055) 1   OK
pyopencl  R2C     (2,2,34+2) axes=      None ndim=   1    float64 lut=None inplace=1  norm=   0   FFT: n2=5.30e-16 ninf=7.55e-16 < 5.77e-15 (0.131) 0 iFFT: n2=5.41e-16 ninf=1.23e-15 < 5.77e-15 (0.213) 0   OK
pyopencl  R2C     (2,2,34+2) axes=      None ndim=   1    float64 lut=None inplace=1  norm=   1   FFT: n2=5.30e-16 ninf=7.55e-16 < 5.77e-15 (0.131) 0 iFFT: n2=5.55e-16 ninf=1.00e-15 < 5.77e-15 (0.174) 0   OK
pyopencl  R2C       (2,2,34) axes=      None ndim=   1    float64 lut=None inplace=0  norm=   0   FFT: n2=5.30e-16 ninf=7.55e-16 < 1.15e-14 (0.065) 1 iFFT: n2=5.41e-16 ninf=1.23e-15 < 1.15e-14 (0.106) 1   OK
pyopencl  R2C       (2,2,34) axes=      None ndim=   1    float64 lut=None inplace=0  norm=   1   FFT: n2=5.30e-16 ninf=7.55e-16 < 1.15e-14 (0.065) 1 iFFT: n2=5.55e-16 ninf=1.00e-15 < 1.15e-14 (0.087) 1   OK
pyopencl  R2C   (2,2,2,34+2) axes=      None ndim=   1    float32 lut=None inplace=1  norm=   0   FFT: n2=2.13e-07 ninf=2.43e-07 < 2.77e-06 (0.088) 0 iFFT: n2=1.96e-07 ninf=3.26e-07 < 2.77e-06 (0.118) 0   OK
pyopencl  R2C   (2,2,2,34+2) axes=      None ndim=   1    float32 lut=None inplace=1  norm=   1   FFT: n2=2.13e-07 ninf=2.43e-07 < 2.77e-06 (0.088) 0 iFFT: n2=2.07e-07 ninf=3.64e-07 < 2.77e-06 (0.132) 0   OK
pyopencl  R2C     (2,2,2,34) axes=      None ndim=   1    float32 lut=None inplace=0  norm=   0   FFT: n2=2.13e-07 ninf=2.43e-07 < 5.53e-06 (0.044) 1 iFFT: n2=1.96e-07 ninf=3.26e-07 < 5.53e-06 (0.059) 1   OK
pyopencl  R2C     (2,2,2,34) axes=      None ndim=   1    float32 lut=None inplace=0  norm=   1   FFT: n2=2.13e-07 ninf=2.43e-07 < 5.53e-06 (0.044) 1 iFFT: n2=2.07e-07 ninf=3.64e-07 < 5.53e-06 (0.066) 1   OK
pyopencl  R2C   (2,2,2,34+2) axes=      None ndim=   1    float32 lut=True inplace=1  norm=   0   FFT: n2=2.07e-07 ninf=2.33e-07 < 2.77e-06 (0.084) 0 iFFT: n2=1.75e-07 ninf=3.26e-07 < 2.77e-06 (0.118) 0   OK
pyopencl  R2C   (2,2,2,34+2) axes=      None ndim=   1    float32 lut=True inplace=1  norm=   1   FFT: n2=2.07e-07 ninf=2.33e-07 < 2.77e-06 (0.084) 0 iFFT: n2=1.95e-07 ninf=3.33e-07 < 2.77e-06 (0.120) 0   OK
pyopencl  R2C     (2,2,2,34) axes=      None ndim=   1    float32 lut=True inplace=0  norm=   0   FFT: n2=2.07e-07 ninf=2.33e-07 < 5.53e-06 (0.042) 1 iFFT: n2=1.75e-07 ninf=3.26e-07 < 5.53e-06 (0.059) 1   OK
pyopencl  R2C     (2,2,2,34) axes=      None ndim=   1    float32 lut=True inplace=0  norm=   1   FFT: n2=2.07e-07 ninf=2.33e-07 < 5.53e-06 (0.042) 1 iFFT: n2=1.95e-07 ninf=3.33e-07 < 5.53e-06 (0.060) 1   OK
pyopencl  R2C   (2,2,2,34+2) axes=      None ndim=   1    float64 lut=None inplace=1  norm=   0   FFT: n2=5.78e-16 ninf=1.12e-15 < 5.77e-15 (0.194) 0 iFFT: n2=5.78e-16 ninf=9.91e-16 < 5.77e-15 (0.172) 0   OK
pyopencl  R2C   (2,2,2,34+2) axes=      None ndim=   1    float64 lut=None inplace=1  norm=   1   FFT: n2=5.78e-16 ninf=1.12e-15 < 5.77e-15 (0.194) 0 iFFT: n2=5.63e-16 ninf=1.07e-15 < 5.77e-15 (0.186) 0   OK
pyopencl  R2C     (2,2,2,34) axes=      None ndim=   1    float64 lut=None inplace=0  norm=   0   FFT: n2=5.78e-16 ninf=1.12e-15 < 1.15e-14 (0.097) 1 iFFT: n2=5.78e-16 ninf=9.91e-16 < 1.15e-14 (0.086) 1   OK
pyopencl  R2C     (2,2,2,34) axes=      None ndim=   1    float64 lut=None inplace=0  norm=   1   FFT: n2=5.78e-16 ninf=1.12e-15 < 1.15e-14 (0.097) 1 iFFT: n2=5.63e-16 ninf=1.07e-15 < 1.15e-14 (0.093) 1   OK
pyopencl  R2C        (808+2) axes=      None ndim=   1    float32 lut=None inplace=1  norm=   0   FFT: n2=3.52e-07 ninf=3.76e-07 < 3.45e-06 (0.109) 0 iFFT: n2=3.05e-07 ninf=4.77e-07 < 3.45e-06 (0.138) 0   OK
pyopencl  R2C        (808+2) axes=      None ndim=   1    float32 lut=None inplace=1  norm=   1   FFT: n2=3.52e-07 ninf=3.76e-07 < 3.45e-06 (0.109) 0 iFFT: n2=2.99e-07 ninf=5.14e-07 < 3.45e-06 (0.149) 0   OK
pyopencl  R2C         (808,) axes=      None ndim=   1    float32 lut=None inplace=0  norm=   0   FFT: n2=3.52e-07 ninf=3.76e-07 < 6.91e-06 (0.054) 1 iFFT: n2=3.05e-07 ninf=4.77e-07 < 6.91e-06 (0.069) 1   OK
pyopencl  R2C         (808,) axes=      None ndim=   1    float32 lut=None inplace=0  norm=   1   FFT: n2=3.52e-07 ninf=3.76e-07 < 6.91e-06 (0.054) 1 iFFT: n2=2.99e-07 ninf=5.14e-07 < 6.91e-06 (0.074) 1   OK
pyopencl  R2C        (808+2) axes=      None ndim=   1    float32 lut=True inplace=1  norm=   0   FFT: n2=2.46e-07 ninf=2.57e-07 < 3.45e-06 (0.074) 0 iFFT: n2=2.01e-07 ninf=4.55e-07 < 3.45e-06 (0.132) 0   OK
pyopencl  R2C        (808+2) axes=      None ndim=   1    float32 lut=True inplace=1  norm=   1   FFT: n2=2.46e-07 ninf=2.57e-07 < 3.45e-06 (0.074) 0 iFFT: n2=1.93e-07 ninf=4.09e-07 < 3.45e-06 (0.119) 0   OK
pyopencl  R2C         (808,) axes=      None ndim=   1    float32 lut=True inplace=0  norm=   0   FFT: n2=2.46e-07 ninf=2.57e-07 < 6.91e-06 (0.037) 1 iFFT: n2=2.01e-07 ninf=4.55e-07 < 6.91e-06 (0.066) 1   OK
pyopencl  R2C         (808,) axes=      None ndim=   1    float32 lut=True inplace=0  norm=   1   FFT: n2=2.46e-07 ninf=2.57e-07 < 6.91e-06 (0.037) 1 iFFT: n2=1.93e-07 ninf=4.09e-07 < 6.91e-06 (0.059) 1   OK
pyopencl  R2C        (808+2) axes=      None ndim=   1    float64 lut=None inplace=1  norm=   0   FFT: n2=7.58e-16 ninf=1.00e-15 < 6.45e-15 (0.155) 0 iFFT: n2=4.26e-16 ninf=8.89e-16 < 6.45e-15 (0.138) 0   OK
pyopencl  R2C        (808+2) axes=      None ndim=   1    float64 lut=None inplace=1  norm=   1   FFT: n2=7.58e-16 ninf=1.00e-15 < 6.45e-15 (0.155) 0 iFFT: n2=5.06e-16 ninf=1.11e-15 < 6.45e-15 (0.172) 0   OK
pyopencl  R2C         (808,) axes=      None ndim=   1    float64 lut=None inplace=0  norm=   0   FFT: n2=7.58e-16 ninf=1.00e-15 < 1.29e-14 (0.078) 1 iFFT: n2=4.26e-16 ninf=8.89e-16 < 1.29e-14 (0.069) 1   OK
pyopencl  R2C         (808,) axes=      None ndim=   1    float64 lut=None inplace=0  norm=   1   FFT: n2=7.58e-16 ninf=1.00e-15 < 1.29e-14 (0.078) 1 iFFT: n2=4.44e-16 ninf=1.00e-15 < 1.29e-14 (0.077) 1   OK
pyopencl  R2C      (2,808+2) axes=      None ndim=   1    float32 lut=None inplace=1  norm=   0   FFT: n2=3.73e-07 ninf=4.34e-07 < 3.45e-06 (0.126) 0 iFFT: n2=3.60e-07 ninf=7.22e-07 < 3.45e-06 (0.209) 0   OK
pyopencl  R2C      (2,808+2) axes=      None ndim=   1    float32 lut=None inplace=1  norm=   1   FFT: n2=3.73e-07 ninf=4.34e-07 < 3.45e-06 (0.126) 0 iFFT: n2=3.50e-07 ninf=6.94e-07 < 3.45e-06 (0.201) 0   OK
pyopencl  R2C        (2,808) axes=      None ndim=   1    float32 lut=None inplace=0  norm=   0   FFT: n2=3.73e-07 ninf=4.34e-07 < 6.91e-06 (0.063) 1 iFFT: n2=3.60e-07 ninf=7.22e-07 < 6.91e-06 (0.104) 1   OK
pyopencl  R2C        (2,808) axes=      None ndim=   1    float32 lut=None inplace=0  norm=   1   FFT: n2=3.73e-07 ninf=4.34e-07 < 6.91e-06 (0.063) 1 iFFT: n2=3.50e-07 ninf=6.94e-07 < 6.91e-06 (0.100) 1   OK
pyopencl  R2C      (2,808+2) axes=      None ndim=   1    float32 lut=True inplace=1  norm=   0   FFT: n2=2.60e-07 ninf=2.70e-07 < 3.45e-06 (0.078) 0 iFFT: n2=2.64e-07 ninf=4.77e-07 < 3.45e-06 (0.138) 0   OK
pyopencl  R2C      (2,808+2) axes=      None ndim=   1    float32 lut=True inplace=1  norm=   1   FFT: n2=2.60e-07 ninf=2.70e-07 < 3.45e-06 (0.078) 0 iFFT: n2=2.53e-07 ninf=4.86e-07 < 3.45e-06 (0.141) 0   OK
pyopencl  R2C        (2,808) axes=      None ndim=   1    float32 lut=True inplace=0  norm=   0   FFT: n2=2.60e-07 ninf=2.70e-07 < 6.91e-06 (0.039) 1 iFFT: n2=2.64e-07 ninf=4.77e-07 < 6.91e-06 (0.069) 1   OK
pyopencl  R2C        (2,808) axes=      None ndim=   1    float32 lut=True inplace=0  norm=   1   FFT: n2=2.60e-07 ninf=2.70e-07 < 6.91e-06 (0.039) 1 iFFT: n2=2.53e-07 ninf=4.86e-07 < 6.91e-06 (0.070) 1   OK
pyopencl  R2C      (2,808+2) axes=      None ndim=   1    float64 lut=None inplace=1  norm=   0   FFT: n2=7.55e-16 ninf=9.57e-16 < 6.45e-15 (0.148) 0 iFFT: n2=4.53e-16 ninf=9.99e-16 < 6.45e-15 (0.155) 0   OK
pyopencl  R2C      (2,808+2) axes=      None ndim=   1    float64 lut=None inplace=1  norm=   1   FFT: n2=7.55e-16 ninf=9.57e-16 < 6.45e-15 (0.148) 0 iFFT: n2=5.30e-16 ninf=9.99e-16 < 6.45e-15 (0.155) 0   OK
pyopencl  R2C        (2,808) axes=      None ndim=   1    float64 lut=None inplace=0  norm=   0   FFT: n2=7.55e-16 ninf=9.57e-16 < 1.29e-14 (0.074) 1 iFFT: n2=4.53e-16 ninf=9.99e-16 < 1.29e-14 (0.077) 1   OK
pyopencl  R2C        (2,808) axes=      None ndim=   1    float64 lut=None inplace=0  norm=   1   FFT: n2=7.55e-16 ninf=9.57e-16 < 1.29e-14 (0.074) 1 iFFT: n2=4.71e-16 ninf=8.88e-16 < 1.29e-14 (0.069) 1   OK
pyopencl  R2C      (808,808) axes=      None ndim=   2    float32 lut=None inplace=0  norm=   0   FFT: n2=5.83e-07 ninf=6.50e-07 < 9.81e-06 (0.066) 1 iFFT: n2=1.41e+00 ninf=3.33e+00 < 9.81e-06 (339051.468) 0 FAIL
pyopencl  R2C      (808,808) axes=      None ndim=   2    float32 lut=None inplace=0  norm=   1   FFT: n2=5.83e-07 ninf=6.50e-07 < 9.81e-06 (0.066) 1 iFFT: n2=1.41e+00 ninf=3.33e+00 < 9.81e-06 (339051.443) 0 FAIL
pyopencl  R2C      (808,808) axes=      None ndim=   2    float32 lut=True inplace=0  norm=   0   FFT: n2=3.71e-07 ninf=3.84e-07 < 9.81e-06 (0.039) 1 iFFT: n2=1.41e+00 ninf=3.33e+00 < 9.81e-06 (339051.516) 0 FAIL
pyopencl  R2C      (808,808) axes=      None ndim=   2    float32 lut=True inplace=0  norm=   1   FFT: n2=3.71e-07 ninf=3.84e-07 < 9.81e-06 (0.039) 1 iFFT: n2=1.41e+00 ninf=3.33e+00 < 9.81e-06 (339051.492) 0 FAIL
pyopencl  R2C      (808,808) axes=      None ndim=   2    float64 lut=None inplace=0  norm=   0   FFT: n2=1.16e-15 ninf=1.62e-15 < 1.58e-14 (0.103) 1 iFFT: n2=1.41e+00 ninf=3.14e+00 < 1.58e-14 (198609444611850.719) 0 FAIL
pyopencl  R2C      (808,808) axes=      None ndim=   2    float64 lut=None inplace=0  norm=   1   FFT: n2=1.16e-15 ninf=1.62e-15 < 1.58e-14 (0.103) 1 iFFT: n2=1.41e+00 ninf=3.14e+00 < 1.58e-14 (198609444611850.719) 0 FAIL
```
My GPU supports `cl_khr_fp64`, but does not support `cl_khr_int64`, so I made a small modification in `vkFFT.h`:
```
	if ((!strcmp(floatType, "double")) || (sc->useUint64)) {
		sc->tempLen = sprintf(sc->tempStr, "\
#pragma OPENCL EXTENSION cl_khr_fp64 : enable\n\
#pragma OPENCL EXTENSION cl_khr_int64_base_atomics : enable\n\
#pragma OPENCL EXTENSION cl_khr_int64_extended_atomics : enable\n\n");
		res = VkAppendLine(sc);
		if (res != VKFFT_SUCCESS) return res;
	}
```


Discussion / hints:

Fix patch:
diff --git a/CHANGELOG.rst b/CHANGELOG.rst
index 6dbfad9..a588d91 100644
--- a/CHANGELOG.rst
+++ b/CHANGELOG.rst
@@ -1,9 +1,15 @@
-Version 2023.1 (2021-XX-XX)
+Version 2023.1 (2023-XX-XX)
 -----------------------------
 * Fix R2C tests when using numpy (scipy unavailable) [#19]
 * Add support for F-ordered arrays (C2C and R2C)
-* Allow selection of backend for non-systemetic pvkfft-test
-* Add parameter for the OpenCL platform in pyvkfft-test
+* Allow selection of backend for non-systematic pvkfft-test
+* Add parameter to select the OpenCL platform in pyvkfft-test
+* For pyopencl, transforms will use the array's queue by default
+  instead of the application's (a warning will be written to
+  notify this change when they differ; it can be disabled using
+  config.WARN_OPENCL_QUEUE_MISMATCH). A queue can also be supplied
+  to the fft() and ifft() methods.
+  (from @isuruf, https://github.com/vincefn/pyvkfft/pull/17)
 * Fix simple fft interface import when only pycuda is used
 
 Version 2022.1.1 (2022-02-14)
diff --git a/pyvkfft/base.py b/pyvkfft/base.py
index 74ba9fb..e11b96d 100644
--- a/pyvkfft/base.py
+++ b/pyvkfft/base.py
@@ -12,7 +12,7 @@
 import warnings
 from enum import Enum
 import numpy as np
-from .config import USE_LUT
+from . import config
 
 # np.complex32 does not exist yet https://github.com/numpy/numpy/issues/14753
 complex32 = np.dtype([('re', np.float16), ('im', np.float16)])
@@ -527,8 +527,8 @@ def __init__(self, shape, dtype: type, ndim=None, inplace=True, norm=1,
                 self.use_lut = -1
             else:
                 self.use_lut = kwargs["useLUT"]
-        elif USE_LUT is not None:
-            self.use_lut = USE_LUT
+        elif config.USE_LUT is not None:
+            self.use_lut = config.USE_LUT
         else:
             self.use_lut = -1
 
diff --git a/pyvkfft/config.py b/pyvkfft/config.py
index 2fbaa80..4e1e3e4 100644
--- a/pyvkfft/config.py
+++ b/pyvkfft/config.py
@@ -16,6 +16,9 @@
 # Valid values: either None or 1
 USE_LUT = None
 
+# Emit warning it the queue is different in the application and the array
+WARN_OPENCL_QUEUE_MISMATCH = True
+
 
 def process_environ(environ):
     if "PYVKFFT_FFT_CACHE_NB" in environ:
@@ -28,6 +31,9 @@ def process_environ(environ):
     else:
         USE_LUT = None
 
+    if "PYVKFFT_WARN_OPENCL_QUEUE_MISMATCH" in environ:
+        WARN_OPENCL_QUEUE_MISMATCH = eval(environ["PYVKFFT_WARN_OPENCL_QUEUE_MISMATCH"])
+
     # Inject values into the module globals
     for name, value in locals().copy().items():
         if name.isupper():
diff --git a/pyvkfft/fft.py b/pyvkfft/fft.py
index 8f193d0..c3e9468 100644
--- a/pyvkfft/fft.py
+++ b/pyvkfft/fft.py
@@ -12,7 +12,7 @@
 from functools import lru_cache
 import numpy as np
 from .base import complex32
-from .config import FFT_CACHE_NB
+from . import config
 
 try:
     from .cuda import VkFFTApp as VkFFTApp_cuda, has_pycuda, has_cupy, vkfft_version
@@ -131,7 +131,7 @@ def _prepare_transform(src, dest, cl_queue, r2c=False):
         return backend, inplace, dest, cl_queue
 
 
-@lru_cache(maxsize=FFT_CACHE_NB)
+@lru_cache(maxsize=config.FFT_CACHE_NB)
 def _get_fft_app(backend, shape, dtype, inplace, ndim, axes, norm, cuda_stream, cl_queue, strides=None):
     if backend in [Backend.PYCUDA, Backend.CUPY]:
         return VkFFTApp_cuda(shape, dtype, ndim=ndim, inplace=inplace,
@@ -141,7 +141,7 @@ def _get_fft_app(backend, shape, dtype, inplace, ndim, axes, norm, cuda_stream,
                            norm=norm, axes=axes, strides=strides)
 
 
-@lru_cache(maxsize=FFT_CACHE_NB)
+@lru_cache(maxsize=config.FFT_CACHE_NB)
 def _get_rfft_app(backend, shape, dtype, inplace, ndim, norm, cuda_stream, cl_queue, strides=None):
     if backend in [Backend.PYCUDA, Backend.CUPY]:
         return VkFFTApp_cuda(shape, dtype, ndim=ndim, inplace=inplace,
@@ -151,7 +151,7 @@ def _get_rfft_app(backend, shape, dtype, inplace, ndim, norm, cuda_stream, cl_qu
                            norm=norm, r2c=True, strides=strides)
 
 
-@lru_cache(maxsize=FFT_CACHE_NB)
+@lru_cache(maxsize=config.FFT_CACHE_NB)
 def _get_dct_app(backend, shape, dtype, inplace, ndim, norm, dct_type,
                  cuda_stream, cl_queue):
     if backend in [Backend.PYCUDA, Backend.CUPY]:
@@ -199,7 +199,10 @@ def fftn(src, dest=None, ndim=None, norm=1, axes=None, cuda_stream=None, cl_queu
     backend, inplace, dest, cl_queue = _prepare_transform(src, dest, cl_queue, False)
     app = _get_fft_app(backend, src.shape, src.dtype, inplace, ndim, axes, norm, cuda_stream, cl_queue,
                        strides=src.strides)
-    app.fft(src, dest)
+    if backend == Backend.PYOPENCL:
+        app.fft(src, dest, queue=cl_queue)
+    else:
+        app.fft(src, dest)
     if return_scale:
         s = app.get_fft_scale()
         return dest, s
@@ -243,7 +246,10 @@ def ifftn(src, dest=None, ndim=None, norm=1, axes=None, cuda_stream=None, cl_que
     backend, inplace, dest, cl_queue = _prepare_transform(src, dest, cl_queue, False)
     app = _get_fft_app(backend, src.shape, src.dtype, inplace, ndim, axes, norm, cuda_stream, cl_queue,
                        strides=src.strides)
-    app.ifft(src, dest)
+    if backend == Backend.PYOPENCL:
+        app.ifft(src, dest, queue=cl_queue)
+    else:
+        app.ifft(src, dest)
     if return_scale:
         s = app.get_fft_scale()
         return dest, s
@@ -291,7 +297,10 @@ def rfftn(src, dest=None, ndim=None, norm=1, cuda_stream=None, cl_queue=None,
     backend, inplace, dest, cl_queue, dtype = _prepare_transform(src, dest, cl_queue, True)
     app = _get_rfft_app(backend, src.shape, src.dtype, inplace, ndim, norm, cuda_stream, cl_queue,
                         strides=src.strides)
-    app.fft(src, dest)
+    if backend == Backend.PYOPENCL:
+        app.fft(src, dest, queue=cl_queue)
+    else:
+        app.fft(src, dest)
     if return_scale:
         s = app.get_fft_scale()
         return dest.view(dtype=dtype), s
@@ -339,7 +348,10 @@ def irfftn(src, dest=None, ndim=None, norm=1, cuda_stream=None, cl_queue=None,
     backend, inplace, dest, cl_queue, dtype = _prepare_transform(src, dest, cl_queue, True)
     app = _get_rfft_app(backend, dest.shape, dest.dtype, inplace, ndim, norm, cuda_stream, cl_queue,
                         strides=dest.strides)
-    app.ifft(src, dest)
+    if backend == Backend.PYOPENCL:
+        app.ifft(src, dest, queue=cl_queue)
+    else:
+        app.ifft(src, dest)
     if return_scale:
         s = app.get_fft_scale()
         return dest.view(dtype=dtype), s
@@ -375,7 +387,10 @@ def dctn(src, dest=None, ndim=None, norm=1, dct_type=2, cuda_stream=None, cl_que
     backend, inplace, dest, cl_queue = _prepare_transform(src, dest, cl_queue, False)
     app = _get_dct_app(backend, src.shape, src.dtype, inplace, ndim, norm,
                        dct_type, cuda_stream, cl_queue)
-    app.fft(src, dest)
+    if backend == Backend.PYOPENCL:
+        app.fft(src, dest, queue=cl_queue)
+    else:
+        app.fft(src, dest)
     return dest
 
 
@@ -408,7 +423,10 @@ def idctn(src, dest=None, ndim=None, norm=1, dct_type=2, cuda_stream=None, cl_qu
     backend, inplace, dest, cl_queue = _prepare_transform(src, dest, cl_queue, False)
     app = _get_dct_app(backend, src.shape, src.dtype, inplace, ndim, norm,
                        dct_type, cuda_stream, cl_queue)
-    app.ifft(src, dest)
+    if backend == Backend.PYOPENCL:
+        app.ifft(src, dest, queue=cl_queue)
+    else:
+        app.ifft(src, dest)
     return dest
 
 
diff --git a/pyvkfft/opencl.py b/pyvkfft/opencl.py
index 1734d73..b7a29b5 100644
--- a/pyvkfft/opencl.py
+++ b/pyvkfft/opencl.py
@@ -11,6 +11,7 @@
 import pyopencl as cl
 import pyopencl.array as cla
 from .base import load_library, primes, VkFFTApp as VkFFTAppBase, VkFFTResult, check_vkfft_result
+from . import config
 
 _vkfft_opencl = load_library("_vkfft_opencl")
 
@@ -158,20 +159,61 @@ def _make_config(self):
                                          int(self.use_lut), int(self.keepShaderCode),
                                          n_batch, skipx, skipy, skipz)
 
-    def fft(self, src: cla.Array, dest: cla.Array = None):
+    def fft(self, src: cla.Array, dest: cla.Array = None, queue: cl.CommandQueue = None):
         """
         Compute the forward FFT
         :param src: the source pyopencl Array
         :param dest: the destination pyopencl Array. Should be None for an inplace transform
+        :param queue: the pyopencl CommandQueue to use for the transform. If not given,
+            the queue of the source array is used. If the queue does not match
+            the application's, a warning is emitted (see config.WARN_OPENCL_QUEUE_MISMATCH).
+            If a queue is not supplied and the source and destination arrays do not have the
+            same queue, then a RuntimeError is raised.
         :raises RuntimeError: in case of a GPU kernel launch error
         :return: the transformed array. For a R2C inplace transform, the complex view of the
             array is returned.
         """
+        if not queue:
+            if dest is None:
+                if src.queue is None:
+                    warnings.warn("queue is not given and the source array does not have a queue "
+                                  "attached to it. Falling back to the queue given to the constructor "
+                                  "of VkFFTApp. This is deprecated and will stop working in the future. "
+                                  "Use src_array.with_queue(queue) to attach a queue to the array or "
+                                  "pass a queue to this method", DeprecationWarning)
+                    queue = self.queue
+                else:
+                    queue = src.queue
+            elif dest.queue is None and src.queue is None:
+                warnings.warn("queue is not given and the source/dest arrays do not have a queue "
+                              "attached to it. Falling back to the queue given to the constructor "
+                              "of VkFFTApp. This is deprecated and will stop working in the future. "
+                              "Use src_array.with_queue(queue) to attach a queue to the array or "
+                              "pass a queue to this method", DeprecationWarning)
+                queue = self.queue
+            elif dest.queue != src.queue:
+                if dest.queue is None:
+                    queue = src.queue
+                elif src.queue is None:
+                    queue = dest.queue
+                else:
+                    raise RuntimeError("queue is not given and the source/dest arrays queues differ. "
+                                       "Please supply a queue when calling fft(...), or "
+                                       "use array.with_queue(queue)")
+            else:
+                queue = src.queue
+
+        if config.WARN_OPENCL_QUEUE_MISMATCH and self.queue != queue:
+            warnings.warn("Using the array queue for transform, which differs from the application "
+                          "queue. NB: this warning will be removed in a future version , and you can "
+                          "suppress it using config.WARN_OPENCL_QUEUE_MISMATCH",
+                          UserWarning)
+
         if self.inplace:
             if dest is not None:
                 if src.data.int_ptr != dest.data.int_ptr:
                     raise RuntimeError("VkFFTApp.fft: dest is not None but this is an inplace transform")
-            res = _vkfft_opencl.fft(self.app, int(src.data.int_ptr), int(src.data.int_ptr), int(self.queue.int_ptr))
+            res = _vkfft_opencl.fft(self.app, int(src.data.int_ptr), int(src.data.int_ptr), int(queue.int_ptr))
             check_vkfft_result(res, src.shape, src.dtype, self.ndim, self.inplace, self.norm, self.r2c,
                                self.dct, backend="opencl")
             if self.norm == "ortho":
@@ -189,27 +231,68 @@ def fft(self, src: cla.Array, dest: cla.Array = None):
                 raise RuntimeError("VkFFTApp.fft: dest and src are identical but this is an out-of-place transform")
             if self.r2c:
                 assert (dest.size == src.size // src.shape[-1] * (src.shape[-1] // 2 + 1))
-            res = _vkfft_opencl.fft(self.app, int(src.data.int_ptr), int(dest.data.int_ptr), int(self.queue.int_ptr))
+            res = _vkfft_opencl.fft(self.app, int(src.data.int_ptr), int(dest.data.int_ptr), int(queue.int_ptr))
             check_vkfft_result(res, src.shape, src.dtype, self.ndim, self.inplace, self.norm, self.r2c,
                                self.dct, backend="opencl")
             if self.norm == "ortho":
                 dest *= self._get_fft_scale(norm=0)
             return dest
 
-    def ifft(self, src: cla.Array, dest: cla.Array = None):
+    def ifft(self, src: cla.Array, dest: cla.Array = None, queue: cl.CommandQueue = None):
         """
         Compute the backward FFT
         :param src: the source pyopencl.Array
         :param dest: the destination pyopencl.Array. Can be None for an inplace transform
+        :param queue: the pyopencl CommandQueue to use for the transform. If not given,
+            the queue of the source array is used. If the queue does not match
+            the application, a warning is emitted (see config.WARN_OPENCL_QUEUE_MISMATCH).
+            If a queue is not supplied and the source and destination arrays do not have the
+            same queue, then a RuntimeError is raised.
         :raises RuntimeError: in case of a GPU kernel launch error
         :return: the transformed array. For a C2R inplace transform, the float view of the
             array is returned.
         """
+        if not queue:
+            if dest is None:
+                if src.queue is None:
+                    warnings.warn("queue is not given and the source array does not have a queue "
+                                  "attached to it. Falling back to the queue given to the constructor "
+                                  "of VkFFTApp. This is deprecated and will stop working in the future. "
+                                  "Use src_array.with_queue(queue) to attach a queue to the array or "
+                                  "pass a queue to this method", DeprecationWarning)
+                    queue = self.queue
+                else:
+                    queue = src.queue
+            elif dest.queue is None and src.queue is None:
+                warnings.warn("queue is not given and the source/dest arrays do not have a queue "
+                              "attached to it. Falling back to the queue given to the constructor "
+                              "of VkFFTApp. This is deprecated and will stop working in the future. "
+                              "Use src_array.with_queue(queue) to attach a queue to the array or "
+                              "pass a queue to this method", DeprecationWarning)
+                queue = self.queue
+            elif dest.queue != src.queue:
+                if dest.queue is None:
+                    queue = src.queue
+                elif src.queue is None:
+                    queue = dest.queue
+                else:
+                    raise RuntimeError("queue is not given and the source/dest arrays queues differ. "
+                                       "Please supply a queue when calling fft(...), or "
+                                       "use array.with_queue(queue)")
+            else:
+                queue = src.queue
+
+        if config.WARN_OPENCL_QUEUE_MISMATCH and self.queue != queue:
+            warnings.warn("Using the array queue for transform, which differs from the application "
+                          "queue. NB: this warning will be removed in a future version , and you can "
+                          "suppress it using config.WARN_OPENCL_QUEUE_MISMATCH",
+                          UserWarning)
+
         if self.inplace:
             if dest is not None:
                 if src.data.int_ptr != dest.data.int_ptr:
                     raise RuntimeError("VkFFTApp.fft: dest!=src but this is an inplace transform")
-            res = _vkfft_opencl.ifft(self.app, int(src.data.int_ptr), int(src.data.int_ptr), int(self.queue.int_ptr))
+            res = _vkfft_opencl.ifft(self.app, int(src.data.int_ptr), int(src.data.int_ptr), int(queue.int_ptr))
             check_vkfft_result(res, src.shape, src.dtype, self.ndim, self.inplace, self.norm, self.r2c,
                                self.dct, backend="opencl")
             if self.norm == "ortho":
@@ -230,10 +313,10 @@ def ifft(self, src: cla.Array, dest: cla.Array = None):
                 # Special case, src and dest buffer sizes are different,
                 # VkFFT is configured to go back to the source buffer
                 res = _vkfft_opencl.ifft(self.app, int(dest.data.int_ptr), int(src.data.int_ptr),
-                                         int(self.queue.int_ptr))
+                                         int(queue.int_ptr))
             else:
                 res = _vkfft_opencl.ifft(self.app, int(src.data.int_ptr), int(dest.data.int_ptr),
-                                         int(self.queue.int_ptr))
+                                         int(queue.int_ptr))
             check_vkfft_result(res, src.shape, src.dtype, self.ndim, self.inplace, self.norm, self.r2c,
                                self.dct, backend="opencl")
             if self.norm == "ortho":


Test patch:
diff --git a/pyvkfft/scripts/pyvkfft_test.py b/pyvkfft/scripts/pyvkfft_test.py
index 3e6d8bf..0097b57 100755
--- a/pyvkfft/scripts/pyvkfft_test.py
+++ b/pyvkfft/scripts/pyvkfft_test.py
@@ -413,13 +413,16 @@ def main():
         t.nproc = args.nproc[0]
         t.opencl_platform = args.opencl_platform
         t.vbackend = args.backend
-        # KLUDGE: remove cuda stream test if neither cupy or pycuda are used
-        test_cuda_stream = False
-        for b in args.backend:
-            if 'pycuda' in b.lower():
-                test_cuda_stream = True
-        if not test_cuda_stream:
-            del t.test_pycuda_streams
+        if args.backend is not None:
+            # Remove tests depending on backend used
+            test_cuda_stream = False
+            for b in args.backend:
+                if 'pycuda' in b.lower():
+                    test_cuda_stream = True
+            if not test_cuda_stream:
+                del t.test_pycuda_streams
+            if 'pyopencl' not in args.backend:
+                del t.test_pyopencl_queues
         suite = unittest.defaultTestLoader.loadTestsFromTestCase(t)
         if t.verbose:
             res = unittest.TextTestRunner(verbosity=2).run(suite)
diff --git a/pyvkfft/test/test_fft.py b/pyvkfft/test/test_fft.py
index e41675d..479b0ac 100644
--- a/pyvkfft/test/test_fft.py
+++ b/pyvkfft/test/test_fft.py
@@ -27,6 +27,7 @@ def ascent():
 from pyvkfft.fft import fftn as vkfftn, ifftn as vkifftn, rfftn as vkrfftn, \
     irfftn as vkirfftn, dctn as vkdctn, idctn as vkidctn
 from pyvkfft.accuracy import test_accuracy, test_accuracy_kwargs, fftn, init_ctx, gpu_ctx_dic, has_dct_ref, has_scipy
+import pyvkfft.config
 
 try:
     import pycuda.gpuarray as cua
@@ -48,6 +49,7 @@ def ascent():
 try:
     import pyopencl as cl
     import pyopencl.array as cla
+    from pyvkfft.opencl import VkFFTApp as clVkFFTApp
 
     has_pyopencl = True
 except ImportError:
@@ -416,6 +418,123 @@ def test_pycuda_streams(self):
                     dn = np.roll(d, i * 7, axis=1)
                     self.assertTrue(np.allclose(dn, vd[i].get(), rtol=rtol, atol=abs(dn).max() * rtol))
 
+    @unittest.skipIf(not has_pyopencl, "pyopencl is not available")
+    def test_pyopencl_queues(self):
+        """
+        Test multiple FFT with queues different from the queue used
+        in creating the VkFFTApp
+        """
+        has_cl_fp64 = gpu_ctx_dic["pyopencl"][3] if "pyopencl" in self.vbackend else True
+        vtype = (np.complex64, np.complex128)
+        if not has_cl_fp64:
+            vtype = (np.complex64,)
+        # Disable warning
+        old_warning = pyvkfft.config.WARN_OPENCL_QUEUE_MISMATCH
+        pyvkfft.config.WARN_OPENCL_QUEUE_MISMATCH = False
+        for dtype in vtype:
+            with self.subTest(dtype=np.dtype(dtype)):
+                init_ctx("pyopencl", gpu_name=self.gpu, opencl_platform=self.opencl_platform, verbose=False)
+                ctx = gpu_ctx_dic["pyopencl"][2].context
+                if dtype == np.complex64:
+                    rtol = 5e-6
+                else:
+                    rtol = 1e-12
+                sh = (256, 256)
+                d = (np.random.uniform(-0.5, 0.5, sh) + 1j * np.random.uniform(-0.5, 0.5, sh)).astype(dtype)
+                n_queues = 5
+                vd = []
+                vapp = []
+
+                for i in range(n_queues):
+                    vapp.append(clVkFFTApp(d.shape, d.dtype, ndim=2, norm=1, queue=cl.CommandQueue(ctx)))
+
+                queues = [cl.CommandQueue(ctx) for _ in range(2 * n_queues)]
+                for i in range(n_queues):
+                    vd.append(cla.to_device(queues[i], np.roll(d, i * 7, axis=1)))
+
+                # test transforms with a supplied queue
+                for i in range(n_queues):
+                    vapp[i].fft(vd[i], queue=queues[i])
+                    dn = fftn(np.roll(d, i * 7, axis=1))
+                    self.assertTrue(np.allclose(dn, vd[i].get(), rtol=rtol, atol=abs(dn).max() * rtol))
+
+                for i in range(n_queues):
+                    vapp[i].ifft(vd[i], queue=queues[i])
+                    dn = np.roll(d, i * 7, axis=1)
+                    self.assertTrue(np.allclose(dn, vd[i].get(), rtol=rtol, atol=abs(dn).max() * rtol))
+
+                # test transforms with a supplied queue, different from the arrays'
+                for i in range(n_queues):
+                    vapp[i].fft(vd[i], queue=queues[i + n_queues])
+                    dn = fftn(np.roll(d, i * 7, axis=1))
+                    queues[i + n_queues].finish()
+                    self.assertTrue(np.allclose(dn, vd[i].get(), rtol=rtol, atol=abs(dn).max() * rtol))
+
+                for i in range(n_queues):
+                    vapp[i].ifft(vd[i], queue=queues[i + n_queues])
+                    dn = np.roll(d, i * 7, axis=1)
+                    queues[i + n_queues].finish()
+                    self.assertTrue(np.allclose(dn, vd[i].get(), rtol=rtol, atol=abs(dn).max() * rtol))
+
+                # test transforms with the arrays queues
+                for i in range(n_queues):
+                    vapp[i].fft(vd[i])
+                    dn = fftn(np.roll(d, i * 7, axis=1))
+                    self.assertTrue(np.allclose(dn, vd[i].get(), rtol=rtol, atol=abs(dn).max() * rtol))
+
+                for i in range(n_queues):
+                    vapp[i].ifft(vd[i])
+                    dn = np.roll(d, i * 7, axis=1)
+                    self.assertTrue(np.allclose(dn, vd[i].get(), rtol=rtol, atol=abs(dn).max() * rtol))
+
+                # Test using the simple fft interface: inplace, same queue as array
+                for i in range(n_queues):
+                    vd[i] = vkfftn(vd[i], vd[i])
+                    dn = fftn(np.roll(d, i * 7, axis=1))
+                    self.assertTrue(np.allclose(dn, vd[i].get(), rtol=rtol, atol=abs(dn).max() * rtol))
+
+                    vd[i] = vkifftn(vd[i], vd[i])
+                    dn = np.roll(d, i * 7, axis=1)
+                    self.assertTrue(np.allclose(dn, vd[i].get(), rtol=rtol, atol=abs(dn).max() * rtol))
+
+                # Test using the simple fft interface: inplace, different queue for the transform
+                # A synchronisation is needed as get() will use the array's queue and not the transform's
+                for i in range(n_queues):
+                    vd[i] = vkfftn(vd[i], vd[i], cl_queue=queues[i + n_queues])
+                    dn = fftn(np.roll(d, i * 7, axis=1))
+                    queues[i + n_queues].finish()
+                    self.assertTrue(np.allclose(dn, vd[i].get(), rtol=rtol, atol=abs(dn).max() * rtol))
+
+                    vd[i] = vkifftn(vd[i], vd[i], cl_queue=queues[i + n_queues])
+                    dn = np.roll(d, i * 7, axis=1)
+                    queues[i + n_queues].finish()
+                    self.assertTrue(np.allclose(dn, vd[i].get(), rtol=rtol, atol=abs(dn).max() * rtol))
+
+                # Test using the simple fft interface: out-of-place, same queue as array
+                # The newly allocated array has the same queu as the source array, so no synchronisation issue
+                for i in range(n_queues):
+                    d1 = vkfftn(vd[i])
+                    dn = fftn(np.roll(d, i * 7, axis=1))
+                    self.assertTrue(np.allclose(dn, d1.get(), rtol=rtol, atol=abs(dn).max() * rtol))
+
+                    d2 = vkifftn(d1)
+                    dn = np.roll(d, i * 7, axis=1)
+                    self.assertTrue(np.allclose(dn, d2.get(), rtol=rtol, atol=abs(dn).max() * rtol))
+
+                # Test using the simple fft interface: out-of-place, different queue for the transform
+                # A synchronisation is needed as get() will use the array's queue and not the transform's
+                for i in range(n_queues):
+                    d1 = vkfftn(vd[i], cl_queue=queues[i + n_queues])
+                    dn = fftn(np.roll(d, i * 7, axis=1))
+                    queues[i + n_queues].finish()
+                    self.assertTrue(np.allclose(dn, d1.get(), rtol=rtol, atol=abs(dn).max() * rtol))
+
+                    d2 = vkifftn(d1, cl_queue=queues[i + n_queues])
+                    dn = np.roll(d, i * 7, axis=1)
+                    queues[i + n_queues].finish()
+                    self.assertTrue(np.allclose(dn, d2.get(), rtol=rtol, atol=abs(dn).max() * rtol))
+        pyvkfft.config.WARN_OPENCL_QUEUE_MISMATCH = old_warning
+
 
 # The class parameters are written in pyvkfft_test.main()
 class TestFFTSystematic(unittest.TestCase):