OpenGL互操作,cudaErrorUnknown

做OpenGL的互操作问题,kernel代码如下:

__global__ void kernel_draw(uchar4* ptr)
{
   int idx = threadIdx.x + blockDim.x*blockIdx.x;
   int idy = threadIdx.y + blockDim.y*blockIdx.y;
   int offset = idx + idy*blockDim.x*gridDim.x;
   
   ptr[offset].x = 255;
   ptr[offset].y = 0;
   ptr[offset].z = 0;        
   ptr[offset].w = 255;
   
   __syncthreads();        
}

调用为:

uchar4* devPtr;
kernel_draw<<<(40,30,1),(16,16,1)>>>(devPtr);
cudaDeviceSyncronize();
cudaError_t err = cudaGetLastError();

检查这个err的值是cudaErrorUnknown,不知道哪里出了问题,之前对OpenGL和CUDA互操作的初始化及缓冲区绑定部分中某些参数的设置不知道会不会对这一部分产生影响。。。还有如果这里的核函数调用正确的话是不是可以看到一片红色。。。求助各位高手!!

__syncthreads(); 没必要写,因为没有使用share memory
你的显存的大小是多少?是不是有个别的线程越界了?

楼主您好,

您的代码有3种可能情况:
(1)您的错误不是贵kernel导致的,而是之前的错误。
(2)您的错误是贵kernel导致的,那么贵kernel可能使用了无效的缓冲区(请检查devPtr是否是有效的缓冲区)
(3)您的错误是贵kernel导致的,同时devPtr有效,但对ptr[offfset]导致了越界。

建议的解决方案:
(1)在kernel_draw前添加一次cudaError_t result = cudaDeviceSynchronize();
然后检查result是否是cudaErrorUnknown, 如果是,则证明是前面的代码的错误;如果是cudaSuccess, 则证明错误在后面。
(2)如果(1)表示错误在后面,请先检查devPtr是否有效,方式如下:
在您的kernel首行下断点,命中后使用debug->windows->memory窗口查看ptr指向的显存的内容。
如果能看到内容,则证明devPtr有效。请继续看3.
(3)如果(1)(2)均通过,请启用nsight的memory check(默认是启用的),取消所有断点,然后直接F5运行到底,看nsight是否在右下角弹出"Access violation in kernel"类似字样。

基本应该是1、2、3情况之一,
请按照本文建议,逐步检查问题所在。

感谢您的来访。

你说的对,,这个是我想当然了~多谢!

感谢千军版主解答~明天上班去试一下,再把结果反馈过来!

版主您好!比较完整的程序如下所示:

GLuint bufferObj = 0;
cudaGraphicsResources *cuda_buffer_resource;

cudaGLSetGLDevice(devID);
glutInit(&argc,argv);
glutDisplayMode(GLUT_DOUBLE|GLUT_RGBA);
glutInitWindowSize(640,480);
glutCreateWindow("Pic");
glewInit();

glGenBuffersARB(1,&bufferObj);
glBindBuffersARB(GL_PIXEL_UNPACK_BUFFER_ARB,bufferObj);
glBufferDataARB(GL_PIXEL_UNPACK_BUFFER_ARB,640*480*4,NULL,GL_DYNAMIC_DRAW_ARB);
cudaGraphicsGLRegisterBuffer(&cuda_buffer_resource,bufferObj,cudaGraphicsMapFlagNone);

uchar4* devPtr;
size_t size;
cudaGraphicsMapResources(1,&cuda_buffer_resource,NULL);
//下面这一句出现中断了,写入冲突
cudaGraphicsResourcesGetMappedPointer((void**)devPtr,&size,cuda_buffer_resource);

kernel_draw<<<(40,30,1),(16,16,1)>>>(devPtr);

cudaGraphicsUnmapResources(1,&cuda_buffer_resource,NULL);
glutDisplayFunc(draw_func);

//这个是在一开始就定义好的
static void draw_func()
{
	glDrawPixels(640,480,GL_RGBA,GL_UNSIGNED_BYTE,0);
	glSwapBuffers();
}

第一个注释地方有问题。不知道是怎么回事。。。。

楼主您好,

您的cudaGraphicsResourcesGetMappedPointer使用错误,
从而导致您的缓冲区无效,
从而导致您的kernel挂掉。
(上文指出的3个可能问题所在的第1点和第2点)

建议的解决方案:
将原代码:
cudaGraphicsResourcesGetMappedPointer((void**)devPtr,&size,cuda_buffer_resource);
改成:
cudaGraphicsResourcesGetMappedPointer((void**)&devPtr,&size,cuda_buffer_resource);

并rebuild贵项目。

感谢您的来访。

果然是这个问题。。。多谢千军版主!还是自己基础没掌握好