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,理解有誤之處在所難免,閱讀本篇文章的讀者如若發現請不吝指正...