Having trouble compiling code with two kernels in a file

Just getting started on OpenCL, and I’ve encountered a peculiar problem. I can’t reliably compile a program containing two kernels read from a file. Here’s what the file contains (two identical kernels, with different names):

__kernel void
simple_add(__global const int* A,
           __global const int* B,
           __global int* C)
{
    C[get_global_id(0)] = A[get_global_id(0)] + B[get_global_id(0)];
}

__kernel void
add_simple(__global const int* A,
           __global const int* B,
           __global int* C)
{
    C[get_global_id(0)] = A[get_global_id(0)] + B[get_global_id(0)];
}

The reading code simply reads the contents of the file as a string, constructs a program, and builds it. Most of the time, I get the following error:

No kernels or only kernel prototypes found when build executable.

Aside from the bad grammar, what is it trying to tell me?

The same code compiles fine when inlined, and (disturbingly) sometimes works even as is. If I remove one of the kernels, it always works.

Other things I’ve tried:

  • Using the double underscore, or not. Makes no difference.
  • Two different reading methods, with ifstream and with stdio. Makes no difference.

I’m on a Mac, with 10.10.5, and OpenCL 1.2. I’m using the C++ bindings from Khronos.

Any help would be appreciated.

As it happens, I was apparently using the OpenCL 1.1 compiler. Switched it to 1.2, and it appears to work correctly.

Still a bit puzzled.

-Arun

I figured out what the problem was. cl::Program::Sources doesn’t copy the string data – it’s just a vector of (const char *, size_t) pairs. The original string must stick around until you’re done.

I had implemented the creation of a program in a separate class, but the string read from file was being deallocated, causing intermittent failure.

API-wise, it’s a bit of a fail, although I get why you wouldn’t want to copy potentially large strings.

-Arun