构建OpenCL内核失败

4

当我在我的OpenCl代码中使用clBuildProgram时,它会失败,并显示错误代码-11,但没有任何日志信息。

以下是我的代码示例:

  ret = clBuildProgram(program, 1, &device_id, NULL, NULL, NULL);

  if (ret != CL_SUCCESS)
    {
        size_t len;
        char buffer[2048];
    cl_build_status bldstatus;
    printf("\nError %d: Failed to build program executable [ %s ]\n",ret,get_error_string(ret));
        ret = clGetProgramBuildInfo(program, device_id, CL_PROGRAM_BUILD_STATUS, sizeof(bldstatus), (void *)&bldstatus, &len);
        printf("Build Status %d: %s\n",ret,get_error_string(ret));
    printf("INFO: %s\n", get_error_string(bldstatus));
        ret = clGetProgramBuildInfo(program, device_id, CL_PROGRAM_BUILD_OPTIONS, sizeof(buffer), buffer, &len);
        printf("Build Options %d: %s\n",ret,get_error_string(ret));
    printf("INFO: %s\n", buffer);   
        ret = clGetProgramBuildInfo(program, device_id, CL_PROGRAM_BUILD_LOG, sizeof(buffer), buffer, &len);    
    printf("Build Log %d: %s\n",ret,get_error_string(ret));
    printf("%s\n", buffer);
    (void)infoinfo(platform_id,device_id);
    exit(1);
    }

以下是输出的样例:
Error -11: Failed to build program executable [ CL_BUILD_PROGRAM_FAILURE ]
Build Status 0: CL_SUCCESS
INFO: CL_DEVICE_NOT_AVAILABLE
Build Options 0: CL_SUCCESS
INFO: 
Build Log -30: CL_INVALID_VALUE


CL_PLATFORM_NAME : NVIDIA CUDA
CL_PLATFORM_VERSION : OpenCL 1.1 CUDA 4.2.1
Device name : Tesla K20m
Driver version : 319.32
Global Memory (MB) : 4799
Global Memory Cache (KB) : 208
Local Memory (KB) : 48
Max clock (MHz) : 705
Max Work Group Size : 1024
Number of parallel compute cores : 13
Is the device available : yes

那么,你们能否偶然发现上面的行中有任何错误或奇怪的地方吗?

谢谢,

Éric。


有人在欺骗你。设备是否可用,正如您的infoinfo函数所说,还是不可用,就像get_error_string(bldstatus)所说的那样?需要更多的代码吗? - Michael Haidl
我认为问题可能出在我的 clGetProgramBuildInfo 调用方式或者是 get_error_string 子程序中使用的错误码定义上。实际上,get_error_string 子程序返回与 OpenCl 错误码对应的字符串。但该代码可能与 cl_build_status 代码不对应! - Éric
2个回答

7
看起来你可能错误地使用了clGetProgramBuildInfo()。第一次调用它时,应该告诉主机需要的缓冲区大小: clGetProgramBuildInfo(program, device_id, CL_PROGRAM_BUILD_LOG, NULL, NULL, &len); 然后在主机上分配内存: char *log = new char[len] //或者你使用的其他方法 接着重新调用clGetProgramBuildInfo(): clGetProgramBuildInfo(program, device_id, CL_PROGRAM_BUILD_LOG, len, log, null);

我使用Austin的建议更新了我的代码。它运行得非常好。谢谢。 - Éric
嗨,Eric,几乎所有查询设备的OpenCL函数都是这样的:从设备请求信息大小,在主机上分配内存,将信息从设备复制到主机。 - Austin

1

我已经修改了代码并增加了缓冲区大小:

  ret = clBuildProgram(program, 1, &device_id, NULL, NULL, NULL);

  if (ret != CL_SUCCESS)
    {
        size_t len;
        char buffer[204800];
    cl_build_status bldstatus;
    printf("\nError %d: Failed to build program executable [ %s ]\n",ret,get_error_string(ret));
        ret = clGetProgramBuildInfo(program, device_id, CL_PROGRAM_BUILD_STATUS, sizeof(bldstatus), (void *)&bldstatus, &len);
        if (ret != CL_SUCCESS)
          {
        printf("Build Status error %d: %s\n",ret,get_error_string(ret));
        exit(1);
      }     
    if (bldstatus == CL_BUILD_SUCCESS) printf("Build Status: CL_BUILD_SUCCESS\n");
    if (bldstatus == CL_BUILD_NONE) printf("Build Status: CL_BUILD_NONE\n"); 
    if (bldstatus == CL_BUILD_ERROR) printf("Build Status: CL_BUILD_ERROR\n");
    if (bldstatus == CL_BUILD_IN_PROGRESS) printf("Build Status: CL_BUILD_IN_PROGRESS\n");  
        ret = clGetProgramBuildInfo(program, device_id, CL_PROGRAM_BUILD_OPTIONS, sizeof(buffer), buffer, &len);
        if (ret != CL_SUCCESS)
          {
        printf("Build Options error %d: %s\n",ret,get_error_string(ret));
        exit(1);
      }        
    printf("Build Options: %s\n", buffer);  
        ret = clGetProgramBuildInfo(program, device_id, CL_PROGRAM_BUILD_LOG, sizeof(buffer), buffer, &len);    
        if (ret != CL_SUCCESS)
          {
        printf("Build Log error %d: %s\n",ret,get_error_string(ret));
        exit(1);
      }     
    printf("Build Log:\n%s\n", buffer);
    exit(1);
    }

我现在得到这个:

Error -11: Failed to build program executable [ CL_BUILD_PROGRAM_FAILURE ]
Build Status: CL_BUILD_ERROR
Build Options:
Build Log:
:4:85: error: must specify ....

所以它可以工作。

感谢您的帮助。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接