现在,我将我的python脚本移植到CUDA程序。 在我的python脚本中,使用了scipy.fftpack.fft2。 为了验证袖口的结果,我使用cufft编写了示例程序。 但是,似乎scipy.fftpack.fft2和cufft之间存在差异。
有什么建议吗?
python脚本:
def test2():
g = [18,19,19,23,24,24,23,24,24]
g = numpy.array(g)
g.shape = [3,3]
G = fft2(g)
print "---------------"
print g
print G
return
python脚本的结果:
---------------
[[18 19 19]
[23 24 24]
[23 24 24]]
[[ 198.+0.j -3.+0.j -3.+0.j]
[ -15.+0.j 0.+0.j 0.+0.j]
[ -15.+0.j 0.+0.j 0.+0.j]]
cuda计划:
cufftHandle plan;
int nRows = 3;
int nCols = 3;
cufftPlan2d(&plan, nRows, nCols, CUFFT_R2C);
float h_in[9] = {18,19,19,23,24,24,23,24,24};
float* d_in;
cudaMalloc(&d_in, sizeof(cufftComplex)*9);
cufftComplex* d_freq;
cudaMalloc(&d_freq, sizeof(cufftComplex)*9);
cudaMemcpy(d_in,h_in,sizeof( cufftComplex)*9,cudaMemcpyHostToDevice);
cufftExecR2C(inverse_plan, d_in, d_freq);
cufftComplex* h_freq = (float2*)malloc(sizeof( cufftComplex)*9);
cudaMemcpy(h_freq,d_freq,sizeof( cufftComplex)*9,cudaMemcpyDeviceToHost);
for(int i=0; i<9; i++) {
printf("%i %f %f\n", i, h_freq[i].x, h_freq[i].y);
}
cuda计划的结果:
0 198.000000 -0.000001
1 -2.999996 -0.000001
2 -15.000000 0.000000
3 -0.000000 0.000000
4 -15.000000 0.000000
5 -0.000000 0.000000
6 497922732955248410000000000000.000000 8589934592.000000
7 572199135312371230000000000000.000000 8589934592.000000
8 -0.000000 0.000000
答案 0 :(得分:2)
我不是袖手专家,但是这种命名方式可以解释所发生的事情:
在numpy中,您正在运行完整的2D FFT。因为您的输入是真实的,所以输出是对称的,如您所见:每行(或列)中的最后一项等于前一项。
您可以利用此功能更快地运行FFT,并且在numpy中使用rfft2
函数实现:
>>> np.fft.rfft2(g)
array([[ 198.+0.j, -3.+0.j],
[ -15.+0.j, 0.+0.j],
[ -15.+0.j, 0.+0.j]])
我的猜测是R2C
计划名称中的CUFFT_R2C
表示“真实到复杂”,因此您要求等同于np.rfft2
。如果你放弃数组中未使用的最后3项,结果几乎完全相同,除了舍入错误,以及你的CUDA实现使用32位浮点数,而不是numpy将默认使用的64
快速谷歌搜索显示CUFFT_C2C
和cufftExecR2C
是有效的袖带标识符。使用它们应该会产生正确的结果。要进行更加精确的再现,请重构代码并使用Z2Z
版本,这些版本适用于double
,而不是float
。