FFTW 单精度库在使用 SIMD 优化时输出不正确的 DFT
FFTW single-precision library outputs incorrect DFT when using SIMD optimizations
我正在测试用于一维离散傅里叶变换 (DFT) 计算的 FFTW 3.3.8 C 库。当我使用 float
(单精度)版本的库时,我得到的结果通常是不正确的,配置了 --enable-generic-simd128
或 --enable-generic-simd256
选项(和 --enable-float
for float
支持)。我已经在 MinGW-w64 以及 Windows 子系统 Linux 中测试过它,使用 gcc 作为编译器。当我使用 MinGW-w64 的预构建 FFTW 包时,我也会遇到相同的错误,该包是通过 pacman 在 MSYS2 中下载的。
作为一个简单的测试,我使用的是 1 的输入向量。预期 DFT 的第一个元素应等于输入向量的长度,所有其他元素为零。
有没有人运行以前处理过这个问题,或者有人愿意尝试重现它吗?我是否认为使用 float
版本的库时不支持 --enable-generic-simd128
和 --enable-generic-simd256
优化?我的 CPU 是英特尔 i7-4720HQ。
这里有一个简单的测试程序来演示这个问题:
main.c
#include <stdio.h>
#include <fftw3.h>
int main()
{
fftwf_complex *in, *out;
fftwf_plan p;
int N = 21;
int i;
in = fftwf_malloc(sizeof(fftwf_complex) * N);
out = fftwf_malloc(sizeof(fftwf_complex) * N);
p = fftwf_plan_dft_1d(N, in, out, FFTW_FORWARD, FFTW_ESTIMATE);
for (i = 0; i < N; i++) {
in[i][0] = 1.0f;
in[i][1] = 0.0f;
}
fftwf_execute(p);
for (i = 0; i < N; i++)
printf("%d: %8.5g\t + j %8.5g\n", i, out[i][0], out[i][1]);
fftwf_destroy_plan(p);
fftwf_free(in);
fftwf_free(out);
}
我用 gcc -o main main.c -lfftw3f -lm
构建它。输出结果如下:
0: 21 + j -7.87
1: 0 + j 0
2: 0 + j 0
3: -5.2972 + j 1.9
4: 0 + j 0
5: 0 + j 0
6: -1.862 + j 1.08
7: 0 + j 0
8: 0 + j 0
9: -0.52584 + j 0.956
10: 0 + j 0
11: 0 + j 0
12: 0.52584 + j 0.956
13: 0 + j 0
14: 0 + j 0
15: 1.862 + j 1.08
16: 0 + j 0
17: 0 + j 0
18: 5.2972 + j 1.9
19: 0 + j 0
20: 0 + j 0
这似乎是 FFTW 3.3.8 中的错误。
我在 2016 15 英寸 MacBook Pro 运行 macOS 10.14.6 和 Clang 11.0.0 和 Xcode 11.3.1 上用 --enable-float
构建了 FFTW 3.3.8 并构建了并执行问题中的代码。它为元素 0 显示输出 21,为其他元素显示接近 0 的值(例如“6.6324e-07 + j -2.0458e-07”)。在我添加 --enable-generic-simd128
重建 FFTW 后,程序给出了问题中显示的输出。
这确实是 FFTW 3.3.8 中的错误。我在几个平台上重现了这个问题,并且有几个人证实了这一点,包括 Eric Postpischil。我已将此问题报告给 FFTW 开发人员,并已在 recent commit.
中修复
我正在测试用于一维离散傅里叶变换 (DFT) 计算的 FFTW 3.3.8 C 库。当我使用 float
(单精度)版本的库时,我得到的结果通常是不正确的,配置了 --enable-generic-simd128
或 --enable-generic-simd256
选项(和 --enable-float
for float
支持)。我已经在 MinGW-w64 以及 Windows 子系统 Linux 中测试过它,使用 gcc 作为编译器。当我使用 MinGW-w64 的预构建 FFTW 包时,我也会遇到相同的错误,该包是通过 pacman 在 MSYS2 中下载的。
作为一个简单的测试,我使用的是 1 的输入向量。预期 DFT 的第一个元素应等于输入向量的长度,所有其他元素为零。
有没有人运行以前处理过这个问题,或者有人愿意尝试重现它吗?我是否认为使用 float
版本的库时不支持 --enable-generic-simd128
和 --enable-generic-simd256
优化?我的 CPU 是英特尔 i7-4720HQ。
这里有一个简单的测试程序来演示这个问题:
main.c
#include <stdio.h>
#include <fftw3.h>
int main()
{
fftwf_complex *in, *out;
fftwf_plan p;
int N = 21;
int i;
in = fftwf_malloc(sizeof(fftwf_complex) * N);
out = fftwf_malloc(sizeof(fftwf_complex) * N);
p = fftwf_plan_dft_1d(N, in, out, FFTW_FORWARD, FFTW_ESTIMATE);
for (i = 0; i < N; i++) {
in[i][0] = 1.0f;
in[i][1] = 0.0f;
}
fftwf_execute(p);
for (i = 0; i < N; i++)
printf("%d: %8.5g\t + j %8.5g\n", i, out[i][0], out[i][1]);
fftwf_destroy_plan(p);
fftwf_free(in);
fftwf_free(out);
}
我用 gcc -o main main.c -lfftw3f -lm
构建它。输出结果如下:
0: 21 + j -7.87
1: 0 + j 0
2: 0 + j 0
3: -5.2972 + j 1.9
4: 0 + j 0
5: 0 + j 0
6: -1.862 + j 1.08
7: 0 + j 0
8: 0 + j 0
9: -0.52584 + j 0.956
10: 0 + j 0
11: 0 + j 0
12: 0.52584 + j 0.956
13: 0 + j 0
14: 0 + j 0
15: 1.862 + j 1.08
16: 0 + j 0
17: 0 + j 0
18: 5.2972 + j 1.9
19: 0 + j 0
20: 0 + j 0
这似乎是 FFTW 3.3.8 中的错误。
我在 2016 15 英寸 MacBook Pro 运行 macOS 10.14.6 和 Clang 11.0.0 和 Xcode 11.3.1 上用 --enable-float
构建了 FFTW 3.3.8 并构建了并执行问题中的代码。它为元素 0 显示输出 21,为其他元素显示接近 0 的值(例如“6.6324e-07 + j -2.0458e-07”)。在我添加 --enable-generic-simd128
重建 FFTW 后,程序给出了问题中显示的输出。
这确实是 FFTW 3.3.8 中的错误。我在几个平台上重现了这个问题,并且有几个人证实了这一点,包括 Eric Postpischil。我已将此问题报告给 FFTW 开发人员,并已在 recent commit.
中修复