Closed mDiracYas closed 1 month ago
Thanks for the report, I can confirm this behaviour also with OpenCL:
import numpy as np
import pyopencl as cl
import pyopencl.array as cla
import pyvkfft.fft
from pyvkfft.base import calc_transform_axes
ctx = cl.create_some_context()
clq = cl.CommandQueue(ctx)
shape = (3,2,2)
size = np.prod(shape)
x0 = np.arange(size,dtype=np.complex64).reshape(shape)
x1 = cla.to_device(clq, x0)
x2 = cla.to_device(clq, x0[:,None])
y1 = pyvkfft.fft.fftn(x1,axes=(-1,-2)).get()
y2 = pyvkfft.fft.fftn(x2,axes=(-1,-2)).get() #.squeeze()
y0 = np.fft.fftn(x0, axes=(-1,-2))
print("shape x1:",x1.shape, "shape x2:", x2.shape)
print("shape y1:",y1.shape, "shape y2:", y2.shape)
print(abs(y1-y0).sum())
print(abs(y2.squeeze()-y0).sum())
which gives:
shape x1: (3, 2, 2) shape x2: (3, 1, 2, 2)
shape y1: (3, 2, 2) shape y2: (3, 1, 2, 2)
0.0
152.34962482055641
Interestingly the initial re-shuffling of the internal array shape passed to VkFFT (collapsing non-transformed arrays) gives the same results:
from pyvkfft.base import calc_transform_axes
print(calc_transform_axes((3,2,2), axes=(-1,-2)))
print(calc_transform_axes((3,1,2,2), axes=(-1,-2)))
([2, 2, 1], 3, [False, False, True], 2, (-1, -2))
([2, 2, 1], 3, [False, False, True], 2, (-1, -2))
So something else is going wrong...
Hmm, I think I understand what is happening - for an axis of size 1 the stride is zero:
print(x1.strides)
print(x2.strides)
(72, 24, 8)
(72, 0, 24, 8)
and pyvkfft will then assume the internal transform order must be changed, and this is where the error occurs:
print(calc_transform_axes((3,2,2), axes=(-1,-2), strides=x1.strides))
print(calc_transform_axes((3,1,2,2), axes=(-1,-2), strides=x2.strides))
([2, 2, 1], 3, [False, False, True], 2, (-1, -2))
([2, 1, 3, 1], 2, [False, True, False, True], 3, [-3, -1])
now I need to understand what is going wrong - probably the easiest solution is to ignore any 1-sized (0-strided) axis
Some background info about why an axis of size 1 has a stride=0: see https://github.com/numpy/numpy/issues/22950
OK, this should be fixed in the current git master.
The main issue was not, in fact, strides equal to zero (that's easily handled). And it is not possible to just ignore (squeeze) axes of length 1, as R2C transforms will give different results due to the handling of the fast axis... Which is surprisingly messy to handle, e.g. when considering arrays where only one axis has a length>1.
Hi! I have found that pyvkfft.fft.fftn exhibits strange behavior. Also, in previous versions of pyvkfft, this code raises an error.
OS:Windows 10 Python: 3.12.2
case (i) pyvkfft == 2024.1.1 vkfft == 1.3.4
case (ii) pyvkfft == 2023.1.1 vkfft == 1.2.9