我正在尝试使用cuFFT的回调功能来动态执行输入格式转换(例如,计算8位整数输入数据的FFT,而不先对输入缓冲区进行显式转换float).在我的许多应用程序中,我需要计算输入缓冲区上的重叠 FFT,如前面的SO问题所述.通常,相邻的FFT可能重叠FFT长度的1/4到1/8.
cuFFT具有类似FFTW的接口,通过函数的idist参数cufftPlanMany()显式支持.具体来说,如果我想计算大小为32768的FFT,并且在连续输入之间重叠4096个样本,我会设置idist = 32768 - 4096.这不,因为它得到正确的输出感正常工作.
但是,当我以这种方式使用cuFFT时,我看到了奇怪的性能下降.我设计了一个测试,它以两种不同的方式实现这种格式转换和重叠:
明确告诉cuFFT有关输入的重叠性质:idist = nfft - overlap如上所述设置.安装负载回调函数只是没有从转换int8_t到float根据需要提供给所述回叫缓冲指数.
不要告诉cuFFT关于输入的重叠性质; 对它说谎idist = nfft.然后,让回调函数通过计算应为每个FFT输入读取的正确索引来处理重叠.
这个GitHub要点提供了一个测试程序,该程序通过时序和等效测试实现这两种方法.为简洁起见,我没有在这里重现所有内容.该程序计算一批1024个32768点FFT,重叠4096个样本; 输入数据类型是8位整数.当我在我的机器上运行它(使用Geforce GTX 660 GPU,在Ubuntu 16.04上使用CUDA 8.0 RC)时,我得到以下结果:
executing method 1...done in 32.523 msec
executing method 2...done in 26.3281 msec
Run Code Online (Sandbox Code Playgroud)
方法2明显更快,我不指望.看一下回调函数的实现:
方法1:
template <typename T>
__device__ cufftReal convert_callback(void * inbuf, size_t fft_index,
void *, void *)
{
return (cufftReal)(((const T …Run Code Online (Sandbox Code Playgroud) 我在主机代码中使用cuFFT库调用它们工作正常,但我想从内核调用cuFFT库.早期版本的CUDA没有这种支持,但动态并行性可能吗?
如果有任何关于如何实现这一点的例子,那将是很棒的.
我目前正在开发一个必须实现 2D-FFT(用于互相关)的程序。我使用 CUDA 进行了 1D FFT,这给了我正确的结果,我现在正在尝试实现 2D 版本。由于网上的示例和文档很少,我发现很难找出错误是什么。
到目前为止,我只使用 cuFFT 手册。
无论如何,我创建了两个 5x5 数组并用 1 填充它们。我将它们复制到 GPU 内存上并进行前向 FFT,将它们相乘,然后对结果进行 ifft。这给了我一个值为 650 的 5x5 数组。我希望在 5x5 数组中仅一个插槽中获得值为 25 的 DC 信号。相反,我在整个数组中得到 650。
此外,在将信号复制到 GPU 内存后,我不允许打印出信号的值。写作
cout << d_signal[1].x << endl;
Run Code Online (Sandbox Code Playgroud)
给我一个访问冲突。我在其他 cuda 程序中做了同样的事情,这不是一个问题。它与复杂变量的工作方式有关,还是人为错误?
如果有人指出出了什么问题,我将不胜感激。这是代码
#include "cuda_runtime.h"
#include "device_launch_parameters.h"
#include <helper_functions.h>
#include <helper_cuda.h>
#include <ctime>
#include <time.h>
#include <stdio.h>
#include <iostream>
#include <math.h>
#include <cufft.h>
#include <fstream>
using namespace std;
typedef float2 Complex;
__global__ void ComplexMUL(Complex *a, Complex *b)
{
int i …Run Code Online (Sandbox Code Playgroud) 每当我绘制一个使用cuFFT程序获得的值并将结果与Matlab进行比较时,我都会得到相同形状的图形,并且最大值和最小值都在相同的点上。但是,cuFFT产生的值比Matlab产生的值大得多。Matlab代码是
fs = 1000; % sample freq
D = [0:1:4]'; % pulse delay times
t = 0 : 1/fs : 4000/fs; % signal evaluation time
w = 0.5; % width of each pulse
yp = pulstran(t,D,'rectpuls',w);
filt = conj(fliplr(yp));
xx = fft(yp,1024).*fft(filt,1024);
xx = (abs(ifft(xx)));
Run Code Online (Sandbox Code Playgroud)
输入相同的CUDA代码如下:
cufftExecC2C(plan, (cufftComplex *)d_signal, (cufftComplex *)d_signal, CUFFT_FORWARD);
cufftExecC2C(plan, (cufftComplex *)d_filter_signal, (cufftComplex *)d_filter_signal, CUFFT_FORWARD);
ComplexPointwiseMul<<<blocksPerGrid, threadsPerBlock>>>(d_signal, d_filter_signal, NX);
cufftExecC2C(plan, (cufftComplex *)d_signal, (cufftComplex *)d_signal, CUFFT_INVERSE);
Run Code Online (Sandbox Code Playgroud)
cuFFT还执行1024批处理大小为的点FFT 2。
使用的比例因子时NX=1024,值不正确。请告诉该怎么办。
我正在尝试使用计算批量1D FFT cufftPlanMany.该数据集来自一个三维场中,存储在一维阵列,其中我想计算1维FFT在x和y方向.数据存储如下图所示; 连续在x然后y然后z.
在x-direction中进行批量FFT 是(我相信)直截了当; 具有输入stride=1,distance=nx并且batch=ny * nz,它计算在元件的FFT {0,1,2,3},{4,5,6,7},...,{28,29,30,31}.但是,我想不出一种方法可以在-direction中实现相同的FFT y.一种用于每批xy平面是再次简单(输入stride=nx,dist=1,batch=nx过度导致的FFT {0,4,8,12},{1,5,9,13}等).但是batch=nx * nz,从那里{3,7,11,15}开始{16,20,24,28},距离大于1.这可以用cufftPlanMany以某种方式完成吗?

我有一个CUDA程序,用于计算大小的FFT 50000.目前,我将整个阵列复制到GPU并执行cuFFT.现在,我正在尝试优化程序,NVIDIA Visual Profiler告诉我通过并行计算并发隐藏memcopy.我的问题是:
例如,是否可以复制第一个5000元素,然后开始计算,然后将下一组数据并行复制到计算等?
由于DFT基本上是时间值乘以复指数函数的总和,我认为应该可以"逐块"地计算FFT.
袖口支持吗?它一般是一个好的计算理念吗?
编辑
为了更清楚,我不想在不同的阵列上并行计算不同的FFT.假设我在时域中有很大的正弦信号,我想知道信号中有哪些频率.我的想法是将例如信号长度的三分之一复制到GPU,然后是下一个三分之一并且用已经复制的输入值的前三分之一并行计算FFT.然后复制最后一个三分之一并更新输出值,直到处理完所有时间值.所以最后应该有一个输出阵列,在窦的频率处有一个峰值.
我在使用CUDA FFT库时遇到一些问题。
我将输入声明为cuDoubleComplex,但编译器返回以下错误:此类型与cufftComplex类型的参数不兼容。通过Internet搜索后,我发现文件cufft.h,其中有一行typedef cuComplex cufftComplex;。我的问题是,在cuComplex.h库中,很显然cuComplex具有单浮点精度(typedef cuFloatComplex cuComplex;),但是我想要双精度。
这可能吗?
特别是,我获得以下信息:
error: argument of type "cufftDoubleComplex *" is incompatible with parameter of type "cufftComplex *"
Run Code Online (Sandbox Code Playgroud)
在这一行:
cufftExecC2C(plan, data1, data2, CUFFT_FORWARD);
Run Code Online (Sandbox Code Playgroud) 我试图找到一个动态分配的数组的fft.使用输入数组从主机复制到设备cudaMemcpy2D.然后获取fft(cufftExecR2C)并将结果从设备复制回主机.
所以我最初的问题是如何在fft中使用音高信息.然后我在这里找到了答案 - CUFFT:如何计算投手指针的fft?
但不幸的是它不起作用.我得到的结果是垃圾值.以下是我的代码.
#define NRANK 2
#define BATCH 10
#include "cuda_runtime.h"
#include "device_launch_parameters.h"
#include <cufft.h>
#include <stdio.h>
#include <iomanip>
#include <iostream>
#include <vector>
using namespace std;
const size_t NX = 4;
const size_t NY = 6;
int main()
{
// Input array (static) - host side
float h_in_data_static[NX][NY] ={
{0.7943 , 0.6020 , 0.7482 , 0.9133 , 0.9961 , 0.9261},
{0.3112 , 0.2630 , 0.4505 , 0.1524 , 0.0782 , 0.1782},
{0.5285 , 0.6541 , 0.0838 …Run Code Online (Sandbox Code Playgroud) 在Matlab中,当我输入一个复数的一维数组时,我有一个具有相同大小和相同维度的实数的数组输出.试图在CUDA C中重复此操作,但输出不同.你能帮忙吗?在Matlab中,当我输入ifft(数组)
我的arrayOfComplexNmbers:
[4.6500 + 0.0000i 0.5964 - 1.4325i 0.4905 - 0.5637i 0.4286 - 0.2976i 0.4345 - 0.1512i 0.4500 + 0.0000i 0.4345 + 0.1512i 0.4286 + 0.2976i 0.4905 + 0.5637i 0.5964 + 1.4325i]
Run Code Online (Sandbox Code Playgroud)
我的arrayOfRealNumbers:
[ 0.9000 0.8000 0.7000 0.6000 0.5000 0.4000 0.3000 0.2000 0.1500 0.1000]
Run Code Online (Sandbox Code Playgroud)
当我进入ifft(arrayOfComplexNmbers)Matlab时,我的输出是arrayOfRealNumbers.谢谢!这是我的CUDA代码:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <cuda_runtime.h>
#include <cufft.h>
#include "device_launch_parameters.h"
#include "device_functions.h"
#define NX 256
#define NY 128
#define NRANK 2
#define BATCH 1
#define SIGNAL_SIZE 10
typedef …Run Code Online (Sandbox Code Playgroud) 从我对fft函数的理解(例如,从类似这样的问题开始)
假设1D fft,给定N点实际数据,对于零频率,我将得到长度为N(但为复数)+1的双面fft。如果我采用相同的fft输出,并对其执行ifft,则将获得N个实数值,在理想情况下,这将与fft的原始输入完全匹配。
在cufft中,这似乎有很大不同。
根据Nvidia的研究,给N个实数分量将导致fft的N2 +1个复杂分量,而N2 + 1个复杂分量将导致N个实数分量。
看到这里(R =实数,C =复数,2 =到):
请注意,我认识到一半的复杂成分实际上是重复的(但共轭并颠倒了),因此对于输入输出值保留重建所需的所有日期而言并不是必需的,但这并不能解释Nvidia如何声称fft的输入和输出数据长度应该结构化,cufft的输入和输出长度所做的事情与我对此情况的预期相反。