001/*
002 * To change this template, choose Tools | Templates
003 * and open the template in the editor.
004 */
005
006package com.nativelibs4java.opencl.util;
007
008import com.nativelibs4java.opencl.CLBuffer;
009import com.nativelibs4java.opencl.CLBuildException;
010import com.nativelibs4java.opencl.CLContext;
011import com.nativelibs4java.opencl.CLEvent;
012import com.nativelibs4java.opencl.CLException;
013import com.nativelibs4java.opencl.CLMem;
014import com.nativelibs4java.opencl.CLQueue;
015import com.nativelibs4java.util.NIOUtils;
016import java.nio.Buffer;
017import java.nio.DoubleBuffer;
018import java.nio.FloatBuffer;
019
020import org.bridj.*;
021import static org.bridj.Pointer.*;
022
023/**
024 * Generic homogeneous transformer class
025 * @author ochafik
026 * @param <A> primitive array class that represents the data consumed and produced by this transformer
027 */
028public interface Transformer<T, A> {
029        CLContext getContext();
030    A transform(CLQueue queue, A input, boolean inverse);
031    //B transform(CLQueue queue, B input, boolean inverse);
032    Pointer<T> transform(CLQueue queue, Pointer<T> input, boolean inverse);
033    CLEvent transform(CLQueue queue, CLBuffer<T> input, CLBuffer<T> output, boolean inverse, CLEvent... eventsToWaitFor) throws CLException;
034    long computeOutputSize(long inputSize);
035    
036    public abstract class AbstractTransformer<T, A> implements Transformer<T, A> {
037        protected final Class<T> primitiveClass;
038        protected final CLContext context;
039
040        public AbstractTransformer(CLContext context, Class<T> primitiveClass) {
041            this.primitiveClass = primitiveClass;
042            this.context = context;
043        }
044        
045        public CLContext getContext() { return context; }
046
047        public long computeOutputSize(long inputSize) {
048            return inputSize;
049        }
050
051        
052        public A transform(CLQueue queue, A input, boolean inverse) {
053                        return (A)transform(queue, (Pointer<T>)pointerToArray(input), inverse).getArray();
054        }
055        public Pointer<T> transform(CLQueue queue, Pointer<T> in, boolean inverse) {
056            long inputSize = (int)in.getValidElements();
057            long length = inputSize / 2;
058
059            CLBuffer<T> inBuf = context.createBuffer(CLMem.Usage.Input, in, true); // true = copy
060            CLBuffer<T> outBuf = context.createBuffer(CLMem.Usage.Output, primitiveClass, computeOutputSize(inputSize));
061
062            CLEvent dftEvt = transform(queue, inBuf, outBuf, inverse);
063            inBuf.release();
064            
065            Pointer<T> out = outBuf.read(queue, dftEvt);
066            outBuf.release();
067            return out;
068        }
069
070    }
071}