2013-04-07 109 views
1

我嘗試使用CUDA執行貝塞爾函數(例如J0(x))。 繼承人公式 enter image description hereCUDA上的貝塞爾函數在某個epsilon內

我試圖得到一些ε值內的結果。因此,這裏的代碼

__device__ void Bessel_j0(int totalBlocks, int totalThreads, float z, float epsilon, float* result){ 
      int n = 1; 
      *result = 0; 

      bool epsilonFlag = true; 

      int idx_start; 
      int idx_end; 

      while(epsilonFlag == true){ 
       initThreadBounds(&idx_start, &idx_end, n, totalBlocks, totalThreads); 
       float a_k; 
       for (int k = idx_start; k < idx_end; k++) { 
        a_k = m_power((-0.25 * z * z), k)/(m_factorial(k) * m_factorial(k)); 
        *result += a_k; 
       } 
       if(a_k < epsilon){ 
         epsilonFlag = false; 
       } 
       n++; 
      } 
     } 

__global__ void J0(int totalBlocks, int totalThreads, float x, float* result){ 
     float res = 0; 

     Bessel_j0(totalBlocks, totalThreads, 10, 0.01, &res); 
     result[(blockIdx.x*totalThreads + threadIdx.x)] = res; 
} 

__host__ void J0test(){ 

    const int blocksNum = 32; 
    const int threadNum = 32; 

    float *device_resultf; //для устройства 
    float host_resultf[threadNum*blocksNum] ={0}; 


    cudaMalloc((void**) &device_resultf, sizeof(float)*threadNum*blocksNum); 

    J0<<<blocksNum, threadNum>>>(blocksNum, threadNum, 10, device_resultf); 
    cudaThreadSynchronize(); 

    cudaMemcpy(host_resultf, device_resultf, sizeof(float)*threadNum*blocksNum, cudaMemcpyDeviceToHost); 

    float sum = 0; 

    for (int i = 0; i != blocksNum*threadNum; ++i) { 
     sum += host_resultf[i]; 
     printf ("result in %i cell = %f \n", i, host_resultf[i]); 
    } 
    printf ("Bessel res = %f \n", sum); 
    cudaFree(device_resultf); 
} 
int main(int argc, char* argv[]) 
{ 
    J0test(); 
} 

當我運行出現黑屏和Windows說,nVidia驅動沒有迴應,並恢復它。在控制檯輸出中,host_resultf數組中只有零。怎麼了?我怎樣才能執行正確的功能,以在一些eps內?

+1

您的程序執行時間過長,而您正在點擊Windows TDR事件。這會卸載停止程序執行的GPU驅動程序。你應該看看你的程序是否有邏輯錯誤導致它花費很長時間,否則看看你是否可以縮短內核執行。您也可以嘗試在CUDA GPU不是在Windows下運行顯示器的WDDM GPU的機器上運行它。在您點擊Windows TDR事件之前,在WDDM GPU上運行的內核被限制在大約2秒的執行時間內。 – 2013-04-07 14:56:11

+3

請注意,CUDA庫已經提供了第一類貝塞爾j0,j1,jn,以及第二類貝塞爾函數y0,y1,yn。 – njuffa 2013-04-07 17:42:03

+0

@njuffa是的我知道了,但我有我自己做的任務-_- – DanilGholtsman 2013-04-07 18:04:42

回答

1

這是不太可能的,但可能是你的內核執行達到了允許的內核執行時間限制。您的代碼不會顯示迭代次數的上限。可能會發生這樣的情況:永遠不會達到epsilon,並且內核會在超出時間限制的範圍內繼續執行。這site可以幫助。

在所有情況下,我會爲epsilon循環添加一個上限,永遠不要讓代碼在迭代次數沒有限制的情況下運行。

+0

哦哇,這比我想它會更復雜 – DanilGholtsman 2013-04-07 16:04:56