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.