cuFFT 是 NVIDIA 提供的 GPU 加速快速傅里叶变换(FFT)库,类似于 CPU 端的 FFTW,但利用 CUDA 并行计算大幅提高性能。
它可以处理 一维、二维、三维的 FFT,支持 复数到复数(C2C)、实数到复数(R2C)、复数到实数(C2R) 的变换,常用于信号处理、图像处理、频谱分析等。
如果用VS写cuda,记得链接器的输入加上cufft.lib
说实话,这一节我也不太懂,因为我之前没接触过傅里叶变换;如果专业的人应该能看懂一些函数的参数选项是啥意思吧
什么是 FFT?
-
FFT(Fast Fourier Transform):把信号从 时域(time domain) 转换到 频域(frequency domain)。
-
在图像处理中,FFT 用于:
-
滤波(高通、低通)
-
卷积加速(卷积定理:卷积 = 频域乘法)
-
-
在信号处理中,FFT 用于:
-
频谱分析(检测信号频率成分)
-
滤波、调制
-
cuFFT 的 API 核心流程
-
创建计划(Plan)
-
用
cufftPlan1d()
、cufftPlan2d()
或cufftPlanMany()
创建 FFT 执行计划
-
-
执行 FFT
-
用
cufftExecC2C()
、cufftExecR2C()
、cufftExecC2R()
执行
-
-
销毁计划
-
用
cufftDestroy()
释放资源
-
cuFFT API 的常见类型
cufftHandle
-
定义:
typedef int cufftHandle;
-
作用:FFT 计划(Plan)的句柄,类似于 cuBLAS 的
cublasHandle_t
。 -
用法:
-
创建计划:
cufftPlan1d(&plan, N, CUFFT_C2C, 1);
-
使用计划执行:
cufftExecC2C(plan, ...)
-
销毁计划:
cufftDestroy(plan);
-
📌 一个计划可以重复使用,只要尺寸(N)和类型一致,执行多次 FFT 不需要重新创建。
cufftResult
-
定义:枚举类型,表示 cuFFT API 的返回状态。
-
常用值:
-
CUFFT_SUCCESS
:成功 -
CUFFT_INVALID_PLAN
:无效计划 -
CUFFT_ALLOC_FAILED
:内存分配失败 -
CUFFT_EXEC_FAILED
:执行失败 -
CUFFT_INVALID_VALUE
:参数错误
-
-
用法:
cufftResult status = cufftPlan1d(&plan, N, CUFFT_C2C, 1);
if (status != CUFFT_SUCCESS) {
printf("Error creating plan!\n");
}
cufftComplex
/ cufftDoubleComplex
-
定义:
typedef float2 cufftComplex; // 单精度复数 (float)
typedef double2 cufftDoubleComplex; // 双精度复数 (double)
-
成员:
-
.x
:实部 -
.y
:虚部
-
-
用法:
cufftComplex val;
val.x = 1.0f; // 实部
val.y = 0.5f; // 虚部
cufftType
-
定义:FFT 类型,决定输入/输出数据格式。
-
常用值:
-
CUFFT_R2C
:实数 → 复数 -
CUFFT_C2R
:复数 → 实数 -
CUFFT_C2C
:复数 → 复数 -
CUFFT_D2Z
:双精度实数 → 双精度复数 -
CUFFT_Z2D
:双精度复数 → 双精度实数
-
其他重要概念
-
cufftReal
:float
,用于实数输入。 -
cufftDoubleReal
:double
,用于双精度实数输入。 -
CUFFT_FORWARD
/CUFFT_INVERSE
:正向/逆向变换。
创建计划
cufftResult cufftPlan1d(cufftHandle *plan, int nx, cufftType type, int batch);
cufftResult cufftPlan2d(cufftHandle *plan, int nx, int ny, cufftType type);
-
nx, ny:信号长度
-
type:
-
CUFFT_C2C
:复数→复数 -
CUFFT_R2C
:实数→复数 -
CUFFT_C2R
:复数→实数
-
-
batch:批处理个数,一次要并行处理多少个 独立的数据集。总输入的大小为nx*batch
执行 FFT
复数 ↔ 复数
cufftResult cufftExecC2C(cufftHandle plan, cufftComplex *idata, cufftComplex *odata, int direction);
-
idata
:输入数据(GPU) -
odata
:输出数据(GPU) -
direction
:-
CUFFT_FORWARD
(正变换) -
CUFFT_INVERSE
(逆变换)
-
实数 → 复数
cufftResult cufftExecR2C(cufftHandle plan,
cufftReal *idata,
cufftComplex *odata);
复数 → 实数
cufftResult cufftExecC2R(cufftHandle plan,
cufftComplex *idata,
cufftReal *odata);
双精度版本
-
cufftExecZ2Z
(复数 ↔ 复数) -
cufftExecD2Z
(实数 → 复数) -
cufftExecZ2D
(复数 → 实数)
方向参数(direction)
仅在 C2C / Z2Z 中使用:
-
CUFFT_FORWARD
(前向FFT:时域→频域) -
CUFFT_INVERSE
(逆向FFT:频域→时域)
绑定 CUDA Stream
cuFFT 和 cuBLAS 一样,也可以通过 绑定 CUDA Stream 来实现异步执行,从而和其他内核或库函数并行化。
cufftResult cufftSetStream(cufftHandle plan, cudaStream_t stream);
-
plan:FFT 计划(
cufftHandle
) -
stream:CUDA 流(
cudaStream_t
)
-
默认情况下,
cufftExec*
是在 默认流(stream 0
)上执行。 -
如果绑定到自定义流,那么:
-
FFT 调用变为异步,不会阻塞主机线程。
-
可以在不同流上运行多个 FFT 并行处理。
-
还能和其他 GPU 任务(比如内核计算、数据拷贝)重叠执行。
-