2012-08-29 38 views
0

我最初的問題是,我有一長串參數的函數,超過了允許作爲參數傳遞給cuda內核的內存(我不不記得有多少字節,因爲我已經處理了一段時間)。所以,我繞過這個問題的方式是定義一個新的結構,它的成員是指向其他結構的指針,以後我可以從內核中取消引用。cuda gdb:內核指示不在代碼中

...這是當前問題開始的地方:在我嘗試從內核中取消引用指針(我之前創建的結構的成員)的地方,我得到CUDA_EXCEPTION_5, Warp Out-of-range Address ...從CUDA-GDB。最重要的是,在我的代碼中創建的內核名稱和參數(這是報告'不在此處生活',cuda-gdb給出的錯誤代碼不是這樣的:

現在,對於更多的細節:

這裏所涉及的結構:

typedef struct { 

    int strx; 
    int stry; 
    int strz; 
    float* el; 

} manmat; 

typedef struct { 

    manmat *x; 
    manmat *y; 
    manmat *z; 

} manmatvec; 

這裏就是我如何努力集團內核的參數主要內:

int main() { 

... 
... 

    manmat resu0; 
    resu0.strx = n+2;  resu0.stry = m+2;  resu0.strz = l+2; 
    if (cudaMalloc((void**)&resu0.el,sizeof(float) * (n+2)*(m+2)*(l+2)) != cudaSuccess) cout << endl << " ERROR allocating memory for manmat resu0" << endl ; 
    manmat resv0; 
    resv0.strx = n+2;  resv0.stry = m+2;  resv0.strz = l+2; 
    if (cudaMalloc((void**)&resv0.el,sizeof(float) * (n+2)*(m+2)*(l+2)) != cudaSuccess) cout << endl << " ERROR allocating memory for manmat resv0" << endl ; 
    manmat resw0; 
    resw0.strx = n+2;  resw0.stry = m+2;  resw0.strz = l+2; 
    if (cudaMalloc((void**)&resw0.el,sizeof(float) * (n+2)*(m+2)*(l+2)) != cudaSuccess) cout << endl << " ERROR allocating memory for manmat resw0" << endl ; 
    manmatvec residues0 ; 

    residues0.x = &resu0; 
    residues0.y = &resv0; 
    residues0.z = &resw0; 

    exec_res_std_2d <<<numBlocks2D, threadsPerBlock2D>>> (residues0, ......) ; 

..... 
} 

...這是在內核中發生的事情:

__global__ void exec_res_std_2d (manmatvec residues, ......) { 

    int i = blockIdx.x * blockDim.x + threadIdx.x; 
    int k = blockIdx.y * blockDim.y + threadIdx.y; 

    manmat *resup; 
    manmat *resvp; 
    manmat *reswp; 

    resup = residues.x; 
    resvp = residues.y; 
    reswp = residues.z; 

    manmat resu, resv, resw ; 

    resu.strx = (*resup).strx;  //LINE 1626 
    resu.stry = (*resup).stry; 
    resu.strz = (*resup).strz; 
    resu.el = (*resup).el; 

    resv = *resvp; 
    resw = *reswp; 

    ..... 
} 

最後,這就是CUDA-GDB給出的輸出:

.................. 
[Launch of CUDA Kernel 1065 (exec_res_std_2d<<<(1,2,1),(32,16,1)>>>) on Device 0] 
[Launch of CUDA Kernel 1066 (exec_res_bot_2d<<<(1,2,1),(32,16,1)>>>) on Device 0] 

Program received signal CUDA_EXCEPTION_5, Warp Out-of-range Address. 
[Switching focus to CUDA kernel 1065, grid 1066, block (0,0,0), thread (0,2,0), device 0, sm 0, warp 2, lane 0] 
0x0000000003179020 in fdivide<<<(1,2,1),(32,16,1)>>> (a=warning: Variable is not live at this point. Value is undetermined. 
..., pt=warning: Variable is not live at this point. Value is undetermined. 
..., cells=warning: Variable is not live at this point. Value is undetermined. 
...) at ola.cu:1626 
1626 ola.cu: No such file or directory. 
    in ola.cu 

我必須指出,我還沒有定義的任何功能,__device____global__我的代碼叫做fdivide .....

另外,可能很重要的一點是,在調試器內部程序運行的開始階段,儘管事實上我編譯了我的cuda c文件,我用-arch=sm_20 -g -G -gencode arch=compute_20,code=sm_20,I得到,

[New Thread 0x7ffff3b69700 (LWP 12465)] 
[Context Create of context 0x1292340 on Device 0] 
warning: no loadable sections found in added symbol-file /tmp/cuda-dbg/12456/session1/elf.1292340.1619c10.o.LkkWns 
warning: no loadable sections found in added symbol-file /tmp/cuda-dbg/12456/session1/elf.1292340.1940ad0.o.aHtC7W 
warning: no loadable sections found in added symbol-file /tmp/cuda-dbg/12456/session1/elf.1292340.2745680.o.bVXEWl 
warning: no loadable sections found in added symbol-file /tmp/cuda-dbg/12456/session1/elf.1292340.2c438b0.o.cgUqiP 
warning: no loadable sections found in added symbol-file /tmp/cuda-dbg/12456/session1/elf.1292340.2c43980.o.4diaQ4 
warning: no loadable sections found in added symbol-file /tmp/cuda-dbg/12456/session1/elf.1292340.2dc9380.o.YYJAr5 

任何答案或提示,或建議,可以幫助我解決這個問題非常歡迎! 請注意,我最近纔開始使用cuda-c進行編程,而且我對cuda-gdb也不是很熟悉。我在C代碼中進行的大多數調試都是通過檢查代碼中各個點的輸出來「手動」進行的......

此外,此代碼在特斯拉M2090上運行,並且也編譯爲運行2.0體系結構。

回答

2

這將是一個問題:

manmatvec residues0 ; 

    residues0.x = &resu0; 
    residues0.y = &resv0; 
    residues0.z = &resw0; 

resu0resv0resw0變量在主機內存分配 - 主機堆棧。您將主機地址放入manmatvec結構中,然後將manmatvec傳入內核。在接收端,CUDA代碼無法訪問結構中提供的主機內存地址。

如果您要傳遞resu0,resv0,resw0變量的地址,則需要從設備內存中分配這些變量。

我不知道這是否是整個問題,但我非常肯定它是最重要的貢獻者。

+0

我理解你的論點,你說得對,這些是在主機端分配的。但他們存在的重點是我使用它們來訪問和操縱設備端的內存(指針成員指向設備內存) 所以我想我的下一個問題是如何從設備端分配它們並讓它們他們在全局內存中,以便他們可以被其他內核使用...? 再次感謝您的回覆 – Panagiotis

+0

不只是分配在主機方。殘留變量*駐留在主機內存中。設備無法訪問主機內存。這就是爲什麼你在第1626行發生異常 - 設備試圖取消引用包含主機內存地址的指針。您需要在主機端的設備內存中分配殘差變量。這使得在主機端設置它們的值更加困難。 – dthorpe

+0

(1)計算設備內存的大小3 *(sizeof(manmat)+(sizeof(float)*((n + 2)+(m + 3)+(l + 2)))注意: (2)malloc是一塊主機內存,cudaMalloc是一塊設備內存;(3)爲每個子內存分配投入主機指針,並填充值;當設置manmat .el字段使用一個deviceptr(不是主機指針)。(4)從主機到設備的cudaMemcpy。(5)用deviceptrs填寫manmatvec。如果你的尺寸計算是(n + m + 1 + 6)* 4,總和小於4K,那麼你可以通過參數傳遞所有這一切。 –