CUDA快速傅利葉變換(cuFFT)閱讀筆記(一)

2021-07-04 01:25:13 字數 3369 閱讀 8562

cuda為開發人員提供了多種庫,每一類庫針對某一特定領域的應用,cufft庫則是cuda中專門用於進行傅利葉變換的函式庫,這一系列的文章是博主近一段時間對cufft庫的學習總結,主要內容是文件的譯文,其間夾雜一些博主自己的理解。初學cuda,理解有誤之處在所難免,閱讀本篇文章的讀者如若發現請不吝指正。

cufft是的全稱是cuda fast fourier transform,顧名思義,它提供了一系列的函式幫助開發者進行快速傅利葉變換的運算。cufft庫由兩個子庫構成,它們分別是cufft和cufftw。cufftw庫是乙個移植工具(porting tool),它為使用者提供了一些介面,以使得使用者使用fftw庫(乙個非常流行的cpu快速傅利葉變換庫)編寫的程式能夠執行在cuda gpu上。而cufft則是純cuda介面的快速傅利葉變換庫。

在cuda toolkit 5.5版本中,cufft庫支援的特性有:

1、對於可以表示為

2、對於所有的輸入規模,cufft的演算法複雜性均為o(nlogn)

3、不同輸入輸出型別的指定:其中c2c代表輸入輸出均為複數,r2c代表輸入為實數而輸出為複數,c2r代表輸入為複數而輸出為實數。

4、可以進行1維、2維和3維變換

5、多個不同的1d、2d、3d變換可以並行進行

6、同時支援單精度浮點和雙精度浮點運算

7、支援就地轉換(輸出直接覆蓋輸入)和外部轉換(輸出和輸入不重疊)

8、與fftw庫相容的資料布局

9、支援跨步輸入資料讀取

10、支援流執行(streamed execution),這樣就同時支援了計算與資料傳輸的非同步並行執行。

11、對於單精度浮點數,一次最多傳輸128百萬元素,雙精度則一次最多傳輸64百萬元素。

12、cufft庫提供的api是執行緒安全的。

在關注具體的api之前,我們先來回顧一下快速傅利葉變換的背景知識。

快速傅利葉變換(fft)是離散傅利葉變換(dft)的快速演算法,在數字訊號處理、大整數乘法和求解偏微分方程等領域都有著廣泛的應用,dft的作用是將時域(time domain)上的一組離散複數與到頻域(frequency domain)上的一組值相互對映,以對輸入資料進行進一步處理。離散傅利葉公式可以表示為:

其中,x

k 是與輸入資料xk

大小相同的陣列,這一公式也被稱作正向(forward)dft。把上式中e的指數符號修改為正(positive),我們就得到了逆向(inverse)dft。cufft api根據n的不同,將使用不同的優化演算法,以達到最佳的效能。

cufft api的原型是fftw庫,fftw則是乙個基於cpu的高效fft庫。cufft提供了乙個簡單的被稱為plan的配置方法,使用plan的好處是可以根據輸入資料的大小預先配置好記憶體和計算資源,使得真正運算時處理器能達到最佳的效能。設定好plan後,執行execution函式,真正的傅利葉變換便開始執行了。一旦配置完成,配置資訊便被儲存起來,這對於多次呼叫來說非常省時。

下面來看乙個**片段,計算batch塊大小為nx的一維dft的cuda**通常如下所示:

[cpp]view plain

copy

#define nx 256

#define batch 10

...   

cufft和cufftw均被實現為共享庫,可以使用編譯器和鏈結器把它們整合到普通的程式當中。這些庫檔案和標頭檔案在不同系統上的預設位置如下圖所示:

最常見的使用這些庫函式的方法是修改乙個已經存在的cuda檔案,以filename.cu為例,在filename.cu中將標頭檔案cufft.h包含進來,然後在程式中呼叫cufft庫函式,為了使得程式可以執行,乙個單一檔案的編譯和鏈結命令的形式可以如下:

在cuda上進行傅利葉變換一般需要做以下幾步工作:

1. 建立乙個plan。呼叫函式cufftplan1d/cufftplan2d/cufftplan3d可以分別建立乙個簡單的1維/2維/3維的傅利葉變換。呼叫函式cufftplanmany則可以建立支援更多配置操作的變換計畫。

2. 執行plan。這一步可以使用cufftexecc2c()、cufftexecr2c()或cufftexecc2r()等函式完成plan的計算任務。

3. 執行完成以後若不再需要該plan,則呼叫cufftdestroy()函式銷毀該plan及為其分配的計算資源。

cufft庫實現了三種不同型別的傅利葉變換:c2c(複數到複數)、c2r(複數到實數)、r2c(實數到複數)。本質上,這三種轉換都可以被看做是複數域到複數域的變換,之所以這樣劃分,其最主要的考量是效能因素。例如,在一般的數字訊號處理中,輸入資料是一些離散的實數域上的取樣點,這時候對它們做傅利葉變換實際上就是r2c,根據埃爾公尺特對稱性(hermitian symmetry),變換後

變換執行函式的單精度和雙精度版本分別定義如下:

1. cufftexecc2c() / cufftexecz2z() - 單精度/雙精度浮點數複數域到複數域的傅利葉變換

2. cufftexecr2c() / cufftexecd2z() - 單精度/雙精度浮點數實數域到複數域的傅利葉變換(正向傅利葉變換)

3. cufftexecc2r() / cufftexecz2d() - 單精度/雙精度浮點數複數域到實數域的傅利葉變換(逆向傅利葉變換)

cufft庫包含有若干種資料型別,對於複數有cufftcomplex / cufftdoublecomplex兩種資料型別,對於實數則分別有cufftreal / cufftdouble兩種資料型別。

根據轉換結果的儲存位置不同,fft變換可分為就地變換(in-place)和外部變換(out-of-place),前者直接在輸入資料上進行變換,而後者則會將變換後的結果存入新的儲存器位址。

就地轉換(in-place)支援兩種資料布局:native和padded,前者用於獲得最佳效能,而後者則用於與fftw庫相容。

在padded布局中輸出訊號的開始位址與輸入訊號一樣,換句話說,實數域到複數域變換的輸入資料和複數域到實數域的輸出資料必須被填充。在native布局中則沒有填充要求。

輸入資料和輸出資料的尺寸總結如下:

cufft的每乙個plan都可以和某個流(stream)結合起來執行,一旦結合,那麼該plan就會在特定的流上面執行。cufft執行的流化使得快速傅利葉變換可以和其它流中的資料拷貝任務並行執行,從而提高了裝置利用率和程式效能。

cufft庫從版本4.1開始擁有執行緒安全特性,也就是說,主機端的多個執行緒同時呼叫cufft中的函式時,cuda可以保證任務執行的正確性。

CUDA快速傅利葉變換 cuFFT

cuda為開發人員提供了多種庫,每一類庫針對某一特定領域的應用,cufft庫則是cuda中專門用於進行傅利葉變換的函式庫,這一系列的文章是博主近一段時間對cufft庫的學習總結,主要內容是文件的譯文,其間夾雜一些博主自己的理解。初學cuda,理解有誤之處在所難免,閱讀本篇文章的讀者如若發現請不吝指正...

CUDA快速傅利葉變換 cuFFT

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!cuda為開發人員提供了多種庫,每一類庫針對某一特定領域的應用,cufft庫則是cuda中專門用於進行傅利葉變換的函式庫,這一系列的文章是博主近一段時間對cufft庫的學習總結,主要內容是文件的譯文,其間夾雜一些博主自己的理解。初學cuda,理解有...

傅利葉變換與快速傅利葉變換

作為電子資訊專業的學生老說,這個不知道,或者理解不清楚,是十分不應該的,作為乙個學渣,有時候確實是理解不清楚的 1 首先離散傅利葉變換目的 簡單點說 就是將乙個訊號從時域變換到頻域 標準點說 將以時間為自變數的訊號 與 頻率為自變數的頻譜函式之間的某種關係變換 數學描述 對於 n點序列 其中自然對數...