OpenCL简单的“Hello World!”程序编译正确,但执行时会吐出垃圾。 但是,Nvidia驱动程序已安装

我有这个职位上完全相同的问题:

OpenCL简单的“Hello World!” 程序编译正确,但执行时吐出垃圾

但我实际上已经安装了Nvidia驱动程序。

我想得到这个程序的工作: http : //www.fixstars.com/en/opencl/book/OpenCLProgrammingBook/first-opencl-program/

所以我得到了来自https://www.khronos.org/的头文件

我编译它是这样的:

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

这是输出:

hello.c:在函数'main'中:

hello.c:56:1:警告:不推荐使用“clCreateCommandQueue”(在/usr/include/CL/cl.h:1359声明)[-Wdeprecated-declarations]

hello.c:75:1:警告:不推荐使用“clEnqueueTask”(在/usr/include/CL/cl.h:1373声明)[-Wdeprecated-declarations]

如果我运行程序,我会得到:

这是我的设置:

OpenSuse 12.3

通过yast安装的Nvidia驱动程序:

nvidia-computeG03 340.65-32.1

glxinfo |的输出 grep -i供应商:

服务器glx供应商string:NVIDIA公司客户端glx供应商string:NVIDIA公司OpenGL供应商string:NVIDIA公司

输出lspci -nnk | grep -i vga -A3

03:00.0 VGA兼容控制器:NVIDIA公司GF119 [Quadro NVS 310] [10de:107d](rev a1)

子系统:NVIDIA公司设备[10de:094e]

正在使用的内核驱动程序:nvidia

03:00.1audio设备[0403]:NVIDIA公司GF119 HDMIaudio控制器[10de:0e08](rev a1)

也许openCL不使用的NVIDIA驱动程序,但我不知道如何检查这一点。 我希望有一个人可以帮助我。

谢谢。


编辑12.02.15 17:08

非常感谢jprice,

我用你的function来绘制错误信息。 我的代码如下所示:

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

我得到这个输出:

运行期间出错'clGetPlatformIDs':-1001

按照build议查看CL.h后,似乎没有find任何设备。

从cl.h:

#define CL_DEVICE_NOT_FOUND -1

正如我已经发布,我在我的系统中有一个Quadro NVS 310在列表中的兼容设备。 你有什么想法是什么问题?

这是我编译的竞争代码:

 #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; }´ 

更新13.02.15感谢您的build议。

我检查了/etc/OpenCL/vendors/nvidia.icd是否存在。 它的确如此:

 libnvidia-opencl.so.1 

图书馆存在于

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

我不明白的是,我可以编译代码和库lopencl被find。 我通过yast安装驱动程序,并手动将头文件手动复制到usr / include。 我还没有安装cuda软件包,因为我只是想使用opencl。 这可能是问题吗?

谢谢

您正在使用的示例代码无法检查所有OpenCL API调用返回的错误代码。 一个或多个这些功能可能失败,但是您的代码只是忽略了失败并试图继续。

我通常在这样的效用函数中包装OpenCL错误检查:

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

然后你可以添加错误检查到你的代码是这样的:

 /* 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 coreel Program from the source */ program = clCreateProgramWithSource(context, 1, (const char **)&source_str, (const size_t *)&source_size, &ret); checkError(ret, "creating program"); /* Build coreel Program */ ret = clBuildProgram(program, 1, &device_id, NULL, NULL, NULL); checkError(ret, "building program"); // etc 

现在,当OpenCL API调用失败时,您的程序将打印出哪个函数失败以及错误代码是什么。 您可以在CL/cl.h头文件中查找错误代码的人类可读名称,并阅读OpenCL规范以找出导致该错误的原因。 您也可以在checkError函数中创建一个查找表来自动检索人类可读的名称。