Reputation: 6178
I am writing a OpenCL program in which multiple kernels are being called on multiple devices. After I have enqueued all of the kernels I would like to wait until any of them has finished and then enqueue work for that device afterwords.
For instance, I have devices A and B and each of them have a kernel. If A finishes first, I want to enqueue a new kernel in it after doing some work. If B finishes first I want to enqueue a new kernel for it after doing some work. I'm looking for something like a clWaitForAnyEvent
which will return after any event passed in has finished.
Looking at the spec, I see a clWaitForEvents
method, but it seems that it will wait for all of the event to finish before continuing, and I want to continue after one event (and need to know which event finished).
The options I can think of right now are:
Busy-wait using clGetEventInfo
to test for event completion.
Multi-thread having one thread for each event (will only need a few threads, but am using the CPU as one of the devices)
Missed something in the specification and there is actually a method that does this for me.
Any suggestions of how to proceed or something that I am missing?
Thanks!
Upvotes: 10
Views: 11210
Reputation: 2413
Your answer is 3.
clWaitForEvents
will do exactly what you want. Let's say you have a command queue for a device which we will call klee_dev
. You can enqueue work on klee_dev like this:
cl_event event;
cl_int status = clEnqueueNDRangeKernel(queue_for_klee_dev, ..., &event);
/* enqueue other work on other devices, perhaps even klee_dev */
clWaitForEvents(1, &event);
The call to clWaitForEvents
will block until the work you enqueued on klee_dev
's command queue completes. It will not wait for other work to complete; just the work specified by enqueue call associated with that one event.
EDIT:
I misunderstood the original question, which was clarified below. The OP was asking if there is a method in the CL specification that, given a set of events, will block until any one of the events completes. There is currently no such method.
EDIT, again:
You could register a callback method for each event with clSetEventCallback
. Within the callback, you can query the event with clGetEventInfo
to find out what command queue was associated with the event.
That gives you what you require, I think: notification of any event completion, and the ability to find out what command queue is associated with the event.
Upvotes: 11