diff options
author | Michael Bien <[email protected]> | 2011-05-03 16:32:29 +0200 |
---|---|---|
committer | Michael Bien <[email protected]> | 2011-05-03 16:32:29 +0200 |
commit | 6fcf15f11e2a982b480855fbc75e430e5f2b9ad6 (patch) | |
tree | c59825ed494930d7ab052272e5e0cb6c3875bf18 | |
parent | 3a149a209e905d05bf05c31f94f7a57c6f79250e (diff) |
initial import of CLMultiContext utility and test.
-rw-r--r-- | src/com/jogamp/opencl/util/CLMultiContext.java | 144 | ||||
-rw-r--r-- | test/com/jogamp/opencl/CLMultiContextTest.java | 51 |
2 files changed, 195 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]"; + } + + + +} 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<CLContext> contexts = mc.getContexts(); + List<CLDevice> 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(); + } + + } + + +} |