summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/com/mbien/opencl/CLBuffer.java36
-rw-r--r--test/com/mbien/opencl/HighLevelBindingTest.java77
2 files changed, 87 insertions, 26 deletions
diff --git a/src/com/mbien/opencl/CLBuffer.java b/src/com/mbien/opencl/CLBuffer.java
index 0a001f6b..fb63b6ec 100644
--- a/src/com/mbien/opencl/CLBuffer.java
+++ b/src/com/mbien/opencl/CLBuffer.java
@@ -36,17 +36,29 @@ public class CLBuffer<B extends Buffer> implements CLResource {
this.context = context;
this.cl = context.cl;
- int[] intArray = new int[1];
+ int[] result = new int[1];
if(glBuffer == 0) {
+ B host_ptr = null;
+ if(isHostPointerFlag(flags)) {
+ host_ptr = directBuffer;
+ }
this.ID = cl.clCreateBuffer(context.ID, flags,
- sizeOfBufferElem(directBuffer)*directBuffer.capacity(), null, intArray, 0);
+ sizeOfBufferElem(directBuffer)*directBuffer.capacity(), host_ptr, result, 0);
}else{
+ if(isHostPointerFlag(flags)) {
+ throw new IllegalArgumentException(
+ "CL_MEM_COPY_HOST_PTR or CL_MEM_USE_HOST_PTR can not be used with OpenGL Buffers.");
+ }
CLGLI clgli = (CLGLI)cl;
- this.ID = clgli.clCreateFromGLBuffer(context.ID, flags, glBuffer, intArray, 0);
+ this.ID = clgli.clCreateFromGLBuffer(context.ID, flags, glBuffer, result, 0);
}
- checkForError(intArray[0], "can not create cl buffer");
+ checkForError(result[0], "can not create cl buffer");
+
+ }
+ private final boolean isHostPointerFlag(int flags) {
+ return (flags & CL_MEM_COPY_HOST_PTR) != 0 || (flags & CL_MEM_USE_HOST_PTR) != 0;
}
public void release() {
@@ -127,26 +139,28 @@ public class CLBuffer<B extends Buffer> implements CLResource {
* object when used inside a kernel. Writing to a buffer or image object
* created withREAD_ONLY inside a kernel is undefined.
*/
- READ_ONLY(CL_MEM_READ_ONLY);
+ READ_ONLY(CL_MEM_READ_ONLY),
/**
+ * Enum representing CL.CL_MEM_USE_HOST_PTR.
* If specified, it indicates that the application wants the OpenCL
* implementation to use memory referenced by host_ptr as the storage
* bits for the memory object. OpenCL implementations are allowed
* to cache the buffer contents pointed to by host_ptr in device memory.
* This cached copy can be used when kernels are executed on a device.
*/
-// USE_HOST_PTR(CL_MEM_USE_HOST_PTR),
+ USE_BUFFER(CL_MEM_USE_HOST_PTR),
// ALLOC_HOST_PTR(CL_MEM_ALLOC_HOST_PTR), // this is the default in java world anyway
/**
+ * Enum representing CL.CL_MEM_COPY_HOST_PTR.
* If CL_MEM_COPY_HOST_PTR specified, it indicates that the application
* wants the OpenCL implementation to allocate memory for the memory object
* and copy the data from memory referenced by host_ptr.<br/>
* COPY_HOST_PTR and USE_HOST_PTR are mutually exclusive.
*/
-// COPY_HOST_PTR(CL_MEM_COPY_HOST_PTR);
+ COPY_BUFFER(CL_MEM_COPY_HOST_PTR);
/**
* Value of wrapped OpenCL flag.
@@ -163,12 +177,12 @@ public class CLBuffer<B extends Buffer> implements CLResource {
return READ_WRITE;
case(CL_MEM_READ_ONLY):
return READ_ONLY;
-// case(CL_MEM_USE_HOST_PTR):
-// return USE_HOST_PTR;
+ case(CL_MEM_USE_HOST_PTR):
+ return USE_BUFFER;
// case(CL_MEM_ALLOC_HOST_PTR):
// return ALLOC_HOST_PTR;
-// case(CL_MEM_COPY_HOST_PTR):
-// return COPY_HOST_PTR;
+ case(CL_MEM_COPY_HOST_PTR):
+ return COPY_BUFFER;
}
return null;
}
diff --git a/test/com/mbien/opencl/HighLevelBindingTest.java b/test/com/mbien/opencl/HighLevelBindingTest.java
index 5515cecc..da1080d1 100644
--- a/test/com/mbien/opencl/HighLevelBindingTest.java
+++ b/test/com/mbien/opencl/HighLevelBindingTest.java
@@ -3,6 +3,7 @@ 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;
@@ -21,6 +22,9 @@ 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,7 +191,7 @@ public class HighLevelBindingTest {
out.println(" - - - highLevelTest; copy buffer test - - - ");
- final int elements = 10000000; //many..
+ final int elements = NUM_ELEMENTS;
CLContext context = CLContext.create();
@@ -208,24 +212,51 @@ public class HighLevelBindingTest {
context.release();
- ByteBuffer a = clBufferA.buffer;
- ByteBuffer b = clBufferB.buffer;
-
- // print first few elements of the resulting buffer to the console.
out.println("validating computed results...");
- 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");
- }
+ 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");
}
- out.println("results are valid");
+ context.release();
}
@Test
@@ -267,5 +298,21 @@ public class HighLevelBindingTest {
context.release();
}
+
+
+ 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();
+ }
}