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

Posted

技术标签:

【中文标题】clBuildProgram() 在 Mac (Catalina) 上使用 clang 总是返回 -11; clGetProgramBuildInfo() 返回空字符串【英文标题】:clBuildProgram() always returns -11 on Mac (Catalina) using clang; clGetProgramBuildInfo() returns empty string 【发布时间】:2021-09-10 22:55:57 【问题描述】:

我有一台运行 macOS Catalina (10.16.7) 的 2019 款 MacBook Pro,该机器配备 AMD Radeon Pro 5300M 以及板载 Intel 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, NULL, &ret);

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

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

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

    cl_int errNum = clBuildProgram(program, 0, NULL, NULL, NULL, 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, device, CL_PROGRAM_BUILD_LOG, 0, NULL, &len);
        char *buffer = calloc(len, sizeof(char));
        ret = clGetProgramBuildInfo(program, device, CL_PROGRAM_BUILD_LOG, len, buffer, NULL);
        fprintf(stderr, "Error: %s\n", buffer);
        exit(1);
    

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

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

    return 0;

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

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

【问题讨论】:

试用Apple的示例,它有完整的Xcode项目developer.apple.com/library/archive/samplecode/… 【参考方案1】:

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

程序尝试为所有可用的 OpenCL 平台构建 OpenCL 内核,在这种情况下可以是 AMD GPU、Intel GPU 和 Intel CPU。我建议尝试构建一个特定的,例如:

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

除了有很多关于在 Mac 上实现 OpenCL 的问题的帖子,你可能也想搜索一下。

【讨论】:

以上是关于clBuildProgram() 在 Mac (Catalina) 上使用 clang 总是返回 -11; clGetProgramBuildInfo() 返回空字符串的主要内容,如果未能解决你的问题,请参考以下文章

OpenCL clBuildProgram 在 OS X 上的 AMD GPU 上失败,并带有非描述性构建日志

获取ip地址对应的mac地址,c/c++编程实现,linux下

在mac上编译C++11代码?

如何在 Unix 控制台/Mac 终端中编译和运行 C/C++?

mac系统vscode配置c/c++环境

C/C++ Linux,如何在不使用 IP 的情况下在网络上查找邻居(仅限 MAC)