2016-01-04 56 views
1

我正在編寫代碼,最近我發現了一些錯誤。簡化版本如下所示。在cuda中,線程索引沒有完全顯示在內核函數中

#include <stdio.h> 
#include <cuda.h> 
#define DEBUG 1 

inline void check_cuda_errors(const char *filename, const int line_number) 
{ 
    #ifdef DEBUG 
    cudaThreadSynchronize(); 
    cudaError_t error = cudaGetLastError(); 
    if(error != cudaSuccess) 
    { 
     printf("CUDA error at %s:%i: %s\n", filename, line_number, cudaGetErrorString(error)); 
     exit(-1); 
    } 
#endif 
} 


__global__ void make_input_matrix_zp() 
{ 
    unsigned int row = blockIdx.y*blockDim.y + threadIdx.y; 
    unsigned int col = blockIdx.x*blockDim.x + threadIdx.x; 
    printf("col: %d (%d*%d+%d) row: %d (%d*%d+%d) \n", col, blockIdx.x, blockDim.x, threadIdx.x, row, blockIdx.y, blockDim.y, threadIdx.y); 
} 



int main() 
{ 
    dim3 blockDim(16, 16, 1); 
    dim3 gridDim(6, 6, 1); 
    make_input_matrix_zp<<<gridDim, blockDim>>>(); 
    //check_cuda_errors(__FILE__, __LINE__); 
    return 0; 
} 

第一個內聯函數用於檢查cuda中的錯誤。 第二個內核函數只是簡單地計算當前線程的'行'和'col'寫入的索引並打印這些值。我想在內聯函數中沒有問題,因爲它來自其他可靠的源。

問題是,當我運行程序時,即使它在主函數中被調用,它也不執行內核函數。但是,如果我在的

check_cuda_error 

前刪除註釋符號「//」方案似乎進入內核函數,它顯示了printf函數打印一些價值。但是,它不會顯示'col'和'row'索引的完整組合。詳細來說,'blockDim.y'的變化不大。它只顯示4和5的值,但不顯示0,1,2,3。

我首先不理解的。 據我所知,'gridDim'是指塊的尺寸。這意味着塊索引具有(0,0)(0,1)(0,2)(0,3)(0,4)(0,5)(1,0)(1,1)(1 ,2)(1,3)...等等。每個塊的大小也是16乘16。但是,如果你運行這個程序,它不會顯示完整的組合。我只是顯示了幾種組合,並結束。

我不明白其次。 爲什麼內核函數依賴於名爲'check_cuda_errors'的函數?當這個函數存在時,程序至少運行雖然不完善。但是,當此錯誤檢查函數被註釋時,內核函數不會顯示任何打印值。

這是非常簡單的代碼,但幾天後我找不到問題。有什麼我錯過了嗎?還是我知道錯了什麼?

我的工作環境是這樣的。 「的GeForce GT 630」 CUDA Driver版本/運行庫版本7.5/7.5 CUDA能力主要/次要版本號:2.1 Ubuntu的14.04

回答

2

的CUDA的GPU printf子系統依賴於一個FIFO緩衝器來存儲打印輸出。如果您的輸出超出緩衝區的大小,那麼先前FIFO緩衝區的部分或全部內容將被隨後的輸出覆蓋。這是在這種情況下將發生的事情。

您可以使用運行時API以cudaDeviceGetLimitcudaDeviceSetLimit查詢和更改緩衝區的大小。如果您的設備具有可用的資源來擴展限制,您應該能夠看到代碼發出的所有輸出。另外,依靠內核printf的特性,除了簡單的診斷或輕量級調試外,其實是一個糟糕的主意,你可能已經向自己證明了你應該查看其他驗證方法的正確性你的代碼。


關於第二個問題,僅當主機與設備同步printf緩衝器被刷新,以輸出。例如,撥打cudaDeviceSynchronize,cudaThreadSynchronize,cudaMemcpy和其他(請參閱格式化輸出附錄的B.17.2 Limitations)。

check_cuda_errors未被註釋時,調用cudaThreadSynchronize是什麼觸發緩衝區被打印。當它被註釋時,主線程在內核運行完成之前就會終止,而沒有其他事情發生。

+0

謝謝你的回答。我理解我的第一個問題可能與緩衝區問題有關,但是第二個問題也與這個緩衝區相關的問題有關? –