Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Waiting for a single event in OpenCL

Tags:

c

opencl

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:

  1. Busy-wait using clGetEventInfo to test for event completion.

  2. Multi-thread having one thread for each event (will only need a few threads, but am using the CPU as one of the devices)

  3. 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!

like image 701
KLee1 Avatar asked Nov 14 '11 05:11

KLee1


1 Answers

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.

like image 57
James Avatar answered Oct 03 '22 18:10

James