buddy
buddy

Reputation: 1

MacOs OpenCL on HD 530 with clBuildProgram error(-11)

I have the latest mac pro(OS:10.12.2) ,with intel intergrated GPU HD 530(Gen9) which runs the OpenCL code. In my OpenCL code, I use vloadx and atomic_add instruction. change my OpenCL kernel code into bitcode like https://developer.apple.com/library/content/samplecode/OpenCLOfflineCompilation/Introduction/Intro.html#//apple_ref/doc/uid/DTS40011196-Intro-DontLinkElementID_2 . and create the program with clCreateProgramWithBinary. But when clBuildProgram, it returns error with -11 .and build log is " error: undefined reference to _Z6vload2mPKU3AS1h()' undefined reference to_Z8atom_addPVU3AS3ii()' " But in my mac air with HD 5500(Gen8), the code is ok. Can someone tell me what should I do?

Upvotes: 0

Views: 374

Answers (1)

parallel highway
parallel highway

Reputation: 354

The problem here is, you cannot use incompatible binaries in different devices. Which means if you compile for Intel, you cannot use the compiled binary for AMD for example. What you need to do is compile the code for the specific device every time from the source.

If you do not want to use the OpenCL codes in different files, what you can do is put them inside your source file by stringifying them. Instead of reading a file, you use the kernel string inside your host code to pass as the kernel string. This will allow you to protect your IP. However, everytime, you need to build the code using clBuildProgram. You can also save the built program as binary, so after the first run, you won't degrade performance by building it everytime. To give an example, lets suppose you have a kernel.cl file as following:

__kernel void foo(__global int* in, __global int* out)
{
  int idx = get_global_id(0);
  out[idx] = in[idx] * in[idx];
}

You probably get this kernel code by reading the file with something like:

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);

What you can do instead is something like:

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);

When you compile your C code, this string will be converted into binary, so you protect your source code.

Upvotes: 0

Related Questions