Parallel GPU OpenCL. No Devices Found

Hi all,

I’m using Ubuntu 14.04, have a Nvidia GeForce GTX 970 GPU, and can run basic CUDA examples. I’m using the OpenCL files that came with the CUDA toolkit.

I’m trying to run a Parallel OpenCL Dijkstra Algorithm from the following link:
https://code.google.com/p/opencl-book-samples/source/browse/trunk/src/?r=2#src%2FChapter_16%2FDijkstra

I am able to compile all files using the following command:
g++ -I/usr/local/cuda-7.0/include/ -I/usr/include/boost/ -L/usr/local/cuda-7.0/lib64/ -o hello *.cpp -lOpenCL -pthread -lboost_program_options

However, when i try to run it, i get the following output.

./hello --gpu
Number of OpenCL Platforms: 1
No GPU devices found.
No CPU devices found.
Vertex Count: 100000
Edge Count: 1000000

In oclDijkstra.cpp, the problem is here:
gpuContext = clCreateContextFromType(0, CL_DEVICE_TYPE_GPU, NULL, NULL, &errNum);
if (errNum != CL_SUCCESS)
{
printf("No GPU devices found.
");
}

Any ideas on how to solve and run this?

Thanks

That usage of clCreateContextFromType isn’t guaranteed to work on systems that use the OpenCL ICD model (which is most of them, these days). Instead, you should be explicit about which platform you wish to use when creating the context:

cl_context_properties properties[3] = {CL_CONTEXT_PLATFORM, platform, 0};
gpuContext = clCreateContextFromType(properties, CL_DEVICE_TYPE_GPU, NULL, NULL, &errNum);

For any real application you would usually want to iterate over all of the platforms available and find the one you wish to use, since there may be more than one.

I get the following error:

error: invalid conversion from ‘cl_platform_id {aka _cl_platform_id*}’ to ‘cl_context_properties {aka long int}’ [-fpermissive]
cl_context_properties properties[3] = {CL_CONTEXT_PLATFORM, platform, 0};

I just copy pasted that code you wrote for now. This thread shows something similar:
http://stackoverflow.com/questions/20422151/opencl-c-context-properties-syntax

The code originally does iterate over all platforms (CPU, GPU etc), then selects one based on the input from the user (maybe i’m incoreect?).

You may need to explicitly cast the platform to a cl_context_properties type:

cl_context_properties properties[3] = {CL_CONTEXT_PLATFORM, (cl_context_properties)platform, 0};

ok thanks now it compiled fine. However, the problem still remains, No GPU devices found (same output as before). Are you able to run this code on your side?

Yes, I’ve just tried this and it works (with the change that I suggested).

You can check whether the issue is with the context creation by explicitly querying the number of devices in the platform:

cl_uint numDevices;
clGetDeviceIDs(platform, CL_DEVICE_TYPE_GPU, 0, NULL, &numDevices);
printf("Number of devices = %d
", numDevices);

If this also reports 0 devices, then there may be an issue with your driver installation.

It’s also possible that there are multiple OpenCL platforms installed on your system, and the first one isn’t NVIDA. You can print out the name of the platform like this:

char platformName[256];
clGetPlatformInfo(platform, CL_PLATFORM_NAME, 256, platformName, NULL);
printf("Platform name = %s
", platformName);

Well I do get the Number of Devices = 1.

For the second code to see if there are multiple OpenCL platforms, the code compiles, however then it doesn’t output anything when I run the executable.

ok here’s a much much simpler program that i’m trying to run (simple vector addition on the GPU):
https://code.google.com/p/opencl-book-samples/source/browse/trunk/src/Chapter_12/VectorAdd/vecadd.cpp?r=2

I get the error:
ERROR: clBuildProgram(-11)

I also tried histogram from the same repo, and still ended up getting the same build program error.

The error code -11 corresponds to CL_BUILD_PROGRAM_FAILURE, which indicates that the kernel code failed to compile. To see the compilation errors, you need to request the build log:

try
{
  program.build(devices);
}
catch (cl::Error error)
{
  if (error.err() == CL_BUILD_PROGRAM_FAILURE)
  {
    std::string log = program.getBuildInfo<CL_PROGRAM_BUILD_LOG>(devices[0]);
    std::cerr << log << std::endl;
  }
  throw(error);
}

ok thanks, it worked!