我有最新的mac pro(操作系统:10.12.2),使用intel集成的GPU HD 530(Gen9)运行OpenCL代码。在我的OpenCL代码中,我使用vloadx和atomic_add指令。将我的OpenCL内核代码更改为像https://developer.apple.com/library/content/samplecode/OpenCLOfflineCompilation/Introduction/Intro.html#//apple_ref/doc/uid/DTS40011196-Intro-DontLinkElementID_2这样的bitcode
。并使用clCreateProgramWithBinary创建程序。但是当clBuildProgram时,它返回错误-11。而构建日志是"
错误:对_Z6vload2mPKU3AS1h()'
undefined reference to
_ Z8atom_addPVU3AS3ii()'的未定义引用
"
但在HD 5500(Gen8)的Mac air中,代码还可以。
有人可以告诉我该怎么办?
答案 0 :(得分:0)
问题在于,您不能在不同的设备中使用不兼容的二进制文件。这意味着如果您为Intel编译,则不能使用已编译的二进制文件用于AMD。您需要做的是每次从源代码编译特定设备的代码。
如果您不想在不同的文件中使用OpenCL代码,您可以通过对它们进行字符串化将它们放在源文件中。您可以使用主机代码中的内核字符串作为内核字符串传递,而不是读取文件。这将允许您保护您的IP。但是,每次都需要使用clBuildProgram
构建代码。您还可以将构建的程序保存为二进制文件,因此在第一次运行后,您不会通过每次构建来降低性能。举个例子,假设您有一个kernel.cl文件,如下所示:
__kernel void foo(__global int* in, __global int* out)
{
int idx = get_global_id(0);
out[idx] = in[idx] * in[idx];
}
您可能通过以下内容读取文件来获取此内核代码:
char *source_str;
fp = fopen("kernel.cl", "r");
source_str = (char *)malloc(MAX_SOURCE_SIZE);
source_size = fread(source_str, 1, MAX_SOURCE_SIZE, fp);
fclose(fp);
program = clCreateProgramWithSource(context, 1, (const char **)&source_str, (const size_t *)&source_size, &ret);
你可以做的是:
const char* src = "__kernel void foo(__global int* in, __global int* out)\
{\
int idx = get_global_id(0);\
out[idx] = in[idx] * in[idx];\
}";
program = clCreateProgramWithSource(context, 1, (const char **)&src, (const size_t *)&src_size, &ret);
编译C代码时,此字符串将转换为二进制文件,因此您可以保护源代码。