【问题标题】:CUDA + OpenGL. Unknown code=4(cudaErrorLaunchFailure) errorCUDA + OpenGL。未知代码=4(cudaErrorLaunchFailure)错误
【发布时间】:2013-06-13 07:53:12
【问题描述】:

我正在 CUDA 上进行简单的 n 体模拟,然后我尝试使用 OpenGL 进行可视化。

在我在 CPU 上初始化我的粒子数据、分配相应的内存并在 GPU 上传输该数据之后,程序必须进入以下循环:

1) 计算每个粒子上的力(CUDA 部分)

2)更新粒子位置(CUDA部分)

3) 显示该时间步的粒子(OpenGL 部分)

4) 回到 1)

CUDA和OpenGL的接口我用下面的代码实现的:

GLuint dataBufferID;
particle_t* Particles_d;
particle_t* Particles_h;
cudaGraphicsResource *resources[1];

我在 OpenGLs Array_Buffer 上分配空间,并使用以下代码将后者注册为 cudaGraphicsResource:

void createVBO()
{

    // create buffer object
    glGenBuffers(1, &dataBufferID);
    glBindBuffer(GL_ARRAY_BUFFER, dataBufferID);
    glBufferData(GL_ARRAY_BUFFER, bufferStride*N*sizeof(float), 0, GL_DYNAMIC_DRAW);
    glBindBuffer(GL_ARRAY_BUFFER, 0);

checkCudaErrors(cudaGraphicsGLRegisterBuffer(resources, dataBufferID, cudaGraphicsMapFlagsNone));

}

最后,我描述的程序循环(步骤1到4)是通过下面的函数update(int)实现的

void update(int value)
{
// map OpenGL buffer object for writing from CUDA
float* dataPtr;
checkCudaErrors(cudaGraphicsMapResources(1, resources, 0));
size_t num_bytes;
//get a pointer to that buffer object for manipulation with cuda! 
checkCudaErrors(cudaGraphicsResourceGetMappedPointer((void **)&dataPtr, &num_bytes,resources[0]));

//fill the Graphics Resource with particle position Data!        
launch_kernel<<<NUM_BLOCKS,NUM_THREADS>>>(Particles_d,dataPtr,1);
// unmap buffer object
checkCudaErrors(cudaGraphicsUnmapResources(1, resources, 0));
glutPostRedisplay();
glutTimerFunc(milisec,update,0);    
}

我编译结束我得到以下错误:

src/main.cu:390 处的 CUDA 错误 code=4(cudaErrorLaunchFailure) "cudaGraphicsMapResources(1, resources, 0)"

src/main.cu:392 处的 CUDA 错误 code=4(cudaErrorLaunchFailure) "cudaGraphicsResourceGetMappedPointer((void **)&dataPtr, &num_bytes,resources[0])"

src/main.cu:397 处的 CUDA 错误 code=4(cudaErrorLaunchFailure) "cudaGraphicsUnmapResources(1, resources, 0)"

有谁知道导致该异常的原因可能是什么?我是否应该在每次执行 update(int) 之前使用 createVBO() 创建 dataBuffer ...?

附言为了更清楚起见,我的内核函数如下:

__global__ void launch_kernel(particle_t* Particles,float* data, int KernelMode){

int i = blockIdx.x*THREADS_PER_BLOCK + threadIdx.x;

if(KernelMode == 1){
//N_d is allocated on device memory 
if(i > N_d) 
    return;
//and update dataBuffer! 
updateX(Particles+i);

for(int d=0;d<DIM_d;d++){
    data[i*bufferStride_d+d] = Particles[i].p[d]; // update the new coordinate positions in the data buffer! 
}
    // fill in also the RGB data and the radius. In general THIS IS NOT NECESSARY!! NEED TO PERFORM ONCE! REFACTOR!!!
data[i*bufferStride_d+DIM_d] =Particles[i].r;
data[i*bufferStride_d+DIM_d+1] =Particles[i].g;
data[i*bufferStride_d+DIM_d+2] =Particles[i].b;
data[i*bufferStride_d+DIM_d+3] =Particles[i].radius;

}else{
// if KernelMode = 2 then Update Y
    float* Fold = new float[DIM_d];
    for(int d=0;d<DIM_d;d++)
        Fold[d]=Particles[i].force[d];

    //of course in parallel :)
    computeForces(Particles,i);
    updateV(Particles+i,Fold);
    delete [] Fold;
    }
// in either case wait for all threads to finish! 
__syncthreads();


}

【问题讨论】:

  • 您可以使用 cuda-memcheck 缩小启动失败的原因。另外,您是否知道 CUDA 工具包中有一个用于 OpenGL 可视化的 nbody 代码示例?您可能会发现它很有帮助。
  • 其实是我弄错了计算能力编译选项。我运行了 cuda-memcheck,结果发现 cuda Api 启动失败了。在我找到正确的编译器选项后,一切都像魅力一样。
  • 请发表一个答案然后接受它(我认为必须等待一天),所以这个问题已经结束了。

标签: opengl cuda


【解决方案1】:

正如我在上面的其中一个 cmets 中提到的,结果我弄错了计算能力编译器选项。我运行了 cuda-memcheck,发现 cuda Api 启动失败。在我找到正确的编译器选项后,一切都像魅力一样。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-08-06
    • 2011-11-12
    • 2017-02-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-19
    相关资源
    最近更新 更多