arrayfire / arrayfire-python

Python bindings for ArrayFire: A general purpose GPU library.

Home Page:https://arrayfire.com

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Error in af.fft2 when using OpenCL backend

shyams2 opened this issue · comments

There seems to be some error raised when using af.fft2 on Arrays of certain sizes.
As far as I've tried out af.fft2(af.randu(i, i)) at values of i = 17, 19, 23, 29, 31, 34, 37, 38, 41... produces the following error:

---------------------------------------------------------------------------
RuntimeError                              Traceback (most recent call last)
<ipython-input-14-d9ab5496accd> in <module>()
      1 for i in range(39, 100):
      2     print(i)
----> 3     a = af.fft2(af.randu(i, i))
      4 

/home/mc0710/anaconda3/lib/python3.6/site-packages/arrayfire/signal.py in fft2(signal, dim0, dim1, scale)
    171     output = Array()
    172     safe_call(backend.get().af_fft2(c_pointer(output.arr), signal.arr, c_double_t(scale),
--> 173                                     c_dim_t(dim0), c_dim_t(dim1)))
    174     return output
    175 

/home/mc0710/anaconda3/lib/python3.6/site-packages/arrayfire/util.py in safe_call(af_error)
     77         err_len = c_dim_t(0)
     78         backend.get().af_get_last_error(c_pointer(err_str), c_pointer(err_len))
---> 79         raise RuntimeError(to_str(err_str))
     80 
     81 def get_version():

RuntimeError: In function void opencl::verifySupported(af::dim4) [with int rank = 2]
In file src/backend/opencl/fft.cpp:251
Invalid argument at index 1
Expected: isSupLen(dims[i])

However, it works when using the CPU backend.

clFFT, the library we use for OpenCL backend only supports sizes with prime factors < 13. Is there a particular size you are interested in ? Can you also provide a bit more context on how you are planning to use it ? There may be workarounds available for some use cases.

Ah OK.
I'm using the FFT functions to solve the Poisson equation on a grid. Here is the function where I am using it:

def fft_poisson(rho, dx, dy):
    k_x = af.to_array(fftfreq(rho.shape[1], dx))
    k_x = af.Array.as_type(k_x, af.Dtype.c64)
    k_y = af.to_array(fftfreq(rho.shape[0], dy))
    k_x = af.tile(af.reorder(k_x), rho.shape[0], 1)
    k_y = af.tile(k_y, 1, rho.shape[1])
    k_y = af.Array.as_type(k_y, af.Dtype.c64)

    rho_hat       = af.fft2(rho)
    potential_hat = af.constant(0, rho.shape[0], rho.shape[1], dtype=af.Dtype.c64)
    
    potential_hat       = (1/(4 * np.pi**2 * (k_x*k_x + k_y*k_y))) * rho_hat
    potential_hat[0, 0] = 0
    
    E_x_hat = -1j * 2 * np.pi * (k_x) * potential_hat
    E_y_hat = -1j * 2 * np.pi * (k_y) * potential_hat

    E_x = af.ifft2(E_x_hat)
    E_y = af.ifft2(E_y_hat)

    af.eval(E_x, E_y)
    return(E_x, E_y)

There's no particular size that I'm looking to solve for. I was surprised that it was failing when I attempted to do consistency checks for different grid resolutions. It's not a big problem - I'll use other resolutions which have prime factors < 13

@ShyamSS-95 fft performs best when the size is a power of 2. If that is a problem try to limit it to smaller prime factors.