AnsweredAssumed Answered

Am having an assertion error arising from clBuildProgram in my code on Visual Studio 2012

Question asked by yaknan on Mar 20, 2014
Latest reply on Apr 9, 2014 by yaknan

I am trying to run a program that has three (3) implementations of raytracing algorithm (C++ Recursive version, C++ Iterative version and OpenCL version). The recursive and the iterative versions both run alright, my challenge is with the  OpenCL version. I getting a lot of errors. After several modifications and tweaking am finally left with just a few errors one of which is caught when the clBuildProgram is called.

 

Perhaps am not entering the right parameters or am missing something minor. The thing is the whole project builds well with no errors only a few warnings.

I am hoping someone can point me in the right direction. Here are the specifications of the system am using:

 

CPU: AMD E-50 processor 1.6Ghz

OpenCL SDK : AMD APP 2.7

IDE: Visual Studio 2012

 

The error occurs on line 23 of the code excerpt below:

 



void OpenCLManager::MapKernelNameToProgram(std::string a_kernelName, std::string a_programName) {
  // Build CPU programs
  {
  cl_int err = 0;
  std::string programName(a_programName);
  std::string kernelName(a_kernelName);
  programName += " OpenCL_CPU";
  kernelName += " OpenCL_CPU";
  cl_program program = m_MapProgramNameToProgram[programName];

  if (!program)
  {
  // Load the source code to a string.
  char* programSource = this->LoadProgramSource(a_programName.c_str());

  // Create the program with source string.
  program = clCreateProgramWithSource(m_ContextCPU, 1, (const char**)&programSource, NULL, &err);
  assert(err == CL_SUCCESS);

  // Build the program.
  err = clBuildProgram(program, 1,&m_DeviceCPU, NULL, NULL, NULL);
  char build[2048];
  clGetProgramBuildInfo(program, m_DeviceCPU, CL_PROGRAM_BUILD_LOG, 2048, build, NULL);
  printf("Build Log:\n%s\n",build); // Prints any build errors
  assert(err == CL_SUCCESS);

  m_MapProgramNameToProgram[programName] = program;
  }

  m_MapKernelNameToProgram[kernelName] = program;
  }

  // Build GPU programs
  {
  cl_int err = 0;
  std::string programName(a_programName);
  std::string kernelName(a_kernelName);
  programName += " OpenCL_GPU";
  kernelName += " OpenCL_GPU";
  cl_program program = m_MapProgramNameToProgram[programName];

  if (!program)
  {
  // Build the program, since it has not yet been built.

  // Load the source code to a string.
  char* programSource = this->LoadProgramSource(a_programName.c_str());

  // Create the program with source string.
  program = clCreateProgramWithSource(m_ContextGPU, 1, (const char**)&programSource, NULL, &err);
  assert(err == CL_SUCCESS);

  // Build the program.
  //err = clBuildProgram(program, 1, &m_DeviceGPU, NULL, NULL, NULL);
  char build[2048];
  clGetProgramBuildInfo(program, m_DeviceGPU, CL_PROGRAM_BUILD_LOG, 2048, build, NULL);
  printf("Build Log:\n%s\n",build); // Prints any build errors
  assert(err == CL_SUCCESS);

  m_MapProgramNameToProgram[programName] = program;
  }

  m_MapKernelNameToProgram[kernelName] = program;
  }
}


char* OpenCLManager::LoadProgramSource(const char* filename) { 
  struct stat statbuf;
  FILE *fh;
  char *source; 


  fh = fopen(filename, "r");
  if (fh == 0)
  return 0; 


  stat(filename, &statbuf);
  source = (char *) malloc(statbuf.st_size + 1);
  fread(source, statbuf.st_size, 1, fh);
  source[statbuf.st_size] = '\0';


  return source; 
} 


//void OpenCLManager::InitContext( void ) {
// cl_int err = 0;
// // Create a context to perform our calculation with the 
// // specified device 
// m_ContextCPU = clCreateContext(0, 1, &m_DeviceCPU, NULL, NULL, &err);
// assert(err == CL_SUCCESS);
// m_ContextGPU = clCreateContext(0, 1, &m_DeviceGPU, NULL, NULL, &err);
// assert(err == CL_SUCCESS);
//
//}
//
//void OpenCLManager::InitCommandQueue() {
// m_CommandQueueCPU = clCreateCommandQueue(m_ContextCPU, m_DeviceCPU, 0, NULL);
// m_CommandQueueGPU = clCreateCommandQueue(m_ContextGPU, m_DeviceGPU, 0, NULL);
//}


  // TODO: give some better way of notifying whether or not this was successful.
void OpenCLManager::InitDevice() {
  // Init CPU device

  m_ContextCPU= NULL;
  m_ContextGPU= NULL;
  m_CommandQueueCPU= NULL;
  m_CommandQueueGPU= NULL;
  m_DeviceCPU= NULL;
  m_DeviceGPU= NULL;
  cl_platform_id platform_id = NULL;
  m_DeviceType= OpenCL_CPU;
  m_raytraceKernelWorkGroupSize= NULL;
  cl_uint ret_num_devices;
  cl_uint ret_num_platforms;
  cl_int err = 0;


  /* Get Platform and Device Info */
  err = clGetPlatformIDs(1, &platform_id, &ret_num_platforms);


  // Find the CPU CL device, as a fallback
  err = clGetDeviceIDs(platform_id, CL_DEVICE_TYPE_DEFAULT, 1, &m_DeviceCPU, &ret_num_devices);
  std::cout << err << std::endl;
  assert(err == CL_SUCCESS);


  // Init GPU device
  // Find the GPU CL device, this is what we really want
  // If there is no GPU device is CL capable, fall back to CPU
  err = clGetDeviceIDs(platform_id, CL_DEVICE_TYPE_GPU, 1, &m_DeviceGPU, NULL);
  if (err != CL_SUCCESS) m_DeviceGPU = m_DeviceCPU;
  assert(m_DeviceGPU);




  // Create a context to perform our calculation with the 
  // specified device 
  m_ContextCPU = clCreateContext(NULL, 1, &m_DeviceCPU, NULL, NULL, &err);
  assert(err == CL_SUCCESS);
  m_ContextGPU = clCreateContext(NULL, 1, &m_DeviceGPU, NULL, NULL, &err);
  assert(err == CL_SUCCESS);


  /* Create Command Queue */
  m_CommandQueueCPU = clCreateCommandQueue(m_ContextCPU, m_DeviceCPU, 0, &err);
  m_CommandQueueGPU = clCreateCommandQueue(m_ContextGPU, m_DeviceGPU, 0, &err);




  // Construct the KernelName -> Program map.
  this->MapKernelNameToProgram(RAYTRACE_KERNEL, RAY_TRACER_PROGRAM);




}

Please also find attached the visual studio solution. Thank you!

Please find attached the Visual studio solution

Attachments

Outcomes