cuda, OpenGL совместимость: cudaErrorMemoryAllocation ошибка на cudaGraphicsGLRegisterBuffer
у меня случайная ошибка выделения памяти cuda при использовании cudaGraphicsGLRegisterBuffer()
. У меня есть довольно большой объект 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. Тем не менее, он выделяет на ГПУ. Теперь я разделяю это между OpenGL и CUDA следующим образом. У меня есть простой класс для управления им следующим образом:
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, которые могут вызвать эту ошибку!
я использую Cuda 7 в linux с квадроциклом K4000 карта.
редактировать
Я обновил драйвера до последней версии 346.72 и ошибка все равно происходит. Это также не зависит от вызова ядра. Звоню cudaGraphicsGLRegisterBuffer()
кажется, утечка памяти на GPU. Запуск nvidia-smi по мере запуска программы показывает, что память неуклонно растет. Я все еще не понимаю, почему происходит копирование...
1 ответов
хорошо, я нашел ответ на свою головоломку, и я надеюсь, что это поможет кому-нибудь еще использовать CUDA-OGL вместе.
проблема была в том, что я звонил:
checkCudaErrors(cudaGraphicsGLRegisterBuffer(&_cgr, pbo_id,
cudaGraphicsRegisterFlagsNone));
каждый раз. На самом деле это нужно вызвать только один раз, а затем мне просто нужно вызвать map/unmap на объекте _cgr.