/*
* Copyright (C) 2014 - Andreas Maier, Magdalena Herbst, Michael Dorner, Salah Saleh, Anja Pohan, Stefan Nottrott, Frank Schebesch, Martin Berger
* CONRAD is developed as an Open Source project under the GNU General Public License (GPL).
*/
package edu.stanford.rsl.conrad.data.numeric.opencl;
import java.io.InputStream;
import java.nio.FloatBuffer;
import com.jogamp.opencl.CLBuffer;
import com.jogamp.opencl.CLCommandQueue;
import com.jogamp.opencl.CLContext;
import com.jogamp.opencl.CLDevice;
import com.jogamp.opencl.CLKernel;
import com.jogamp.opencl.CLMemory.Mem;
import edu.stanford.rsl.conrad.data.numeric.NumericGrid;
/**
* This is an extension to 'OpenCLGridOperators'. Here you can implement your own kernels and other ideas.
* All 'runKernel(...)' methods are not meant to be 'protected' or 'public', they belong to the class OpenCLGridOperators exclusively.
* If you move your new code to 'OpenCLGridOperators', you are welcome to use this methods.
* Unfortunately I have not found a good solution for avoiding the singleton and constructor code.
* Good ideas for avoiding this boilerplate code are welcome.
*
* @author Michael Dorner
*/
public class ExtendedOpenCLGridOperators extends OpenCLGridOperators {
protected ExtendedOpenCLGridOperators() {
extendedKernelFile = "ExtendedPointwiseOperators.cl";
}
static ExtendedOpenCLGridOperators op = new ExtendedOpenCLGridOperators();
public static ExtendedOpenCLGridOperators getInstance() {
return op;
}
/**
* Returns the extended OpenCL resource file
* @return The corresponding cl kernel file as stream
*/
@Override
protected InputStream getExtendedCLResourceAsStream() {
return ExtendedOpenCLGridOperators.class.getResourceAsStream(extendedKernelFile);
}
public double sumGlobalMemory(final NumericGrid grid) {
OpenCLGridInterface clGrid = (OpenCLGridInterface)grid;
CLDevice device = clGrid.getDelegate().getCLDevice();
clGrid.getDelegate().prepareForDeviceOperation();
CLBuffer<FloatBuffer> gridBuffer = clGrid.getDelegate().getCLBuffer();
int elementCount = gridBuffer.getCLCapacity();
OpenCLSetup openCLSetup = new OpenCLSetup("sumGlobalMemory", device);
CLKernel kernel = openCLSetup.getKernel();
CLCommandQueue queue = openCLSetup.getCommandQueue();
CLContext context = openCLSetup.getContext();
int localSize = openCLSetup.getLocalSize();
int globalSize = openCLSetup.getGlobalSize(elementCount);
CLBuffer<FloatBuffer> resultBuffer = context.createFloatBuffer(elementCount, Mem.READ_ONLY);
kernel.putArg(gridBuffer).putArg(resultBuffer).putArg(elementCount);
queue.put1DRangeKernel(kernel, 0, globalSize, localSize);
queue.putReadBuffer(resultBuffer, true);
queue.finish();
double sum = 0;
while (resultBuffer.getBuffer().hasRemaining()) {
sum += resultBuffer.getBuffer().get();
}
kernel.rewind();
resultBuffer.release();
return sum;
}
}