2

I've just started fiddling around with OpenCL and I've come across a problem: I do not know how to pass complex data structures as arguments. I'm using LWJGL's OpenCL binding, and the example provided in the wiki http://lwjgl.org/wiki/index.php?title=Sum_Example. In that example 2 float buffers are created and passed as arguments (LWGJL provides methods in a class named BufferUtils for creating these buffers).

Now, how would I create a buffer of points, typedef struct {int x, int y} tpoint, or structs in general? There are no structs in Java. Moreover there is no BufferUtils.createStructBuffer method.

adrianton3
  • 2,258
  • 3
  • 20
  • 33

1 Answers1

1

Reading and writing OpenCL structs on the host can be non-trivial. Their in-memory layout can depend on the OpenCL device's architecture, and their endianness is not necessarily the host's.

You can control the layout by using the packed attribute. If you use packed, this specifies exactly the layout of the struct's members, as opposed to the default which will align the members depending on the OpenCL device's architecture. Note, however, that with packed you may lose performance.

Alternatively, you can also 'ask' the OpenCL device for the struct layout with a small kernel:

kernel void struct_layout(global unsigned long* totalSize, global unsigned long* fieldOffsets)
{
    tpoint theStruct;
    totalSize[0] = sizeof(theStruct);
    unsigned long baseOffset = (unsigned long)&theStruct;
    fieldOffsets[0] = (unsigned long)&theStruct.x - baseOffset;
    fieldOffsets[1] = (unsigned long)&theStruct.y - baseOffset;
}

For your particular case, If you packed the tpoint struct then from Java you could just use a byte buffer and read/write ints to it and alternate between the x and y members of each struct value.

ByteBuffer buf = ...;

int x1, y1 = ...;
int x2, y2 = ...;

buf.putInt(x1).putInt(y1);
buf.putInt(x2).putInt(y2);
prunge
  • 22,460
  • 3
  • 73
  • 80