最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網 會員登陸 & 注冊

使用CUDA計算傅里葉變換

2023-02-17 13:22 作者:焚香落燼  | 我要投稿

使用cuda中自帶的cufft庫計算fft

再cuda設備中無法計算cucomplex與double、float的乘法,無法計算cufftcomplex與double、float的乘法,所以在實際計算中先試用double之間的乘法計算。然后再將結果使用cufftcomplex的構造函數來構造復數變量進行計算。

我目前沒找到cuda中復數與double的直接乘法計算,如果有大佬看到可以教我一下

代碼原文:

#include "cuda_runtime.h"

#include "device_launch_parameters.h"

#include "cufft.h"

#include <string>

#include <stdlib.h>

#include <ctime>

#include <Windows.h>

#include <mmSystem.h>

using namespace std;

#include<iostream>

#include <math.h>



//這是一個用于檢查cuda函數是否正常運行的函數,直接復制粘貼就好

#define CHECK(call)\

{\

if ((call) != cudaSuccess)\

{\

printf("Error: %s:%d, ", __FILE__, __LINE__);\

printf("code:%d, reason: %s\n", (call), cudaGetErrorString(cudaGetLastError()));\

exit(1);\

}\

}



__global__ void com(cufftComplex* in, cufftComplex* out, int m) //cuda計算

{

int ii = threadIdx.x;

//int jj = threadIdx.y;

double a1 = 2.0;

double a2 = 3.0;

double a3 = a1 * a2;

cufftComplex aa = { a3, a3 };

cufftComplex bb = { 1, 2 };

out[ii] = cuCmulf(aa, bb);

}


const double PI = 3.141592653;


int main() {


const int NX = 16; //進行傅里葉變換的數據長度

const int fs = 4000000; //頻率

double T = 2e-6; //周期


const int BATCH = 1;

int bei = fs / NX;

double timebei = T / NX;

double aaa = 1.0 / NX;

double Lk = 1 / T;

cufftHandle plan;? //創(chuàng)建句柄

cufftComplex* data;

cufftComplex* data_cpu;


double t[NX]; //時間單位


data_cpu = (cufftComplex*)malloc(sizeof(cufftComplex) * NX);

if (data_cpu == NULL) return -1;


CHECK(cudaMalloc((void**)&data, sizeof(cufftComplex) * NX));


CHECK(cufftPlan1d(&plan, NX, CUFFT_C2C, 1)); //對句柄進行配置,主要是配置句柄對應的信號長度,信號類型,在內存中的存儲形式等信息。

//第一個參數就是要配置的 cuFFT 句柄;

//第二個參數為要進行 fft 的信號的長度;

//第三個CUFFT_C2C為要執(zhí)行 fft 的信號輸入類型及輸出類型都為復數;

//第四個參數BATCH表示要執(zhí)行 fft 的信號的個數,新版的已經使用cufftPlanMany()來同時完成多個信號的 fft


//輸入數據

//for (int i = 0; i < NX; ++i) //給一個三角函數時間信號,用于傅里葉變換

//{

// t[i] = i * timebei;

// //printf("%.15lf\n", t[i]);

// data_cpu[i].x = cos(PI * 8 * 0.25 * fs / (3 * T * T) * pow(t[i] - T / 2.0, 3) + 2 * PI * 0.25 * fs * t[i]);

// data_cpu[i].y = sin(PI * 8 * 0.25 * fs / (3 * T * T) * pow(t[i] - T / 2.0, 3) + 2 * PI * 0.25 * fs * t[i]);

//}


for (int i = 0; i < NX; ++i) //給一個好設定的時域信號,用于檢驗傅里葉變換

{

data_cpu[i].x =(float) i;

data_cpu[i].y = 0;

printf("(%.15lf,%.15lf)\n", data_cpu[i].x, data_cpu[i].y);

}



//for (int i = 0; i < NX; ++i) //輸出時間信號的時間序列和模值

//{

// //printf("%f? %f\n", data_cpu[i].x, data_cpu[i].y);

// double mo = sqrt(data_cpu[i].x * data_cpu[i].x + data_cpu[i].y * data_cpu[i].y);

// double time = i*timebei;

// printf("%.15f? %.20f\n", time, mo);

//}


//數據傳輸cpu->gpu

CHECK(cudaMemcpy(data, data_cpu, sizeof(cufftComplex) * NX * BATCH, cudaMemcpyHostToDevice));

CHECK(cudaDeviceSynchronize());


clock_t ct1, ct2,ct3,ct4; //添加計時

ct1 = clock();


CHECK(cufftExecC2C(plan, data, data, CUFFT_FORWARD));

//CHECK(cufftExecC2C(plan, data, data, CUFFT_INVERSE) != CUFFT_SUCCESS);

//第一個參數就是配置好的 cuFFT 句柄;

//第二個參數為輸入信號的首地址;

//第三個參數為輸出信號的首地址;

//第四個參數CUFFT_FORWARD表示執(zhí)行的是 fft 正變換;CUFFT_INVERSE表示執(zhí)行 fft 逆變換。

//!!!需要注意的是,執(zhí)行完逆 fft 之后,要對信號中的每個值乘以 1/N

CHECK(cudaDeviceSynchronize());

ct2 = clock();

CHECK(cudaMemcpy(data_cpu, data, sizeof(cufftComplex) * NX, cudaMemcpyDeviceToHost));

CHECK(cudaDeviceSynchronize());

//for (int i = 0; i < NX; ++i) //這個不是輸出傅里葉變換,這個是輸出頻域信號的

//{

// //printf("%f? %f\n", data_cpu[i].x, data_cpu[i].y);

// double mo = sqrt(data_cpu[i].x * data_cpu[i].x + data_cpu[i].y * data_cpu[i].y);

// //double Fre = i*F;

// printf("%d? %.15f\n", i * bei, mo * aaa);

//}


for (int i = 0; i < NX; ++i) //這個輸出的是傅里葉變換的實部和虛部

{

printf("(%.15lf,%.15lf)\n", data_cpu[i].x, data_cpu[i].y);

}

ct3 = clock();

com << <1, 16 >> > (data, data, NX); //測試計算的函數

CHECK(cudaDeviceSynchronize());

ct4 = clock();

//數據傳輸gpu->cpu

CHECK(cudaMemcpy(data_cpu, data, sizeof(cufftComplex) * NX, cudaMemcpyDeviceToHost));

CHECK(cudaDeviceSynchronize());


printf("\n");

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

{

printf("(%.15lf,%.15lf)\n", data_cpu[i].x,data_cpu[i].y);

}


double cputime = ((double)(ct2 - ct1)) / CLOCKS_PER_SEC;

double cputime2 = ((double)(ct4 - ct3)) / CLOCKS_PER_SEC;

cout << "ct1=" << ct1 << endl;

cout << "ct2=" << ct2 << endl;

cout << "ct3=" << ct3 << endl;

cout << "ct4=" << ct4 << endl;

cout << "傅里葉變換時間=" << cputime << endl;

cout << "計算操作的時間=" << cputime2 << endl;

//printf("變換用時: %dms\n", End - Start);


cufftDestroy(plan);? //釋放 GPU 資源

cudaFree(data);


//printf("CUFFT_FORWARD:\n");


system("pause");

return 0;


}

頭文件和函數
main函數part1
main函數part2
main函數part3
main函數part4
運行結果示例

運行結果,16個一個單位,前面一部分忘記分開了

代碼參考來源

https://blog.csdn.net/lqbird/article/details/127054520?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522167591186216800217024470%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=167591186216800217024470&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduend~default-1-127054520-null-null.142^v73^insert_down4,201^v4^add_ask,239^v1^insert_chatgpt&utm_term=CUFFT&spm=1018.2226.3001.4187

使用CUDA計算傅里葉變換的評論 (共 條)

分享到微博請遵守國家法律
襄樊市| 英德市| 高州市| 哈密市| 浏阳市| 韩城市| 乐亭县| 涟源市| 通辽市| 泰安市| 广东省| 遵化市| 荆州市| 遂溪县| 伽师县| 历史| 通州区| 赫章县| 华池县| 荃湾区| 泊头市| 尚志市| 丽江市| 璧山县| 珠海市| 舒城县| 南汇区| 南皮县| 乌恰县| 阿合奇县| 且末县| 普格县| 夏津县| 新昌县| 门源| 蒲城县| 老河口市| 渝中区| 萍乡市| 滁州市| 肃南|