aboutsummaryrefslogtreecommitdiffstats
path: root/src/com/jogamp/opencl/util
diff options
context:
space:
mode:
Diffstat (limited to 'src/com/jogamp/opencl/util')
-rw-r--r--src/com/jogamp/opencl/util/CLBuildListener.java2
-rw-r--r--src/com/jogamp/opencl/util/CLDeviceFilters.java7
-rw-r--r--src/com/jogamp/opencl/util/CLMultiContext.java158
-rw-r--r--src/com/jogamp/opencl/util/CLPlatformFilters.java25
-rw-r--r--src/com/jogamp/opencl/util/concurrent/CLCommandQueuePool.java280
-rw-r--r--src/com/jogamp/opencl/util/concurrent/CLQueueContext.java72
-rw-r--r--src/com/jogamp/opencl/util/concurrent/CLQueueContextFactory.java51
-rw-r--r--src/com/jogamp/opencl/util/concurrent/CLTask.java18
8 files changed, 606 insertions, 7 deletions
diff --git a/src/com/jogamp/opencl/util/CLBuildListener.java b/src/com/jogamp/opencl/util/CLBuildListener.java
index 7e6dfc0b..9a520582 100644
--- a/src/com/jogamp/opencl/util/CLBuildListener.java
+++ b/src/com/jogamp/opencl/util/CLBuildListener.java
@@ -40,7 +40,7 @@ import com.jogamp.opencl.CLProgram;
* Note1: registering a build callback can make {@link com.jogamp.opencl.CL#clBuildProgram} non blocking (OpenCL implementation dependent).<br/>
* Note2: the thread which calls this method is unspecified. The Application should ensure propper synchronization.
* @author Michael Bien
- * @see com.jogamp.opencl.CL#clBuildProgram(long, int, com.jogamp.common.nio.PointerBuffer, java.lang.String, com.jogamp.opencl.impl.BuildProgramCallback)
+ * @see com.jogamp.opencl.CL#clBuildProgram(long, int, com.jogamp.common.nio.NativeSizeBuffer, java.lang.String, com.jogamp.opencl.impl.BuildProgramCallback)
*/
public interface CLBuildListener {
diff --git a/src/com/jogamp/opencl/util/CLDeviceFilters.java b/src/com/jogamp/opencl/util/CLDeviceFilters.java
index a2ba0475..045d4c7f 100644
--- a/src/com/jogamp/opencl/util/CLDeviceFilters.java
+++ b/src/com/jogamp/opencl/util/CLDeviceFilters.java
@@ -32,6 +32,7 @@ import com.jogamp.opencl.CLCommandQueue.Mode;
import com.jogamp.opencl.CLDevice;
import java.nio.ByteOrder;
import java.util.Arrays;
+import java.util.List;
/**
* Pre-defined filters.
@@ -82,8 +83,9 @@ public class CLDeviceFilters {
*/
public static Filter<CLDevice> extension(final String... extensions) {
return new Filter<CLDevice>() {
+ private final List<String> extensionList = Arrays.asList(extensions);
public boolean accept(CLDevice item) {
- return item.getExtensions().containsAll(Arrays.asList(extensions));
+ return item.getExtensions().containsAll(extensionList);
}
};
}
@@ -93,8 +95,9 @@ public class CLDeviceFilters {
*/
public static Filter<CLDevice> queueMode(final Mode... modes) {
return new Filter<CLDevice>() {
+ private final List<Mode> modeList = Arrays.asList(modes);
public boolean accept(CLDevice item) {
- return item.getQueueProperties().containsAll(Arrays.asList(modes));
+ return item.getQueueProperties().containsAll(modeList);
}
};
}
diff --git a/src/com/jogamp/opencl/util/CLMultiContext.java b/src/com/jogamp/opencl/util/CLMultiContext.java
new file mode 100644
index 00000000..f74c0a35
--- /dev/null
+++ b/src/com/jogamp/opencl/util/CLMultiContext.java
@@ -0,0 +1,158 @@
+/*
+ * Created on Thursday, April 28 2011 22:10
+ */
+package com.jogamp.opencl.util;
+
+import com.jogamp.opencl.CLContext;
+import com.jogamp.opencl.CLDevice;
+import com.jogamp.opencl.CLPlatform;
+import com.jogamp.opencl.CLResource;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import static java.util.Arrays.*;
+import static com.jogamp.opencl.CLDevice.Type.*;
+
+/**
+ * Utility for organizing multiple {@link CLContext}s.
+ *
+ * @author Michael Bien
+ */
+public class CLMultiContext implements CLResource {
+
+ private final List<CLContext> contexts;
+
+ private CLMultiContext() {
+ contexts = new ArrayList<CLContext>();
+ }
+
+ /**
+ * Creates a multi context with all devices of the specified platforms.
+ */
+ public static CLMultiContext create(CLPlatform... platforms) {
+ return create(platforms, ALL);
+ }
+
+ /**
+ * 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<CLDevice> devices = new ArrayList<CLDevice>();
+ for (CLPlatform platform : platforms) {
+ devices.addAll(asList(platform.listCLDevices(types)));
+ }
+ return create(devices);
+ }
+
+ /**
+ * Creates a multi context with the specified devices.
+ * The devices don't have to be from the same platform.
+ */
+ public static CLMultiContext create(Collection<CLDevice> devices) {
+
+ if(devices.isEmpty()) {
+ throw new IllegalArgumentException("device list was empty");
+ }
+
+ Map<CLPlatform, List<CLDevice>> platformDevicesMap = filterPlatformConflicts(devices);
+
+ // create contexts
+ CLMultiContext mc = new CLMultiContext();
+ for (Map.Entry<CLPlatform, List<CLDevice>> entry : platformDevicesMap.entrySet()) {
+ List<CLDevice> list = entry.getValue();
+ // one context per device to workaround driver bugs
+ for (CLDevice device : list) {
+ CLContext context = CLContext.create(device);
+ mc.contexts.add(context);
+ }
+ }
+
+ return mc;
+ }
+
+ /**
+ * Creates a multi context with specified contexts.
+ */
+ public static CLMultiContext wrap(CLContext... contexts) {
+ CLMultiContext mc = new CLMultiContext();
+ mc.contexts.addAll(asList(contexts));
+ return mc;
+ }
+
+ /**
+ * filter devices; don't allow the same device to be used in more than one platform.
+ * example: a CPU available via the AMD and Intel SDKs shouldn't end up in two contexts
+ */
+ private static Map<CLPlatform, List<CLDevice>> filterPlatformConflicts(Collection<CLDevice> devices) {
+
+ // FIXME: devicename-platform is used as unique device identifier - replace if we have something better
+
+ Map<CLPlatform, List<CLDevice>> filtered = new HashMap<CLPlatform, List<CLDevice>>();
+ Map<String, CLPlatform> used = new HashMap<String, CLPlatform>();
+
+ for (CLDevice device : devices) {
+
+ String name = device.getName();
+
+ CLPlatform platform = device.getPlatform();
+ CLPlatform usedPlatform = used.get(name);
+
+ if(usedPlatform == null || platform.equals(usedPlatform)) {
+ if(!filtered.containsKey(platform)) {
+ filtered.put(platform, new ArrayList<CLDevice>());
+ }
+ filtered.get(platform).add(device);
+ used.put(name, platform);
+ }
+
+ }
+ return filtered;
+ }
+
+
+ /**
+ * Releases all contexts.
+ * @see CLContext#release()
+ */
+ public void release() {
+ for (CLContext context : contexts) {
+ context.release();
+ }
+ contexts.clear();
+ }
+
+ public List<CLContext> getContexts() {
+ return Collections.unmodifiableList(contexts);
+ }
+
+ /**
+ * Returns a list containing all devices used in this multi context.
+ */
+ public List<CLDevice> getDevices() {
+ List<CLDevice> devices = new ArrayList<CLDevice>();
+ for (CLContext context : contexts) {
+ devices.addAll(asList(context.getDevices()));
+ }
+ return devices;
+ }
+
+ @Override
+ public String toString() {
+ return getClass().getSimpleName()+" [" + contexts.size()+" contexts, "
+ + getDevices().size()+ " devices]";
+ }
+
+
+
+}
diff --git a/src/com/jogamp/opencl/util/CLPlatformFilters.java b/src/com/jogamp/opencl/util/CLPlatformFilters.java
index dab7448f..48d20916 100644
--- a/src/com/jogamp/opencl/util/CLPlatformFilters.java
+++ b/src/com/jogamp/opencl/util/CLPlatformFilters.java
@@ -33,7 +33,8 @@ import com.jogamp.opencl.CLDevice;
import com.jogamp.opencl.CLPlatform;
import com.jogamp.opencl.CLVersion;
import java.util.Arrays;
-import java.util.List;
+import javax.media.opengl.GL;
+import javax.media.opengl.GLContext;
/**
* Pre-defined filters.
@@ -70,10 +71,11 @@ public class CLPlatformFilters {
*/
public static Filter<CLPlatform> glSharing() {
return new Filter<CLPlatform>() {
+ private final Filter<CLDevice> glFilter = CLDeviceFilters.glSharing();
public boolean accept(CLPlatform item) {
CLDevice[] devices = item.listCLDevices();
for (CLDevice device : devices) {
- if(device.isGLMemorySharingSupported()) {
+ if(glFilter.accept(device)) {
return true;
}
}
@@ -83,6 +85,21 @@ public class CLPlatformFilters {
}
/**
+ * Accepts all with the given OpenGL context compatible platforms containing at least one
+ * devices of which supports OpenGL-OpenCL interoparability.
+ */
+ public static Filter<CLPlatform> glSharing(final GLContext context) {
+ return new Filter<CLPlatform>() {
+ private final Filter<CLPlatform> glFilter = glSharing();
+ public boolean accept(CLPlatform item) {
+ String glVendor = context.getGL().glGetString(GL.GL_VENDOR);
+ String clVendor = item.getVendor();
+ return clVendor.equals(glVendor) && glFilter.accept(item);
+ }
+ };
+ }
+
+ /**
* Accepts all platforms supporting the given extensions.
*/
public static Filter<CLPlatform> extension(final String... extensions) {
@@ -98,10 +115,10 @@ public class CLPlatformFilters {
*/
public static Filter<CLPlatform> queueMode(final Mode... modes) {
return new Filter<CLPlatform>() {
+ private final Filter<CLDevice> queueModeFilter = CLDeviceFilters.queueMode(modes);
public boolean accept(CLPlatform item) {
- List<Mode> modesList = Arrays.asList(modes);
for (CLDevice device : item.listCLDevices()) {
- if(device.getQueueProperties().containsAll(modesList)) {
+ if(queueModeFilter.accept(device)) {
return true;
}
}
diff --git a/src/com/jogamp/opencl/util/concurrent/CLCommandQueuePool.java b/src/com/jogamp/opencl/util/concurrent/CLCommandQueuePool.java
new file mode 100644
index 00000000..9ea960ae
--- /dev/null
+++ b/src/com/jogamp/opencl/util/concurrent/CLCommandQueuePool.java
@@ -0,0 +1,280 @@
+/*
+ * Created on Tuesday, May 03 2011
+ */
+package com.jogamp.opencl.util.concurrent;
+
+import com.jogamp.opencl.CLCommandQueue;
+import com.jogamp.opencl.CLDevice;
+import com.jogamp.opencl.CLResource;
+import com.jogamp.opencl.util.CLMultiContext;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.concurrent.Callable;
+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.
+ * 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 and provides a per-queue context for resource sharing across all tasks of one queue.
+ * @author Michael Bien
+ */
+public class CLCommandQueuePool<C extends CLQueueContext> implements CLResource {
+
+ private List<CLQueueContext> contexts;
+ private ExecutorService excecutor;
+ private FinishAction finishAction = FinishAction.DO_NOTHING;
+
+ 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));
+ }
+
+ public static <C extends CLQueueContext> CLCommandQueuePool<C> create(CLQueueContextFactory<C> factory, CLMultiContext mc, CLCommandQueue.Mode... modes) {
+ return create(factory, mc.getDevices(), modes);
+ }
+
+ public static <C extends CLQueueContext> CLCommandQueuePool<C> create(CLQueueContextFactory<C> factory, Collection<CLDevice> devices, CLCommandQueue.Mode... modes) {
+ List<CLCommandQueue> queues = new ArrayList<CLCommandQueue>(devices.size());
+ for (CLDevice device : devices) {
+ queues.add(device.createCommandQueue(modes));
+ }
+ return create(factory, queues);
+ }
+
+ public static <C extends CLQueueContext> CLCommandQueuePool create(CLQueueContextFactory<C> factory, Collection<CLCommandQueue> queues) {
+ return new CLCommandQueuePool(factory, queues);
+ }
+
+ /**
+ * Submits this task to the pool for execution returning its {@link Future}.
+ * @see ExecutorService#submit(java.util.concurrent.Callable)
+ */
+ public <R> Future<R> submit(CLTask<? super C, R> 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 <R> List<Future<R>> submitAll(Collection<? extends CLTask<? super C, R>> tasks) {
+ List<Future<R>> futures = new ArrayList<Future<R>>(tasks.size());
+ for (CLTask<? super C, R> 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 <R> List<Future<R>> invokeAll(Collection<? extends CLTask<? super C, R>> tasks) throws InterruptedException {
+ List<TaskWrapper<C, R>> wrapper = wrapTasks(tasks);
+ return excecutor.invokeAll(wrapper);
+ }
+
+ /**
+ * 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 <R> List<Future<R>> invokeAll(Collection<? extends CLTask<? super C, R>> tasks, long timeout, TimeUnit unit) throws InterruptedException {
+ List<TaskWrapper<C, R>> wrapper = wrapTasks(tasks);
+ return excecutor.invokeAll(wrapper, timeout, unit);
+ }
+
+ private <R> List<TaskWrapper<C, R>> wrapTasks(Collection<? extends CLTask<? super C, R>> tasks) {
+ List<TaskWrapper<C, R>> wrapper = new ArrayList<TaskWrapper<C, R>>(tasks.size());
+ for (CLTask<? super C, R> task : tasks) {
+ if(task == null) {
+ throw new NullPointerException("at least one task was null");
+ }
+ wrapper.add(new TaskWrapper<C, R>(task, finishAction));
+ }
+ return 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.
+ * @return this
+ */
+ 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.
+ */
+ public void flushQueues() {
+ for (CLQueueContext context : contexts) {
+ context.queue.flush();
+ }
+ }
+
+ /**
+ * Calls {@link CLCommandQueue#finish()} on all queues.
+ */
+ public void finishQueues() {
+ for (CLQueueContext context : contexts) {
+ context.queue.finish();
+ }
+ }
+
+ /**
+ * Releases all queues.
+ */
+ public void release() {
+ excecutor.shutdown();
+ for (CLQueueContext context : contexts) {
+ context.queue.finish().release();
+ context.release();
+ }
+ }
+
+ /**
+ * Returns the command queues used in this pool.
+ */
+ public List<CLCommandQueue> getQueues() {
+ List<CLCommandQueue> queues = new ArrayList<CLCommandQueue>(contexts.size());
+ for (CLQueueContext context : contexts) {
+ queues.add(context.queue);
+ }
+ return queues;
+ }
+
+ /**
+ * Returns the size of this pool (number of command queues).
+ */
+ public int getSize() {
+ return contexts.size();
+ }
+
+ public FinishAction getFinishAction() {
+ 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;
+ }
+
+ @Override
+ public String toString() {
+ return getClass().getSimpleName()+" [queues: "+contexts.size()+" on finish: "+finishAction+"]";
+ }
+
+ private static class QueueThreadFactory implements ThreadFactory {
+
+ private final List<CLQueueContext> context;
+ private int index;
+
+ private QueueThreadFactory(List<CLQueueContext> queues) {
+ this.context = queues;
+ this.index = 0;
+ }
+
+ public synchronized Thread newThread(Runnable runnable) {
+
+ SecurityManager sm = System.getSecurityManager();
+ ThreadGroup group = (sm != null) ? sm.getThreadGroup() : Thread.currentThread().getThreadGroup();
+
+ CLQueueContext queue = context.get(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(ThreadGroup group, Runnable runnable, CLQueueContext context, int index) {
+ super(group, runnable, "queue-worker-thread-"+index+"["+context+"]");
+ this.context = context;
+ }
+ }
+
+ private static class TaskWrapper<C extends CLQueueContext, R> implements Callable<R> {
+
+ private final CLTask<? super C, R> task;
+ private final FinishAction mode;
+
+ public TaskWrapper(CLTask<? super C, R> task, FinishAction mode) {
+ this.task = task;
+ this.mode = mode;
+ }
+
+ public R call() throws Exception {
+ CLQueueContext context = ((QueueThread)Thread.currentThread()).context;
+ R result = task.execute((C)context);
+ if(mode.equals(FinishAction.FLUSH)) {
+ context.queue.flush();
+ }else if(mode.equals(FinishAction.FINISH)) {
+ context.queue.finish();
+ }
+ return result;
+ }
+
+ }
+
+ /**
+ * The action executed after a task completes.
+ */
+ public enum FinishAction {
+
+ /**
+ * Does nothing, the task is responsible to make sure all computations
+ * have finished when the task finishes
+ */
+ DO_NOTHING,
+
+ /**
+ * Flushes the queue on task completion.
+ */
+ FLUSH,
+
+ /**
+ * Finishes the queue on task completion.
+ */
+ FINISH
+ }
+
+}
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..3f89ad0e
--- /dev/null
+++ b/src/com/jogamp/opencl/util/concurrent/CLQueueContext.java
@@ -0,0 +1,72 @@
+/*
+ * Created on Friday, May 06 2011 21:02
+ */
+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;
+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.
+ * <p>
+ * Possible candidates for those resources can be compiled CLPrograms, CLKernels
+ * or even pre allocated CLBuffers.
+ * </p>
+ * @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 CLContext getCLContext() {
+ 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;
+ public final Map<String, CLKernel> kernels;
+
+ public CLSimpleQueueContext(CLCommandQueue queue, CLProgram program) {
+ super(queue);
+ this.program = program;
+ this.kernels = program.createCLKernels();
+ }
+
+ public Map<String, CLKernel> getKernels() {
+ return kernels;
+ }
+
+ public CLKernel getKernel(String name) {
+ return kernels.get(name);
+ }
+
+ public CLProgram getProgram() {
+ return program;
+ }
+
+ public void release() {
+ program.release();
+ }
+
+ }
+
+}
diff --git a/src/com/jogamp/opencl/util/concurrent/CLQueueContextFactory.java b/src/com/jogamp/opencl/util/concurrent/CLQueueContextFactory.java
new file mode 100644
index 00000000..58f389bf
--- /dev/null
+++ b/src/com/jogamp/opencl/util/concurrent/CLQueueContextFactory.java
@@ -0,0 +1,51 @@
+/*
+ * Created onSaturday, May 07 2011 00:40
+ */
+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<C extends CLQueueContext> {
+
+ /**
+ * Creates a new queue context for the given queue.
+ * @param old the old context or null.
+ */
+ public abstract C setup(CLCommandQueue queue, CLQueueContext old);
+
+
+ /**
+ * Creates a simple context factory producing single program contexts.
+ * @param source sourcecode of a OpenCL program.
+ */
+ public static CLSimpleContextFactory createSimple(String source) {
+ return new CLSimpleContextFactory(source);
+ }
+
+ /**
+ * Creates {@link CLSimpleQueueContext}s containing a precompiled program.
+ * @author Michael Bien
+ */
+ public static class CLSimpleContextFactory extends CLQueueContextFactory<CLSimpleQueueContext> {
+
+ private final String source;
+
+ public CLSimpleContextFactory(String source) {
+ this.source = source;
+ }
+
+ @Override
+ public CLSimpleQueueContext setup(CLCommandQueue queue, CLQueueContext old) {
+ CLProgram program = queue.getContext().createProgram(source).build(queue.getDevice());
+ return new CLSimpleQueueContext(queue, program);
+ }
+
+ }
+
+}
diff --git a/src/com/jogamp/opencl/util/concurrent/CLTask.java b/src/com/jogamp/opencl/util/concurrent/CLTask.java
new file mode 100644
index 00000000..0cfd24a5
--- /dev/null
+++ b/src/com/jogamp/opencl/util/concurrent/CLTask.java
@@ -0,0 +1,18 @@
+/*
+ * Created on Tuesday, May 03 2011 18:09
+ */
+package com.jogamp.opencl.util.concurrent;
+
+
+/**
+ * A task executed on a command queue.
+ * @author Michael Bien
+ */
+public interface CLTask<C extends CLQueueContext, R> {
+
+ /**
+ * Runs the task on a queue and returns a result.
+ */
+ R execute(C context);
+
+}