Package com.jogamp.opencl.util

Source Code of com.jogamp.opencl.util.CLMultiContext

/*
* 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.Arrays;
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 boolean released;

    private CLMultiContext() {
        contexts = new ArrayList<CLContext>();
    }

    /**
     * Creates a multi context with all devices of the specified platforms.
     */
    @SuppressWarnings("unchecked")
    public static CLMultiContext create(CLPlatform... platforms) {
        return create(platforms, CLDeviceFilters.type(ALL));
    }

    /**
     * Creates a multi context with all matching devices of the specified platforms.
     */
    public static CLMultiContext create(CLPlatform[] platforms, Filter<CLDevice>... filters) {
        return create(Arrays.asList(platforms), filters);
    }

    /**
     * Creates a multi context with all matching devices of the specified platforms.
     */
    public static CLMultiContext create(Collection<CLPlatform> platforms, Filter<CLDevice>... filters) {

        if(platforms == null) {
            throw new NullPointerException("platform list was null");
        }else if(platforms.isEmpty()) {
            throw new IllegalArgumentException("platform list was empty");
        }

        List<CLDevice> devices = new ArrayList<CLDevice>();
        for (CLPlatform platform : platforms) {
            devices.addAll(asList(platform.listCLDevices(filters)));
        }
        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<? extends 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<? extends 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()
     */
    @Override
    public void release() {
        if(released) {
            throw new RuntimeException(getClass().getSimpleName()+" already released");
        }
        released = true;
        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 boolean isReleased() {
        return released;
    }

    @Override
    public String toString() {
        return getClass().getSimpleName()+" [" + contexts.size()+" contexts, "
                                               + getDevices().size()+ " devices]";
    }



}
TOP

Related Classes of com.jogamp.opencl.util.CLMultiContext

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.