Maybe.
- Create two command queues in context.
- Create two cores, one to do the work, and the other to stop the execution. Each core has access to a global global buffer.
- Load the first kernel in queue1.
- Load the second core in queue2 if you want to stop execution.
Alternatively, you can use the queue out of turn and load the second core into the same command queue to stop execution. You should be a little more careful (using clFinish / clFlush if necessary), however this is a more natural way to do this.
Some pseudo codes (for multiple queues):
clEnqueueNDRange(queue1, kernel1, ...); //start work kernel // do other stuff // ... if (condition) clEnqueueNDRange(queue2, kernel2, ...); //stop work kernel clFinish(queue1); clFinish(queue2); // entirely unnecessary if using in-order queues
Use the ints or float buffer as a stop variable and access them through global_id in your kernels to reduce the cost of reading from the global in a loop. The disadvantage is that your state will be undefined: without additional variables for counting performances, etc. You will not know how many work items and which ones were completed.
And the kernels:
void kernel1( ... ,global int * g_stop) { int index_from_ids = ...; while (g_stop[index_from_ids] == 0) // or 'if' for single pass execution { // do work here } } void kernel2( ... ,global int * g_stop) { int index_from_ids = ...; g_stop[index_from_ids] = 1; }
source share