cuFFT 簡單使用

2021-08-21 09:17:36 字數 3328 閱讀 4407

1. 流程

使用cufftplan1d(),cufftplan3d(),cufftplan3d(),cufftplanmany()對控制代碼進行配置,主要是配置控制代碼對應的訊號長度,訊號型別,在記憶體中的儲存形式等資訊。

使用cufftexec()函式執行 fft

使用cufftdestroy()函式釋放 gpu 資源

2. 單個 1 維訊號的 fft

// 初始資料

for (int i = 0; i < nx; i++)

cufftplan1d(&plan, n, cufft_c2c, batch);

cufftexecc2c(plan, data_dev, data_dev, cufft_forward); // 執行 cufft,正變換

第二個引數為要進行 fft 的訊號的長度;

第三個cufft_c2c為要執行 fft 的訊號輸入型別及輸出型別都為複數;cufft_c2r表示輸入複數,輸出實數;cufft_r2c表示輸入實數,輸出複數;cufft_r2r表示輸入實數,輸出實數;

第四個引數batch表示要執行 fft 的訊號的個數,新版的已經使用cufftplanmany()來同時完成多個訊號的 fft。

第二個引數為輸入訊號的首位址;

第三個引數為輸出訊號的首位址;

第四個引數cufft_forward表示執行的是 fft 正變換;cufft_inverse表示執行 fft 逆變換。

3. 多個 1 維訊號的 fft

int *inembed, int istride, int idist,

int *onembed, int ostride, int odist,

cuffttype type, int batch);

rank:表示進行 fft 的每個訊號的維度數,一維訊號為 1,二維訊號為2,三維訊號為 3 ,針對上圖,rank = 1

n:表示進行 fft 的每個訊號的行數,列數,頁數,必須用陣列形式表示,例如假設要進行 fft 的每個訊號的行、列、頁為(m, n, k),則 int n[rank] = ;針對上圖,int n[1] =

inembed:表示輸入資料的[頁數,列數,行數],這是三維訊號的情況;二維訊號則為[列數,行數];一維訊號為[行數];inembed[0] 這個引數會被忽略,也就是此處 inembed 可以為,,等等。

istride:表示每個輸入訊號相鄰兩個元素的距離,在此處 istride = 16(每個訊號相鄰兩個元素間的距離為16)

idist:表示兩個連續輸入訊號的起始元素之間的間隔,在此處為 idist = 1(第乙個訊號的第乙個元素與第二個訊號的第乙個元素的間隔為1);如果把上圖資料的每一行看成乙個訊號,那麼應該為 idist = 16;

onembed:表示輸出資料的[頁數,列數,行數],這是三維訊號的情況;二維訊號則為[列數,行數];一維訊號為[行數];onembed[0] 這個引數會被忽略,也就是此處 onembed 可以為,,等等。

ostride:表示每個輸出訊號相鄰兩個元素的距離,在此處 ostride = 16(每個訊號相鄰兩個元素間的距離為16)

odist:表示兩個連續訊號的起始元素之間的間隔,在此處為 odist = 1(第乙個訊號的第乙個元素與第二個訊號的第乙個元素的間隔為1);如果把上圖資料的每一行看成乙個訊號,那麼應該為 odist = 16;

input[ b * idist + x * istride ]output[ b * odist + x * ostride ]

‣ 2d

input[ b * idist + (x * inembed[1] + y) * istride ]output[ b * odist + (x * onembed[1] + y) * ostride ]

‣ 3d

input[b * idist + (x * inembed[1] * inembed[2] + y * inembed[2] + z) * istride]output[b * odist + (x * onembed[1] * onembed[2] + y * onembed[2] + z) * ostride]

cuffthandle plan_nfft_many; // 建立cufft控制代碼

const

int rank = 1; // 一維 fft

int n[rank] = ; // 進行 fft 的訊號的長度為 nfft

int inembed[1] = ; // 輸入資料的[頁數,列數,行數](3維);[列數,行數](2維)

int onembed[1] = ; // 輸出資料的[頁數,列數,行數];[列數,行數](2維)

int istride = nxwith0; // 每個輸入訊號相鄰兩個元素的距離

int idist = 1; // 每兩個輸入訊號第乙個元素的距離

int ostride = nxwith0; // 每個輸出訊號相鄰兩個元素的距離

int odist = 1; // 每兩個輸出訊號第乙個元素的距離

int batch = nx; // 進行 fft 的訊號個數

cufftplanmany(&plan_nfft_many, rank, n, inembed, istride, idist, onembed, ostride, odist, cufft_c2c, batch);

/* 核心部份 */

cudamemcpy(data_dev, data_host, nfft * nxwith0 * sizeof(cufftcomplex), cudamemcpyhosttodevice);

cufftexecc2c(plan_nfft_many, data_dev, data_dev, cufft_forward); // 執行 cufft,正變換

cufftexecc2c(plan_nfft_many, data_dev, data_dev, cufft_inverse); // 執行 cufft,逆變換

cufftcomplexscale<<>>(data_dev, data_dev, 1.0f / nfft); // 乘以係數

cudamemcpy(resultifft, data_dev, nfft * nxwith0 * sizeof(cufftcomplex), cudamemcpydevicetohost);

CUDA快速傅利葉變換 cuFFT

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

CUDA快速傅利葉變換 cuFFT

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

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

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