2013-05-27 44 views
0

我有以下代碼在執行反向FFT時存在錯誤。正向FFT在打印輸出並對其進行驗證時起作用。但似乎並非如此。有任何想法嗎?這看起來像是我錯過了一個概念嗎?CUDA反向FFT錯誤

碼 - http://pastebin.com/iZYtdcqR

編輯 - 我已經基本上重寫自帶的CUDA工具包樣品代碼。我試圖使用FFT執行卷積,但使用了修改後的算法(實際上是DIF)。

EDIT2 - 對問題的dding代碼。

#include <stdio.h> 
#include <stdlib.h> 
#include <math.h> 

#include <cuda_runtime.h> 
#include <cufft.h> 

typedef enum signaltype {REAL, COMPLEX} signal; 

typedef float2 Complex; 

void 
printData(Complex *a, int size, char *msg) { 

    if (msg == "") printf("\n"); 
    else printf("%s\n", msg); 

    for (int i = 0; i < size; i++) 
    printf("%f %f\n", a[i].x, a[i].y); 
} 

void 
normData(Complex *a, int size, float norm) { 

    for (int i = 0; i < size; i++) { 
    a[i].x /= norm; 
    a[i].y /= norm; 
    } 
} 

void 
randomFill(Complex *h_signal, int size, int flag) { 

    // Real signal. 
    if (flag == REAL) { 
    for (int i = 0; i < size; i++) { 
     h_signal[i].x = rand()/(float) RAND_MAX; 
     h_signal[i].y = 0; 
    } 
    } 
} 

// FFT a signal that's on the _DEVICE_. 
void 
signalFFT(Complex *d_signal, int signal_size) { 

    cufftHandle plan; 
    if (cufftPlan1d(&plan, signal_size, CUFFT_C2C, 1) != CUFFT_SUCCESS) { 
    printf("Failed to plan FFT\n"); 
    exit(0); 
    } 

    // Execute the plan. 
    if (cufftExecC2C(plan, (cufftComplex *) d_signal, (cufftComplex *) d_signal, CUFFT_FORWARD) != CUFFT_SUCCESS) { 
    printf ("Failed Executing FFT\n"); 
    exit(0); 
    } 

} 

void 
signalIFFT(Complex *d_signal, int signal_size) { 

    cufftHandle plan; 
    if (cufftPlan1d(&plan, signal_size, CUFFT_C2C, 1) != CUFFT_SUCCESS) { 
    printf("Failed to plan IFFT\n"); 
    exit(0); 
    } 

    // Execute the plan. 
    if (cufftExecC2C(plan, (cufftComplex *) d_signal, (cufftComplex *) d_signal, CUFFT_INVERSE) != CUFFT_SUCCESS) { 
    printf ("Failed Executing IFFT\n"); 
    exit(0); 
    } 

} 

int main() 
{ 

    Complex *h_signal, *d_signal1; 

    int alloc_size, i; 

    alloc_size = 16; 

    // Kernel Block and Grid Size. 
    const dim3 blockSize(16, 16, 1); 
    const dim3 gridSize(alloc_size/16 + 1, alloc_size/16 + 1, 1); 

    h_signal = (Complex *) malloc(sizeof(Complex) * alloc_size); 

    cudaMalloc(&d_signal1, sizeof(Complex) * alloc_size); 
    if (cudaGetLastError() != cudaSuccess){ 
    printf("Cuda error: Failed to allocate\n"); 
    exit(0); 
    } 
    //cudaMalloc(&d_signal2, sizeof(Complex) * alloc_size); 

    // Add random data to signal. 
    randomFill(h_signal, alloc_size, REAL); 
    printData(h_signal, alloc_size, "Random H1"); 

    cudaMemcpy(d_signal1, h_signal, sizeof(Complex) * alloc_size, cudaMemcpyHostToDevice); 

    signalFFT(d_signal1, alloc_size); 

    signalIFFT(d_signal1, alloc_size); 

    cudaDeviceSynchronize(); 

    cudaMemcpy(h_signal, d_signal1, sizeof(Complex) * alloc_size, cudaMemcpyDeviceToHost); 

    printData(h_signal, alloc_size, "IFFT"); 

    return 0; 
} 

回答

5

建議寫一個很好的問題:

  • 發佈您的代碼中的問題,而不是在一個外部鏈接。有一天,這個鏈接將變得無效,你的問題對未來的讀者也是如此。
  • 在問題中發佈您的實際數據(在這種情況下沒有那麼多)。
  • 發佈或標識您期望的數據以及原因。

另注:

  • 的CUFFT documentationn instructs you to use cufftComplex,而不是你自己的數據類型,雖然你的工作確定。如果由於某種奇怪的原因,cufft的開發者改變了他們的數據佈局,那麼你的代碼就會在重新編譯時崩潰。如果您使用推薦的數據類型,則不應該。

現在關於你的問題,我跑你的代碼,並得到的結果是這樣的:

Random H1 
0.840188 0.000000 
0.394383 0.000000 
0.783099 0.000000 
0.798440 0.000000 
0.911647 0.000000 
0.197551 0.000000 
0.335223 0.000000 
0.768230 0.000000 
0.277775 0.000000 
0.553970 0.000000 
0.477397 0.000000 
0.628871 0.000000 
0.364784 0.000000 
0.513401 0.000000 
0.952230 0.000000 
0.916195 0.000000 
IFFT 
13.443005 0.000000 
6.310127 -0.000000 
12.529589 0.000000 
12.775041 0.000000 
14.586359 -0.000000 
3.160823 0.000000 
5.363565 0.000000 
12.291674 -0.000000 
4.444397 -0.000000 
8.863521 0.000000 
7.638353 0.000000 
10.061934 -0.000000 
5.836554 0.000000 
8.214415 -0.000000 
15.235678 -0.000000 
14.659121 -0.000000 

,這似乎是在代碼中唯一缺少的是你沒有除以該結果轉換的長度(在這種情況下爲16)以獲取原始數據(如示例代碼here中所建議的那樣)。當我這樣做,我得到了我認爲是預期的結果:

Random H1 
0.840188 0.000000 
0.394383 0.000000 
0.783099 0.000000 
0.798440 0.000000 
0.911647 0.000000 
0.197551 0.000000 
0.335223 0.000000 
0.768230 0.000000 
0.277775 0.000000 
0.553970 0.000000 
0.477397 0.000000 
0.628871 0.000000 
0.364784 0.000000 
0.513401 0.000000 
0.952230 0.000000 
0.916195 0.000000 
IFFT 
0.840188 0.000000 
0.394383 -0.000000 
0.783099 0.000000 
0.798440 0.000000 
0.911647 -0.000000 
0.197551 0.000000 
0.335223 0.000000 
0.768230 -0.000000 
0.277775 -0.000000 
0.553970 0.000000 
0.477397 0.000000 
0.628871 -0.000000 
0.364785 0.000000 
0.513401 -0.000000 
0.952230 -0.000000 
0.916195 -0.000000 

順便說一句,爲了提供一個完整的,可編譯的代碼示例榮譽。

+0

謝謝你的發現。不是一個真正的數學人員,cuda文件讓我不知所措。將修復代碼鏈接和數據,以及你的真棒答案:D –

+0

似乎有什麼好笑的事情發生。我不斷收到這些瞬態運行時邏輯錯誤。很多時候,當我嘗試向信號添加填充數據並嘗試fft時,我得到了奇怪的答案,當我回來一段時間後再次運行該程序時,它運行並匹配了我的參考輸出。任何重置內存的提示或沿着這些線的東西? –

+0

除非你有一些片狀的設置(片狀硬件,軟件損壞),否則不需要重置內存或類似的東西。可能最好發表一個新問題將您的意見和問題。試圖在這樣的評論中深入研究是困難的。 –