2013-09-30 119 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在设备上分配它。一些对象仍然通过封装从主机分配,所以设备堆在访问期间不知道,并且会引发访问冲突。