2013-05-01 3 views
1

GPU/OpenCL NBody 코드 작업 중입니다. AMD APP SDK의 OpenGL을 사용하여 입자 위치 렌더링을합니다. 코드를 실행할 때 무작위로 세그먼트 오류가 있습니다.GPU/OpenCL/OpenGL 코드의 랜덤 분할 오류

요약하면, 저는 OpenGL 렌더링을 수행하는 GLWidget을 가지고 있습니다. 초기 위치가 생성되면이 GLWidget에서 렌더링합니다. 그 후에 시뮬레이션을 실행하고 모든 단계에서 다음 위치를 계산하여 GLwidget에 표시합니다. 여기

년대 역 추적 :

여기
Program received signal SIGSEGV, Segmentation fault. 
0x00007ffff4a46cd7 in memcpy() from /lib/libc.so.6 
(gdb) bt 
#0 0x00007ffff4a46cd7 in memcpy() from /lib/libc.so.6 
#1 0x00007fffeda2da64 in ??() from /usr/lib/x86_64-linux-gnu/dri/fglrx_dri.so 
#2 0x00007fffedbba74a in ??() from /usr/lib/x86_64-linux-gnu/dri/fglrx_dri.so 
#3 0x00007fffedbba9af in ??() from /usr/lib/x86_64-linux-gnu/dri/fglrx_dri.so 
#4 0x00007fffed9c56e4 in ??() from /usr/lib/x86_64-linux-gnu/dri/fglrx_dri.so 
#5 0x00007fffed17371d in ??() from /usr/lib/x86_64-linux-gnu/dri/fglrx_dri.so 
#6 0x000000000040b185 in GLWidget::createVBO()() 
#7 0x000000000040b3c9 in GLWidget::draw()() 
#8 0x000000000040c36d in GLWidget::processCurrent()() 
... 

createVBO의 나는 시뮬레이션이 실행되는 동안, 나는 세그먼트 오류가 매개 변수의 GUI의 버튼을 "초기 조건을 생성"을 클릭하면 내 문제는, 때로는입니다 루틴 :

void GLWidget::createVBO() 
{ 
    GLuint vbo; 
    int memSize = sizeof(cl_double4) * 4 * Galaxy->getNumParticles(); 
    glGenBuffers(1, &vbo); 
    glBindBuffer(GL_ARRAY_BUFFER, vbo); 
    glBufferData(GL_ARRAY_BUFFER, memSize, Galaxy->pos, GL_DYNAMIC_DRAW); 
} 

는 segfault가 이해가 안 glBufferData(GL_ARRAY_BUFFER, memSize, Galaxy->pos, GL_DYNAMIC_DRAW);

에서 발생하는 이유를이 happe ns. "IC 생성"버튼을 누르면 할당 된 Galaxy->pos 배열을 삭제하고 새 배열을 만듭니다. 당신이 무엇을 잘못 볼 수 있었다 첫눈에서

int NBody::cleanup() 
{ 
    if (glEvent) 
    clReleaseEvent(glEvent); 

    // Releases OpenCL resources (Context, Memory etc.) 
    cl_int status; 

    if (hasRunKernel) 
    { 
    status = clFinish(commandQueue); 
    CHECK_OPENCL_ERROR(status, "clFinish failed.(commandQueue)"); 

    status = clReleaseKernel(kernel); 
    CHECK_OPENCL_ERROR(status, "clReleaseKernel failed.(kernel)"); 

    status = clReleaseProgram(program); 
    CHECK_OPENCL_ERROR(status, "clReleaseProgram failed.(program)"); 

    status = clReleaseMemObject(currPos); 
    CHECK_OPENCL_ERROR(status, "clReleaseMemObject failed.(currPos)"); 

    status = clReleaseMemObject(currVel); 
    CHECK_OPENCL_ERROR(status, "clReleaseMemObject failed.(currVel)"); 

    status = clReleaseMemObject(newPos); 
    CHECK_OPENCL_ERROR(status, "clReleaseMemObject failed.(newPos)"); 

    status = clReleaseMemObject(newVel); 
    CHECK_OPENCL_ERROR(status, "clReleaseMemObject failed.(newVel)"); 

    status = clReleaseCommandQueue(commandQueue); 
    CHECK_OPENCL_ERROR(status, "clReleaseCommandQueue failed.(commandQueue)"); 

    status = clReleaseContext(context); 
    CHECK_OPENCL_ERROR(status, "clReleaseContext failed.(context)"); 

    hasRunKernel = false; 
    } 

    // Release program resources 
    delete [] pos; 
    delete [] vel; 
    delete [] initPos; 
    delete [] initVel; 
    delete [] devices; 
    // Delete current instance 
    delete this; 

    return NBODY_SUCCESS; 
} 

: (나는 pos 배열을 삭제) cleanup 루틴

//Clean Galaxy already existing 
    if (parent->widget_2->isGalaxyExist) 
    { 
    if (parent->widget_2->animation) 
     parent->resetSimu(); 
    parent->widget_2->Galaxy->cleanup(); 
    } 

: 여기

내가 "IC를 생성"일상에서 할거야 또는이 세그 폴트에 대한 단서를주세요. 가장 성가신 일은 모든 실행이 아니라 무작위로 오류가 발생한다는 것입니다.

답변

1

이 계산이 정확합니까?

특히 "* 4": sizeof (cl_double4)는 이미 벡터의 4 가지 요소를 고려합니다.

1

이와 같은 충돌은 glBufferData OpenGL API 기능을 통해 호출 된 드라이버 코드의 범위를 벗어난 액세스를 나타냅니다. glBufferData에 전달 된 매개 변수가 올바른지 확인합니다. 즉, 읽을 glBufferData에 지정된 길이가 데이터 매개 변수로 전달 된 메모리 범위 내에 있는지 확인합니다.