InPlace FFT Plan and view

Hi All,

I have this view problem with plan_fft!,

Part of the code is below:

using FFTW
L = (128,16,16);
pad = 2;

data = rand(ComplexF32,128,16,16);
FFT_buffer = zeros(ComplexF32,128,32,32);

FFT_buffer[:,1:L[2],1:L[3]] .= data;

I want to apply 1D FFT along second dimension in FFT_buffer, because I know half of the data in the second and third dimension are zero.

Therefore, I have created a FFTPlan to do 1D FFT along second dimension as below:

FFTPlan = plan_fft!(rand(ComplexF32,L[1],L[2],L[3].pad),2,flags=FFTW.MEASURE); # for size 12816*32

FFTPlan * view(FFT_buffer,:,1:L[2],:); # this doesn’t work

=> ERROR: ArgumentError: FFTW plan applied to wrong-strides array

FFTPlan * FFT_buffer[:,1:L[2],:] # this works but then it doesn’t update FFT_buffer file.

I have to do this to get it working

FFT_buffer[:,1:L[2],:] .= FFTPlan * FFT_buffer[:,1:L[2],:] ;

But then I am allocating the memory by doing this as shown below:

@time FFT_buffer[:,1:L[2],:] .= FFTPlan * FFT_buffer[:,1:L[2],:] ;
0.000603 seconds (22 allocations: 512.750 KiB)

I don’t want to reallocate memory again. I already have done the allocation in FFT_buffer file, I want to avoid any memory allocation now.
I could have avoided if view(FFT_buffer,:,1:L[2],:slight_smile: had worked.

Does anyone have any idea how to avoid memory allocation here and use view in FFT_buffer to do such operation?

This is the part of my code, and it runs in the loop for many many iterations, that’s why I want to avoid this memory allocation.

Thank you.

Welcome AmarjeetK,
let me try to help. I think what you want is this:

using FFTW

L = (128,16,16);
pad = 2;

data = rand(ComplexF32,128,16,16);
FFT_buffer = zeros(ComplexF32,128,32,32);

FFT_buffer[:,1:L[2],1:L[3]] .= data;
FFT_buffer_copy = deepcopy(FFT_buffer);

FFTPlan = plan_fft!(FFT_bufferview,2,flags=FFTW.MEASURE);

@time FFTPlan*FFT_bufferview #gives 0 allocations (on the second evaluation)

FFT_buffer==FFT_buffer_copy #gives false, as FFT_buffer is mutated

If you don’t like the view syntax, you can also use the macro

@views X[1:n,1:m,1:l] .= XXX
#is equivalent to
view(X,1:n,1:m,1:l) .= XXX

I hope this is what you wanted! Also, check out Please read: make it easier to help you - #103 to see how you can highlight code snippets :wink:

1 Like

Thank you @fgerick

This might serve my problem, will implement in my code and will then let you know.

Does this mean I have to carry FFT_bufferview file as well?
because this viewing also takes some allocation as well right?
For example:

@time FFT_bufferview=view(FFT_buffer,1:L[1],1:L[2],1:L[3]*pad);
 0.000006 seconds (11 allocations: 464 bytes)

Oh wow this PSA think worked nicely, thanks for letting me know.

I’m not sure what you mean by this, but a small allocation for each newly generated view is needed (I think). But judging from the fact that you plan your fft I assume that the view remains the same?