2015-05-21 14 views
6

Ich habe zufällig cuda Speicherzuordnungsfehler bei Verwendung von cudaGraphicsGLRegisterBuffer(). Ich habe ein ziemlich großes OpenGL PBO-Objekt, das mit ihm und CUDA geteilt wird. Das PBO-Objekt wird wie folgt erzeugt:cuda, OpenGL-Interoperabilität: cudaErrorMemoryAllocation-Fehler auf cudaGraphicsGLRegisterBuffer

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); 

Das Objekt ist ziemlich groß. Breite und Höhe sind 5000. Allerdings teilt es meiner Grafikkarte gut. Jetzt teile ich das wie folgt zwischen OpenGL und CUDA. Ich habe eine einfache Klasse, die es zu verwalten, wie folgt:

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)); 
    } 
} 

Jetzt kann ich die OpenGL und CUDA Interoperabilität wie folgt:

{ 
    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); 
} 

dies für eine Weile für meine Eingaben läuft, aber nach einiger Zeit stürzt mit:

Ich bin nicht sicher, warum es Speicherzuteilung geht, als ich dachte, dass es geteilt wurde. Ich habe cudaDeviceSynchronize() nach dem Kernel-Aufruf hinzugefügt, aber der Fehler besteht immer noch. Meine call_my_kernel() Funktion macht jetzt ziemlich nichts, so dass es keine anderen CUDA-Aufrufe gibt, die diesen Fehler auslösen können!

Ich benutze Cuda 7 auf Linux mit einer K4000 Quadro-Karte.

EDIT Ich aktualisierte den Treiber auf die neueste 346.72-Version und der Fehler tritt noch immer auf. Es hängt auch nicht vom Kernel-Aufruf ab. Nur cudaGraphicsGLRegisterBuffer() zu rufen scheint Speicher auf der GPU zu verlieren. Wenn nvidia-smi ausgeführt wird, während das Programm läuft, wird der Speicher ständig erhöht. Ich bin immer noch ratlos, warum es Kopiervorgänge gibt ...

Antwort

3

Ok, ich habe die Antwort auf mein Rätsel gefunden und hoffe, dass es jedem anderen hilft, der CUDA-OGL zusammen benutzt.

Das Problem war, dass ich rufe:

checkCudaErrors(cudaGraphicsGLRegisterBuffer(&_cgr, pbo_id, 
       cudaGraphicsRegisterFlagsNone)); 

jedes Mal. Das muss eigentlich nur einmal aufgerufen werden und dann muss ich einfach map/unmap auf dem _cgr Objekt aufrufen.