---
title: cuFFT的使用
description: "cuFFT是CUDA快速傅里叶变换库的API接口，它由两个独立的库cuFFT和cuFFTW组成。cuFFT库能够充分发挥NVIDIA GPU卡的性能，cuFFTW库能够让用户快速地在NVIDIA GPU卡使用FFTW算法。FFT（Fast Fourier Transform）是一个分治算法，能够高效地计算复数或实数数据集的离散傅里叶变换，它是物理学和通用信号处理中最重要、最广泛使用的算法。cuFFT库提供了一个简单的FFT算法接口，用户可以迅速地利用GPU的浮点算力和并行能力去加速FFT算法。"
url: https://www.hikunpeng.com/document/detail/zh/perftuning/gputuing-wp/kunpenggpu_19_0032.html
sourcePath: /source/zh/perftuning/gputuing-wp/kunpenggpu_19_0032.html
indexId: d6ef2d2025ab9039374cfcfab22efb53a8bd288db2417794571d7db7f2a531a057
---
# cuFFT的使用

cuFFT是CUDA快速傅里叶变换库的API接口，它由两个独立的库cuFFT和cuFFTW组成。cuFFT库能够充分发挥NVIDIA GPU卡的性能，cuFFTW库能够让用户快速地在NVIDIA GPU卡使用FFTW算法。FFT（Fast Fourier Transform）是一个分治算法，能够高效地计算复数或实数数据集的离散傅里叶变换，它是物理学和通用信号处理中最重要、最广泛使用的算法。cuFFT库提供了一个简单的FFT算法接口，用户可以迅速地利用GPU的浮点算力和并行能力去加速FFT算法。

#### cuFFT API主要特性

1. 输入格式可以写成：，算法经过高度优化，素数因子越小，其性能越好。2的次方表示输入时，性能最优。
2. 对于每个输入算法复杂度都为：。
3. 支持半精度（16bit）浮点、单精度（32bit）浮点和双精度（64bit）浮点，精度越多，性能越好。
4. 支持实数和复数的输入和输出。实数的输入输出比复数需要更少的计算和数据，其性能更好。支持类型有：

  - C2C：复数输入复数输出
  - R2C：实数输入复数输出
  - C2R：复数输入实数输出
5. 支持1D、2D、3D的快速傅里叶变换。
6. 支持同时计算多个1D、2D、3D的快速傅里叶变换，这样批处理变换比单个变换有更好的性能表现。
7. 支持不需要额外内存空间的算法。
8. 支持任意维度内和维度之间的步长。
9. 支持兼容FFTW的数据格式。
10. 支持多个GPU卡执行FFT。
11. 支持流式执行、异步计算和数据移动。


#### cuFFT库使用方法

1. 代码引用头文件：

  - inc/cufft.h：cuFFT库（libcufft.so）
  - inc/cufftXt.h：包含Xt功能的cuFFT库（libcufft.so）
  - inc/cufftw.h：cuFFTW库（libcufftw.so）
2. 编译时链接动态库：-lcufft。

示例代码：一维输入数据复数到复数的傅里叶变换，然后在频域执行逆变换。

```
#define NX 256
#define BATCH 1
cufftHandle plan;
cufftComplex *data;
cudaMalloc((void**)&data, sizeof(cufftComplex)*NX*BATCH);
if (cudaGetLastError() != cudaSuccess){
fprintf(stderr, "Cuda error: Failed to allocate\n");
return;
}
if (cufftPlan1d(&plan, NX, CUFFT_C2C, BATCH) != CUFFT_SUCCESS){
fprintf(stderr, "CUFFT error: Plan creation failed");
return;
}
/* Note:
*  Identical pointers to input and output arrays implies in-place transformation
*/
if (cufftExecC2C(plan, data, data, CUFFT_FORWARD) != CUFFT_SUCCESS){
fprintf(stderr, "CUFFT error: ExecC2C Forward failed");
return;
}
if (cufftExecC2C(plan, data, data, CUFFT_INVERSE) != CUFFT_SUCCESS){
fprintf(stderr, "CUFFT error: ExecC2C Inverse failed");
return;
}
/*
*  Results may not be immediately available so block device until all
*  tasks have completed
*/
if (cudaDeviceSynchronize() != cudaSuccess){
fprintf(stderr, "Cuda error: Failed to synchronize\n");
return;
}
/*
*  Divide by number of elements in data set to get back original data
*/
cufftDestroy(plan);
cudaFree(data);
```
