Subject: Re: [boost] Synchronization (RE: [compute] review)
From: Thomas M (firespot71_at_[hidden])
Date: 2014-12-30 02:48:42
On 30/12/2014 00:56, Gruenke,Matt wrote:
> -----Original Message-----
> From: Boost [mailto:boost-bounces_at_[hidden]] On Behalf Of Thomas M
> Sent: December 29, 2014 16:20
> To: boost_at_[hidden]
> Subject: Re: [boost] Synchronization (RE: [compute] review)
>> If input/output ranges generally refer to iterators from the boost::compute library, then:
>> -) an iterator can store the container (or other data structure it belongs to, if any)
>> -) an algorithm can, via the iterators, "communicate" with the container(s)
>> For an input operation the data must be available throughout & in unaltered manner from
>> the time of enqueuing the input operation until its >completion.
> Essentially, what I think you want is to embed the equivalent of a shared_ptr to the underlying storage. Event callbacks could be used to decrement it, when the operation has completed. That way, even if the container object is deleted, the device memory sticks around so long as any pending operations reference it.
yes, I was thinking of a shared_ptr for the implementation part.
> BTW, for command_queue-level operations, Kyle seems to agree with my proposal to have a sort of guard object that calls event::wait(), upon destruction. I actually wonder if it makes sense to call this a 'guarantee', since it doesn't quite behave like traditional guard objects. He's even accepted my offer to code this up.
If you want to code that functionality up that's more than fine with me.
I am not happy though with the need to explicitly, i.e. manually,
associate guards with command-queue operations just for the sake of
exception-safety (I am referring only to that here). And out of the box
I cannot come up with a single example when a memory container is fine
to die while OpenCL operations are still running on it or enqueued to
run on it, so that's why I prefer a mechanisms which does it always,
implicitly (unless maybe the user wants to take over it explicitly).
Your proposal looks like:
boost::compute::guard wg(cq.enqueue_write_buffer_async(dv, 0, hv.size(),
which appears to me quite lengthy and more error-prone (forgetting the
guard) to get exception safety.
Now assume that an iterator can store its underlying container, isn't it
possible that the enqueue_write_buffer_async itself places some
guard-like structure into the container, and when the container's
destructor is invoked it calls wait() on all of them?