4

I am trying to pass an array to OpenCL kernel, then do something with it and pass it back to host. I have modified code in this tutorial.

This is just kernel for figuring out how OpenCL actually works. I hope that this would just substract 2 from the first element of array1 and store it into the first element of array2:

__kernel void test(global int* array1, global int* array2) {
    array2[0] = array1[0] - 2;
}

In main I have two arrays, one (host1) with some numbers and the second (host2) initialized to zeros. Than to create memory buffers I use:

memobj = clCreateBuffer(context, CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR, MEM_SIZE * sizeof(int), &host1, &ret);
memobj2 = clCreateBuffer(context, CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR, MEM_SIZE * sizeof(int), &host2, &ret);

After building program I set arguments:

ret = clSetKernelArg(kernel, 0, sizeof(cl_mem), &host1);
ret = clSetKernelArg(kernel, 1, sizeof(cl_mem), &host2);

And then after execution I try to get that array back.

ret = clEnqueueReadBuffer(command_queue, memobj2, CL_TRUE, 0, MEM_SIZE * sizeof(int), host2, 0, NULL, NULL);

Here if I change memobj2 to memobj the host2 will contain values of host1, otherwise it stays the same. I guess that this is not how one will return arrays.

I am stuck at this point.

9
  • How do you execute the kernel? You should give it a local and global work size of 1x1x1. Also: Do you check every single return value against errors? Commented Dec 23, 2013 at 21:06
  • @leemes Like in tutorial ret = clEnqueueTask(command_queue, kernel, 0, NULL,NULL); Commented Dec 23, 2013 at 21:07
  • Ok that's actually equivalent to clEnqueueNDRangeKernel with a range of 1x1x1 I was talking about. Now about the errors, do you check them all? Commented Dec 23, 2013 at 21:08
  • 1
    Every cl* function returns an error code (or almost every). You should check this error. Your tutorial doesn't, and that's bad. You could add something like this to your project and wrap every cl call in some function void check(cl_int e) { if (e) { throw std::runtime_error(get_error_string(e)); } } or similar; so all your calls look like check(clCreateBuffer(...)); Commented Dec 23, 2013 at 21:21
  • 1
    I guess it's __global, not global Commented Dec 23, 2013 at 21:38

1 Answer 1

6

Your calls to clSetKernelArg() are invalid - you should be passing the OpenCL buffer, not the host pointer. For example:

ret = clSetKernelArg(kernel, 0, sizeof(cl_mem), &memobj);
ret = clSetKernelArg(kernel, 1, sizeof(cl_mem), &memobj2);

As was already pointed out, you should check the return codes from every OpenCL runtime API call. This would point you towards the error pretty quickly.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.