cuda、OpenGL 互操作性:cudaGraphicsGLRegisterBuffer 上的 cudaErrorMemoryAllocation 错误
cuda, OpenGL interoperability: cudaErrorMemoryAllocation error on cudaGraphicsGLRegisterBuffer
我在使用 cudaGraphicsGLRegisterBuffer()
时遇到随机 cuda 内存分配错误。我有一个相当大的 OpenGL PBO 对象,它与它和 CUDA 共享。 PBO对象创建如下:
GLuint buffer;
glGenBuffers(1, &buffer);
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, buffer);
glBufferData(target, rows * cols * 4, NULL, GL_DYNAMIC_COPY);
glUnmapBuffer(_target);
glBindBuffer(_target, 0);
对象很大。宽度和高度是 5000。但是,它在我的 GPU 上分配得很好。现在,我在 OpenGL 和 CUDA 之间分享这个,如下所示。我有一个简单的 class 来管理它,如下所示:
class CudaPBOGraphicsResource
{
public:
CudaPBOGraphicsResource(GLuint pbo_id);
~CudaPBOGraphicsResource();
inline cudaGraphicsResource_t resource() const { return _cgr; }
private:
cudaGraphicsResource_t _cgr;
};
CudaPBOGraphicsResource::CudaPBOGraphicsResource(GLuint pbo_id)
{
checkCudaErrors(cudaGraphicsGLRegisterBuffer(&_cgr, pbo_id,
cudaGraphicsRegisterFlagsNone));
checkCudaErrors(cudaGraphicsMapResources(1, &_cgr, 0));
}
CudaPBOGraphicsResource::~CudaPBOGraphicsResource()
{
if (_cgr) {
checkCudaErrors(cudaGraphicsUnmapResources(1, &_cgr, 0));
}
}
现在我做OpenGL和CUDA互操作如下:
{
CudaPBOGraphicsResource input_cpgr(pbo_id);
uchar4 * input_ptr = 0;
size_t num_bytes;
checkCudaErrors(cudaGraphicsResourceGetMappedPointer((void
**)&input_ptr, &num_bytes,
input_cpgr.resource()));
call_my_kernel(input_ptr);
}
这会为我的输入运行一段时间,但一段时间后它崩溃了:
CUDA error code=2(cudaErrorMemoryAllocation)
"cudaGraphicsGLRegisterBuffer(&_cgr, pbo_id,
cudaGraphicsRegisterFlagsNone)"
Segmentation fault
我不确定为什么会进行内存分配,因为我认为这是共享的。我在内核调用后添加了 cudaDeviceSynchronize()
但错误仍然存在。我的 call_my_kernel()
函数现在几乎什么都不做,所以没有其他 CUDA 调用可以引发此错误!
我在 linux 上使用 Cuda 7 和 K4000 Quadro 卡。
编辑
我把驱动更新到最新的346.72版本,还是报错。它也不依赖于内核调用。只是调用 cudaGraphicsGLRegisterBuffer()
似乎会泄漏 GPU 上的内存。 运行 作为程序的 nvidia-smi 运行 显示内存稳步上升。我仍然不知道为什么会发生任何复制...
好的,我找到了我的难题的答案,我希望它能帮助其他一起使用 CUDA-OGL 的人。
问题是我在打电话:
checkCudaErrors(cudaGraphicsGLRegisterBuffer(&_cgr, pbo_id,
cudaGraphicsRegisterFlagsNone));
每次。这实际上只需要调用一次,然后我只需要在 _cgr 对象上调用 map/unmap。
我在使用 cudaGraphicsGLRegisterBuffer()
时遇到随机 cuda 内存分配错误。我有一个相当大的 OpenGL PBO 对象,它与它和 CUDA 共享。 PBO对象创建如下:
GLuint buffer;
glGenBuffers(1, &buffer);
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, buffer);
glBufferData(target, rows * cols * 4, NULL, GL_DYNAMIC_COPY);
glUnmapBuffer(_target);
glBindBuffer(_target, 0);
对象很大。宽度和高度是 5000。但是,它在我的 GPU 上分配得很好。现在,我在 OpenGL 和 CUDA 之间分享这个,如下所示。我有一个简单的 class 来管理它,如下所示:
class CudaPBOGraphicsResource
{
public:
CudaPBOGraphicsResource(GLuint pbo_id);
~CudaPBOGraphicsResource();
inline cudaGraphicsResource_t resource() const { return _cgr; }
private:
cudaGraphicsResource_t _cgr;
};
CudaPBOGraphicsResource::CudaPBOGraphicsResource(GLuint pbo_id)
{
checkCudaErrors(cudaGraphicsGLRegisterBuffer(&_cgr, pbo_id,
cudaGraphicsRegisterFlagsNone));
checkCudaErrors(cudaGraphicsMapResources(1, &_cgr, 0));
}
CudaPBOGraphicsResource::~CudaPBOGraphicsResource()
{
if (_cgr) {
checkCudaErrors(cudaGraphicsUnmapResources(1, &_cgr, 0));
}
}
现在我做OpenGL和CUDA互操作如下:
{
CudaPBOGraphicsResource input_cpgr(pbo_id);
uchar4 * input_ptr = 0;
size_t num_bytes;
checkCudaErrors(cudaGraphicsResourceGetMappedPointer((void
**)&input_ptr, &num_bytes,
input_cpgr.resource()));
call_my_kernel(input_ptr);
}
这会为我的输入运行一段时间,但一段时间后它崩溃了:
CUDA error code=2(cudaErrorMemoryAllocation)
"cudaGraphicsGLRegisterBuffer(&_cgr, pbo_id,
cudaGraphicsRegisterFlagsNone)"
Segmentation fault
我不确定为什么会进行内存分配,因为我认为这是共享的。我在内核调用后添加了 cudaDeviceSynchronize()
但错误仍然存在。我的 call_my_kernel()
函数现在几乎什么都不做,所以没有其他 CUDA 调用可以引发此错误!
我在 linux 上使用 Cuda 7 和 K4000 Quadro 卡。
编辑
我把驱动更新到最新的346.72版本,还是报错。它也不依赖于内核调用。只是调用 cudaGraphicsGLRegisterBuffer()
似乎会泄漏 GPU 上的内存。 运行 作为程序的 nvidia-smi 运行 显示内存稳步上升。我仍然不知道为什么会发生任何复制...
好的,我找到了我的难题的答案,我希望它能帮助其他一起使用 CUDA-OGL 的人。
问题是我在打电话:
checkCudaErrors(cudaGraphicsGLRegisterBuffer(&_cgr, pbo_id,
cudaGraphicsRegisterFlagsNone));
每次。这实际上只需要调用一次,然后我只需要在 _cgr 对象上调用 map/unmap。