1

GPU/OpenCL NBody コードに取り組んでいます。AMD APP SDKのOpenGLでパーティクル位置のレンダリングを行っています。コードを実行すると、ランダムにセグメンテーション違反が発生します。

要約すると、OpenGL レンダリングを行う GLWidget があります。初期位置が生成されたら、この GLWidget でレンダリングします。その後、シミュレーションを実行し、すべてのステップで次の位置を計算して GLwidget に表示します。私の問題は、シミュレーションの実行中にパラメーター GUI の [初期条件の生成] ボタンをクリックすると、セグメンテーション エラーが発生することがあります。

バックトレースは次のとおりです。

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ルーチンは次のとおりです。

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

セグメンテーション違反が発生する場所glBufferData(GL_ARRAY_BUFFER, memSize, Galaxy->pos, GL_DYNAMIC_DRAW);

なぜこれが起こるのかわかりません。「IC の生成」ボタンを押すと、割り当てられた配列が削除されGalaxy->pos、新しい配列が作成されます。

「ICの生成」ルーチンで行うことは次のとおりです。

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

cleanupルーチンで(配列を削除する場所)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;
}

一目で何が問題なのか、またはこの segfault の手がかりを教えていただけますか。最も厄介なのは、実行ごとではなく、エラーがランダムに発生することです。

4

2 に答える 2