package edu.stanford.rsl.conrad.opencl.shapes;
import java.util.ArrayList;
import edu.stanford.rsl.conrad.geometry.shapes.simple.PointND;
import edu.stanford.rsl.conrad.geometry.splines.BSpline;
import edu.stanford.rsl.conrad.opencl.OpenCLEvaluatable;
import edu.stanford.rsl.conrad.opencl.OpenCLUtil;
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 java.nio.FloatBuffer;
public class OpenCLUniformBSpline extends BSpline implements OpenCLEvaluatable {
CLContext context;
CLDevice device;
CLBuffer<FloatBuffer> controlPoints;
public OpenCLUniformBSpline(BSpline s, CLDevice device) {
this(s.getControlPoints(), s.getKnots(), device);
}
public OpenCLUniformBSpline(ArrayList<PointND> controlPoints,
double[] uVector, CLDevice device) {
super(controlPoints, uVector);
this.context = device.getContext();
this.device = device;
OpenCLUtil.initProgram(context);
handleControlPoints(controlPoints);
}
protected void handleControlPoints(ArrayList<PointND> controlPoints){
this.controlPoints = context.createFloatBuffer(controlPoints.size()*3, Mem.READ_ONLY);
for(int i=0;i<controlPoints.size();i++) {
this.controlPoints.getBuffer().put((float)controlPoints.get(i).get(0));
this.controlPoints.getBuffer().put((float)controlPoints.get(i).get(1));
this.controlPoints.getBuffer().put((float)controlPoints.get(i).get(2));
}
this.controlPoints.getBuffer().rewind();
device.createCommandQueue().putWriteBuffer(this.controlPoints, true);
}
@Override
public void evaluate(CLBuffer<FloatBuffer> samplingPoints, CLBuffer<FloatBuffer> outputBuffer){
int elementCount = samplingPoints.getBuffer().capacity(); // Length of arrays to process
int localWorkSize = Math.min(device.getMaxWorkGroupSize(), 256); // Local work size dimensions
int globalWorkSize = OpenCLUtil.roundUp(localWorkSize, elementCount); // rounded up to the nearest multiple of the localWorkSize
CLKernel kernel = OpenCLUtil.getProgramInstance().createCLKernel("evaluate");
kernel.putArgs(controlPoints, samplingPoints, outputBuffer)
.putArg(getKnots().length)
.putArg(getControlPoints().size())
.putArg(elementCount);
CLCommandQueue clc = device.createCommandQueue();
clc.put1DRangeKernel(kernel, 0, globalWorkSize, localWorkSize).finish();
kernel.release();
clc.release();
}
@Override
public void evaluate(CLBuffer<FloatBuffer> samplingPoints, CLBuffer<FloatBuffer> outputBuffer, int elementCountU, int elementCountV) {
evaluate(samplingPoints, outputBuffer);
}
/**
*
*/
private static final long serialVersionUID = 5895570242152310515L;
@Override
public boolean isClockwise() {
// TODO Auto-generated method stub
return false;
}
@Override
public boolean isTimeVariant() {
return false;
}
}
/*
* Copyright (C) 2010-2014 Andreas Maier
* CONRAD is developed as an Open Source project under the GNU General Public License (GPL).
*/