an opencl binding - zcl/panama

Maurizio Cimadamore maurizio.cimadamore at oracle.com
Mon Jan 27 12:37:08 UTC 2020


On 26/01/2020 04:52, Michael Zucchi wrote:
> Unfortunately no, no general code extractor will be able to generate 
> those opencl accessors.  OpenCL doen't really use structures, it's all 
> via clGet*Info procedures.  It's a pain as there are many (16) of 
> them.  They all output values via a void * buffer which can contain 
> any type - primitives, pointers, one even takes a pointer of pointers 
> you have to allocate memory for.  It basically has to be hand-coded or 
> using a generator which would be far more work than just hand-coding 
> it.  All the stuff in CLObject() is to try to avoid having to write 
> code for all 16 getInfo functions so although it looks like 
> duplication it is anything but.  There there are only 3 signature 
> types amongst them and not all return types are required. It can 
> definitely be improved, that was just the 2nd cut.  Using judicious 
> lambdas i could move it to one set of functions rather than 3, I just 
> didn't think of it at the time.
>
> But here's why it can't be auto-generated without some app-specific 
> knowledge:
>
> There's about a dozen calls that follow this signature:
>
> extern CL_API_ENTRY cl_int CL_API_CALL
> clGetPlatformInfo(cl_platform_id   /* platform */,
>                   cl_platform_info /* param_name */,
>                   size_t           /* param_value_size */,
>                   void *           /* param_value */,
>                   size_t *         /* param_value_size_ret */) 
> CL_API_SUFFIX__VERSION_1_0;
>
> So to get a cl_int (conveniently cl types match java types and are 
> platform independent) in c it's trivial:
>
> cl_int value;
> clGetPlatformInfo(plat, name,  sizeof(int), &value, NULL);
> use value

So, here's my thinking on this topic; right now jextract is pretty good 
at dealing with foreign functions - generating a static wrapper around 
each native function declared in the header. It also tries, for structs, 
to generate layouts and pairs of getters/setters (one per field).

But there's a gap (which was also present in the old jextract) when it 
comes to primitive data types - many well-behaved libraries (opencl and 
OpenGL comes to mind - but there are more) define the 'vocabulary' of 
types they are going to work on, using a bunch of typedefs. Typically 
(but I guess not always) these types are defined in a way so that they 
are portable across platforms.

Since jextract drops such typedefs on the floor, you get no benefit 
there. E.g. as the user, you have to work out that CL_INT is really 
C_INT (but is it, really?). Or that "cl_platform_info" is just 
C_POINTER. This is suboptimal IMHO. As we try to wrap struct access and 
function access, I think jextract should similarly auto-generate layouts 
and accessors for these 'basic types'. This means that users will be 
able to do:

segment = MemorySegment.allocateNative(CL_INT);
cl_int$set(segment, 42);

I'm not saying this will not remove _all_ the boilerplate in your 
Native.java - but I think this will go a long way to make bindings more 
usable than they are right now. And, as an added bonus, I believe that a 
client using these bindings will be more portable as well (to work on a 
new platform you probably just have to tweak the set of static imports - 
but the bulk of the code should remain valid, since the code speaks in 
terms of CL_INT and not interms of plain ABI types).

Maurizio



More information about the panama-dev mailing list