Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

support split complex arrays (separate real/imag arrays) #255

Open
photor opened this issue Nov 11, 2022 · 5 comments
Open

support split complex arrays (separate real/imag arrays) #255

photor opened this issue Nov 11, 2022 · 5 comments

Comments

@photor
Copy link

photor commented Nov 11, 2022

MethodError: no method matching plan_fft(::StructVector{ComplexF64, NamedTuple{(:re, :im), Tuple{Vector{Float64}, Vector{Float64}}}, Int64}, ::UnitRange{Int64}; flags=0x00000000)

@photor photor changed the title Support StructArrays? Support StructArrays.jl? Nov 12, 2022
@jishnub
Copy link
Contributor

jishnub commented Dec 13, 2023

The best approach is for StructArrays to add an FFTW extension

@stevengj
Copy link
Member

stevengj commented Dec 13, 2023

Yes, this could utilize the FFTW's fftw_plan_guru_split_dft and fftw_execute_split_dft interface to transform the split complex format directly.

Although specifically supporting StructArrays.jl is something for an extension, we could help out in FFTW.jl by adding plan_fft_split and execute_fft_split functions, that take separate real and imaginary arrays as arguments. This might be useful for other people as well, and will allow StructArrays to avoid low level ccalls.

@stevengj stevengj changed the title Support StructArrays.jl? support split complex arrays (separate real/imag arrays) Dec 13, 2023
@minecraft2048
Copy link

I have a use case for this:

One of the common operations in GPS signal processing is signal correlation in frequency domain by doing fft -> multiply by complex conjugate of fft(local signal) -> ifft -> abs2 (for some operations, for example for signal acquisition)

But for LoopVectorization or SIMD in general to work with complex multiplication we need to deinterleave the complex array. Then we need to reinterleave it so we can feed it to ifft.

So what we have now is

interleaved array -> fft -> deinterleave -> complex conjugate SIMD multiply -> interleave -> ifft -> deinterleave -> SIMD abs2

I haven't see FFTW source code myself, but it might do deinterleaving and interleaving inside, so we have so many useless data movement:

interleaved array ->(deinterleave -> fft -> interleave) -> deinterleave -> complex conjugate SIMD multiply -> interleave -> (deinterleave -> ifft -> interleave) -> deinterleave -> SIMD abs2

If we have FFTW split complex interface implemented in FFTW.jl, we have a cleaner workflow:

interleaved array -> deinterleave -> fft -> complex conjugate SIMD multiply -> ifft -> SIMD abs2

@jishnub
Copy link
Contributor

jishnub commented Jan 12, 2024

A higher level interface would certainly be useful

@stevengj
Copy link
Member

stevengj commented Jan 12, 2024

But for LoopVectorization or SIMD in general to work with complex multiplication we need to deinterleave the complex array. Then we need to reinterleave it so we can feed it to ifft.

Is the time for complex multiplication significant compared to the time for the FFT?

(Note that the FFT performance may suffer for split complex arrays, IIRC.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants