CUDA C编程(二十六)cuFFT库

  cuFFT库提供了一个优化的且基于CUDA实现的快速傅里叶变换(FFT)。FFT在信号处理中可以将信号从时域转换到频域,逆FFT过程则相反。换句话说,一个FFT以规则的时间间隔接受信号中的序列样本并作为输入。然后使用这些样本生成一组叠加的分量频率,按频率抽取作为输入样本的信号。如下图所示,两个信号叠加生成信号cos(x)+cos(2x),并通过FFT将两个信号的分量转为频率1.0和2.0。至于FFT其他的内容,这里不做介绍。
在这里插入图片描述

使 用 cuFFT API
  cuFFT通常指两个独立的库:核心高性能的cuFFT库和可移植的cuFFTW库。cuFFT库是在CUDA中能提供自身API的FFT实现。另一方面,cuFFTW与标准的FFTW(快速傅里叶变换的标准C语言程序集)主机端FFT库有相同的API。和cuBLAS与传统的BLAS库共享大部分的API的情况类似,cuFFW则是用来最大限度地提高使用FFTW现有代码的可移植性。FFTW库的很多函数在cuFFTW中同样适用。此外,cuFFTW库假设所有要传输的输入数据都存储在主机内存中,并为用户处理所有的内存分布(cudaMalloc)和内存拷贝(cudaMemcpy)。虽然这可能对性能有所影响,但它大大加快了程序移植的过程。至于cuFFTW和cuFFT支持的操作,请参阅cuFFT用户指南。
  cuFFT库的配置是用FFT plan完成的。即cuFFT是用来指代它的操作术语。一个plan定义了一个要进行的单一变换操作。cuFFT使用plan来获取内存分配、内存转移以及内存启动来执行变换请求。不同的plan创建函数可以用来生成增大复杂性和维数的plan:

cufftResult cufftPlan1d(cufftHandle *plan,int nx,cufftType type,int batch);
cufftResult cufftPlan2d(cufftHandle *plan,int nx,int ny,cufftType type);
cufftResult cufftPlan3d(cufftHandle *plan,int nx,int ny,int nz,cufftType type);

  cuFFT还支持多种输入和输出数据类型,包括以下几种:复数到复数、实数到复数、复数到实数。当然,对于许多实际的应用程序,最实用的是实数到复数这种类型,它允许我们从实际系统输入实际的测量结果到cuFFT中。
  一旦配置好一个cuFFT plan,使用cufftExec* 函数来对它进行调用执行(例如,cufftExecC2C)。一般来说,无论该变换是一种正向FFT(时域到频域)还是怒向FFT(频域到时域),函数调用都可以将plan、输入数据的存储位置、输出数据的存放位置作为输入。
cuFFT 功 能 示 范
  一个cuFFT应用程序的工作流的不同取决于变换的复杂性。一个cuFFT应用程序的工作流一般应包括:
  1.创建并配置一个cuFFT plan;
  2.用cudamalloc函数分配设备内存来存储输入样本和输出频率。注意,所分配的内存必须支持对应执行的变换类型(例如,复数到复数、实数到复数、复数到实数)我们可以使用相同的设备内存对输入和输出直接进行变换;
  3.用cudaMemcpy用输入样本传送设备内存;
  使用cudaExec* 函数执行plan;
  用cudaMemcpy取回设备内存中的结果;
  用cudaFree和cufftDestroy释放CUDA和cuFFT资源;
  接下来的示例代码从函数cos(x)中生成一个输入样本序列,将其转换为复数后传给GPU,在将结果拷贝回主机端之前执行复数到复数的一维plan。值得注意的是,对于输入和输出参数,因为可以将相同的内存位置dComplexSamples传给cufftExecC2C,所以这是一个就地FFT运算。可以预先分配一个独立的输出缓存区,并用来存储输出结果。

// Setup the cuFFT plan
    cufftPlan1d(&plan, N, CUFFT_C2C, 1);

    // Allocate device memory
    cudaMalloc((void **)&dComplexSamples,
            sizeof(cufftComplex) * N);

    // Transfer inputs into device memory
    cudaMemcpy(dComplexSamples, complexSamples,
            sizeof(cufftComplex) * N, cudaMemcpyHostToDevice);

    // Execute a complex-to-complex 1D FFT
    cufftExecC2C(plan, dComplexSamples, dComplexSamples,
                             CUFFT_FORWARD);

    // Retrieve the results into host memory
    cudaMemcpy(complexFreq, dComplexSamples,
            sizeof(cufftComplex) * N, cudaMemcpyDeviceToHost);
This document describes CUFFT, the NVIDIA® CUDA™ Fast Fourier Transform (FFT) library. The FFT is a divide-and-conquer algorithm for efficiently computing discrete Fourier transforms of complex or real-valued data sets. It is one of the most important and widely used numerical algorithms in computational physics and general signal processing. The CUFFT library provides a simple interface for computing parallel FFTs on an NVIDIA GPU, which allows users to leverage the floating-point power and parallelism of the GPU without having to develop a custom, CUDA FFT implementation. FFT libraries typically vary in terms of supported transform sizes and data types. For example, some libraries only implement radix-2 FFTs, restricting the transform size to a power of two. The CUFFT Library aims to support a wide range of FFT options efficiently on NVIDIA GPUs. This version of the CUFFT library supports the following features: I Complex and real-valued input and output I 1D, 2D, and 3D transforms I Batch execution for doing multiple transforms of any dimension in parallel I Transform sizes up to 64 million elements in single precision and up to 128 million elements in double precision in any dimension, limited by the available GPU memory I In-place and out-of-place transforms I Double-precision (64-bit floating point) on compatible hardware (sm1.3 and later) I Support for streamed execution, enabling asynchronous computation and data movement I FFTW compatible data layouts I Arbitrary intra- and inter-dimension element strides I Thread-safe API that can be called from multiple independent host threads
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值