OpenCL-CTS icon indicating copy to clipboard operation
OpenCL-CTS copied to clipboard

Compiling programs for only a subset of devices in context causes clCreateKernelsInProgram to fail on some drivers

Open jansol opened this issue 2 years ago • 0 comments

The following sample code fails with CL_INVALID_KERNEL_DEFINITION in clCreateKernelsInProgram on some implementations. According to my understanding of the spec this is perfectly valid API usage.

Assuming this is intended to be valid use, it would probably be good to have some tests for it since it's niche enough that problems will likely go unnoticed for a long time.

#include <CL/opencl.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>

#define STR(x) #x

#define CHECK(x) \
do { \
  err = (x);  \
  if (err != CL_SUCCESS) { \
          printf("CL error %d in "__FILE__":%d: %s\n", err, __LINE__, STR(x)); \
	  return -1;\
  } \
} while (0)

int main (int argc, const char * argv) {
    cl_int err;
    cl_uint num_platforms;
    CHECK( clGetPlatformIDs(0, NULL, &num_platforms) );
    cl_platform_id *platforms = (cl_platform_id*)malloc(sizeof (cl_platform_id) * num_platforms);
    CHECK( clGetPlatformIDs(num_platforms, platforms, NULL) );

    cl_uint num_devices;
    CHECK( clGetDeviceIDs(platforms[0], CL_DEVICE_TYPE_ALL, 0, NULL, &num_devices) );
    cl_device_id *devices = (cl_device_id*)malloc(sizeof (cl_device_id) * num_devices);
    CHECK( clGetDeviceIDs(platforms[0], CL_DEVICE_TYPE_ALL, num_devices, devices, NULL) );
    assert (num_devices > 1);

    cl_context ctx = clCreateContext(NULL, num_devices, devices, NULL, NULL, &err);
    CHECK(err/*clCreateContext*/);

    const char *clsrc = "kernel void incr(global int *a) { *a = *a+1; }";
    cl_program prog = clCreateProgramWithSource(ctx, 1, &clsrc, NULL, &err);
    CHECK(err/*clCreateProgram*/);
    CHECK( clBuildProgram(prog, 1, &devices[1], NULL, NULL, NULL) );

    cl_uint num_kernels;
    CHECK( clCreateKernelsInProgram(prog, 0, NULL, &num_kernels) );
    cl_kernel *kernels = (cl_kernel*)malloc(sizeof (cl_kernel) * num_kernels);
    CHECK( clCreateKernelsInProgram(prog, num_kernels, kernels, NULL) );

    printf("All is well, exiting.\n");

    return 0;
}

jansol avatar Mar 03 '23 13:03 jansol