package edu.stanford.rsl.conrad.data;
import java.nio.FloatBuffer;
import com.jogamp.opencl.CLBuffer;
import com.jogamp.opencl.CLCommandQueue;
import com.jogamp.opencl.CLContext;
import com.jogamp.opencl.CLDevice;
public abstract class OpenCLMemoryDelegate implements AutoCloseable{
protected CLBuffer<FloatBuffer> fBuffer;
protected float [] linearHostMemory;
protected CLContext context;
protected CLDevice device;
protected boolean hostChanged;
protected boolean deviceChanged;
boolean debug = false;
/**
* Returns the pointer the the CLBuffer object.
* @return the CLBuffer
*/
public CLBuffer<FloatBuffer> getCLBuffer(){
return fBuffer;
}
public float[] getBuffer(){
return linearHostMemory;
}
/**
* Call this method before you want to run a host operation on the grid.
*/
public void prepareForHostOperation() {
if (deviceChanged && hostChanged) throw new RuntimeException("Memory is in inconsistent state. Host and Device have changed independently.");
if (deviceChanged){
pull();
deviceChanged = false;
}
}
/**
* Call this method before you want to run a device operation.
*/
public void prepareForDeviceOperation() {
if (deviceChanged && hostChanged) throw new RuntimeException("Memory is in inconsistent state. Host and Device have changed independently.");
if (hostChanged){
push();
hostChanged = false;
}
}
/**
* This method sends the current data from the host memory to the device memory.
*/
public void push() {
if (debug) System.out.println("writing to device");
copyToLinearHostMemory();
fBuffer.getBuffer().put(linearHostMemory);
fBuffer.getBuffer().rewind();
CLCommandQueue queue = device.createCommandQueue();
queue.putWriteBuffer(fBuffer, true).finish();
queue.release();
fBuffer.getBuffer().rewind();
}
/**
* This method fetches the current data from the device memory to the host memory.
*/
public void pull() {
if (debug) System.out.println("writing to host");
fBuffer.getBuffer().rewind();
CLCommandQueue queue = device.createCommandQueue();
queue.putReadBuffer(fBuffer, true).finish();
queue.release();
fBuffer.getBuffer().get(linearHostMemory);
fBuffer.getBuffer().rewind();
copyFromLinearHostMemory();
}
/**
* Call this method after you performed changes in the device memory, e.g. by calling a kernel function.
*/
public void notifyDeviceChange(){
deviceChanged = true;
}
public void notifyHostChange(){
hostChanged = true;
}
/**
* release the memory from the device
*/
public void release() {
if (fBuffer!=null && !fBuffer.isReleased())
fBuffer.release();
}
public CLDevice getCLDevice() {
return device;
}
public CLContext getCLContext() {
return context;
}
@Override
public void close(){
if(debug == true)
System.out.println("Was at the autocloseable close() function!");
this.release();
}
protected abstract void copyToLinearHostMemory();
protected abstract void copyFromLinearHostMemory();
}