summaryrefslogtreecommitdiffstats
path: root/src/com/jogamp/opencl
diff options
context:
space:
mode:
Diffstat (limited to 'src/com/jogamp/opencl')
-rw-r--r--src/com/jogamp/opencl/util/CLMultiContext.java144
1 files changed, 144 insertions, 0 deletions
diff --git a/src/com/jogamp/opencl/util/CLMultiContext.java b/src/com/jogamp/opencl/util/CLMultiContext.java
new file mode 100644
index 00000000..f45df90f
--- /dev/null
+++ b/src/com/jogamp/opencl/util/CLMultiContext.java
@@ -0,0 +1,144 @@
+/*
+ * 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) {
+ 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) {
+
+ 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();
+ CLContext context = CLContext.create(list.toArray(new CLDevice[list.size()]));
+ 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]";
+ }
+
+
+
+}