I am new to reikna (and pyopencl) and was wondering whether or not it is possible to use a reikna function within a context created by pyopencl. I am trying to parallelize the following loop from python. It solves the Gross-Pitaevskii equation with a split-step Fourier method. This involves applying a nonlinear operator in real space to the wavefunction (the complex 2D array U), transforming to frequency space, then applying the Laplacian operator there, and transforming back. The loop can be seen below, where: potential_mat, U, kxx, kyy, and dt are defined earlier in the code.
So far I have written the following pyopencl code to perform the first exponential step:
$ ctx = cl.create_some_context()
$ queue = cl.CommandQueue(ctx)
$
$ U = U.astype(np.complex128)
$ potential_mat = potential_mat.astype(np.float64)
$ dtmat = np.array(dt).astype(np.float64)
$
$ U_dev = cl_array.to_device(queue, U)
$ potential_mat_dev = cl_array.to_device(queue, initmat)
$ dt_dev = cl_array.to_device(queue, dtmat)
$ dest_dev = cl_array.empty_like(U_dev)
$ prg = cl.Program(ctx, """
$ #pragma OPENCL EXTENSION cl_khr_fp64: enable
$ #define PYOPENCL_DEFINE_CDOUBLE
$ #include <pyopencl-complex.h>
$ __kernel void part1(__global const cdouble_t *U, __global const double *potential_mat, __global const double *dt, __global cdouble_t *mult)
$ {
$
$ // get thread id numbers
$ int gid0 = get_global_id(0);
$ int gid1 = get_global_id(1);
$
$ // get the global sizes of the various blocks
$ int num0 = get_global_size(0);
$
$ // declare a place to store the magnitude value
$ __local double mag;
$ mag = cdouble_abs(U[gid0 + num0 * gid1]) * cdouble_abs(U[gid0 + num0 * gid1]);
$
$ //declare a place to store exponentiated value
$ __local double expo;
$ expo = exp(- dt[0] * mag - dt[0] * potential_mat[gid0 + num0 * gid1]);
$
$
$ // Multiply real exponent by complex wavefct
$ mult[gid0 + num0 * gid1] = cdouble_rmul( expo, U[gid0 + num0 * gid1]);
$
$ }
$ """).build()
$
$ prg.part1(queue, U_dev.shape, None, U_dev.data, potential_mat_dev.data, dt_dev.data, dest_dev.data)
Now I would like to use reikna's FFT function to transform the array dest_dev (currently sitting on the device) into C_dev = fftshift(fft2(dest_dev)). Is there a way that I can convert the current pyopencl queue into a cluda thread, so that I can follow prg.part1 with this FFT transform?