微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

clBuildProgram() 在 Mac (Catalina) 上使用 clang 总是返回 -11; clGetProgramBuildInfo() 返回空字符串

如何解决clBuildProgram() 在 Mac (Catalina) 上使用 clang 总是返回 -11; clGetProgramBuildInfo() 返回空字符串

我有一台运行 macOS Catalina (10.16.7) 的 2019 款 MacBook Pro,这台机器配备了 AMD Radeon Pro 5300M 和板载英特尔 UHD 显卡。我正在尝试使用 Clang 构建一个“Hello World”OpenCL 程序(我能够很好地查询平台和设备信息),但我永远无法成功完成 clBuildProgram。如果我尝试在另一台(非 Mac)机器上编译和运行该程序,它会编译并运行良好。

在下面的代码中,我想我正在为 cpu 获取设备,但无论我选择哪种设备,我都会收到相同的错误。如果我尝试编译并运行我从 Internet 下载的其他几个“Hello World”openCL 示例,我也会遇到同样的错误。所以我认为我编译程序的方式或其他配置有问题。我不知道从这里去哪里。有什么想法吗?

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

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

#define MAX_NUM_DEVICES_PER_PLATFORM 128
#define MEM_SIZE 128

int main() {
    static const char source[] =
        "__kernel void hello(__global char* string)\n"
        "{\n"
        "    string[0] = 'H';  string[1] = 'e'; string[2] = 'l';  string[3] = 'l';\n"
        "    string[4] = 'o';  string[5] = ','; string[6] = ' ';  string[7] = 'W';\n"
        "    string[8] = 'o';  string[9] = 'r'; string[10] = 'l'; string[11] = 'd';\n"
        "    string[12] = '!'; string[13] = '\\0';\n"
        "}";

    // Get OpenCL device and create an OpenCL context
    cl_platform_id platforms;  cl_uint numPlatforms;
    cl_int ret = clGetPlatformIDs(1,&platforms,&numPlatforms);

    cl_uint numDevices;  cl_device_id devices[MAX_NUM_DEVICES_PER_PLATFORM];
    clGetdeviceids(platforms,CL_DEVICE_TYPE_ALL,MAX_NUM_DEVICES_PER_PLATFORM,devices,&numDevices);
    cl_device_id device = devices[0];

    cl_context context = clCreateContext(NULL,1,&device,NULL,&ret);

    cl_command_queue commandQueue = clCreateCommandQueue(context,device,&ret);
    cl_mem memBuffer = clCreateBuffer(context,CL_MEM_READ_WRITE,MEM_SIZE * sizeof(char),NULL);

    // Build program
    size_t programSize;
    const char *src=source;
    size_t srcsize = strlen(source);
    cl_program program = clCreateProgramWithSource(context,(const char**)&src,&srcsize,NULL);

    if(program == NULL) {
        fprintf(stderr,"Unable to create OpenCL program.\n");
        exit(1);
    }

    cl_int errNum = clBuildProgram(program,NULL);
    if (errNum != CL_SUCCESS) {
        fprintf(stderr,"Unable to build OpenCL program (error %i)\n",errNum);
        size_t len = 0;
        cl_int ret = CL_SUCCESS;
        ret = clGetProgramBuildInfo(program,CL_PROGRAM_BUILD_LOG,&len);
        char *buffer = calloc(len,sizeof(char));
        ret = clGetProgramBuildInfo(program,len,buffer,NULL);
        fprintf(stderr,"Error: %s\n",buffer);
        exit(1);
    }

    cl_kernel kernel = clCreateKernel(program,"hello",NULL);
    ret = clSetKernelArg(kernel,sizeof(cl_mem),(void *)&memBuffer);

    // Run the kernel
    ret = clEnqueueTask(commandQueue,kernel,NULL);
     
    // Get results from memory buffer
    char string[MEM_SIZE];
    ret = clEnqueueReadBuffer(commandQueue,memBuffer,CL_TRUE,string,NULL);
    puts(string);

    return 0;
}

如果我编译并运行,我会得到以下输出

+ clang hello.c -framework opencl -o hello
+ ./hello
Unable to build OpenCL program (error -11)
Error:

解决方法

使用 clang 或其他编译器构建主机代码与用于构建 OpenCL 内核的编译器无关。

该程序尝试为所有可用的 OpenCL 平台构建 OpenCL 内核,在本例中可以是 AMD GPU、Intel GPU 和 Intel CPU。我建议尝试为一个特定的对象进行构建,例如:

ret = clBuildProgram(program,1,&device_id,"-I. -Werror",NULL,NULL);

除此之外,还有很多关于 Mac 上 OpenCL 实现问题的帖子,您可能也想搜索一下。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。