diff options
3 files changed, 46 insertions, 17 deletions
diff --git a/src/com/jogamp/opencl/util/concurrent/CLCommandQueuePool.java b/src/com/jogamp/opencl/util/concurrent/CLCommandQueuePool.java index ee6dc86b..b80f09e6 100644 --- a/src/com/jogamp/opencl/util/concurrent/CLCommandQueuePool.java +++ b/src/com/jogamp/opencl/util/concurrent/CLCommandQueuePool.java @@ -9,7 +9,6 @@ import com.jogamp.opencl.CLResource; import com.jogamp.opencl.util.CLMultiContext; import java.util.ArrayList; import java.util.Collection; -import java.util.Collections; import java.util.List; import java.util.concurrent.Callable; import java.util.concurrent.ExecutorService; @@ -26,15 +25,32 @@ import java.util.concurrent.ThreadFactory; */ public class CLCommandQueuePool implements CLResource { - private final List<CLQueueContext> contexts; + private List<CLQueueContext> contexts; private ExecutorService excecutor; private FinishAction finishAction = FinishAction.DO_NOTHING; - private CLCommandQueuePool(Collection<CLQueueContext> contexts) { - this.contexts = Collections.unmodifiableList(new ArrayList<CLQueueContext>(contexts)); + private CLCommandQueuePool(CLQueueContextFactory factory, Collection<CLCommandQueue> queues) { + this.contexts = initContexts(queues, factory); initExecutor(); } + private List<CLQueueContext> initContexts(Collection<CLCommandQueue> queues, CLQueueContextFactory factory) { + List<CLQueueContext> newContexts = new ArrayList<CLQueueContext>(queues.size()); + + int index = 0; + for (CLCommandQueue queue : queues) { + + CLQueueContext old = null; + if(this.contexts != null && !this.contexts.isEmpty()) { + old = this.contexts.get(index++); + old.release(); + } + + newContexts.add(factory.setup(queue, old)); + } + return newContexts; + } + private void initExecutor() { this.excecutor = Executors.newFixedThreadPool(contexts.size(), new QueueThreadFactory(contexts)); } @@ -52,11 +68,7 @@ public class CLCommandQueuePool implements CLResource { } public static CLCommandQueuePool create(CLQueueContextFactory factory, Collection<CLCommandQueue> queues) { - List<CLQueueContext> contexts = new ArrayList<CLQueueContext>(queues.size()); - for (CLCommandQueue queue : queues) { - contexts.add(factory.setup(queue, null)); - } - return new CLCommandQueuePool(contexts); + return new CLCommandQueuePool(factory, queues); } public <R> Future<R> submit(CLTask<R> task) { @@ -70,6 +82,20 @@ public class CLCommandQueuePool implements CLResource { } return excecutor.invokeAll(wrapper); } + + /** + * Switches the context of all queues - this operation can be expensive. + * Blocks until all tasks finish and sets up a new context for all queues. + */ + public <C extends CLQueueContext> CLCommandQueuePool switchContext(CLQueueContextFactory<C> factory) { + + excecutor.shutdown(); + finishQueues(); // just to be sure + + contexts = initContexts(getQueues(), factory); + initExecutor(); + return this; + } /** * Calls {@link CLCommandQueue#flush()} on all queues. @@ -96,6 +122,7 @@ public class CLCommandQueuePool implements CLResource { excecutor.shutdown(); for (CLQueueContext context : contexts) { context.queue.finish().release(); + context.release(); } } @@ -121,6 +148,10 @@ public class CLCommandQueuePool implements CLResource { return finishAction; } + /** + * Sets the action which is run after every completed task. + * This is mainly intended for debugging, default value is {@link FinishAction#DO_NOTHING}. + */ public void setFinishAction(FinishAction action) { this.finishAction = action; } diff --git a/src/com/jogamp/opencl/util/concurrent/CLQueueContext.java b/src/com/jogamp/opencl/util/concurrent/CLQueueContext.java index fef0047d..3956f93d 100644 --- a/src/com/jogamp/opencl/util/concurrent/CLQueueContext.java +++ b/src/com/jogamp/opencl/util/concurrent/CLQueueContext.java @@ -44,7 +44,7 @@ public abstract class CLQueueContext implements CLResource { } public void release() { - throw new UnsupportedOperationException("Not supported yet."); + program.release(); } } diff --git a/test/com/jogamp/opencl/util/concurrent/CLMultiContextTest.java b/test/com/jogamp/opencl/util/concurrent/CLMultiContextTest.java index f076324a..7a1ed7aa 100644 --- a/test/com/jogamp/opencl/util/concurrent/CLMultiContextTest.java +++ b/test/com/jogamp/opencl/util/concurrent/CLMultiContextTest.java @@ -23,8 +23,8 @@ import static java.lang.System.*; */ public class CLMultiContextTest { -// @Rule -// public MethodRule methodTimeout= new Timeout(10000); + @Rule + public MethodRule methodTimeout= new Timeout(10000); @Test public void createMultiContextTest() { @@ -52,15 +52,11 @@ public class CLMultiContextTest { } private final static String programSource = - " // OpenCL Kernel Function for element by element vector addition \n" - + "kernel void vectorAdd(global const int* a, global const int* b, global int* c, int iNumElements) { \n" - + " // get index in global data array \n" + "kernel void vectorAdd(global const int* a, global const int* b, global int* c, int iNumElements) { \n" + " int iGID = get_global_id(0); \n" - + " // bound check (equivalent to the limit on a 'for' loop for standard/serial C code \n" + " if (iGID >= iNumElements) { \n" + " return; \n" + " } \n" - + " // add the vector elements \n" + " c[iGID] = a[iGID] + b[iGID]; \n" + "} \n"; @@ -75,6 +71,8 @@ public class CLMultiContextTest { CLCommandQueuePool pool = CLCommandQueuePool.create(factory, mc); assertTrue(pool.getSize() > 0); + + pool.switchContext(factory); pool.release(); }finally{ |