To create a cl_mem object, one calls clCreateBuffer(), which takes a cl_context as an argument. I assume that this means that the cl_mem object has affinity with the cl_context used to create it and that it is an error to use it in any other context (the standard does not seem to state this explicitly). Since the cl_context was created with a set of cl_device_ids, I assume that it is valid to use cl_mem object with any of the devices used to create the cl_context that was passed to clCreateBuffer().
To read data out of a cl_mem object, one uses the clEnqueueReadBuffer() method, which takes a cl_command_queue as an argument. A cl_command_queue is created for a specific cl_device. It seems very strange that I need to specify a device when reading form a cl_mem object as it does not have device affinity.
This certainly lacks symmetry with creating a buffer with the CL_MEM_COPY_HOST_PTR flag as no device is passed to the clCreateBuffer() method. I've seen it said in other posts that the following are equivalent:
Code :cl_mem buf = clCreateBuffer( context, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, size, ptr, 0 );
Code :cl_mem buf = clCreateBuffer( context, CL_MEM_READ_ONLY, size, 0, 0 ); clEnqueueWriteBuffer( queue, buf, true, 0, size, ptr, 0, 0, 0);
However, there is one distinction - the second case requires you to nominate a device (needed to create the queue) while the first does not!
Can someone clarify what is going on here? I am working within a context that has multiple devices and want to read data out of a cl_mem object using clEnqueueReadBuffer() - what device should the cl_command_queue that I use be associated with? Does it not matter?
Thanks in advance,