diff options
-rw-r--r-- | src/com/mbien/opencl/CLCommandQueue.java | 5 | ||||
-rw-r--r-- | src/com/mbien/opencl/CLEvent.java | 4 | ||||
-rw-r--r-- | test/com/mbien/opencl/CLBufferTest.java | 94 | ||||
-rw-r--r-- | test/com/mbien/opencl/CLConcurrencyTest.java | 83 | ||||
-rw-r--r-- | test/com/mbien/opencl/HighLevelBindingTest.java | 91 | ||||
-rw-r--r-- | test/com/mbien/opencl/TestUtils.java | 23 |
6 files changed, 206 insertions, 94 deletions
diff --git a/src/com/mbien/opencl/CLCommandQueue.java b/src/com/mbien/opencl/CLCommandQueue.java index dd2ab075..38ec7274 100644 --- a/src/com/mbien/opencl/CLCommandQueue.java +++ b/src/com/mbien/opencl/CLCommandQueue.java @@ -177,7 +177,7 @@ public class CLCommandQueue implements CLResource { } public CLCommandQueue putWaitForEvent(CLEventList list, int index) { - int marker = list.IDs.position(); + int marker = list.IDs.position()-1; list.IDs.position(index); int ret = cl.clWaitForEvents(1, list.IDs); list.IDs.position(marker); @@ -186,6 +186,7 @@ public class CLCommandQueue implements CLResource { } public CLCommandQueue putWaitForEvents(CLEventList list) { + list.IDs.rewind(); int ret = cl.clWaitForEvents(list.size, list.IDs); checkForError(ret, "error while waiting for events"); return this; @@ -217,7 +218,7 @@ public class CLCommandQueue implements CLResource { locWS = bufferC.put(1, localWorkSize).position(1); } - this.putNDRangeKernel(kernel, 1, globWO, globWS, locWS); + this.putNDRangeKernel(kernel, events, 1, globWO, globWS, locWS); return this; } diff --git a/src/com/mbien/opencl/CLEvent.java b/src/com/mbien/opencl/CLEvent.java index 45117bc6..0855ec7e 100644 --- a/src/com/mbien/opencl/CLEvent.java +++ b/src/com/mbien/opencl/CLEvent.java @@ -3,6 +3,7 @@ package com.mbien.opencl; import java.nio.Buffer; import static com.mbien.opencl.CL.*; +import static com.mbien.opencl.CLException.*; /** * @@ -25,7 +26,8 @@ public class CLEvent implements CLResource { } public void release() { - throw new UnsupportedOperationException("Not supported yet."); + int ret = cl.clReleaseEvent(ID); + checkForError(ret, "can not release event"); } public ExecutionStatus getStatus() { diff --git a/test/com/mbien/opencl/CLBufferTest.java b/test/com/mbien/opencl/CLBufferTest.java new file mode 100644 index 00000000..5395ef6f --- /dev/null +++ b/test/com/mbien/opencl/CLBufferTest.java @@ -0,0 +1,94 @@ +package com.mbien.opencl; + +import com.mbien.opencl.CLBuffer.Mem; +import com.sun.opengl.util.BufferUtil; +import java.nio.ByteBuffer; +import org.junit.Test; + +import static org.junit.Assert.*; +import static java.lang.System.*; +import static com.mbien.opencl.TestUtils.*; +import static com.sun.gluegen.runtime.BufferFactory.*; + +/** + * + * @author Michael Bien + */ +public class CLBufferTest { + + @Test + public void writeCopyReadBufferTest() { + + out.println(" - - - highLevelTest; copy buffer test - - - "); + + final int elements = NUM_ELEMENTS; + + CLContext context = CLContext.create(); + + // the CL.MEM_* flag is probably completly irrelevant in our case since we do not use a kernel in this test + CLBuffer<ByteBuffer> clBufferA = context.createByteBuffer(elements*SIZEOF_INT, Mem.READ_ONLY); + CLBuffer<ByteBuffer> clBufferB = context.createByteBuffer(elements*SIZEOF_INT, Mem.READ_ONLY); + + // fill only first read buffer -> we will copy the payload to the second later. + fillBuffer(clBufferA.buffer, 12345); + + CLCommandQueue queue = context.getCLDevices()[0].createCommandQueue(); + + // asynchronous write of data to GPU device, blocking read later to get the computed results back. + queue.putWriteBuffer(clBufferA, false) // write A + .putCopyBuffer(clBufferA, clBufferB, clBufferA.buffer.capacity()) // copy A -> B + .putReadBuffer(clBufferB, true) // read B + .finish(); + + context.release(); + + out.println("validating computed results..."); + checkIfEqual(clBufferA.buffer, clBufferB.buffer, elements); + out.println("results are valid"); + + } + + @Test + public void bufferWithHostPointerTest() { + + out.println(" - - - highLevelTest; host pointer test - - - "); + + final int elements = NUM_ELEMENTS; + + CLContext context = CLContext.create(); + + ByteBuffer buffer = BufferUtil.newByteBuffer(elements*SIZEOF_INT); + // fill only first read buffer -> we will copy the payload to the second later. + fillBuffer(buffer, 12345); + + CLCommandQueue queue = context.getCLDevices()[0].createCommandQueue(); + + Mem[] bufferConfig = new Mem[] {Mem.COPY_BUFFER, Mem.USE_BUFFER}; + + for(int i = 0; i < bufferConfig.length; i++) { + + out.println("testing with "+bufferConfig[i] + " config"); + + CLBuffer<ByteBuffer> clBufferA = context.createBuffer(buffer, Mem.READ_ONLY, bufferConfig[i]); + CLBuffer<ByteBuffer> clBufferB = context.createByteBuffer(elements*SIZEOF_INT, Mem.READ_ONLY); + + // asynchronous write of data to GPU device, blocking read later to get the computed results back. + queue.putCopyBuffer(clBufferA, clBufferB, clBufferA.buffer.capacity()) // copy A -> B + .putReadBuffer(clBufferB, true) // read B + .finish(); + + assertEquals(2, context.getCLBuffers().size()); + clBufferA.release(); + assertEquals(1, context.getCLBuffers().size()); + clBufferB.release(); + assertEquals(0, context.getCLBuffers().size()); + + // uploading worked when a==b. + out.println("validating computed results..."); + checkIfEqual(clBufferA.buffer, clBufferB.buffer, elements); + out.println("results are valid"); + } + + context.release(); + } +} diff --git a/test/com/mbien/opencl/CLConcurrencyTest.java b/test/com/mbien/opencl/CLConcurrencyTest.java new file mode 100644 index 00000000..057b57ee --- /dev/null +++ b/test/com/mbien/opencl/CLConcurrencyTest.java @@ -0,0 +1,83 @@ +package com.mbien.opencl; + +import com.mbien.opencl.CLBuffer.Mem; +import com.mbien.opencl.CLCommandQueue.Mode; +import java.io.IOException; +import java.nio.ByteBuffer; +import org.junit.Test; + +import static org.junit.Assert.*; +import static java.lang.System.*; +import static com.mbien.opencl.TestUtils.*; +import static com.sun.gluegen.runtime.BufferFactory.*; + +/** + * + * @author Michael Bien + */ +public class CLConcurrencyTest { + + @Test + public void testEvents() throws IOException { + + out.println(" - - - event synchronisation test - - - "); + + final int elements = ONE_MB/SIZEOF_INT * 5; // 5MB per buffer + + CLContext context = CLContext.create(); + + CLBuffer<ByteBuffer> clBufferA = context.createByteBuffer(elements*SIZEOF_INT, Mem.READ_ONLY); + CLBuffer<ByteBuffer> clBufferB = context.createByteBuffer(elements*SIZEOF_INT, Mem.READ_ONLY); + CLBuffer<ByteBuffer> clBufferC = context.createByteBuffer(elements*SIZEOF_INT, Mem.READ_ONLY); + CLBuffer<ByteBuffer> clBufferD = context.createByteBuffer(elements*SIZEOF_INT, Mem.READ_ONLY); + + fillBuffer(clBufferA.buffer, 12345); + fillBuffer(clBufferB.buffer, 67890); + + CLProgram program = context.createProgram(getClass().getResourceAsStream("testkernels.cl")).build(); + + CLKernel vectorAddKernel = program.getCLKernel("VectorAddGM") + .setArg(3, elements); + + CLCommandQueue queue = context.getCLDevices()[0].createCommandQueue(); + + final CLEventList events = new CLEventList(2); + + assertEquals(0, events.size()); + + // asynchronous write of data to GPU device, blocking read later to get the computed results back. + queue.putWriteBuffer(clBufferA, events, false) // write A + .putWriteBuffer(clBufferB, events, false); // write B + + assertEquals(2, events.size()); + queue.putWaitForEvents(events); + + events.release(); + assertEquals(0, events.size()); + + vectorAddKernel.setArgs(clBufferA, clBufferB, clBufferC); // C = A+B + queue.put1DRangeKernel(vectorAddKernel, events, 0, elements, 256); + + vectorAddKernel.setArgs(clBufferA, clBufferB, clBufferD); // D = A+B + queue.put1DRangeKernel(vectorAddKernel, events, 0, elements, 256); + + assertEquals(2, events.size()); + queue.putWaitForEvent(events, 0) + .putWaitForEvent(events, 1); + + queue.putReadBuffer(clBufferC, false) + .putReadBuffer(clBufferD, true); + + events.release(); + + checkIfEqual(clBufferC.buffer, clBufferD.buffer, elements); + + + context.release(); + + + out.println("results are valid"); + + } + +}
\ No newline at end of file diff --git a/test/com/mbien/opencl/HighLevelBindingTest.java b/test/com/mbien/opencl/HighLevelBindingTest.java index da1080d1..cf19c5b1 100644 --- a/test/com/mbien/opencl/HighLevelBindingTest.java +++ b/test/com/mbien/opencl/HighLevelBindingTest.java @@ -3,7 +3,6 @@ package com.mbien.opencl; import com.mbien.opencl.CLBuffer.Mem; import com.mbien.opencl.CLCommandQueue.Mode; import com.mbien.opencl.CLDevice.SingleFPConfig; -import com.sun.opengl.util.BufferUtil; import java.io.IOException; import java.nio.ByteBuffer; import java.util.EnumSet; @@ -22,9 +21,6 @@ import static com.sun.gluegen.runtime.BufferFactory.*; */ public class HighLevelBindingTest { - //decrease this value on systems with few memory. - private final static int NUM_ELEMENTS = 10000000; - @BeforeClass public static void setUpClass() throws Exception { out.println("OS: " + System.getProperty("os.name")); @@ -187,79 +183,6 @@ public class HighLevelBindingTest { } @Test - public void writeCopyReadBufferTest() throws IOException { - - out.println(" - - - highLevelTest; copy buffer test - - - "); - - final int elements = NUM_ELEMENTS; - - CLContext context = CLContext.create(); - - // the CL.MEM_* flag is probably completly irrelevant in our case since we do not use a kernel in this test - CLBuffer<ByteBuffer> clBufferA = context.createByteBuffer(elements*SIZEOF_INT, Mem.READ_ONLY); - CLBuffer<ByteBuffer> clBufferB = context.createByteBuffer(elements*SIZEOF_INT, Mem.READ_ONLY); - - // fill only first read buffer -> we will copy the payload to the second later. - fillBuffer(clBufferA.buffer, 12345); - - CLCommandQueue queue = context.getCLDevices()[0].createCommandQueue(); - - // asynchronous write of data to GPU device, blocking read later to get the computed results back. - queue.putWriteBuffer(clBufferA, false) // write A - .putCopyBuffer(clBufferA, clBufferB, clBufferA.buffer.capacity()) // copy A -> B - .putReadBuffer(clBufferB, true) // read B - .finish(); - - context.release(); - - out.println("validating computed results..."); - checkIfEqual(clBufferA.buffer, clBufferB.buffer, elements); - out.println("results are valid"); - - } - - @Test - public void bufferWithHostPointerTest() throws IOException { - - out.println(" - - - highLevelTest; host pointer test - - - "); - - final int elements = NUM_ELEMENTS; - - CLContext context = CLContext.create(); - - ByteBuffer buffer = BufferUtil.newByteBuffer(elements*SIZEOF_INT); - // fill only first read buffer -> we will copy the payload to the second later. - fillBuffer(buffer, 12345); - - CLCommandQueue queue = context.getCLDevices()[0].createCommandQueue(); - - Mem[] bufferConfig = new Mem[] {Mem.COPY_BUFFER, Mem.USE_BUFFER}; - - for(int i = 0; i < bufferConfig.length; i++) { - - out.println("testing with "+bufferConfig[i] + " config"); - - CLBuffer<ByteBuffer> clBufferA = context.createBuffer(buffer, Mem.READ_ONLY, bufferConfig[i]); - CLBuffer<ByteBuffer> clBufferB = context.createByteBuffer(elements*SIZEOF_INT, Mem.READ_ONLY); - - // asynchronous write of data to GPU device, blocking read later to get the computed results back. - queue.putCopyBuffer(clBufferA, clBufferB, clBufferA.buffer.capacity()) // copy A -> B - .putReadBuffer(clBufferB, true) // read B - .finish(); - - clBufferA.release(); - clBufferB.release(); - - // uploading worked when a==b. - out.println("validating computed results..."); - checkIfEqual(clBufferA.buffer, clBufferB.buffer, elements); - out.println("results are valid"); - } - - context.release(); - } - - @Test public void rebuildProgramTest() throws IOException { out.println(" - - - highLevelTest; rebuild program test - - - "); @@ -300,19 +223,5 @@ public class HighLevelBindingTest { } - private final void checkIfEqual(ByteBuffer a, ByteBuffer b, int elements) { - for(int i = 0; i < elements; i++) { - int aVal = a.getInt(); - int bVal = b.getInt(); - if(aVal != bVal) { - out.println("a: "+aVal); - out.println("b: "+bVal); - out.println("position: "+a.position()); - fail("a!=b"); - } - } - a.rewind(); - b.rewind(); - } } diff --git a/test/com/mbien/opencl/TestUtils.java b/test/com/mbien/opencl/TestUtils.java index 70bade8a..803474e5 100644 --- a/test/com/mbien/opencl/TestUtils.java +++ b/test/com/mbien/opencl/TestUtils.java @@ -3,11 +3,19 @@ package com.mbien.opencl; import java.nio.ByteBuffer; import java.util.Random; +import static java.lang.System.*; +import static org.junit.Assert.*; + /** * @author Michael Bien */ public class TestUtils { + //decrease this value on systems with few memory. + final static int ONE_MB = 1048576; + + final static int NUM_ELEMENTS = 10000000; + public static final void fillBuffer(ByteBuffer buffer, int seed) { Random rnd = new Random(seed); @@ -26,4 +34,19 @@ public class TestUtils { return globalSize + groupSize - r; } } + + public static final void checkIfEqual(ByteBuffer a, ByteBuffer b, int elements) { + for(int i = 0; i < elements; i++) { + int aVal = a.getInt(); + int bVal = b.getInt(); + if(aVal != bVal) { + out.println("a: "+aVal); + out.println("b: "+bVal); + out.println("position: "+a.position()); + fail("a!=b"); + } + } + a.rewind(); + b.rewind(); + } } |