CUDA的cufft库可以实现(复数C-复数C),(实数R-复数C)和(复数C-实数R)的单精度,双精度福利变换。其变换前后的输入,输出数据的长度如图所示。在C2R和R2C模式中,根据埃尔米特对称性(Hermitian symmetry),变换后,*代表共轭复数。CUFFT的傅里叶变换类型则利用了这些冗余,将计算量降到最低。

注意:下表都是单精度(C-表示float复数,R表示float实数)。而双精度标识(Z表示double复数,D表示double实数)

下面分别给出示例程序:

(1)C2C(Z2Z)模式

1.单精度代码

#include"iostream"
#include"cuda_runtime_api.h"
#include"device_launch_parameters.h"
#include"cufft.h"
using namespace std;
//FFT反变换后,用于规范化的函数
__global__ void normalizing(cufftComplex* data, int data_len)
{int idx = blockDim.x*blockIdx.x + threadIdx.x;data[idx].x /= data_len;data[idx].y /= data_len;
}
void Check(cudaError_t status)
{if (status != cudaSuccess){cout << "行号:" << __LINE__ << endl;cout << "错误:" << cudaGetErrorString(status) << endl;}
}
int main()
{const int Nt = 256;const int BATCH = 1;//BATCH用于批量处理一批一维数据,当BATCH=2时//则将0-1024,1024-2048作为两个一维信号做FFT处理变换cufftComplex* host_in, *host_out, *device_in, *device_out;//主机内存申请及初始化--主机锁页内存Check(cudaMallocHost((void**)&host_in, Nt * sizeof(cufftComplex)));Check(cudaMallocHost((void**)&host_out, Nt * sizeof(cufftComplex)));for (int i = 0; i < Nt; i++){host_in[i].x = i + 1;host_in[i].y = i + 1;}//设备内存申请Check(cudaMalloc((void**)&device_in, Nt * sizeof(cufftComplex)));Check(cudaMalloc((void**)&device_out, Nt * sizeof(cufftComplex)));//数据传输--H2DCheck(cudaMemcpy(device_in, host_in, Nt * sizeof(cufftComplex), cudaMemcpyHostToDevice));//创建cufft句柄cufftHandle cufftForwrdHandle, cufftInverseHandle;cufftPlan1d(&cufftForwrdHandle, Nt, CUFFT_C2C, BATCH);cufftPlan1d(&cufftInverseHandle, Nt, CUFFT_C2C, BATCH);//执行fft正变换cufftExecC2C(cufftForwrdHandle, device_in, device_out, CUFFT_FORWARD);//数据传输--D2HCheck(cudaMemcpy(host_out, device_out, Nt * sizeof(cufftComplex), cudaMemcpyDeviceToHost));//设置输出精度--正变换结果输出cout << "正变换结果:" << endl;cout.setf(20);for (int i = 0; i < Nt; i++){cout << host_out[i].x << "+j*" << host_out[i].y << endl;}//执行fft反变换cufftExecC2C(cufftInverseHandle, device_out, device_in, CUFFT_INVERSE);//IFFT结果是真值的N倍,因此要做/N处理dim3 grid(Nt / 128);dim3 block(128);normalizing << <grid, block >> > (device_in, Nt);//数据传输--D2HCheck(cudaMemcpy(host_in, device_in, Nt * sizeof(cufftComplex), cudaMemcpyDeviceToHost));//设置输出精度--反变换结果输出cout << "反变换结果:" << endl;cout.setf(20);for (int i = 0; i < Nt; i++){cout << host_in[i].x << "+j*" << host_in[i].y << endl;}cin.get();return 0;
}

2.双精度代码

#include"iostream"
#include"cuda_runtime_api.h"
#include"device_launch_parameters.h"
#include"cufft.h"
using namespace std;
//FFT反变换后,用于规范化的函数
__global__ void normalizing(cufftDoubleComplex* data,int data_len)
{int idx = blockDim.x*blockIdx.x + threadIdx.x;data[idx].x /= data_len;data[idx].y /= data_len;
}
void Check(cudaError_t status)
{if (status != cudaSuccess){cout << "行号:" << __LINE__ << endl;cout << "错误:" << cudaGetErrorString(status) << endl;}
}
int main()
{const int Nt =256;const int BATCH = 1;//BATCH用于批量处理一批一维数据,当BATCH=2时//则将0-1024,1024-2048作为两个一维信号做FFT处理变换cufftDoubleComplex* host_in, *host_out, *device_in, *device_out;//主机内存申请及初始化--主机锁页内存Check(cudaMallocHost((void**)&host_in, Nt * sizeof(cufftDoubleComplex)));Check(cudaMallocHost((void**)&host_out, Nt * sizeof(cufftDoubleComplex)));for (int i = 0; i < Nt; i++){host_in[i].x = i + 1;host_in[i].y = i + 1;}//设备内存申请Check(cudaMalloc((void**)&device_in, Nt * sizeof(cufftDoubleComplex)));Check(cudaMalloc((void**)&device_out, Nt * sizeof(cufftDoubleComplex)));//数据传输--H2DCheck(cudaMemcpy(device_in, host_in, Nt * sizeof(cufftDoubleComplex), cudaMemcpyHostToDevice));//创建cufft句柄cufftHandle cufftForwrdHandle, cufftInverseHandle;cufftPlan1d(&cufftForwrdHandle, Nt, CUFFT_Z2Z, BATCH);cufftPlan1d(&cufftInverseHandle, Nt, CUFFT_Z2Z, BATCH);//执行fft正变换cufftExecZ2Z(cufftForwrdHandle, device_in, device_out, CUFFT_FORWARD);//数据传输--D2HCheck(cudaMemcpy(host_out, device_out, Nt * sizeof(cufftDoubleComplex), cudaMemcpyDeviceToHost));//设置输出精度--正变换结果输出cout << "正变换结果:" << endl;cout.setf(20);for (int i = 0; i < Nt; i++){cout << host_out[i].x<< "+j*" << host_out[i].y << endl;}//执行fft反变换cufftExecZ2Z(cufftInverseHandle,  device_out, device_in, CUFFT_INVERSE);//IFFT结果是真值的N倍,因此要做/N处理dim3 grid(Nt/128); dim3 block(128);normalizing << <grid, block >> > (device_in,Nt);//数据传输--D2HCheck(cudaMemcpy(host_in, device_in, Nt * sizeof(cufftDoubleComplex), cudaMemcpyDeviceToHost));//设置输出精度--反变换结果输出cout << "反变换结果:" << endl;cout.setf(20);for (int i = 0; i < Nt; i++){cout << host_in[i].x << "+j*" << host_in[i].y << endl;}cin.get();return 0;
}

(2)R2C(D2Z)模式-双精度(单精度类似)&&C2R(Z2D)模式双精度(单精度类似)  包括正反变换

#include"iostream"
#include"cuda_runtime_api.h"
#include"device_launch_parameters.h"
#include"cufft.h"
using namespace std;
#define Check(call)                                                     \
{                                                                       \cudaError_t status = call;                                            \if (status != cudaSuccess)                                            \{                                                                  \cout << "行号:" << __LINE__ << endl;                         \cout << "错误:" << cudaGetErrorString(status) << endl;           \}                                                                  \
}//FFT反变换后,用于规范化的函数
__global__ void normalizing(cufftDoubleReal* data, int data_len)
{int idx = blockDim.x*blockIdx.x + threadIdx.x;if (idx<data_len){data[idx] /=(data_len);}
}int main()
{const int Nt =512;const int BATCH = 1;//BATCH用于批量处理一批一维数据,当BATCH=2时//则将0-511,512-1023作为两个一维信号做FFT处理变换cufftDoubleReal* host_in,  *device_in;cufftDoubleComplex* host_out, *device_out;//主机内存申请及初始化--主机锁页内存Check(cudaMallocHost((void**)&host_in, Nt * sizeof(cufftDoubleReal)));//特别要注意:这里的输出长度变为(Nt/2+1)Check(cudaMallocHost((void**)&host_out, (Nt / 2 + 1) * sizeof(cufftDoubleComplex)));for (int i = 0; i < Nt; i++){host_in[i] = i + 1;}//设备内存申请Check(cudaMalloc((void**)&device_in, Nt * sizeof(cufftDoubleReal)));//特别要注意:这里的输出长度变为(Nt/2+1)Check(cudaMalloc((void**)&device_out, (Nt / 2 + 1) * sizeof(cufftDoubleComplex)));//数据传输--H2DCheck(cudaMemcpy(device_in, host_in, Nt * sizeof(cufftDoubleReal), cudaMemcpyHostToDevice));//创建cufft句柄cufftHandle cufftForwrdHandle, cufftInverseHandle;cufftPlan1d(&cufftForwrdHandle, Nt, CUFFT_D2Z, BATCH);cufftPlan1d(&cufftInverseHandle, Nt, CUFFT_Z2D, BATCH);//执行fft正变换cufftExecD2Z(cufftForwrdHandle, device_in, device_out);//由于D2Z的方向是固定的,无需填入参数//数据传输--D2HCheck(cudaMemcpy(host_out, device_out, (Nt/2+1) * sizeof(cufftDoubleComplex), cudaMemcpyDeviceToHost));//设置输出精度--正变换结果输出cout << "正变换结果:" << endl;cout.setf(20);for (int i = 0; i < (Nt / 2 + 1); i++){cout << host_out[i].x << "+j*" << host_out[i].y << endl;}//执行fft反变换cufftExecZ2D(cufftInverseHandle, device_out, device_in);//由于Z2D的方向是固定的,无需填入参数//IFFT结果是真值的N倍,因此要做/N处理dim3 grid(ceil((Nt / 2 + 1) / 128.0) + 1);dim3 block(128);normalizing << <grid, block >> > (device_in, Nt);//数据传输--D2HCheck(cudaMemcpy(host_in, device_in, Nt * sizeof(cufftDoubleReal), cudaMemcpyDeviceToHost));//设置输出精度--反变换结果输出cout << "反变换结果:" << endl;cout.setf(20);for (int i = 0; i < Nt; i++){cout << host_in[i] << endl;}cin.get();return 0;
}

CUFFT库(cufft_C2C,cufft_R2C,cufft_C2R,cufft_Z2C,cufft_D2Z,cufft_Z2D)相关推荐

  1. CUDA快速傅里叶变换 cuFFT

    分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow 也欢迎大家转载本篇文章.分享知识,造福人民,实现我们中华民族伟大复兴! CUDA ...

  2. C语言使用CUDA中cufft函数做GPU加速FFT运算,与调用fftw函数的FFT做运算速度对比

    目录 任务介绍 环境所需相关软件下载与安装 C语言:不调用库的GPU加速FFT代码 C语言:调用fftw库的未使用GPU的FFT代码 C语言:调用cufft库的GPU加速FFT gnuplot安装画图 ...

  3. 2能不用cuda_cuda学习-1-cufft的使用

    一.函数的定义与执行 一般的函数定义 void function(); cuda的函数定义 __global__ void function(); global前缀表明这个函数在哪里执行,由谁呼叫 g ...

  4. NVIDIA GPU的快速傅立叶变换

    NVIDIA GPU的快速傅立叶变换 cuFFT库提供GPU加速的FFT实现,其执行速度比仅CPU的替代方案快10倍.cuFFT用于构建跨学科的商业和研究应用程序,例如深度学习,计算机视觉,计算物理, ...

  5. CUDA Samples目录

    简介 Simple Reference  基础CUDA示例,适用于初学者, 反映了运用CUDA和CUDA runtime APIs的一些基本概念. Utilities Reference  演示如何查 ...

  6. 最牛逼的开源机器学习框架,你知道几个

    最牛逼的开源机器学习框架,你知道几个 作者 大白鲸团队 关注 2015.12.29 20:16 字数 1829 阅读 3689评论 0喜欢 7 机器学习毫无疑问是当今最热的话题,它已经渗透到生活的方方 ...

  7. 避免关注底层硬件,Nvidia将机器学习与GPU绑定

    Nvidia释放的一组cuDNN的库,有效的实现了其与多种深度学习框架的整合.基于cuDNN,加速了代码的运行,同时让研究员避免去关心底层硬件性能. 关键字: 编程语言语音识别Nvidia 原文链接: ...

  8. python gpu编程_Python笔记_第四篇_高阶编程_进程、线程、协程_5.GPU加速

    Numba:高性能计算的高生产率 在这篇文章中,笔者将向你介绍一个来自Anaconda的Python编译器Numba,它可以在CUDA-capable GPU或多核cpu上编译Python代码.Pyt ...

  9. 28款GitHub最流行的开源机器学习项目,推荐GitHub上10 个开源深度学习框架

    20 个顶尖的 Python 机器学习开源项目 机器学习 2015-06-08 22:44:30 发布 您的评价: 0.0 收藏 1收藏 我们在Github上的贡献者和提交者之中检查了用Python语 ...

最新文章

  1. [C++] Lvalue and Rvalue Reference
  2. Azure SQL 数据库最新版本现已提供预览版
  3. SQL Server 排序规则(摘)
  4. 八边形点坐标数的lisp_图形学入门第五课:齐次坐标
  5. java icon动态变换,以编程方式自动更改ImageIcon [Java]
  6. 剑指Offer面试题:30.第一个只出现一次的字符
  7. RTT线程管理篇——RTT时间片
  8. Oracle数据库基础1-数据类型与约束
  9. OAuth2.0学习(1-11)新浪开放平台微博认证-使用OAuth2.0调用微博的开放API
  10. ACR122U-A9|ACR1251|ACM1252系列NFC读写器读卡器PCSC Tool测试工具使用步骤说明
  11. 谈谈我选择VC界面皮肤库的标准
  12. smobiler中实现页面切换_使用Smobiler实现类似美团的界面
  13. ios10 申请拍照权限_iOS 10 获取相册相机权限
  14. 安卓日历每日提醒_好用的安卓日历Jorte:可添加待办事项和提醒
  15. Python 利用多线程进行爬虫(一)
  16. Windows系统远程连接Linux系统操作
  17. 4.3 协方差及相关系数、矩
  18. HASH和HMAC(3):SHA-1算法原理
  19. cin.tie(0)和ios::sync_with_stdio(false)
  20. 医药保健行业crm系统有何特色

热门文章

  1. win10 第一次开机卡死强制关闭第二次开机才正常
  2. 电气自动化学c语言有什么作用,电气工程及其自动化专业C语言课程教学改革-2019年教育文档...
  3. 量化投资学习——全球交易所交易时间
  4. 新闻报道数量如何掌握?
  5. 使用正则表达式获取字符串中的数字
  6. 关于电脑显示器屏幕看不出灰色,灰色和白色几乎一样无法区分,色彩调整方法
  7. redis我记不住的那些命令(九)
  8. 定时器工作方式0初值除32_51单片机C语言程序100例分析(2)定时器+中断
  9. 《网络安全0-100》-网络攻击方式
  10. UML 太极建模口诀(建模助手)