package com.nativelibs4java.opencl;
import java.nio.LongBuffer;
import java.util.Random;
import junit.framework.TestCase;
import com.nativelibs4java.util.IOUtils;
import com.nativelibs4java.util.NIOUtils;
import com.nativelibs4java.opencl.CLContext;
import com.nativelibs4java.opencl.CLDevice;
import com.nativelibs4java.opencl.CLEvent;
import com.nativelibs4java.opencl.CLKernel;
import com.nativelibs4java.opencl.CLMem;
import com.nativelibs4java.opencl.CLProgram;
import com.nativelibs4java.opencl.CLQueue;
import com.nativelibs4java.opencl.JavaCL;
import org.bridj.Pointer;
public class BufferReadTest extends TestCase {
private CLProgram program;
private CLContext context;
private CLQueue q;
private Random r;
@Override
protected void setUp() throws Exception {
super.setUp();
r = new Random(2011);
initializeCLStuff();
compileProgram();
}
@Override
protected void tearDown() throws Exception {
super.tearDown();
if(context != null)
context.release();
if(q != null)
q.release();
if(program != null)
program.release();
context = null;
q = null;
program = null;
}
public void testBufferRead() throws Exception {
int size = 50;
CLKernel kernel = program.createKernel("testLongRead");
CLBuffer<Long> clInBuff = context.createLongBuffer(CLMem.Usage.Input, size);
CLBuffer<Long> clOutBuff = context.createLongBuffer(CLMem.Usage.Output, size);
long[] longArray = new long[size];
for(int i = 0; i < longArray.length ; i ++) {
longArray[i] = i;
}
clInBuff.write(q, Pointer.pointerToLongs(longArray), true);
kernel.setArg(0, clInBuff);
kernel.setArg(1, clOutBuff);
CLEvent completion = kernel.enqueueNDRange(q, new int[] {size});
completion.waitFor();
///////////////////////////////////////////////////
//we tried to make a buffer before the clOutBuff.read() so that it isn't creating new ones
//this way when we're on a loop we won't have to waste memory creating more buffers
//we thought that the read would simply read everything into the LongBuffer,
//and since the LongBuffer is wrapped around the outPrim, it would update the values as soon as it is read.
long[] outPrim = new long[size];
if (false) {
Pointer<Long> outBuffJava = Pointer.pointerToLongs(outPrim);
clOutBuff.read(q, 0, size,outBuffJava, true);
} else {
Pointer<Long> outBuffJava = Pointer.allocateLongs(size).order(context.getByteOrder());
clOutBuff.read(q, 0, size,outBuffJava, true);
//LongBuffer outBuffJava = clOutBuff.read(q, 0, size);
outBuffJava.getLongs(outPrim);
}
System.out.println("test1:\nThese should read 1, 2, 3, 4, 5");
for(int i = 0 ; i < 5 ; i ++) {
System.out.print(outPrim[i] + ", ");
}
System.out.println();
////////////////////////////////////////////////////
//this is the way that we know works, but it creates a new LongBuffer every read, and we also have to do a
//outBuffJava2.get(), which forces us to separate the outPrim2 from the java LongBuffer, and require us to create a new array.
Pointer<Long> outBuffJava2 = clOutBuff.read(q);
long[] outPrim2 = new long[size];
outBuffJava2.getLongs(outPrim2);
System.out.println("test2:\nThese should read 1, 2, 3, 4, 5");
for(int i = 0 ; i < 5 ; i ++) {
System.out.print(outPrim2[i] + ", ");
}
System.out.println();
}
private void initializeCLStuff() {
initializeCLContextAndQueueOrNothing(0, 0);
}
private void compileProgram() throws Exception{
String sources = IOUtils.readText(BufferReadTest.class.getResourceAsStream("BufferReadTest.c"));
program = context.createProgram(sources).build();
}
private synchronized void initializeCLContextAndQueueOrNothing(int platformNumber, int deviceNumber) {
//should check for index out of bounds later. need to figure out how I should throw the errors
if(context==null || q == null) {
CLDevice device = JavaCL.listPlatforms()[platformNumber].listAllDevices(false)[deviceNumber];
System.out.println("Device = " + device);
context = (JavaCL.createContext(null, device));
q = (context.createDefaultQueue());
}
}
}