-
Notifications
You must be signed in to change notification settings - Fork 19
ReadFromAndWriteToBuffersAndImages
This page describes common properties and principles of buffers and images, but another page is dedicated to image-specific features : [UsingImages].
OpenCL lets you create memory objects of three types : buffers (1D arrays), 2D images and 3D images.
These memory objects can be stored in the host memory (typically, in RAM) or in the device memory (typically, in GRAM directly on the graphic card).
For host memory-stored memory objects, you can either ask OpenCL to allocate memory on its own or directly providing the pointer to some memory you allocated (and initialized) by yourself.
When using a host-allocated memory object, OpenCL might let the kernels access directly to the data from the host or instead choose to cache some of this data, in read and/or write modes. What it means is that if you create a direct buffer of values and create an OpenCL buffer out of it, in "use host pointer" mode, you cannot expect your changes done on your direct buffer to be visible from OpenCL kernels using the OpenCL buffer. Before and after doing any change to or reading any data from a host pointer, you must call the CLBuffer.map / unmap methods.
Lastly, OpenCL might let you read/write directly from an OpenCL memory object with the map/unmap mechanism. Mapping a memory object gives a direct pointer to the memory object's data (for instance using a DMA mechanism). However, mapping a memory object's data is only guaranteed to work in the case of host-allocated pointers, so it should be used with caution.
While OpenCL defines buffers as arrays of bytes, JavaCL provides support for typed buffers with 1 to 1 mapping to NIO buffers.
If you use a __global float* argument in a kernel of yours, you can either choose to use a CLBuffer<Byte> and do the float <-> byte conversion and offsets calculations on your own or directly use a CLBuffer<Float> that will take care of everything.
| JavaCL / BridJ | JavaCL / JNA |
|---|---|
|
```
CLContext context = ... ;
int size = 100; Pointer ptr = Pointer.allocateFloats(size).order(context.getByteOrder()); // Last 'false' argument requires that no copy of the pointer is made : // keep ptr as the primary data source CLBuffer clBuffer = context.createBuffer(CLMem.Usage.InputOutput, ptr, false); CLContext context = ... ; int size = 100; FloatBuffer ptr = ByteBuffer.allocateDirect(size * 4).byteOrder(context.getByteOrder()).asFloatBuffer(); // Last 'false' argument requires that no copy of the pointer is made : // keep ptr as the primary data source CLBuffer clBuffer = context.createBuffer(CLMem.Usage.InputOutput, ptr, false); int size = 100; CLBuffer buffer = context.createFloatBuffer(CLMem.Usage.InputOutput, size); // Last 'true' argument asks for a copy of ptr to be made in the device memory. // The clBuffer will have no further link to ptr. CLBuffer clBuffer = context.createBuffer(CLMem.Usage.InputOutput, ptr, true); CLContext context = ... ; // e.g. JavaCL.getBestContext() CLQueue queue = ... ; // e.g. context.createDefaultQueue() CLBuffer clBuffer = ... ; // e.g. context.createFloatBuffer(CLMem.Usage.InputOutput, size) // Reading everything to a new native memory location : Pointer data = clBuffer.read(queue); // Reading elements 3 to 9 included to a new native memory location : data = clBuffer.read(queue, 3, 7); // Reading elements 3 to 9 included to existing data memory location : data = Pointer.allocateFloats(7).order(context.getByteOrder()); clBuffer.read(queue, 3, 7, data, true); // 'true' : blocking operation // Reading everything to a new buffer : FloatBuffer data = clBuffer.read(queue); // Reading elements 3 to 9 included to a new buffer : data = clBuffer.read(queue, 3, 7); // Reading elements 3 to 9 included to existing data buffer : // (note that while indirect buffers will work, direct buffers will provide much better performance) data = NIOUtils.directFloats(7, context.getByteOrder()); clBuffer.read(queue, 3, 7, data, true); // 'true' : blocking operation CLBuffer clBuffer = ... ; try { Pointer data = clBuffer.map(queue. CLMem.MapFlags.Write); data.set(10f); // write something to the buffer clBuffer.unmap(queue, data); } catch (CLException.MapFailure ex) { // map didn't succeed : maybe use CLBuffer.write / read instead. } CLBuffer clBuffer = ... ; try { FloatBuffer data = clBuffer.map(queue. CLMem.MapFlags.Write); data.put(0, 10f); // write something to the buffer clBuffer.unmap(queue, data); } catch (CLException.MapFailure ex) { // map didn't succeed : maybe use CLBuffer.write / read instead. } |