jextract woes

Michael Zucchi notzed at gmail.com
Mon Jan 27 11:00:45 UTC 2020


Hi there,

I had a look at using jextract for zcl while waiting for dinner to cook 
and basically banged it out in 5 minutes - then spent an hour on this 
email and the git bits.

summary:

- mostly trivial because the downcalls and downcall method handles were 
identical to what i had apart from the exception handling of the calls.
- also because upcall wrappers are also identical apart from the 
function name to call
- one of the upcalls is genericised in the high-level interface 
(CLNotify<>) over a few functions.  my extractor just outputs one type 
for this but jextract creates one for each call.  Since they share the 
same signature I just chose one (cl_h.clBuildProgram$x0$make)

To reduce changes I edit the file in the makefile to delete the 
constants (already in CL.java and part of the public api), and make cl_h 
non-final (so i can subclass it to CLLib so I didn't need to change 
existing imports - ok just lazy on that one but it works). So infact 
apart from a couple of incorrect catch() clauses due to paste-o's that 
the method changes exposed, the only real changes i needed to make are 
the upcall resolution calls.

It's on the foreign-jextract branch, or in diff form:

https://code.zedzone.space/cvs?p=zcl;a=commitdiff;h=9455cfeb8c9097987819ada835b05d98a04abc07

(trivia: this roughly doubles the time to compile the whole project).

I did hit one problem with the generator but i hacked around it.

This:

extern CL_API_ENTRY cl_int CL_API_CALL
clEnqueueSVMFree(cl_command_queue  /* command_queue */,
                  cl_uint           /* num_svm_pointers */,
                  void *[]          /* svm_pointers[] */,
                  void (CL_CALLBACK * 
/*pfn_free_func*/)(cl_command_queue /* queue */,
cl_uint          /* num_svm_pointers */,
                                                         void 
*[]         /* svm_pointers[] */,
                                                         void 
*           /* user_data */),
                  void *            /* user_data */,
                  cl_uint           /* num_events_in_wait_list */,
                  const cl_event *  /* event_wait_list */,
                  cl_event *        /* event */) CL_API_SUFFIX__VERSION_2_0;


Gets turned into:

     public static final MethodHandle clEnqueueSVMFree = 
RuntimeHelper.downcallHandle(
         LIBRARIES, "clEnqueueSVMFree",
"(Ljdk/incubator/foreign/MemoryAddress;ILjdk/incubator/foreign/MemorySegment;Ljdk/incubator/foreign/MemoryAddress;Ljdk/incubator/foreign/MemoryAddress;ILjdk/incubator/foreign/MemoryAddress;Ljdk/incubator/foreign/MemoryAddress;)I",
         FunctionDescriptor.of(MemoryLayouts.SysV.C_INT, false,
             MemoryLayouts.SysV.C_POINTER,
             MemoryLayouts.SysV.C_INT,
*MemoryLayout.ofSequence(MemoryLayouts.SysV.C_POINTER),*
             MemoryLayouts.SysV.C_POINTER,
             MemoryLayouts.SysV.C_POINTER,
             MemoryLayouts.SysV.C_INT,
             MemoryLayouts.SysV.C_POINTER,
             MemoryLayouts.SysV.C_POINTER
         )
     );

Which causes this at runtime:

Failed to classify layout: [:b64]
Exception in thread "main" java.lang.ExceptionInInitializerError
         at 
notzed.zcl/au.notzed.zcl.CLPlatform.getPlatforms(CLPlatform.java:90)
         at notzed.zcl.demo/au.notzed.zcl.tools.clinfo.main(clinfo.java:179)
Caused by: java.lang.UnsupportedOperationException: Cannot compute size 
of a layout which is, or depends on a sequence layout with unspecified size
         at 
jdk.incubator.foreign/jdk.incubator.foreign.AbstractLayout.badSizeException(AbstractLayout.java:121)
         at 
java.base/java.util.OptionalLong.orElseThrow(OptionalLong.java:271)
         at 
jdk.incubator.foreign/jdk.incubator.foreign.AbstractLayout.bitSize(AbstractLayout.java:113)
         at 
jdk.incubator.foreign/jdk.incubator.foreign.SequenceLayout.bitSize(SequenceLayout.java:65)
         at 
jdk.incubator.foreign/jdk.incubator.foreign.MemoryLayout.byteSize(MemoryLayout.java:214)
         at 
jdk.incubator.foreign/jdk.internal.foreign.abi.x64.sysv.CallArranger.classifyArrayType(CallArranger.java:489)
         at 
jdk.incubator.foreign/jdk.internal.foreign.abi.x64.sysv.CallArranger.classifyType(CallArranger.java:641)
         at 
jdk.incubator.foreign/jdk.internal.foreign.abi.x64.sysv.CallArranger.classifyLayout(CallArranger.java:654)
         at 
jdk.incubator.foreign/jdk.internal.foreign.abi.x64.sysv.CallArranger$UnboxBindingCalculator.getBindings(CallArranger.java:350)
         at 
jdk.incubator.foreign/jdk.internal.foreign.abi.x64.sysv.CallArranger.arrangeDowncall(CallArranger.java:126)
         at 
jdk.incubator.foreign/jdk.internal.foreign.abi.x64.sysv.SysVx64ABI.downcallHandle(SysVx64ABI.java:72)
         at 
notzed.zcl/au.notzed.zcl.RuntimeHelper.lambda$downcallHandle$6(RuntimeHelper.java:74)
         at java.base/java.util.Optional.map(Optional.java:258)
         at 
notzed.zcl/au.notzed.zcl.RuntimeHelper.downcallHandle(RuntimeHelper.java:69)
         at notzed.zcl/au.notzed.zcl.cl_h.<clinit>(cl_h.java:1846)
         ... 2 more

The ed script which makes the other edits just changes that sequence to 
a plain pointer.

Cheers,
  Michael



More information about the panama-dev mailing list