2013-09-30 118 views
0

當我創建一個具有3深層結構的結構,並且最深層次有一個2 diminsional數組時,在設備上分配內存並訪問該數組會導致內存檢查器訪問衝突錯誤CUDA調試器。下面是一個例子:CUDA結構封裝靜態2D對象

#include "stdafx.h" 

#include <stdio.h> 
#include <cuda.h> 
#include <cuda_runtime.h> 
#include <device_launch_parameters.h> 

typedef struct { 
    int value; 
} Level3; 

typedef struct { 
    Level3 lvl3ObjArr[10][10]; 
} Level2; 

typedef struct { 
    Level2 lvl2Obj; 
} Level1; 

__global__ void AccessViolationKernel(Level1 *_lvl1Ptr) 
{ 
    int _value; 

    _lvl1Ptr->lvl2Obj.lvl3ObjArr[2][5].value = 4; 
    _value = _lvl1Ptr->lvl2Obj.lvl3ObjArr[2][5].value; 

    printf("Value = %i\n", _value); 
} 

int _tmain(int argc, _TCHAR* argv[]) 
{ 
    Level1 *lvl1Ptr; 
    cudaMalloc((void **)&lvl1Ptr, sizeof(Level1)); 
    AccessViolationKernel<<<5, 1>>>(lvl1Ptr); 

    return 0; 
} 

即使在看存儲和添加正確的字節,一切似乎正常加起來爲lvl1Ptr的包封的參考lvl3ObjArr [2] [5]當使用CUDA調試器。不過,訪問的數據不正確,memchecker會拋出訪問衝突。

Level1未在設備上正確分配嗎?爲什麼我得到訪問違規?

在此先感謝!

- 更新(2013年9月30日16:29 PM CST) -

此代碼編譯(對不起!),但它不會出現錯誤。我認爲它是因爲我不是使用cudaMalloc,而是使用設備API malloc來嘗試稍後從主機的CUDA API訪問數據。我需要一段時間來生成代碼來重現這一點,我的歉意 - 我減少的源代碼是2800行。

+0

你能發佈可編譯的實際代碼嗎? – talonmies

+0

只需確認您目前發佈的代碼看起來有效,運行正確,並且可以打印出預期結果。 'cuda-memcheck'報告沒有錯誤。如果您正在使用設備'malloc',則無法使用運行時API以這種方式訪問​​分配的內存。相反,您首先需要將數據從該區域複製到已經使用的區域中,例如, 'cudaMalloc',然後將該數據複製到主機。 –

+0

羅伯特,再次感謝您的幫助。我似乎仍然有混合主機CUDA API和設備內核malloc的潛在問題。奇怪的是我使用cudaMalloc在我的大代碼集中分配了第一級對象,並訪問了其中一個隱藏的2D對象數組的值,並且我得到了單獨的訪問衝突。只有當我訪問最深的值時纔會發生,而不是在訪問隱藏結構中的指針時引用和取消引用以獲取該隱藏值。當我找到顯示相同錯誤的解決方案或縮減版本的代碼時,我會重新發布。 – user2712376

回答

0

好的,找到了解決方案。我在內核中將cudaMalloc與malloc/free混合在一起。這並不直觀,因爲我正在用cudaMalloc分配根目錄,之後再用malloc在設備上分配它。一些對象仍然通過封裝從主機分配,所以設備堆在訪問期間不知道,並且會引發訪問衝突。