当前位置: 首页 > news >正文

cuda编程笔记(12)--学习cuFFT的简单使用

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 核心流程

  1. 创建计划(Plan)

    • cufftPlan1d()cufftPlan2d()cufftPlanMany() 创建 FFT 执行计划

  2. 执行 FFT

    • cufftExecC2C()cufftExecR2C()cufftExecC2R() 执行

  3. 销毁计划

    • 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:双精度复数 → 双精度实数

其他重要概念

  • cufftRealfloat,用于实数输入。

  • cufftDoubleRealdouble,用于双精度实数输入。

  • 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 任务(比如内核计算、数据拷贝)重叠执行

http://www.lryc.cn/news/608460.html

相关文章:

  • Java单元测试和设计模式
  • 【LeetCode 热题 100】739. 每日温度——(解法一)单调栈+从右到左
  • 【语音技术】什么是动态实体
  • 【Django】-6- 登录用户身份鉴权
  • Mybatis学习之获取参数值(四)
  • 第14届蓝桥杯Python青少组中/高级组选拔赛(STEMA)2023年1月15日真题
  • STM32学习记录--Day6
  • 如何解决pip安装报错ModuleNotFoundError: No module named ‘seaborn’问题
  • Baumer工业相机堡盟工业相机如何通过YoloV8深度学习模型实现道路车辆事故的检测识别(C#代码UI界面版)
  • SpringBoot 服务器配置
  • 面经——电子电路技术知识详解
  • 【Python3教程】Python3高级篇之网络编程
  • 文心4.5开源测评:国产大模型的轻量化革命与全栈突破
  • GaussDB 约束的使用举例
  • 高效轻量的C++ HTTP服务:cpp-httplib使用指南
  • Redis核心机制与实践深度解析:从持久化到分布式锁
  • 路面障碍物识别漏检率↓76%:陌讯多模态融合算法实战解析
  • 基于 LFU 策略的存储缓存系统设计与实现
  • 人工智能之数学基础:离散型随机事件概率(古典概型)
  • 兰空图床部署教程
  • LQR个人笔记
  • Unity_数据持久化_C#处理XML文件
  • ollama 多实例部署
  • 睡岗识别误报率↓76%:陌讯动态时序融合算法实战解析
  • JP3-3-MyClub后台后端(三)
  • 小迪23-28~31-js简单回顾
  • 解决mac在安装nvm过程中可能遇到的一些问题
  • 小迪23年-22~27——php简单回顾(2)
  • (nice!!!)(LeetCode 每日一题) 2561. 重排水果 (哈希表 + 贪心)
  • 【自动化运维神器Ansible】YAML支持的数据类型详解:构建高效Playbook的基石