0
votes

Taken from OpenCL by Action

The following code achieves the target shown in the figure. It creates two buffer objects and copies the content of Buffer 1 to Buffer 2 with clEnqueueCopyBuffer.

Then clEnqueueMapBuffer maps the content of Buffer 2 to host memory and memcpy transfers the mapped memory to an array.

enter image description here

My question is will my code still work If I do not write the following lines in the code:

    err = clSetKernelArg(kernel, 0, sizeof(cl_mem),  
                 &buffer_one);                     
    err |= clSetKernelArg(kernel, 1, sizeof(cl_mem), 
                  &buffer_two);              
    queue = clCreateCommandQueue(context, device, 0, &err);
    err = clEnqueueTask(queue, kernel, 0, NULL, NULL);     

The kernel is blank, it's doing nothing. What is the need of setting kernel argument, and enqueueing the task?

...
float data_one[100], data_two[100], result_array[100];
cl_mem buffer_one, buffer_two;
void* mapped_memory;
...

 buffer_one = clCreateBuffer(context,           
  CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR,             
  sizeof(data_one), data_one, &err);       
 buffer_two = clCreateBuffer(context,                  
  CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR,       
  sizeof(data_two), data_two, &err);  



  err = clSetKernelArg(kernel, 0, sizeof(cl_mem),  
                 &buffer_one);                     
  err |= clSetKernelArg(kernel, 1, sizeof(cl_mem), 
                  &buffer_two);              
 queue = clCreateCommandQueue(context, device, 0, &err);
 err = clEnqueueTask(queue, kernel, 0, NULL, NULL);     



 err = clEnqueueCopyBuffer(queue, buffer_one,  
  buffer_two, 0, 0, sizeof(data_one),           
  0, NULL, NULL);            



  mapped_memory = clEnqueueMapBuffer(queue, 
  buffer_two, CL_TRUE, CL_MAP_READ, 0,            
  sizeof(data_two), 0, NULL, NULL, &err);
  memcpy(result_array, mapped_memory, sizeof(data_two));       
  err = clEnqueueUnmapMemObject(queue, buffer_two, 
  mapped_memory, 0, NULL, NULL);                  
  }

...

1

1 Answers

0
votes

I believe the point of calling the enqueueTask would be to ensure that the data is actually resident on the device. It is possible that when using the CL_MEM_COPY_HOST_PTR flag that the memory is still kept on the host side until it is needed by a kernel. Enqueueing the task therefore ensures that the memory is brought to the device. This may also happen on some devices but not others.

You could test this theory by instrumenting your code and measuring the time taken to run the task, both when the task has arguments, and when it does not. If the task takes significantly longer with arguments, then this is likely what is going on.