I'm trying to run a basic kernel in OpenCL. See the snipped attached
const char kernel_source[] = "__kernel void matmul(__global float* A, __global float* B, __global float* C) { int row = get_global_id(0); int col = get_global_id(1); int N = get_global_size(0); int idx = (row * N) + col; for (int i = 0; i < N; i++) { C[idx] += A[row * N + i] * B[i * N + col]; } }";
void check_error(cl_int err, char step[]);
int check_result(float mat_a[NUM_ROWS][NUM_COLS], float mat_b[NUM_ROWS][NUM_COLS], float mat_c[NUM_ROWS][NUM_COLS]);
int main()
{
// Set up platform, device and context
cl_int CL_err = CL_SUCCESS;
cl_platform_id platform;
CL_err = clGetPlatformIDs(1, &platform, NULL);
check_error(CL_err, "Couldn't find platform");
cl_device_id device;
CL_err = clGetDeviceIDs(platform, CL_DEVICE_TYPE_GPU, 1, &device, NULL);
check_error(CL_err, "Couldn't find device");
cl_context context = clCreateContext(NULL, 1, &device, NULL, NULL, &CL_err);
check_error(CL_err, "Couldn't create context");
cl_command_queue command_queue = clCreateCommandQueue(context, device, 0, &CL_err);
check_error(CL_err, "Couldn't create command queue");
cl_program program = clCreateProgramWithSource(context, 1, (const char**)&kernel_source, NULL, &CL_err);
check_error(CL_err, "Couldn't create the program");
As it is, I get a read access violation on clCreateProgramWithSource. I tried removing the const qualifier and moving the string declaration into function scope but got the same issue either way. String literals are guaranteed to be null terminated by C, but I also did try passing in the length explicitly.
However, I switched to C++ and used the cl::Program constructor to build the kernel and the kernel compiled without issue. Later, in the same C program, I dynamically allocated the same string like so
int length = strlen(kernel_source);
char* temp = malloc(length + 1);
if (temp == NULL) {
return -1;
}
memcpy(temp, kernel_source, length + 1);
I passed in a pointer to the dynamically allocated string instead and this also fixed the issue. Note that with the C++ wrapper, the actual call to clCreateProgramWithSource has the same arguments that my C code does, but with a new copy of the string - since the string is converted to an std::string and then back to a C-string.
Does Visual Studio treat strings differenly than other compilers and make it somehow inaccessible to OpenCL? I've seen many examples online of kernel source code being passed in the same way.