From 19cc9195c73002f84c153a1ffc60f00408e1176e Mon Sep 17 00:00:00 2001 From: Michael Bien Date: Sat, 7 May 2011 02:11:44 +0200 Subject: introduced CLQueueContext and its factory - WIP. --- .../opencl/util/concurrent/CLQueueContext.java | 52 ++++++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 src/com/jogamp/opencl/util/concurrent/CLQueueContext.java (limited to 'src/com/jogamp/opencl/util/concurrent/CLQueueContext.java') diff --git a/src/com/jogamp/opencl/util/concurrent/CLQueueContext.java b/src/com/jogamp/opencl/util/concurrent/CLQueueContext.java new file mode 100644 index 00000000..fef0047d --- /dev/null +++ b/src/com/jogamp/opencl/util/concurrent/CLQueueContext.java @@ -0,0 +1,52 @@ +/* + * Created on Friday, May 06 2011 21:02 + */ +package com.jogamp.opencl.util.concurrent; + +import com.jogamp.opencl.CLCommandQueue; +import com.jogamp.opencl.CLKernel; +import com.jogamp.opencl.CLProgram; +import com.jogamp.opencl.CLResource; +import java.util.Map; + +/** + * @author Michael Bien + */ +public abstract class CLQueueContext implements CLResource { + + public final CLCommandQueue queue; + + public CLQueueContext(CLCommandQueue queue) { + this.queue = queue; + } + + public CLCommandQueue getQueue() { + return queue; + } + + public static class CLSimpleQueueContext extends CLQueueContext { + + public final CLProgram program; + public final Map kernels; + + public CLSimpleQueueContext(CLCommandQueue queue, CLProgram program) { + super(queue); + this.program = program; + this.kernels = program.createCLKernels(); + } + + public Map getKernels() { + return kernels; + } + + public CLProgram getProgram() { + return program; + } + + public void release() { + throw new UnsupportedOperationException("Not supported yet."); + } + + } + +} -- cgit v1.2.3 From dedded707fc70fda3e40cf963d208202f8d6c42b Mon Sep 17 00:00:00 2001 From: Michael Bien Date: Sun, 8 May 2011 19:46:28 +0200 Subject: added context switching functionality. --- .../opencl/util/concurrent/CLCommandQueuePool.java | 49 ++++++++++++++++++---- .../opencl/util/concurrent/CLQueueContext.java | 2 +- .../opencl/util/concurrent/CLMultiContextTest.java | 12 +++--- 3 files changed, 46 insertions(+), 17 deletions(-) (limited to 'src/com/jogamp/opencl/util/concurrent/CLQueueContext.java') 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 contexts; + private List contexts; private ExecutorService excecutor; private FinishAction finishAction = FinishAction.DO_NOTHING; - private CLCommandQueuePool(Collection contexts) { - this.contexts = Collections.unmodifiableList(new ArrayList(contexts)); + private CLCommandQueuePool(CLQueueContextFactory factory, Collection queues) { + this.contexts = initContexts(queues, factory); initExecutor(); } + private List initContexts(Collection queues, CLQueueContextFactory factory) { + List newContexts = new ArrayList(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 queues) { - List contexts = new ArrayList(queues.size()); - for (CLCommandQueue queue : queues) { - contexts.add(factory.setup(queue, null)); - } - return new CLCommandQueuePool(contexts); + return new CLCommandQueuePool(factory, queues); } public Future submit(CLTask 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 CLCommandQueuePool switchContext(CLQueueContextFactory 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{ -- cgit v1.2.3 From c59bc50229181ab9cb0e5012d7bb5caf2faa781f Mon Sep 17 00:00:00 2001 From: Michael Bien Date: Mon, 9 May 2011 03:00:55 +0200 Subject: concurrent utils bugfixes and improvements. - more utility methods - generics fixes - basic junit test for CLCommandQueuePool - javadoc and argument validation --- src/com/jogamp/opencl/util/CLMultiContext.java | 11 +++ .../opencl/util/concurrent/CLCommandQueuePool.java | 69 +++++++++---- .../opencl/util/concurrent/CLQueueContext.java | 9 ++ src/com/jogamp/opencl/util/concurrent/CLTask.java | 4 +- .../opencl/util/concurrent/CLMultiContextTest.java | 107 +++++++++++++++++++-- 5 files changed, 168 insertions(+), 32 deletions(-) (limited to 'src/com/jogamp/opencl/util/concurrent/CLQueueContext.java') diff --git a/src/com/jogamp/opencl/util/CLMultiContext.java b/src/com/jogamp/opencl/util/CLMultiContext.java index f588fcef..f74c0a35 100644 --- a/src/com/jogamp/opencl/util/CLMultiContext.java +++ b/src/com/jogamp/opencl/util/CLMultiContext.java @@ -41,6 +41,13 @@ public class CLMultiContext implements CLResource { * Creates a multi context with all devices of the specified platforms and types. */ public static CLMultiContext create(CLPlatform[] platforms, CLDevice.Type... types) { + + if(platforms == null) { + throw new NullPointerException("platform list was null"); + }else if(platforms.length == 0) { + throw new IllegalArgumentException("platform list was empty"); + } + List devices = new ArrayList(); for (CLPlatform platform : platforms) { devices.addAll(asList(platform.listCLDevices(types))); @@ -54,6 +61,10 @@ public class CLMultiContext implements CLResource { */ public static CLMultiContext create(Collection devices) { + if(devices.isEmpty()) { + throw new IllegalArgumentException("device list was empty"); + } + Map> platformDevicesMap = filterPlatformConflicts(devices); // create contexts diff --git a/src/com/jogamp/opencl/util/concurrent/CLCommandQueuePool.java b/src/com/jogamp/opencl/util/concurrent/CLCommandQueuePool.java index b80f09e6..a6bbe4d0 100644 --- a/src/com/jogamp/opencl/util/concurrent/CLCommandQueuePool.java +++ b/src/com/jogamp/opencl/util/concurrent/CLCommandQueuePool.java @@ -15,6 +15,7 @@ import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; import java.util.concurrent.ThreadFactory; +import java.util.concurrent.TimeUnit; /** * A multithreaded fixed size pool of OpenCL command queues. @@ -23,7 +24,7 @@ import java.util.concurrent.ThreadFactory; * instead of {@link Callable}s. * @author Michael Bien */ -public class CLCommandQueuePool implements CLResource { +public class CLCommandQueuePool implements CLResource { private List contexts; private ExecutorService excecutor; @@ -55,11 +56,11 @@ public class CLCommandQueuePool implements CLResource { this.excecutor = Executors.newFixedThreadPool(contexts.size(), new QueueThreadFactory(contexts)); } - public static CLCommandQueuePool create(CLQueueContextFactory factory, CLMultiContext mc, CLCommandQueue.Mode... modes) { + public static CLCommandQueuePool create(CLQueueContextFactory factory, CLMultiContext mc, CLCommandQueue.Mode... modes) { return create(factory, mc.getDevices(), modes); } - public static CLCommandQueuePool create(CLQueueContextFactory factory, Collection devices, CLCommandQueue.Mode... modes) { + public static CLCommandQueuePool create(CLQueueContextFactory factory, Collection devices, CLCommandQueue.Mode... modes) { List queues = new ArrayList(devices.size()); for (CLDevice device : devices) { queues.add(device.createCommandQueue(modes)); @@ -67,21 +68,43 @@ public class CLCommandQueuePool implements CLResource { return create(factory, queues); } - public static CLCommandQueuePool create(CLQueueContextFactory factory, Collection queues) { + public static CLCommandQueuePool create(CLQueueContextFactory factory, Collection queues) { return new CLCommandQueuePool(factory, queues); } - public Future submit(CLTask task) { + /** + * @see ExecutorService#submit(java.util.concurrent.Callable) + */ + public Future submit(CLTask task) { return excecutor.submit(new TaskWrapper(task, finishAction)); } - public List> invokeAll(Collection> tasks) throws InterruptedException { - List> wrapper = new ArrayList>(tasks.size()); - for (CLTask task : tasks) { - wrapper.add(new TaskWrapper(task, finishAction)); - } + /** + * @see ExecutorService#invokeAll(java.util.Collection) + */ + public List> invokeAll(Collection> tasks) throws InterruptedException { + List> wrapper = wrapTasks(tasks); return excecutor.invokeAll(wrapper); } + + /** + * @see ExecutorService#invokeAll(java.util.Collection, long, java.util.concurrent.TimeUnit) + */ + public List> invokeAll(Collection> tasks, long timeout, TimeUnit unit) throws InterruptedException { + List> wrapper = wrapTasks(tasks); + return excecutor.invokeAll(wrapper, timeout, unit); + } + + private List> wrapTasks(Collection> tasks) { + List> wrapper = new ArrayList>(tasks.size()); + for (CLTask task : tasks) { + if(task == null) { + throw new NullPointerException("at least one task was null"); + } + wrapper.add(new TaskWrapper(task, finishAction)); + } + return wrapper; + } /** * Switches the context of all queues - this operation can be expensive. @@ -171,35 +194,41 @@ public class CLCommandQueuePool implements CLResource { this.index = 0; } - public synchronized Thread newThread(Runnable r) { + public synchronized Thread newThread(Runnable runnable) { + + SecurityManager sm = System.getSecurityManager(); + ThreadGroup group = (sm != null)? sm.getThreadGroup() : Thread.currentThread().getThreadGroup(); + CLQueueContext queue = context.get(index); - return new QueueThread(queue, index++); + QueueThread thread = new QueueThread(group, runnable, queue, index++); + thread.setDaemon(true); + + return thread; } } private static class QueueThread extends Thread { private final CLQueueContext context; - public QueueThread(CLQueueContext context, int index) { - super("queue-worker-thread-"+index+"["+context+"]"); + public QueueThread(ThreadGroup group, Runnable runnable, CLQueueContext context, int index) { + super(group, runnable, "queue-worker-thread-"+index+"["+context+"]"); this.context = context; - this.setDaemon(true); } } - private static class TaskWrapper implements Callable { + private static class TaskWrapper implements Callable { - private final CLTask task; + private final CLTask task; private final FinishAction mode; - public TaskWrapper(CLTask task, FinishAction mode) { + public TaskWrapper(CLTask task, FinishAction mode) { this.task = task; this.mode = mode; } - public T call() throws Exception { + public R call() throws Exception { CLQueueContext context = ((QueueThread)Thread.currentThread()).context; - T result = task.run(context); + R result = task.execute((C)context); if(mode.equals(FinishAction.FLUSH)) { context.queue.flush(); }else if(mode.equals(FinishAction.FINISH)) { diff --git a/src/com/jogamp/opencl/util/concurrent/CLQueueContext.java b/src/com/jogamp/opencl/util/concurrent/CLQueueContext.java index 3956f93d..11b86889 100644 --- a/src/com/jogamp/opencl/util/concurrent/CLQueueContext.java +++ b/src/com/jogamp/opencl/util/concurrent/CLQueueContext.java @@ -4,6 +4,7 @@ package com.jogamp.opencl.util.concurrent; import com.jogamp.opencl.CLCommandQueue; +import com.jogamp.opencl.CLContext; import com.jogamp.opencl.CLKernel; import com.jogamp.opencl.CLProgram; import com.jogamp.opencl.CLResource; @@ -24,6 +25,10 @@ public abstract class CLQueueContext implements CLResource { return queue; } + public CLContext getCLContext() { + return queue.getContext(); + } + public static class CLSimpleQueueContext extends CLQueueContext { public final CLProgram program; @@ -39,6 +44,10 @@ public abstract class CLQueueContext implements CLResource { return kernels; } + public CLKernel getKernel(String name) { + return kernels.get(name); + } + public CLProgram getProgram() { return program; } diff --git a/src/com/jogamp/opencl/util/concurrent/CLTask.java b/src/com/jogamp/opencl/util/concurrent/CLTask.java index ff0f7614..0cfd24a5 100644 --- a/src/com/jogamp/opencl/util/concurrent/CLTask.java +++ b/src/com/jogamp/opencl/util/concurrent/CLTask.java @@ -8,11 +8,11 @@ package com.jogamp.opencl.util.concurrent; * A task executed on a command queue. * @author Michael Bien */ -public interface CLTask { +public interface CLTask { /** * Runs the task on a queue and returns a result. */ - R run(CLQueueContext context); + R execute(C context); } diff --git a/test/com/jogamp/opencl/util/concurrent/CLMultiContextTest.java b/test/com/jogamp/opencl/util/concurrent/CLMultiContextTest.java index 7a1ed7aa..e5bcb1c5 100644 --- a/test/com/jogamp/opencl/util/concurrent/CLMultiContextTest.java +++ b/test/com/jogamp/opencl/util/concurrent/CLMultiContextTest.java @@ -3,14 +3,24 @@ */ package com.jogamp.opencl.util.concurrent; +import com.jogamp.common.nio.Buffers; +import com.jogamp.opencl.CLBuffer; +import com.jogamp.opencl.CLCommandQueue; import com.jogamp.opencl.CLContext; import com.jogamp.opencl.CLDevice; +import com.jogamp.opencl.CLKernel; import com.jogamp.opencl.CLPlatform; +import com.jogamp.opencl.util.concurrent.CLQueueContext.CLSimpleQueueContext; import com.jogamp.opencl.util.concurrent.CLQueueContextFactory.CLSimpleContextFactory; +import java.nio.IntBuffer; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; import org.junit.Rule; import org.junit.rules.MethodRule; import org.junit.rules.Timeout; import com.jogamp.opencl.util.CLMultiContext; +import java.nio.Buffer; +import java.util.ArrayList; import java.util.List; import org.junit.Test; @@ -52,27 +62,97 @@ public class CLMultiContextTest { } private final static String programSource = - "kernel void vectorAdd(global const int* a, global const int* b, global int* c, int iNumElements) { \n" - + " int iGID = get_global_id(0); \n" - + " if (iGID >= iNumElements) { \n" - + " return; \n" - + " } \n" - + " c[iGID] = a[iGID] + b[iGID]; \n" - + "} \n"; + "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"; + + private final class CLTestTask implements CLTask { + + private final Buffer data; + + public CLTestTask(Buffer buffer) { + this.data = buffer; + } + + public Buffer execute(CLSimpleQueueContext qc) { + + CLCommandQueue queue = qc.getQueue(); + CLContext context = qc.getCLContext(); + CLKernel kernel = qc.getKernel("increment"); + + CLBuffer buffer = null; + try{ + buffer = context.createBuffer(data); + int gws = buffer.getCLCapacity(); + + kernel.putArg(buffer).putArg(gws).rewind(); + + queue.putWriteBuffer(buffer, true); + queue.put1DRangeKernel(kernel, 0, gws, 0); + queue.putReadBuffer(buffer, true); + }finally{ + if(buffer != null) { + buffer.release(); + } + } + + return data; + } + + } @Test - public void commandQueuePoolTest() { + public void commandQueuePoolTest() throws InterruptedException, ExecutionException { CLMultiContext mc = CLMultiContext.create(CLPlatform.listCLPlatforms()); try { CLSimpleContextFactory factory = CLQueueContextFactory.createSimple(programSource); - CLCommandQueuePool pool = CLCommandQueuePool.create(factory, mc); + CLCommandQueuePool pool = CLCommandQueuePool.create(factory, mc); assertTrue(pool.getSize() > 0); + + final int slice = 64; + final int tasksPerQueue = 10; + final int taskCount = pool.getSize() * tasksPerQueue; + + IntBuffer data = Buffers.newDirectIntBuffer(slice*taskCount); + + List tasks = new ArrayList(taskCount); + + for (int i = 0; i < taskCount; i++) { + IntBuffer subBuffer = Buffers.slice(data, i*slice, slice); + assertEquals(slice, subBuffer.capacity()); + tasks.add(new CLTestTask(subBuffer)); + } + + out.println("invoking "+tasks.size()+" tasks on "+pool.getSize()+" queues"); + + pool.invokeAll(tasks); + checkBuffer(1, data); + + + 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)); + } + for (Future future : futures) { + future.get(); + } + checkBuffer(3, data); - pool.switchContext(factory); +// pool.switchContext(factory); pool.release(); }finally{ @@ -80,4 +160,11 @@ public class CLMultiContextTest { } } + private void checkBuffer(int expected, IntBuffer data) { + while(data.hasRemaining()) { + assertEquals(expected, data.get()); + } + data.rewind(); + } + } -- cgit v1.2.3 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(-) (limited to 'src/com/jogamp/opencl/util/concurrent/CLQueueContext.java') 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