pybind11
pybind11 copied to clipboard
[BUG]: Binding an FFTW algorithm gives different results
Problem description
Hello everyone,
As I am not sure if the bug I am seeing comes from pybind, the underlying library FFTW3 or the compiling/linking, I also adress this issue in the fftw3 project
Here is the minimal example that I think illustrates my problem in a practical way.
In the Git repository, we have a function foo() that uses an hard-coded vector of size 300 and computes its DFT using the FFTW3 library. I followed what is in the tutorial but with real-to-complex DFT instead.
This function is duplicated in two sources files : main.c that is built into a Main program, and bindings.cpp that is built into a Python module. Both outputs are built using cmake in a conda environment.
To compare the results, the foo() function prints the FFT plan and the ouput complex array.
When launching the foo function from both module and program, I get differences in the output vector (left is the C program call, right is the Python module call) :

Because the input vector for the FFT is hard-coded, I don't think there is a data corruption from pybind. Any idea why we see this behavior ?
Note : the hard-coded vector has been generated with random numbers with numpy, then scaled to 100. Note 2: taking a small vector (10 elements) shows no differences.
pybind version: 2.9.2 fftw3 version: 3.3.4
Reproducible example code
[minimal example](https://github.com/robin-cls/fftw3_pybind)
I did notice in the example code that the out memory is first freed, and after that the code prints data from that released memory.
https://github.com/robin-cls/fftw3_pybind/blob/298c860091cc6306a6eec01c899671944fc45af2/src/bindings.cpp#L89
@Wiskerke Thanks for pointing that obvious (newbie) mistake ! Although after fixing it there are still differences between C and Python output.
@robin-cls It looks like the remaining difference are in the last half of the out memory. My guess is that the fft algorithm only overwrites the first part of that memory. And the rest of the data is undefined after the memory was alloced with malloc. And the pybind build probably has slightly different compiler / linker settings, so it has slightly different behavior for undefined memory.
You could try filling out with zero's before doing the FFT algorithm, to make sure.
Anyway, I don't think this is a pybind bug.