From 6fcf15f11e2a982b480855fbc75e430e5f2b9ad6 Mon Sep 17 00:00:00 2001 From: Michael Bien Date: Tue, 3 May 2011 16:32:29 +0200 Subject: initial import of CLMultiContext utility and test. --- src/com/jogamp/opencl/util/CLMultiContext.java | 144 +++++++++++++++++++++++++ test/com/jogamp/opencl/CLMultiContextTest.java | 51 +++++++++ 2 files changed, 195 insertions(+) create mode 100644 src/com/jogamp/opencl/util/CLMultiContext.java create mode 100644 test/com/jogamp/opencl/CLMultiContextTest.java 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 contexts; + + private CLMultiContext() { + contexts = new ArrayList(); + } + + /** + * 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 devices = new ArrayList(); + 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 devices) { + + Map> platformDevicesMap = filterPlatformConflicts(devices); + + // create contexts + CLMultiContext mc = new CLMultiContext(); + for (Map.Entry> entry : platformDevicesMap.entrySet()) { + List 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> filterPlatformConflicts(Collection devices) { + + // FIXME: devicename-platform is used as unique device identifier - replace if we have something better + + Map> filtered = new HashMap>(); + Map used = new HashMap(); + + 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()); + } + 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 getContexts() { + return Collections.unmodifiableList(contexts); + } + + /** + * Returns a list containing all devices used in this multi context. + */ + public List getDevices() { + List devices = new ArrayList(); + 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/test/com/jogamp/opencl/CLMultiContextTest.java b/test/com/jogamp/opencl/CLMultiContextTest.java new file mode 100644 index 00000000..20274601 --- /dev/null +++ b/test/com/jogamp/opencl/CLMultiContextTest.java @@ -0,0 +1,51 @@ +/* + * Created on Tuesday, May 03 2011 + */ +package com.jogamp.opencl; + +import org.junit.Rule; +import org.junit.rules.MethodRule; +import org.junit.rules.Timeout; +import com.jogamp.opencl.util.CLMultiContext; +import java.util.List; +import org.junit.Test; + +import static org.junit.Assert.*; +import static java.lang.System.*; + +/** + * + * @author Michael Bien + */ +public class CLMultiContextTest { + + @Rule + public MethodRule methodTimeout= new Timeout(10000); + + @Test + public void createMultiContextTest() { + + CLMultiContext mc = CLMultiContext.create(CLPlatform.listCLPlatforms()); + + try{ + List contexts = mc.getContexts(); + List devices = mc.getDevices(); + + assertFalse(contexts.isEmpty()); + assertFalse(devices.isEmpty()); + + for (CLContext context : contexts) { + out.println(context); + } + for (CLDevice device : devices) { + out.println(device); + } + + }finally{ + mc.release(); + } + + } + + +} -- cgit v1.2.3