cuFFT R2C 批量输出大小与输入大小不匹配
cuFFT R2C batch output size doesn't match input size
我正在试验 cuFFT 的批处理。但我认为我没有得到正确的输出。
int NX = 16; // size of the array
int BATCH = 16; // # of batch
我正在 GPU 上分配两个数组:
float *src;
cufftComplex *dst;
cudaMalloc((void**)&src, sizeof(float)*NX*BATCH);
cudaMalloc((void**)&dst, sizeof(cufftComplex)*NX*BATCH);
我正在使用像这样的简单内核初始化源数组:
__global__ void initFloatArray(float *data, const int size) {
const int i = (blockIdx.x * blockDim.x) + threadIdx.x;
if (i < size) {
data[i] = i % NX;
}
}
基本上,每个数组的值都在 0 到 15 之间。我得到了 16 次。
我这样制定我的计划:
cufftPlanMany(&plan, 1, &NX, nullptr, 1, NX, nullptr, 1, NX, CUFFT_R2C, BATCH);
然后我正在执行我的计划:
cufftExecR2C(plan, src, dst);
最后,我将dst的内容传回宿主。但是当我打印出这些值时,我得到了这个:
BATCH 0:
<120, 0>.length = 120
<-8, 40.2187>.length = 41.0066
<-8, 19.3137>.length = 20.905
<-8, 11.9728>.length = 14.3996
<-8, 8>.length = 11.3137
<-8, 5.34543>.length = 9.62152
<-8, 3.31371>.length = 8.65914
<-8, 1.5913>.length = 8.15673
<-8, 0>.length = 8
<120, 0>.length = 120
<-8, 40.2187>.length = 41.0066
<-8, 19.3137>.length = 20.905
<-8, 11.9728>.length = 14.3996
<-8, 8>.length = 11.3137
<-8, 5.34543>.length = 9.62152
<-8, 3.31371>.length = 8.65914
BATCH 1:
<-8, 1.5913>.length = 8.15673
<-8, 0>.length = 8
<120, 0>.length = 120
<-8, 40.2187>.length = 41.0066
<-8, 19.3137>.length = 20.905
<-8, 11.9728>.length = 14.3996
...
我期待重复输出,但它每 9 个数字重复一次,而不是像它应该的那样每 16 个重复一次。
我做错了什么吗?或者有什么我不明白的地方。
real-valued 信号的 DFT 表现出厄密对称性(参见 real-input DFT on wikipedia)。因此,N
点 DFT 的完整 N
复数输出值可以仅从第一个 N/2+1
输出值构造(即其他输出是冗余的)。
相应地,与 real-valued 输入的许多 FFT 实现一样,cuFFT 不会 return 频谱的冗余上部(如 cuFFT library user's guide 的第 2.4 节所示)。在您使用 16 点 FFT 的情况下,您将因此获得 16/2 + 1 = 9
non-redundant 输出。然后将每个 FFT 的 9 个值打包 back-to-back 到您的最终 dst
缓冲区中(因此新的 FFT 结果每 9 个复数开始一次)。
我正在试验 cuFFT 的批处理。但我认为我没有得到正确的输出。
int NX = 16; // size of the array
int BATCH = 16; // # of batch
我正在 GPU 上分配两个数组:
float *src;
cufftComplex *dst;
cudaMalloc((void**)&src, sizeof(float)*NX*BATCH);
cudaMalloc((void**)&dst, sizeof(cufftComplex)*NX*BATCH);
我正在使用像这样的简单内核初始化源数组:
__global__ void initFloatArray(float *data, const int size) {
const int i = (blockIdx.x * blockDim.x) + threadIdx.x;
if (i < size) {
data[i] = i % NX;
}
}
基本上,每个数组的值都在 0 到 15 之间。我得到了 16 次。
我这样制定我的计划:
cufftPlanMany(&plan, 1, &NX, nullptr, 1, NX, nullptr, 1, NX, CUFFT_R2C, BATCH);
然后我正在执行我的计划:
cufftExecR2C(plan, src, dst);
最后,我将dst的内容传回宿主。但是当我打印出这些值时,我得到了这个:
BATCH 0:
<120, 0>.length = 120
<-8, 40.2187>.length = 41.0066
<-8, 19.3137>.length = 20.905
<-8, 11.9728>.length = 14.3996
<-8, 8>.length = 11.3137
<-8, 5.34543>.length = 9.62152
<-8, 3.31371>.length = 8.65914
<-8, 1.5913>.length = 8.15673
<-8, 0>.length = 8
<120, 0>.length = 120
<-8, 40.2187>.length = 41.0066
<-8, 19.3137>.length = 20.905
<-8, 11.9728>.length = 14.3996
<-8, 8>.length = 11.3137
<-8, 5.34543>.length = 9.62152
<-8, 3.31371>.length = 8.65914
BATCH 1:
<-8, 1.5913>.length = 8.15673
<-8, 0>.length = 8
<120, 0>.length = 120
<-8, 40.2187>.length = 41.0066
<-8, 19.3137>.length = 20.905
<-8, 11.9728>.length = 14.3996
...
我期待重复输出,但它每 9 个数字重复一次,而不是像它应该的那样每 16 个重复一次。
我做错了什么吗?或者有什么我不明白的地方。
real-valued 信号的 DFT 表现出厄密对称性(参见 real-input DFT on wikipedia)。因此,N
点 DFT 的完整 N
复数输出值可以仅从第一个 N/2+1
输出值构造(即其他输出是冗余的)。
相应地,与 real-valued 输入的许多 FFT 实现一样,cuFFT 不会 return 频谱的冗余上部(如 cuFFT library user's guide 的第 2.4 节所示)。在您使用 16 点 FFT 的情况下,您将因此获得 16/2 + 1 = 9
non-redundant 输出。然后将每个 FFT 的 9 个值打包 back-to-back 到您的最终 dst
缓冲区中(因此新的 FFT 结果每 9 个复数开始一次)。