1
votes

I'm very beginner with OpenCL. To learn the basics of the library I tried to execute the first program at the following URL :

https://www.olcf.ornl.gov/tutorials/opencl-vector-addition/

I previously linked the openCL include and libraries from the NVIDIA GPU Computing SDK and of course the compilation of the program is ok. However if I run it the execution fails within the clCreateContext function.

// Bind to platform
err = clGetPlatformIDs(1, &cpPlatform, NULL);

// Get ID for the device
err = clGetDeviceIDs(cpPlatform, CL_DEVICE_TYPE_GPU, 1, &device_id, NULL);

// Create a context  
context = clCreateContext(0, 1, &device_id, NULL, NULL, &err);

The problem comes from the previous method clGetDeviceIDs which seems not feel the device_id variable (if a replace in the function clGetDeviceIDs the flag CL_DEVICE_TYPE_GPU by CL_DEVICE_TYPE_CPU the program works perfectly). Nevertheless, my graphic card drivers have been updated. According to the execution, it would appear that I don't have any GPU device on my computer. It's very strange. Do you think my drivers are not correct and there is a miss of dependencies? I'm really lost. Does anyone can help me, please?

Thanks a lot in advance for your help.

2

2 Answers

3
votes

Did you check to make sure that you have only 1-platform defined?

cl_uint nPlatforms;
cl_uint err = CL_SUCCESS;
err = clGetPlatformIDs(1, NULL, &nPlatforms);

If more than one platform you can do this:

cl_platform_id* platformID_Array;
platformID_Array = (cl_platform_id *)malloc(sizeof(cl_platform_id)*nPlatforms);
err = CL_SUCCESS;
err = clGetPlatformIDs(nPlatforms, platformID_Array, NULL);

And then check the names:

for (cl_uint i = 0; i < nPlatforms; i++) {
    size_t vendorSize;
    char* vendorCstring;
    err = clGetPlatformInfo(platformID_Array[i], CL_PLATFORM_VENDOR, 0, NULL, &vendorSize);
    vendorCstring = (char*)malloc(sizeof(char)*vendorSize);
    err = clGetPlatformInfo(platformID_Array[i], CL_PLATFORM_VENDOR, vendorSize, vendorCstring, NULL);
    printf("Platform name = %s\n",vendorCstring);
}

You could also try:

err = clGetDeviceIDs(NULL, CL_DEVICE_TYPE_GPU, 1, &device_id, NULL); 

noting the NULL argument for the platform ID. In that case, the behavior is implementation-defined so you can then see which device is supported. I suspect that you will get back a CPU Device but its worth checking.

2
votes

If as you said, the option CL_DEVICE_TYPE_CPU works for you, then the platform you are getting does not have a GPU device.

You should try another platform, since Intel and nVIDIA devices are in separate platforms.

You could try with err = clGetPlatformIDs(2, &cpPlatform, NULL); and get two platforms instead of 1, or with another more clever algorithm to find a valid GPU accross all the platforms available.

Definitely it is NOT a linking or compiling issue, since the methods work OK.

I would do it this way:

// Num of platforms
int numplat;
err = clGetPlatformIDs(0, NULL, &numplat);

// Num of platforms
int cpPlat[numplat];
err = clGetPlatformIDs(numplat, &cpPlat, NULL);

// Get ID for the device
for(int i=0; i<numplat; i++){
    err = clGetDeviceIDs(cpPlatform[i], CL_DEVICE_TYPE_GPU, 1, &device_id, NULL);
    if (err == CL_SUCCESS )
       break;
}

// Create a context  
context = clCreateContext(0, 1, &device_id, NULL, NULL, &err);