2
votes

I have the exact same problem like in this post:

OpenCL Simple "Hello World!" program compiles correctly but spits out garbage when executed

but I actually have installed the Nvidia drivers.

I want to get this program to work: http://www.fixstars.com/en/opencl/book/OpenCLProgrammingBook/first-opencl-program/

So I got the headerfiles from: https://www.khronos.org/

And I compiled it like this:

gcc -I /usr/include/ hello.c -L/usr/lib64 -lOpenCL

this is the output:

hello.c: In function ‘main’:

hello.c:56:1: warning: ‘clCreateCommandQueue’ is deprecated (declared at /usr/include/CL/cl.h:1359) [-Wdeprecated-declarations]

hello.c:75:1: warning: ‘clEnqueueTask’ is deprecated (declared at /usr/include/CL/cl.h:1373) [-Wdeprecated-declarations]

And if i run the program I get:

���-�

Here is my setup:

OpenSuse 12.3

Nvidia drivers installed via yast:

nvidia-computeG03 340.65-32.1

output of glxinfo | grep -i vendor:

server glx vendor string: NVIDIA Corporation client glx vendor string: NVIDIA Corporation OpenGL vendor string: NVIDIA Corporation

output of lspci -nnk | grep -i vga -A3

03:00.0 VGA compatible controller [0300]: NVIDIA Corporation GF119 [Quadro NVS 310] [10de:107d] (rev a1)

Subsystem: NVIDIA Corporation Device [10de:094e]

Kernel driver in use: nvidia

03:00.1 Audio device [0403]: NVIDIA Corporation GF119 HDMI Audio Controller [10de:0e08] (rev a1)

maybe openCL does not use the nvidia driver but I do not know how to check this. I hope someone can help me.

Thank you.


Edit 12.02.15 17:08

Thank you very much jprice,

I used your function to plot the error message. My code looks like this:

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

I get this output:

Error during operation 'clGetPlatformIDs': -1001

After looking in the CL.h as suggested it seems that no device was found.

From cl.h:

#define CL_DEVICE_NOT_FOUND -1

As I already posted, I have a Quadro NVS 310 in my system which is on the list for cl compatible devices. Do you have any idea what is going wrong?

Here is the compete CODE which I compile:

#include <stdio.h>
#include <stdlib.h>


#ifdef __APPLE__
#include <OpenCL/opencl.h>
#else
#include <CL/cl.h>
#endif

#define MEM_SIZE (128)
#define MAX_SOURCE_SIZE (0x100000)

void checkError(cl_int err, const char *operation)
{
  if (err != CL_SUCCESS)
  {
    fprintf(stderr, "Error during operation '%s': %d\n", operation, err);
    exit(1);
  }
}



int main()
{
cl_device_id device_id = NULL;
cl_context context = NULL;
cl_command_queue command_queue = NULL;
cl_mem memobj = NULL;
cl_program program = NULL;
cl_kernel kernel = NULL;
cl_platform_id platform_id = NULL;
cl_uint ret_num_devices;
cl_uint ret_num_platforms;
cl_int ret;

char string[MEM_SIZE];
char test_string[20];
/*strcpy(test_string, "ENDE");*/

FILE *fp;
char fileName[] = "./hello.cl";
char *source_str;
size_t source_size;

/* Load the source code containing the kernel*/
fp = fopen(fileName, "r");
if (!fp) {
fprintf(stderr, "Failed to load kernel.\n");
exit(1);
}
source_str = (char*)malloc(MAX_SOURCE_SIZE);
source_size = fread(source_str, 1, MAX_SOURCE_SIZE, fp);
fclose(fp);

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

ret = clGetDeviceIDs(platform_id, CL_DEVICE_TYPE_DEFAULT, 1, &device_id,     &ret_num_devices);
checkError(ret, "clGetDeviceIDs");

/* Create OpenCL context */
context = clCreateContext(NULL, 1, &device_id, NULL, NULL, &ret);
checkError(ret, "clCreateContext");

/* Create Command Queue */
command_queue = clCreateCommandQueue(context, device_id, 0, &ret);
checkError(ret, "clCreateCommandQueue");

/* Create Memory Buffer */
memobj = clCreateBuffer(context, CL_MEM_READ_WRITE,MEM_SIZE * sizeof(char),     NULL, &ret);
checkError(ret, "clCreateBuffer");

/* Create Kernel Program from the source */
program = clCreateProgramWithSource(context, 1, (const char **)&source_str,
(const size_t *)&source_size, &ret);
checkError(ret, "clCreateProgramWithSource");

/* Build Kernel Program */
ret = clBuildProgram(program, 1, &device_id, NULL, NULL, NULL);
checkError(ret, "clBuildProgram");

/* Create OpenCL Kernel */
kernel = clCreateKernel(program, "hello", &ret);
checkError(ret, "clCreateKernel");

/* Set OpenCL Kernel Parameters */
ret = clSetKernelArg(kernel, 0, sizeof(cl_mem), (void *)&memobj);
checkError(ret, "clSetKernelArg");

/* Execute OpenCL Kernel */
ret = clEnqueueTask(command_queue, kernel, 0, NULL,NULL);
checkError(ret, "clEnqueueTask");

/* Copy results from the memory buffer */
ret = clEnqueueReadBuffer(command_queue, memobj, CL_TRUE, 0,
MEM_SIZE * sizeof(char),string, 0, NULL, NULL);

/* Display Result */
puts(string);


/* Finalization */
ret = clFlush(command_queue);
ret = clFinish(command_queue);
ret = clReleaseKernel(kernel);
ret = clReleaseProgram(program);
ret = clReleaseMemObject(memobj);
ret = clReleaseCommandQueue(command_queue);
ret = clReleaseContext(context);

free(source_str);

return 0;
}´

UPDATE 13.02.15 Thank you for your advise.

I checked if the /etc/OpenCL/vendors/nvidia.icd exists. It does and it looks like this:

libnvidia-opencl.so.1

The library exists in

/usr/lib64/libnvidia-opencl.so.1

What I do not understand is, that I can compile the code and the library lopencl is found. I installed the driver via yast and solely copied the header files manually to usr/include. I have not installed the cuda package yet, because I just want to use opencl. Could this be the problem?

Thank you

1
And what does the code do? Please show it.Some programmer dude
-1001 is GPU not supported. Something is still wrong with your driver installation.user58697
-1001 means that there were no OpenCL platforms found. Check that you have a /etc/OpenCL/vendors/nvidia.icd file, and look at its contents, which should be the name of the NVIDIA OpenCL library (typically libnvidia-opencl.so), and make sure that this library exists (it should be installed by the NVIDIA driver, but there could be some broken symlinks).jprice

1 Answers

2
votes

The example code you are working from fails to check the error codes that are returned by all of the OpenCL API calls. One or more of these functions are likely failing, but your code is just ignoring the failures and trying to continue.

I typically wrap up OpenCL error checking in a utility function like this:

void checkError(cl_int err, const char *operation)
{
  if (err != CL_SUCCESS)
  {
    fprintf(stderr, "Error during operation '%s': %d\n", operation, err);
    exit(1);
  }
}

Then you can add error checking to your code like this:

/* Create OpenCL context */
context = clCreateContext(NULL, 1, &device_id, NULL, NULL, &ret);
checkError(ret, "creating context");

/* Create Command Queue */
command_queue = clCreateCommandQueue(context, device_id, 0, &ret);
checkError(ret, "creating command queue");

/* Create Memory Buffer */
memobj = clCreateBuffer(context, CL_MEM_READ_WRITE,MEM_SIZE * sizeof(char), NULL, &ret);
checkError(ret, "creating buffer");

/* Create Kernel Program from the source */
program = clCreateProgramWithSource(context, 1, (const char **)&source_str,
                                    (const size_t *)&source_size, &ret);
checkError(ret, "creating program");

/* Build Kernel Program */
ret = clBuildProgram(program, 1, &device_id, NULL, NULL, NULL);
checkError(ret, "building program");

// etc 

Now when an OpenCL API call fails, your program will print out which function failed and what the error code was. You can look up the human-readable name of the error code in the CL/cl.h header, and read the OpenCL specification to find out what causes that error. You could also create a look-up table in the checkError function to automatically retrieve the human-readable name.