001package org.openimaj.image.processing;
002
003import java.io.IOException;
004import java.io.InputStream;
005import java.net.URL;
006
007import org.apache.commons.io.IOUtils;
008import org.openimaj.image.Image;
009import org.openimaj.image.analyser.ImageAnalyser;
010
011import com.nativelibs4java.opencl.CLBuildException;
012import com.nativelibs4java.opencl.CLContext;
013import com.nativelibs4java.opencl.CLKernel;
014import com.nativelibs4java.opencl.CLPlatform.DeviceFeature;
015import com.nativelibs4java.opencl.CLProgram;
016import com.nativelibs4java.opencl.JavaCL;
017
018/**
019 * Base {@link ImageAnalyser} for GPGPU accelerated analysis.
020 * 
021 * @author Jonathon Hare (jsh2@ecs.soton.ac.uk)
022 *
023 * @param <I> Type of {@link Image} being processed
024 */
025public abstract class CLImageAnalyser<I extends Image<?, I>> implements ImageAnalyser<I> {
026        protected CLContext context;
027        protected CLKernel kernel;
028
029        /**
030         * Construct with the given OpenCL program
031         * @param program the OpenCL program
032         */
033        public CLImageAnalyser(CLProgram program) {
034                try {
035                        this.context = JavaCL.createBestContext(DeviceFeature.GPU);
036                        this.kernel = program.createKernels()[0];
037                } catch (CLBuildException e) {
038                        //fallback to OpenCL on the CPU
039                        this.context = JavaCL.createBestContext(DeviceFeature.CPU);
040                        this.kernel = program.createKernels()[0];                       
041                }
042        }
043
044        /**
045         * Construct with the given OpenCL program source, given in
046         * the form of {@link String}s.
047         * 
048         * @param programSrcs the source of the program
049         */
050        public CLImageAnalyser(String... programSrcs) {
051                CLProgram program;
052                try {
053                        this.context = JavaCL.createBestContext(DeviceFeature.GPU);
054                        program = context.createProgram(programSrcs);
055                        this.kernel = program.createKernels()[0];
056                } catch (CLBuildException e) {
057                        //fallback to OpenCL on the CPU
058                        this.context = JavaCL.createBestContext(DeviceFeature.CPU);
059                        program = context.createProgram(programSrcs);
060                        this.kernel = program.createKernels()[0];
061                }
062        }
063
064        /**
065         * Construct with the program sourcecode at the given URL. 
066         * @param srcUrl the url
067         * @throws IOException
068         */
069        public CLImageAnalyser(URL srcUrl) throws IOException {
070                this(IOUtils.toString(srcUrl));
071        }
072
073        /**
074         * Construct by reading the program source from a stream
075         * @param src the source stream
076         * @throws IOException
077         */
078        public CLImageAnalyser(InputStream src) throws IOException {
079                this(IOUtils.toString(src));
080        }
081
082        /**
083         * Construct with the given OpenCL program
084         * @param context the OpenCL context to use
085         * @param program the OpenCL program
086         */
087        public CLImageAnalyser(CLContext context, CLProgram program) {
088                this.context = context;
089                this.kernel = program.createKernels()[0];
090        }
091
092        /**
093         * Construct with the given OpenCL program source, given in
094         * the form of {@link String}s.
095         * @param context the OpenCL context to use
096         * 
097         * @param programSrcs the source of the program
098         */
099        public CLImageAnalyser(CLContext context, String... programSrcs) {
100                this.context = context;
101                CLProgram program = context.createProgram(programSrcs);
102                this.kernel = program.createKernels()[0];
103        }
104        
105        /**
106         * Construct with the given OpenCL kernel
107         * @param kernel the OpenCL kernel to use
108         */
109        public CLImageAnalyser(CLKernel kernel) {
110                this.context = kernel.getProgram().getContext();
111                this.kernel = kernel;
112        }
113
114        /**
115         * Construct with the program sourcecode at the given URL. 
116         * @param context the OpenCL context to use
117         * @param srcUrl the url
118         * @throws IOException
119         */
120        public CLImageAnalyser(CLContext context, URL srcUrl) throws IOException {
121                this(context, IOUtils.toString(srcUrl));
122        }
123
124        /**
125         * Construct by reading the program source from a stream
126         * @param context the OpenCL context to use
127         * @param src the source stream
128         * @throws IOException
129         */
130        public CLImageAnalyser(CLContext context, InputStream src) throws IOException {
131                this(context, IOUtils.toString(src));
132        }
133}