From 1c38b7ef96910260b64843214279ac4683005609 Mon Sep 17 00:00:00 2001 From: Michael Bien Date: Mon, 9 May 2011 17:30:19 +0200 Subject: added submitAll() utility method junit test now covering queue contexts switching improved javadoc. --- .../opencl/util/concurrent/CLCommandQueuePool.java | 26 +++++++++++++---- .../opencl/util/concurrent/CLQueueContext.java | 11 +++++++ .../util/concurrent/CLQueueContextFactory.java | 13 ++++++--- .../opencl/util/concurrent/CLMultiContextTest.java | 34 ++++++++++++---------- 4 files changed, 59 insertions(+), 25 deletions(-) diff --git a/src/com/jogamp/opencl/util/concurrent/CLCommandQueuePool.java b/src/com/jogamp/opencl/util/concurrent/CLCommandQueuePool.java index a6bbe4d0..9ea960ae 100644 --- a/src/com/jogamp/opencl/util/concurrent/CLCommandQueuePool.java +++ b/src/com/jogamp/opencl/util/concurrent/CLCommandQueuePool.java @@ -18,10 +18,10 @@ import java.util.concurrent.ThreadFactory; import java.util.concurrent.TimeUnit; /** - * A multithreaded fixed size pool of OpenCL command queues. - * It serves as a multiplexer distributing tasks over N queues. + * A multithreaded, fixed size pool of OpenCL command queues. + * It serves as a multiplexer distributing tasks over N queues usually run on N devices. * The usage of this pool is similar to {@link ExecutorService} but it uses {@link CLTask}s - * instead of {@link Callable}s. + * instead of {@link Callable}s and provides a per-queue context for resource sharing across all tasks of one queue. * @author Michael Bien */ public class CLCommandQueuePool implements CLResource { @@ -73,13 +73,27 @@ public class CLCommandQueuePool implements CLResource } /** + * Submits this task to the pool for execution returning its {@link Future}. * @see ExecutorService#submit(java.util.concurrent.Callable) */ - public Future submit(CLTask task) { + public Future submit(CLTask task) { return excecutor.submit(new TaskWrapper(task, finishAction)); } /** + * Submits all tasks to the pool for execution and returns their {@link Future}. + * Calls {@link #submit(com.jogamp.opencl.util.concurrent.CLTask)} for every task. + */ + public List> submitAll(Collection> tasks) { + List> futures = new ArrayList>(tasks.size()); + for (CLTask task : tasks) { + futures.add(submit(task)); + } + return futures; + } + + /** + * Submits all tasks to the pool for immediate execution (blocking) and returns their {@link Future} holding the result. * @see ExecutorService#invokeAll(java.util.Collection) */ public List> invokeAll(Collection> tasks) throws InterruptedException { @@ -88,6 +102,7 @@ public class CLCommandQueuePool implements CLResource } /** + * Submits all tasks to the pool for immediate execution (blocking) and returns their {@link Future} holding the result. * @see ExecutorService#invokeAll(java.util.Collection, long, java.util.concurrent.TimeUnit) */ public List> invokeAll(Collection> tasks, long timeout, TimeUnit unit) throws InterruptedException { @@ -109,6 +124,7 @@ public class CLCommandQueuePool implements CLResource /** * 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. + * @return this */ public CLCommandQueuePool switchContext(CLQueueContextFactory factory) { @@ -197,7 +213,7 @@ public class CLCommandQueuePool implements CLResource public synchronized Thread newThread(Runnable runnable) { SecurityManager sm = System.getSecurityManager(); - ThreadGroup group = (sm != null)? sm.getThreadGroup() : Thread.currentThread().getThreadGroup(); + ThreadGroup group = (sm != null) ? sm.getThreadGroup() : Thread.currentThread().getThreadGroup(); CLQueueContext queue = context.get(index); QueueThread thread = new QueueThread(group, runnable, queue, index++); diff --git a/src/com/jogamp/opencl/util/concurrent/CLQueueContext.java b/src/com/jogamp/opencl/util/concurrent/CLQueueContext.java index 11b86889..3f89ad0e 100644 --- a/src/com/jogamp/opencl/util/concurrent/CLQueueContext.java +++ b/src/com/jogamp/opencl/util/concurrent/CLQueueContext.java @@ -11,6 +11,13 @@ import com.jogamp.opencl.CLResource; import java.util.Map; /** + * Superclass for all per-queue contexts as used in {@link CLCommandQueuePool}s. + * A context will usually hold queue (and therefore often device) specific resources used + * in tasks of the same queue. + *

+ * Possible candidates for those resources can be compiled CLPrograms, CLKernels + * or even pre allocated CLBuffers. + *

* @author Michael Bien */ public abstract class CLQueueContext implements CLResource { @@ -29,6 +36,10 @@ public abstract class CLQueueContext implements CLResource { return queue.getContext(); } + /** + * A simple queue context holding a precompiled program and its kernels. + * @author Michael Bien + */ public static class CLSimpleQueueContext extends CLQueueContext { public final CLProgram program; diff --git a/src/com/jogamp/opencl/util/concurrent/CLQueueContextFactory.java b/src/com/jogamp/opencl/util/concurrent/CLQueueContextFactory.java index 64fdfbcd..58f389bf 100644 --- a/src/com/jogamp/opencl/util/concurrent/CLQueueContextFactory.java +++ b/src/com/jogamp/opencl/util/concurrent/CLQueueContextFactory.java @@ -5,9 +5,10 @@ package com.jogamp.opencl.util.concurrent; import com.jogamp.opencl.CLCommandQueue; import com.jogamp.opencl.CLProgram; +import com.jogamp.opencl.util.concurrent.CLQueueContext.CLSimpleQueueContext; /** - * + * Creates {@link CLQueueContext}s. * @author Michael Bien */ public abstract class CLQueueContextFactory { @@ -27,7 +28,11 @@ public abstract class CLQueueContextFactory { return new CLSimpleContextFactory(source); } - public static class CLSimpleContextFactory extends CLQueueContextFactory { + /** + * Creates {@link CLSimpleQueueContext}s containing a precompiled program. + * @author Michael Bien + */ + public static class CLSimpleContextFactory extends CLQueueContextFactory { private final String source; @@ -36,9 +41,9 @@ public abstract class CLQueueContextFactory { } @Override - public CLQueueContext.CLSimpleQueueContext setup(CLCommandQueue queue, CLQueueContext old) { + public CLSimpleQueueContext setup(CLCommandQueue queue, CLQueueContext old) { CLProgram program = queue.getContext().createProgram(source).build(queue.getDevice()); - return new CLQueueContext.CLSimpleQueueContext(queue, program); + return new CLSimpleQueueContext(queue, program); } } diff --git a/test/com/jogamp/opencl/util/concurrent/CLMultiContextTest.java b/test/com/jogamp/opencl/util/concurrent/CLMultiContextTest.java index e5bcb1c5..81d34907 100644 --- a/test/com/jogamp/opencl/util/concurrent/CLMultiContextTest.java +++ b/test/com/jogamp/opencl/util/concurrent/CLMultiContextTest.java @@ -62,13 +62,13 @@ public class CLMultiContextTest { } private final static String programSource = - "kernel void increment(global int* array, int numElements) { \n" - + " int index = get_global_id(0); \n" - + " if (index >= numElements) { \n" - + " return; \n" - + " } \n" - + " array[index]++; \n" - + "} \n"; + "kernel void compute(global int* array, int numElements) { \n" + + " int index = get_global_id(0); \n" + + " if (index >= numElements) { \n" + + " return; \n" + + " } \n" + + " array[index]++; \n" + + "} \n"; private final class CLTestTask implements CLTask { @@ -82,7 +82,7 @@ public class CLMultiContextTest { CLCommandQueue queue = qc.getQueue(); CLContext context = qc.getCLContext(); - CLKernel kernel = qc.getKernel("increment"); + CLKernel kernel = qc.getKernel("compute"); CLBuffer buffer = null; try{ @@ -133,26 +133,28 @@ public class CLMultiContextTest { out.println("invoking "+tasks.size()+" tasks on "+pool.getSize()+" queues"); + // blocking invoke pool.invokeAll(tasks); checkBuffer(1, data); - + // submit blocking emediatly for (CLTestTask task : tasks) { pool.submit(task).get(); } checkBuffer(2, data); - - List> futures = new ArrayList>(taskCount); - for (CLTestTask task : tasks) { - futures.add(pool.submit(task)); - } + // submitAll using futures + List> futures = pool.submitAll(tasks); for (Future future : futures) { future.get(); } checkBuffer(3, data); - -// pool.switchContext(factory); + + // switching contexts using different program + factory = CLQueueContextFactory.createSimple(programSource.replaceAll("\\+\\+", "--")); + pool.switchContext(factory); + pool.invokeAll(tasks); + checkBuffer(2, data); pool.release(); }finally{ -- cgit v1.2.3