From 9f48df918968321a6481c04985aa04f06389db4c Mon Sep 17 00:00:00 2001 From: Not Zed Date: Fri, 24 Jan 2020 13:18:05 +1030 Subject: [PATCH] Started a panama (no jni) based implementation. --- README | 10 + config.make.in | 11 +- java.make | 1 - nbproject/build-impl.xml | 121 +- nbproject/genfiles.properties | 6 +- nbproject/project.properties | 13 +- nbproject/project.xml | 13 +- .../api/Allocator.java} | 47 +- src/notzed.zcl/classes/api/Callback.java | 61 + src/notzed.zcl/classes/api/Memory.java | 221 + src/notzed.zcl/classes/api/Native.java | 931 ++++ .../classes/au/notzed/zcl/CLBuffer.java | 32 +- .../classes/au/notzed/zcl/CLBufferInfo.java | 2 +- .../classes/au/notzed/zcl/CLCommandQueue.java | 1280 ++++- .../classes/au/notzed/zcl/CLContext.java | 723 ++- .../au/notzed/zcl/CLContextNotify.java | 21 + .../classes/au/notzed/zcl/CLDevice.java | 40 +- .../au/notzed/zcl/CLDeviceProperty.java | 11 + .../classes/au/notzed/zcl/CLEvent.java | 86 +- .../classes/au/notzed/zcl/CLEventList.java | 52 +- .../classes/au/notzed/zcl/CLEventNotify.java | 15 + .../classes/au/notzed/zcl/CLException.java | 180 +- .../classes/au/notzed/zcl/CLExtendable.java | 16 +- .../classes/au/notzed/zcl/CLExtension.java | 9 +- .../classes/au/notzed/zcl/CLImage.java | 29 +- .../classes/au/notzed/zcl/CLImageDesc.java | 59 +- .../classes/au/notzed/zcl/CLImageFormat.java | 34 + .../classes/au/notzed/zcl/CLKernel.java | 251 +- .../classes/au/notzed/zcl/CLMemory.java | 158 +- .../classes/au/notzed/zcl/CLNotify.java | 17 + .../classes/au/notzed/zcl/CLObject.java | 343 +- .../classes/au/notzed/zcl/CLPipe.java | 19 +- .../classes/au/notzed/zcl/CLPlatform.java | 111 +- .../classes/au/notzed/zcl/CLProgram.java | 174 +- .../classes/au/notzed/zcl/CLProperty.java | 94 +- .../au/notzed/zcl/CLRuntimeException.java | 42 +- .../classes/au/notzed/zcl/CLSampler.java | 35 +- .../classes/au/notzed/zcl/khr/GLEvent.java | 4 +- .../classes/au/notzed/zcl/khr/GLSharing.java | 4 +- src/notzed.zcl/classes/module-info.java | 9 +- src/notzed.zcl/gen/export-defines | 44 + src/notzed.zcl/gen/gen.make | 45 + src/notzed.zcl/gen/generate-api | 1418 +++++ src/notzed.zcl/gen/opencl.pm | 2301 ++++++++ src/notzed.zcl/gen/opencl.txt | 108 + src/notzed.zcl/{jni => }/include/CL/cl.h | 0 .../{jni => }/include/CL/cl_d3d10.h | 0 .../{jni => }/include/CL/cl_d3d11.h | 0 .../include/CL/cl_dx9_media_sharing.h | 0 src/notzed.zcl/{jni => }/include/CL/cl_egl.h | 0 src/notzed.zcl/{jni => }/include/CL/cl_ext.h | 0 src/notzed.zcl/{jni => }/include/CL/cl_gl.h | 0 .../{jni => }/include/CL/cl_gl_ext.h | 0 .../{jni => }/include/CL/cl_platform.h | 0 src/notzed.zcl/{jni => }/include/CL/opencl.h | 0 src/notzed.zcl/jni/jni.make | 41 - src/notzed.zcl/jni/zcl-extension.h | 81 - src/notzed.zcl/jni/zcl-generate | 100 - src/notzed.zcl/jni/zcl-init-dll.c | 44 - src/notzed.zcl/jni/zcl-jni.c | 4930 ----------------- src/notzed.zcl/jni/zcl-jni.def | 73 - src/notzed.zcl/jni/zcl-khr-gl-event.c | 89 - src/notzed.zcl/jni/zcl-khr-gl-sharing.c | 278 - 63 files changed, 8326 insertions(+), 6511 deletions(-) rename src/notzed.zcl/{jni/zcl-init-so.c => classes/api/Allocator.java} (54%) create mode 100644 src/notzed.zcl/classes/api/Callback.java create mode 100644 src/notzed.zcl/classes/api/Memory.java create mode 100644 src/notzed.zcl/classes/api/Native.java create mode 100755 src/notzed.zcl/gen/export-defines create mode 100644 src/notzed.zcl/gen/gen.make create mode 100755 src/notzed.zcl/gen/generate-api create mode 100644 src/notzed.zcl/gen/opencl.pm create mode 100644 src/notzed.zcl/gen/opencl.txt rename src/notzed.zcl/{jni => }/include/CL/cl.h (100%) rename src/notzed.zcl/{jni => }/include/CL/cl_d3d10.h (100%) rename src/notzed.zcl/{jni => }/include/CL/cl_d3d11.h (100%) rename src/notzed.zcl/{jni => }/include/CL/cl_dx9_media_sharing.h (100%) rename src/notzed.zcl/{jni => }/include/CL/cl_egl.h (100%) rename src/notzed.zcl/{jni => }/include/CL/cl_ext.h (100%) rename src/notzed.zcl/{jni => }/include/CL/cl_gl.h (100%) rename src/notzed.zcl/{jni => }/include/CL/cl_gl_ext.h (100%) rename src/notzed.zcl/{jni => }/include/CL/cl_platform.h (100%) rename src/notzed.zcl/{jni => }/include/CL/opencl.h (100%) delete mode 100644 src/notzed.zcl/jni/jni.make delete mode 100644 src/notzed.zcl/jni/zcl-extension.h delete mode 100755 src/notzed.zcl/jni/zcl-generate delete mode 100644 src/notzed.zcl/jni/zcl-init-dll.c delete mode 100644 src/notzed.zcl/jni/zcl-jni.c delete mode 100644 src/notzed.zcl/jni/zcl-jni.def delete mode 100644 src/notzed.zcl/jni/zcl-khr-gl-event.c delete mode 100644 src/notzed.zcl/jni/zcl-khr-gl-sharing.c diff --git a/README b/README index a51ca98..591c71f 100644 --- a/README +++ b/README @@ -1,4 +1,14 @@ +foreign-abi branch note +----------------------- + +This is still work in progress, expect breakage, out of date doco, +other issues. + +Various native support code is in the temporary package api.*, +eventually to be moved to a new nativez. + + INTRODUCTION ------------ diff --git a/config.make.in b/config.make.in index f0186c5..dba9824 100644 --- a/config.make.in +++ b/config.make.in @@ -3,15 +3,12 @@ TARGET ?= linux-amd64 JAVA_HOME ?= /usr/local/jdk-13+33 -# See also JAVACFLAGS --module-path -NATIVEZ_HOME=../nativez/bin/$(TARGET) - -JAVAMODPATH = $(NATIVEZ_HOME)/lib JAVACFLAGS += -source 13 +JAVACFLAGS += --add-exports jdk.incubator.foreign/jdk.incubator.foreign.unsafe=notzed.zcl -JAVAC ?= javac -JAR ?= jar -JMOD ?= jmod +JAVAC ?= $(JAVA_HOME)/bin/javac +JAR ?= $(JAVA_HOME)/bin/jar +JMOD ?= $(JAVA_HOME)/bin/jmod # Linux options linux-amd64_CPPFLAGS = \ diff --git a/java.make b/java.make index ee876b1..01df66d 100644 --- a/java.make +++ b/java.make @@ -347,4 +347,3 @@ dist: --transform=s,^,$(dist_NAME)-$(dist_VERSION)/, \ config.make java.make Makefile src \ $(dist_EXTRA) - diff --git a/nbproject/build-impl.xml b/nbproject/build-impl.xml index 489097b..9cc58e9 100644 --- a/nbproject/build-impl.xml +++ b/nbproject/build-impl.xml @@ -69,7 +69,43 @@ is divided into following sections: - + + + + + + + + + + + + + + + + + + + + + + + + + + Must set platform.home + Must set platform.bootcp + Must set platform.java + Must set platform.javac + + The J2SE Platform is not correctly set up. + Your active platform is: ${platform.active}, but the corresponding property "platforms.${platform.active}.home" is not found in the project's properties files. + Either open the project in the IDE and setup the Platform with the same name or add it manually. + For example like this: + ant -Duser.properties.file=<path_to_property_file> jar (where you put the property "platforms.${platform.active}.home" in a .properties file) + or ant -Dplatforms.${platform.active}.home=<path_to_JDK_home> jar (where no properties file is used) + @@ -94,11 +130,16 @@ is divided into following sections: + + + + + @@ -106,6 +147,9 @@ is divided into following sections: + + + @@ -177,20 +221,6 @@ is divided into following sections: - - - - - - - - - - - - - - @@ -262,6 +292,7 @@ is divided into following sections: + Must set src.gen2.dir Must set src.dir Must set test.src.dir Must set build.dir @@ -293,7 +324,7 @@ is divided into following sections: - + @@ -314,7 +345,7 @@ is divided into following sections: - + @@ -346,7 +377,7 @@ is divided into following sections: - + @@ -407,7 +438,7 @@ is divided into following sections: - + @@ -492,7 +523,7 @@ is divided into following sections: - + @@ -723,6 +754,9 @@ is divided into following sections: + + + @@ -772,7 +806,7 @@ is divided into following sections: - + @@ -842,15 +876,6 @@ is divided into following sections: - - - - - - - - - @@ -999,10 +1024,16 @@ is divided into following sections: - + + + + + + + @@ -1170,8 +1201,8 @@ is divided into following sections: - - + + @@ -1414,19 +1445,25 @@ is divided into following sections: + + + - + - + - + + + + @@ -1438,6 +1475,9 @@ is divided into following sections: + + + @@ -1695,15 +1735,6 @@ is divided into following sections: - - - - - - - - - diff --git a/nbproject/genfiles.properties b/nbproject/genfiles.properties index c2d597c..29eae41 100644 --- a/nbproject/genfiles.properties +++ b/nbproject/genfiles.properties @@ -3,6 +3,6 @@ build.xml.script.CRC32=b55362bc build.xml.stylesheet.CRC32=32069288@1.6.1 # This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml. # Do not edit this file. You may delete it but then the IDE will never regenerate such files for you. -nbproject/build-impl.xml.data.CRC32=e7caf820 -nbproject/build-impl.xml.script.CRC32=2c69bf13 -nbproject/build-impl.xml.stylesheet.CRC32=0f0529df@1.6.1 +nbproject/build-impl.xml.data.CRC32=2c0455af +nbproject/build-impl.xml.script.CRC32=68c8182d +nbproject/build-impl.xml.stylesheet.CRC32=0f0529df@1.7 diff --git a/nbproject/project.properties b/nbproject/project.properties index f1aaa57..20b0bb1 100644 --- a/nbproject/project.properties +++ b/nbproject/project.properties @@ -40,11 +40,10 @@ includes=** jar.compress=false javac.classpath= # Space-separated list of extra javac options -javac.compilerargs=-Xlint:unchecked +javac.compilerargs=-Xlint:unchecked --add-exports jdk.incubator.foreign/jdk.incubator.foreign.unsafe=notzed.zcl javac.deprecation=false javac.external.vm=false -javac.modulepath=\ - ${reference.notzed_nativez.notzed_nativez_jar} +javac.modulepath= javac.processormodulepath= javac.processorpath=\ ${javac.classpath} @@ -75,9 +74,7 @@ jlink.additionalmodules= jlink.additionalparam= jlink.launcher=true jlink.launcher.name=notzed.zcl -platform.active=default_platform -project.notzed_nativez=../nativez -reference.notzed_nativez.notzed_nativez_jar=${project.notzed_nativez}/dist/notzed.nativez.jar +platform.active=JDK_15 run.classpath= # Space-separated list of JVM arguments used when running the project. # You may also define separate properties like run-sys-prop.name=value instead of -Dname=value. @@ -94,5 +91,9 @@ run.test.modulepath=\ source.encoding=UTF-8 src.dir=src src.dir.path=classes +src.gen.dir=bin/gen +src.gen.dir.path=classes +src.gen2.dir=bin/gen +src.gen2.dir.path=classes test.src.dir=src test.src.dir.path=tests diff --git a/nbproject/project.xml b/nbproject/project.xml index 15787d7..575ebab 100644 --- a/nbproject/project.xml +++ b/nbproject/project.xml @@ -4,22 +4,15 @@ notzed.zcl + + - - - notzed_nativez - jar - - jar - clean - notzed.nativez.jar - - + diff --git a/src/notzed.zcl/jni/zcl-init-so.c b/src/notzed.zcl/classes/api/Allocator.java similarity index 54% rename from src/notzed.zcl/jni/zcl-init-so.c rename to src/notzed.zcl/classes/api/Allocator.java index 8465a4a..87f96f9 100644 --- a/src/notzed.zcl/jni/zcl-init-so.c +++ b/src/notzed.zcl/classes/api/Allocator.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015 Michael Zucchi + * Copyright (C) 2020 Michael Zucchi * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -15,29 +15,28 @@ * along with this program. If not, see . */ -/* - shared library init - */ - -#include -#include -#include - -#include "zcl-extension.h" - -#define ZCL_DL_TABLE 1 -#include "zcl-functions.h" +package api; -static void *lib_opencl; +import jdk.incubator.foreign.MemoryAddress; +import jdk.incubator.foreign.MemorySegment; -int init_dynamic(JNIEnv *env) { - lib_opencl = dlopen("libOpenCL.so", RTLD_LAZY|RTLD_GLOBAL); - - if (lib_opencl) { - for (int i=0;i. + */ + +/* + Not sure on this. + + Something needs to handle gc of callback stubs. + This uses Native to do it. + */ + +package api; + +import jdk.incubator.foreign.*; + +public class Callback extends Native implements AutoCloseable { + T func; + + public Callback(MemoryAddress addr, T func) { + super(addr); + + this.func = func; + } + + /* + * A callback that resolve to MemoryAddress.NULL. + * This can be released safely any number of times. + * This must never be registerd with ref queue. + */ + public static final Callback NULL = new Callback<>(MemoryAddress.NULL, null) { + @Override + public void release() { + } + @Override + public void close() { + } + }; + + private static void release(MemoryAddress p) { + System.err.printf("** release upcall stub %016x\n", Memory.toLong(p)); + freeUpcallStub(p); + } + + @Override + public void close() { + release(); + } +} diff --git a/src/notzed.zcl/classes/api/Memory.java b/src/notzed.zcl/classes/api/Memory.java new file mode 100644 index 0000000..8107d6c --- /dev/null +++ b/src/notzed.zcl/classes/api/Memory.java @@ -0,0 +1,221 @@ +/* + * Copyright (C) 2020 Michael Zucchi + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package api; + +import jdk.incubator.foreign.*; +import jdk.incubator.foreign.unsafe.ForeignUnsafe; +import java.lang.invoke.MethodHandles; +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodType; + +/** + * A utility library for memory operations including a stack allocator. + * + * The stack allocator works like this + * try (Memory.Frame f = Memory.frame()) { + * MemoryAddress a = Memory.alloca(size); + * } + * Any memory allocated is freed when the frame is closed. + * + * Note that unlike C's alloca() the frame scope is not per-function + * but application defined. + */ +public class Memory { + + private static final ThreadLocal stacks = ThreadLocal.withInitial(() -> Native.resolve(malloc(4096), (p) -> new Stack(p, 4096))); + private static final ThreadLocal stackAllocators = new ThreadLocal<>(); + + /* older idea */ + + // eh, this isn't really necessary, it's just a safety check/debug? + //private static final ThreadLocal frames = new ThreadLocal<>(); + + /** + * Alloc memory in the current frame. The size is not enforced. + */ + /* + public static MemoryAddress alloca(long size) { + if (frames.get() == null) + throw new UnsupportedOperationException("Must have a frame"); + return stack().alloca(size); + }*/ + + /** + * Allocate a segment in the current frame. The segment must not be closed. + */ +/* + public static MemorySegment slicea(long size) { + if (frames.get() == null) + throw new UnsupportedOperationException("Must have a frame"); + return stack().slicea(size); + } + + public static Frame frame() { + Stack stack = stack(); + long fp = stack.sp; + Frame old = frames.get(); + Frame gnu = () -> { + frames.set(old); + stack.sp = fp; + }; + frames.set(gnu); + + return gnu; + } + + public interface Frame extends AutoCloseable { + @Override + public void close(); + } +*/ + static class Stack extends Native { + final MemorySegment stack; + final MemoryAddress base; + long sp; + + Stack(MemoryAddress p, long size) { + super(p); + + stack = ForeignUnsafe.ofNativeUnchecked(addr(), size); + base = stack.baseAddress(); + sp = size; + } + + private static void release(MemoryAddress p) { + System.err.printf("** release stack " + p); + free(p); + } + + public MemoryAddress alloca(long size) { + sp -= (size + 7 ) & ~7; + return base.addOffset(sp); + } + + public MemorySegment allocs(long size) { + sp -= (size + 7 ) & ~7; + return stack.asSlice(sp, size); + } + + public MemorySegment slicea(long size) { + sp -= (size + 7 ) & ~7; + return stack.asSlice(sp, size); + } + } + + /* + Alternatative version. + This allows different allocators to be used for functions that use one. + Individual memory cannot be freed. + */ + + /** + * Create a stack allocator. + * The stack allocator uses thread-specific backing buffer. + * This should only be used for small allocations. + */ + public static Allocator stack() { + Stack stack = stacks.get(); + long fp = stack.sp; + Allocator old = stackAllocators.get(); + Thread me = Thread.currentThread(); + + Allocator gnu = new Allocator() { + public void close() { + stack.sp = fp; + stackAllocators.set(old); + } + public MemoryAddress alloca(long size) { + if (stackAllocators.get() != this || me != Thread.currentThread()) + throw new IllegalStateException(); + return stack.alloca(size); + } + public MemorySegment allocs(long size) { + if (stackAllocators.get() != this || me != Thread.currentThread()) + throw new IllegalStateException(); + return stack.allocs(size); + } + }; + + stackAllocators.set(gnu); + return gnu; + } + + + static final MethodHandle malloc; + static final MethodHandle free; + + static { + // So for whatever reason it's been decided that MemorySegment can't be freed normally on another thread + SystemABI abi = SystemABI.getInstance(); + MethodHandles.Lookup lookup = MethodHandles.lookup(); + LibraryLookup libc = LibraryLookup.ofDefault(); + + try { + malloc = abi.downcallHandle(libc.lookup("malloc"), + MethodType.methodType(MemoryAddress.class, + long.class), + FunctionDescriptor.of(MemoryLayouts.SysV.C_POINTER, + false, + MemoryLayouts.SysV.C_ULONG)); + free = abi.downcallHandle(libc.lookup("free"), + MethodType.methodType(void.class, + MemoryAddress.class), + FunctionDescriptor.ofVoid(false, + MemoryLayouts.SysV.C_POINTER)); + } catch (NoSuchMethodException x) { + throw new RuntimeException(x); + } + } + + /** + * Create a sized memory segment from a segment allocated with malloc. + * Closing this segment has no effect on the original, and the original must be used for that. + */ + public static MemorySegment ofNative(MemoryAddress addr, long size) { + return ForeignUnsafe.ofNativeUnchecked(addr, size); + } + + /** + * Get the physical address. I mean how is this an "offset"? + */ + public static long toLong(MemoryAddress addr) { + return ForeignUnsafe.getUnsafeOffset(addr); + } + + /** + * Allocate C memory. + * This is not usable by java directly, see memsize() + */ + public static MemoryAddress malloc(long size) { + try { + MemoryAddress addr = (MemoryAddress)malloc.invokeExact(size); + + return addr; + } catch (Throwable t) { + throw new RuntimeException(t); + } + } + + public static void free(MemoryAddress ptr) { + try { + free.invokeExact(ptr); + } catch (Throwable t) { + throw new RuntimeException(t); + } + } +} diff --git a/src/notzed.zcl/classes/api/Native.java b/src/notzed.zcl/classes/api/Native.java new file mode 100644 index 0000000..ef599df --- /dev/null +++ b/src/notzed.zcl/classes/api/Native.java @@ -0,0 +1,931 @@ +/* + * Copyright (C) 2020 Michael Zucchi + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package api; + +import java.io.StringReader; +import java.lang.invoke.*; +import java.lang.reflect.Method; +import java.nio.ByteOrder; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.function.Function; +import java.util.function.IntFunction; +import jdk.incubator.foreign.*; +import jdk.incubator.foreign.unsafe.ForeignUnsafe; +import java.lang.ref.ReferenceQueue; +import java.lang.ref.WeakReference; +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.lang.System.Logger.Level; + +public class Native { + + private final MemoryAddress p; + + private final static boolean dolog = true; + + final static VarHandle byteHandle = MemoryHandles.varHandle(byte.class, ByteOrder.nativeOrder()); + final static VarHandle shortHandle = MemoryHandles.varHandle(short.class, ByteOrder.nativeOrder()); + final static VarHandle intHandle = MemoryHandles.varHandle(int.class, ByteOrder.nativeOrder()); + final static VarHandle longHandle = MemoryHandles.varHandle(long.class, ByteOrder.nativeOrder()); + final static VarHandle floatHandle = MemoryHandles.varHandle(float.class, ByteOrder.nativeOrder()); + final static VarHandle doubleHandle = MemoryHandles.varHandle(double.class, ByteOrder.nativeOrder()); + final static VarHandle addrHandle = MemoryHandles.varHandle(MemoryAddress.class, ByteOrder.nativeOrder()); + + final static VarHandle byteVHandle = MemoryHandles.withStride(byteHandle, 1); + final static VarHandle shortVHandle = MemoryHandles.withStride(shortHandle, 2); + final static VarHandle intVHandle = MemoryHandles.withStride(intHandle, 4); + final static VarHandle longVHandle = MemoryHandles.withStride(longHandle, 8); + final static VarHandle floatVHandle = MemoryHandles.withStride(floatHandle, 4); + final static VarHandle doubleVHandle = MemoryHandles.withStride(doubleHandle, 8); + final static VarHandle addrVHandle = MemoryHandles.withStride(addrHandle, 8); + + protected Native(MemoryAddress p) { + this.p = p; + } + + static System.Logger log() { + return System.getLogger("notzed.native"); + } + + public MemoryAddress addr() { + return p; + } + + public static MemoryAddress addr(Native o) { + return o != null ? o.addr() : MemoryAddress.NULL; + } + + public static MemoryAddress addr(MemorySegment o) { + return o != null ? o.baseAddress() : MemoryAddress.NULL; + } + + public static byte getByte(MemoryAddress p) { + return (byte)byteHandle.get(p); + } + + public static byte getByte(MemoryAddress p, long i) { + return (byte)byteVHandle.get(p, i); + } + + public static void setByte(MemoryAddress p, byte v) { + byteHandle.set(p, v); + } + + public static void setByte(MemoryAddress p, int i, byte v) { + byteVHandle.set(p, i, v); + } + + public static int getInt(MemoryAddress p) { + return (int)intHandle.get(p); + } + + public static int getInt(MemoryAddress p, long i) { + return (int)intVHandle.get(p, i); + } + + public static void setInt(MemoryAddress p, int v) { + intHandle.set(p, v); + } + + public static void setInt(MemoryAddress p, long i, int v) { + intVHandle.set(p, i, v); + } + + public static short getShort(MemoryAddress p) { + return (short)shortHandle.get(p); + } + + public static void setShort(MemoryAddress p, short v) { + shortHandle.set(p, v); + } + + public static void setShort(MemoryAddress p, long i, short v) { + shortVHandle.set(p, i, v); + } + + public static long getLong(MemoryAddress p) { + return (long)longHandle.get(p); + } + + public static long getLong(MemoryAddress p, long i) { + return (long)longVHandle.get(p, i); + } + + public static void setLong(MemoryAddress p, long v) { + longHandle.set(p, v); + } + + public static void setLong(MemoryAddress p, long i, long v) { + longVHandle.set(p, i, v); + } + + public static float getFloat(MemoryAddress p) { + return (float)floatHandle.get(p); + } + + public static float getFloat(MemoryAddress p, long i) { + return (float)floatVHandle.get(p, i); + } + + public static void setFloat(MemoryAddress p, float v) { + floatHandle.set(p, v); + } + + public static void setFloat(MemoryAddress p, long i, float v) { + floatVHandle.set(p, i, v); + } + + public static double getDouble(MemoryAddress p) { + return (int)doubleHandle.get(p); + } + + public static double getDouble(MemoryAddress p, long i) { + return (int)doubleVHandle.get(p, i); + } + + public static void setDouble(MemoryAddress p, double v) { + doubleHandle.set(p, v); + } + + public static void setDouble(MemoryAddress p, long i, double v) { + doubleVHandle.set(p, i, v); + } + + public static MemoryAddress getAddr(MemoryAddress p) { + return (MemoryAddress)addrHandle.get(p); + } + + public static MemoryAddress getAddr(MemoryAddress p, long i) { + return (MemoryAddress)addrVHandle.get(p, i); + } + + public static void setAddr(MemoryAddress p, MemoryAddress v) { + addrHandle.set(p, v); + } + + public static void setAddr(MemoryAddress p, long i, MemoryAddress v) { + addrVHandle.set(p, i, v); + } + + /* helpers - java to native */ + public static MemoryAddress toAddrV(Allocator frame, T[]array) { + MemoryAddress list = frame.alloca(8 * array.length); + + for (int i=0;i MemoryAddress toAddrV(Allocator frame, String[]array) { + if (array != null) { + MemoryAddress list = frame.alloca(8 * array.length); + + for (int i=0;i MemoryAddress toLongV(Allocator frame, long[]array) { + MemoryAddress list = frame.alloca(8 * array.length); + + for (int i=0;i MemoryAddress toByteV(Allocator frame, byte[] data) { + if (data != null) { + MemoryAddress list = frame.alloca(data.length); + + for (int i=0;i MemoryAddress toByteV(Allocator frame, String string) { + if (string != null) { + byte[] data = string.getBytes(); + MemoryAddress list = frame.alloca(data.length + 1); + + for (int i=0;i T[] toObjectV(MemoryAddress list, T[] array, Function create) { + for (int i=0;i T[] toObjectV(MemorySegment list, Function create, IntFunction createArray) { + return toObjectV(list.baseAddress(), createArray.apply((int)(list.byteSize() >>> 3)), create); + } + + public static String toString(MemoryAddress cstr) { + MemorySegment seg = ForeignUnsafe.ofNativeUnchecked(cstr, Integer.MAX_VALUE); + MemoryAddress add = seg.baseAddress(); + byte[] data; + int len = 0; + + while (getByte(add, len) != 0) + len++; + + data = new byte[len]; + for (int i=0;i>> 3); + long[] list = new long[len]; + + for (int i=0;i resClass = sig.classes[n-1]; + MemoryLayout resLayout = sig.layouts[n-1]; + + for (LibraryLookup lib: libs) { + try { + return abi.downcallHandle(lib.lookup(name), + MethodType.methodType(resClass, Arrays.copyOf(sig.classes, n-1)), + FunctionDescriptor.of(resLayout, false, Arrays.copyOf(sig.layouts, n-1))); + } catch (NoSuchMethodException x) { + } + } + // or use some 'unsupportedoperation' one? + System.err.println("not found: "+ name); + + return null; + } + + public static MethodHandle downcallHandle(MemoryAddress addr, String signature) { + Signature sig = Signature.parse(signature); + int n = sig.classes.length; + SystemABI abi = SystemABI.getInstance(); + + if (sig.classes.length != sig.layouts.length) + throw new RuntimeException("layout class mismatch"); + Class resClass = sig.classes[n-1]; + MemoryLayout resLayout = sig.layouts[n-1]; + + return abi.downcallHandle(addr, + MethodType.methodType(resClass, Arrays.copyOf(sig.classes, n-1)), + FunctionDescriptor.of(resLayout, false, Arrays.copyOf(sig.layouts, n-1))); + } + + // instance must be of a functional interface + public static MemoryAddress upcallStub(MethodHandles.Lookup lookup, Object instance, String signature) { + Signature sig = Signature.parse(signature); + int n = sig.classes.length; + SystemABI abi = SystemABI.getInstance(); + + if (sig.classes.length != sig.layouts.length) + throw new RuntimeException("layout class mismatch"); + Class resClass = sig.classes[n-1]; + MemoryLayout resLayout = sig.layouts[n-1]; + + + Method m = instance.getClass().getMethods()[0]; + MethodType mt = MethodType.methodType(m.getReturnType(), m.getParameterTypes()); + + //System.out.printf("instance %s\n", instance); + //System.out.printf("declaring class %s\n", m.getDeclaringClass()); + + try { + return abi.upcallStub(lookup.findVirtual( + m.getDeclaringClass(), + m.getName(), + mt) + .bindTo(instance), + FunctionDescriptor.of(resLayout, false, Arrays.copyOf(sig.layouts, n-1))); + } catch (NoSuchMethodException | IllegalAccessException x) { + throw new RuntimeException(x); + } + } + + public static void freeUpcallStub(MemoryAddress addr) { + SystemABI.getInstance().freeUpcallStub(addr); + } + + public static LibraryLookup[] loadLibraries(String... libraries) { + LibraryLookup[] libs = new LibraryLookup[libraries.length]; + MethodHandles.Lookup lookup = MethodHandles.lookup(); + for (int i=0;i argClass = new ArrayList<>(); + List argLayout = new ArrayList<>(); + StringReader r = new StringReader(s); + int c; + int size = 0; + StringBuilder sb = new StringBuilder(); + int pointerDepth = 0; + int type = 0; // func/struct/union + + //System.out.printf("parse: '%s'\n", s); + try { + c = r.read(); + switch (c) { + case '(': + type = 0; + break; + case '[': + type = 1; + break; + default: + throw new RuntimeException("Unknown type: " + (char)c); + } + c = r.read(); + + while ( c != -1) { + switch (c) { + case 'u': + case 'i': + case 'f': + case 'x': { + int d; + size = 0; + while ((d = r.read()) != -1 && d >= '0' && d <= '9') + size = size * 10 + (d - '0'); + + // named field + if (d == '(') { + while ((d = r.read()) != -1 && d != ')') + ; + d = r.read(); + } + + if (d == ':') { + //System.out.printf(" pointer: size=%d\n", size); + pointerDepth++; + } else { + if (d == '=') { + // actually it's bitfield, but ignore internal details + d = r.read(); + if (d != '[') + throw new UnsupportedOperationException("expecting ["); + while ((d = r.read()) != -1 && d != ']') + ; + d = r.read(); + } else { + //System.out.printf(" prim: *=%d size=%d\n", pointerDepth, size); + } + + if (pointerDepth > 0) { + argClass.add(MemoryAddress.class); + argLayout.add(MemoryLayouts.SysV.C_POINTER); + } else { + switch (c) { + case 'u': + switch (size) { + case 8: + argClass.add(byte.class); + argLayout.add(MemoryLayouts.SysV.C_UCHAR); + break; + case 16: + // char.class? + argClass.add(short.class); + argLayout.add(MemoryLayouts.SysV.C_USHORT); + break; + case 32: + argClass.add(int.class); + argLayout.add(MemoryLayouts.SysV.C_UINT); + break; + case 64: + argClass.add(long.class); + argLayout.add(MemoryLayouts.SysV.C_ULONG); + break; + } + break; + case 'i': + switch (size) { + case 8: + argClass.add(byte.class); + argLayout.add(MemoryLayouts.SysV.C_SCHAR); + break; + case 16: + argClass.add(short.class); + argLayout.add(MemoryLayouts.SysV.C_SHORT); + break; + case 32: + argClass.add(int.class); + argLayout.add(MemoryLayouts.SysV.C_INT); + break; + case 64: + argClass.add(long.class); + argLayout.add(MemoryLayouts.SysV.C_LONG); + break; + } + break; + case 'f': + switch (size) { + case 32: + argClass.add(float.class); + argLayout.add(MemoryLayouts.SysV.C_FLOAT); + break; + case 64: + argClass.add(double.class); + argLayout.add(MemoryLayouts.SysV.C_DOUBLE); + break; + } + break; + case 'x': + switch (size) { + case 8: + argLayout.add(MemoryLayouts.PAD_8); + break; + case 16: + argLayout.add(MemoryLayouts.PAD_16); + break; + case 32: + argLayout.add(MemoryLayouts.PAD_32); + break; + case 64: + argLayout.add(MemoryLayouts.PAD_64); + break; + } + break; + } + } + c = d; + pointerDepth = 0; + continue; + } + break; + } + case 'v': + //System.out.printf("void *=%d\n", pointerDepth); + if (pointerDepth > 0) { + argClass.add(MemoryAddress.class); + argLayout.add(MemoryLayouts.SysV.C_POINTER); + } else { + // can only be return value + argClass.add(void.class); + argLayout.add(null); + } + pointerDepth = 0; + break; + case '$': + c = r.read(); + if (c != '{') + throw new RuntimeException(); + sb.setLength(0); + boolean cap = true; + while ((c = r.read()) != -1 && c != '}') { + if (c == '_') { + cap = true; + continue; + } + if (cap) { + c = Character.toUpperCase(c); + cap = false; + } + sb.append((char)c); + } + //System.out.printf(" type: *=%d %s\n", pointerDepth, sb); + if (pointerDepth > 0) { + argClass.add(MemoryAddress.class); + argLayout.add(MemoryLayouts.SysV.C_POINTER); + } else { + argClass.add(MemorySegment.class); + try { + Class stype = Class.forName("api." + sb.toString()); + argLayout.add((MemoryLayout)stype.getDeclaredMethod("layout").invoke(null)); + } catch (Exception x) { + throw new RuntimeException(x); + } + } + pointerDepth = 0; + break; + case '(': // named field, ignore it + while ((c = r.read()) != -1 && c != ')') + ; + break; + case '|': + // wrong! could be inline union sub-part + if (type == 1 || type == 2) + type = 2; + else + throw new UnsupportedOperationException("union in thing?"); + break; + case ')': + break; + case ']': + break; + default: + throw new UnsupportedOperationException("Unknown token: " + (char)c); + } + c = r.read(); + } + } catch (java.io.IOException x) { + throw new RuntimeException(x); + } + + return new Signature(argClass.stream().toArray(Class[]::new), + argLayout.stream().toArray(MemoryLayout[]::new)); + } + } + + /* ********************************************************************** */ + /* GC handling */ + /* ********************************************************************** */ + + /** + * Resource index. + */ + static private final PointerTable map = new PointerTable(); + + /** + * Reference queue for stale objects. + */ + static private final ReferenceQueue references = new ReferenceQueue<>(); + + private static T createInstance(Class jtype, MemoryAddress p) { + cleanerStep(); + try { + Class[] params = {MemoryAddress.class}; + Constructor cc = jtype.getDeclaredConstructor(params); + + cc.setAccessible(true); + + return cc.newInstance(p); + } catch (NoSuchMethodException | SecurityException | InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) { + log().log(Level.ERROR, "createInstance", ex); + throw new RuntimeException(ex); + } + } + + /* + public static T resolve(Class jtype, MemoryAddress p) { + T o; + + //if (dolog) + log().log(Level.DEBUG, () -> String.format(" resolve $%016x %s", p.offset(), jtype.getName())); + + // Instantiation needs to be synchronized for obvious reasons. + synchronized (map) { + CHandle h = (CHandle) map.get(p); + + if (h == null || (o = jtype.cast(h.get())) == null) { + o = createInstance(jtype, p); + h = new CHandle(o, references, p); + map.putAlways(h); + } + } + return o; + }*/ + + public static T resolve(MemoryAddress p, Function create) { + T o; + boolean step = false; + + if (dolog) + log().log(Level.DEBUG, () -> String.format(" resolv $%016x %s", Memory.toLong(p), create)); + + // ??? who the fuck knows if this will work + if (p.offset() == 0) + return null; + + // Instantiation needs to be synchronized for obvious reasons. + synchronized (map) { + CHandle h = (CHandle) map.get(p); + + if (h == null || (o = (T)(h.get())) == null) { + o = create.apply(p); + h = new CHandle(o, references, p); + map.put(h); + step = true; + } + } + + if (step) + cleanerStep(); + + return o; + } + + /* + public static void register(T o) { + T o; + boolean step = false; + + if (dolog) + log().log(Level.DEBUG, () -> String.format(" regist $%016x %s", o.addr().offset(), o.getClass().getName())); + + CHandle h = new CHandle(o, references, o.addr()); + + synchronized (map) { + map.put(h); + step = true; + } + + if (step) + cleanerStep(); + + return o; + }*/ + + public void release() { + WeakReference ref; + + synchronized (map) { + ref = map.remove(p); + } + + if (ref != null) { + if (dolog) + log().log(Level.DEBUG, () -> String.format(" force $%016x %s", Memory.toLong(p), getClass().getName())); + + ref.enqueue(); + } + } + + public static void release(T a) { + if (a != null) + a.release(); + } + + public static void release(Native... list) { + for (Native o : list) + release(o); + } + + static { + Thread cleanup = new Thread(Native::cleaner, "Native cleaner"); + cleanup.setPriority(Thread.MAX_PRIORITY); + cleanup.setDaemon(true); + cleanup.start(); + } + + private static void cleanerStep() { + try { + CHandle stale = (CHandle) references.poll(); + if (stale != null) { + synchronized (map) { + map.remove(stale.p); + } + stale.release(); + } + } catch (Throwable ex) { + } + } + + /** + * Cleaner thread. + *

+ * This polls the reference queue and releases objects via + * their static release method. + */ + private static void cleaner() { + if (dolog) + log().log(Level.INFO, "Native finaliser started"); + try { + while (true) { + CHandle stale = (CHandle) references.remove(); + do { + try { + synchronized (map) { + map.remove(stale.p); + } + stale.release(); + } catch (Throwable ex) { + } + stale = (CHandle) references.poll(); + } while (stale != null); + } + } catch (InterruptedException ex) { + } + } + + private static class CHandle extends WeakReference { + protected MemoryAddress p; + final Class jtype; + CHandle next; + + CHandle(Native referent, ReferenceQueue references, MemoryAddress p) { + super(referent, references); + this.p = p; + this.jtype = referent.getClass(); + } + + void release() { + try { + if (p != null) { + if (dolog) + log().log(Level.DEBUG, () -> String.format(" releas $%016x %s", Memory.toLong(p), jtype.getName())); + + Method mm = jtype.getDeclaredMethod("release", MemoryAddress.class); + mm.setAccessible(true); + mm.invoke(null, p); + } + } catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) { + log().log(Level.ERROR, jtype.getName(), ex); + } finally { + p = null; + } + } + + @Override + public boolean equals(Object obj) { + return (obj instanceof CHandle) && ((CHandle) obj).p == p; + } + + @Override + public int hashCode() { + //return p.hashCode(); + return hashCode(p); + } + + /** + * Simple hashcode for native pointers. + *

+ * This simply strips the bottom 4 bits from the pointer as + * on a 64-bit system the low 3 bits are typically zero and the 4th + * isn't very well distributed. + * + * @param p + * @return + */ + public static final int hashCode(long p) { + return (int) p >>> 4; + } + + /** + * Sigh, memoryaddress has a miserable hashCode(), it's even worse than Long.hashCode() + */ + public static final int hashCode(MemoryAddress p) { + return p.hashCode() >>> 5; + } + } + + /** + * Lightweight pointer hashtable. + *

+ * This serves two purposes: + *

    + *
  1. Track and resolve unique objects based on memory address; + *
  2. Hold hard references to the WeakReference as required by the gc system. + *
+ *

+ * CHandle's are chained directly from the index table, the p field + * is used as a key directly, and hash values are not cached. This combines + * to save significant memory per node. + */ + private static class PointerTable { + + int mask = 63; + int size = 0; + CHandle[] table = new CHandle[64]; + + private void resize(int length) { + CHandle[] ntable = new CHandle[length]; + int nmask = length - 1; + + for (int i = 0; i < table.length; i++) { + CHandle h = table[i]; + + while (h != null) { + CHandle n = h.next; + int k = h.hashCode() & nmask; + + h.next = ntable[k]; + ntable[k] = h; + + h = n; + } + } + + table = ntable; + mask = nmask; + } + + public CHandle put(CHandle h) { + CHandle o = remove(h.p); + + putAlways(h); + + return o; + } + + public void putAlways(CHandle h) { + if (size > table.length * 2) + resize(table.length * 2); + + int i = h.hashCode() & mask; + + h.next = table[i]; + table[i] = h; + size += 1; + } + + public CHandle get(MemoryAddress p) { + int i = CHandle.hashCode(p) & mask; + CHandle h = table[i]; + + while (h != null && !h.p.equals(p)) + h = h.next; + return h; + } + + public CHandle remove(MemoryAddress p) { + int i = CHandle.hashCode(p) & mask; + CHandle h = table[i]; + CHandle a = null; + + while (h != null && !h.p.equals(p)) { + a = h; + h = h.next; + } + if (h != null) { + if (a != null) + a.next = h.next; + else + table[i] = h.next; + size -= 1; + } + + return h; + } + } +} diff --git a/src/notzed.zcl/classes/au/notzed/zcl/CLBuffer.java b/src/notzed.zcl/classes/au/notzed/zcl/CLBuffer.java index 731823a..d0f59af 100644 --- a/src/notzed.zcl/classes/au/notzed/zcl/CLBuffer.java +++ b/src/notzed.zcl/classes/au/notzed/zcl/CLBuffer.java @@ -16,7 +16,10 @@ */ package au.notzed.zcl; +import jdk.incubator.foreign.*; + import java.nio.ByteBuffer; +import java.lang.invoke.MethodHandle; /** * Interface for memory buffers. @@ -24,43 +27,24 @@ import java.nio.ByteBuffer; */ public class CLBuffer extends CLMemory { - /** - * Use USE_HOST_PTR was used then this keeps track of the host ptr reference - * to avoid java freeing it. - */ - private final ByteBuffer hostPtr; - /** * Create an interface for a native pointer of type cl_mem that refers to a * buffer object. * * @param p Native pointer. */ - public CLBuffer(long p) { - super(p); - hostPtr = null; + public CLBuffer(MemoryAddress p) { + this(p, null); } - public CLBuffer(long p, ByteBuffer hostPtr) { - super(p); - - this.hostPtr = hostPtr; + public CLBuffer(MemoryAddress p, MemorySegment seg) { + super(p, seg); } - static void release(long p) { + static void release(MemoryAddress p) { CLMemory.release(p); } - @Override - int getInfoType() { - return TYPE_MEM_OBJECT; - } - - @Override - public ByteBuffer getHostPtr() { - return hostPtr; - } - /** * Parameter to define a region for createSubBuffer(). * diff --git a/src/notzed.zcl/classes/au/notzed/zcl/CLBufferInfo.java b/src/notzed.zcl/classes/au/notzed/zcl/CLBufferInfo.java index 94ef9ec..fa97c8a 100644 --- a/src/notzed.zcl/classes/au/notzed/zcl/CLBufferInfo.java +++ b/src/notzed.zcl/classes/au/notzed/zcl/CLBufferInfo.java @@ -20,7 +20,7 @@ package au.notzed.zcl; * Parameters for Buffer.createSubBuffer() *

* Specific types are defined on CLBuffer. - * + * */ public abstract class CLBufferInfo { diff --git a/src/notzed.zcl/classes/au/notzed/zcl/CLCommandQueue.java b/src/notzed.zcl/classes/au/notzed/zcl/CLCommandQueue.java index ed2539b..c73cfa7 100644 --- a/src/notzed.zcl/classes/au/notzed/zcl/CLCommandQueue.java +++ b/src/notzed.zcl/classes/au/notzed/zcl/CLCommandQueue.java @@ -16,9 +16,25 @@ */ package au.notzed.zcl; -import java.nio.ByteBuffer; import static au.notzed.zcl.CL.*; -import au.notzed.zcl.khr.GLSharing; +import static au.notzed.zcl.CLLib.*; +import jdk.incubator.foreign.*; +import api.Native; +import api.Allocator; +import api.Memory; +import api.Callback; + +import java.util.ArrayList; + +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.nio.BufferOverflowException; +import java.nio.BufferUnderflowException; +//import static au.au.notzed.zcl.CL.*; +//import au.notzed.zcl.khr.GLSharing; + +import java.lang.invoke.MethodHandle; +import java.util.function.Function; /** * Interface for cl_command_queue. @@ -44,15 +60,24 @@ public class CLCommandQueue extends CLExtendable { * * @param p Native pointer. */ - public CLCommandQueue(long p) { + CLCommandQueue(MemoryAddress p) { super(p); } - private native static void release(long p); + public static CLCommandQueue create(MemoryAddress p) { + return Native.resolve(p, CLCommandQueue::new); + } + + private static void release(MemoryAddress p) { + try { + clReleaseCommandQueue(p); + } catch (Throwable t) { + } + } @Override - int getInfoType() { - return TYPE_COMMAND_QUEUE; + MethodHandle getInfoFunc() { + return clGetCommandQueueInfo; } public static CLQueueProperty PROPERTIES(long flags) { @@ -82,36 +107,92 @@ public class CLCommandQueue extends CLExtendable { * * @throws CLException */ - public native void flush() throws CLException; + public void flush() throws CLException { + try { + int res = clFlush(addr()); + if (res != 0) + throw new CLException(res); + } catch (CLException | RuntimeException | Error t) { + throw t; + } catch (Throwable t) { + throw new RuntimeException(t); + } + } /** * Calls clFinish. * * @throws CLException */ - public native void finish() throws CLException; + public void finish() throws CLException { + try { + int res = clFinish(addr()); + if (res != 0) + throw new CLException(res); + } catch (CLException | RuntimeException | Error t) { + throw t; + } catch (Throwable t) { + throw new RuntimeException(t); + } + } /** - * Calls clEnqueueReadBuffer for a direct Buffer. + * Calls clEnqueueReadBuffer for a MemorySegment. * * @param mem * @param blocking * @param mem_offset source memory offset in bytes. * @param size memory transfer size in bytes. - * @param buffer destination buffer. Must be a direct buffer. + * @param buffer destination buffer. It must be a native segment. * @param wait * @param event * @throws CLException */ - native public void enqueueReadBuffer(CLBuffer mem, boolean blocking, + public void enqueueReadBuffer(CLBuffer mem, boolean blocking, + long mem_offset, long size, + MemorySegment buffer, + CLEventList wait, + CLEventList event) throws CLException { + if (size > buffer.byteSize()) + throw new BufferOverflowException(); + + try (Allocator frame = Memory.stack()) { + EventInfo info = new EventInfo(frame, wait, event); + int res; + + res = clEnqueueReadBuffer(addr(), mem.addr(), blocking ? 1 : 0, + mem_offset, size, + buffer.baseAddress(), + info.nwait, info.wait, info.event); + if (res != 0) + throw new CLException(res); + + info.post(event); + } catch (CLException | RuntimeException | Error t) { + throw t; + } catch (Throwable t) { + throw new RuntimeException(t); + } + } + + public void enqueueReadBuffer(CLBuffer mem, boolean blocking, long mem_offset, long size, ByteBuffer buffer, CLEventList wait, - CLEventList event) throws CLException; + CLEventList event) throws CLException { + try (MemorySegment seg = MemorySegment.ofByteBuffer(buffer)) { + enqueueReadBuffer(mem, blocking, + mem_offset, size, + seg, + wait, event); + } + } /** * Calls clEnqueueReadBuffer for a byte array. * + * panama note: the buffer must always be copied. + * * @param mem * @param blocking ignored, array reads are always blocking. * @param mem_offset source memory offset in bytes. @@ -122,15 +203,22 @@ public class CLCommandQueue extends CLExtendable { * @param event * @throws CLException */ - native public void enqueueReadBuffer(CLBuffer mem, boolean blocking, - long mem_offset, long size, - byte[] buffer, long buf_offset, + public void enqueueReadBuffer(CLBuffer mem, boolean blocking, + long mem_offset, int size, + byte[] buffer, int buf_offset, CLEventList wait, - CLEventList event) throws CLException; + CLEventList event) throws CLException { + try (MemorySegment seg = MemorySegment.allocateNative(size)) { + enqueueReadBuffer(mem, true, mem_offset, size, seg, wait, event); + seg.asByteBuffer().order(ByteOrder.nativeOrder()).get(buffer, buf_offset, size); + } + } /** * Calls clEnqueueReadBuffer for a short array. * + * Note that mem_offset and size are in terms of the buffer element size. + * * @param mem * @param blocking ignored, array reads are always blocking. * @param mem_offset source memory offset in shorts. @@ -141,35 +229,78 @@ public class CLCommandQueue extends CLExtendable { * @param event * @throws CLException */ - native public void enqueueReadBuffer(CLBuffer mem, boolean blocking, - long mem_offset, long size, - short[] buffer, long buf_offset, + public void enqueueReadBuffer(CLBuffer mem, boolean blocking, + long mem_offset, int size, + short[] buffer, int buf_offset, CLEventList wait, - CLEventList event) throws CLException; + CLEventList event) throws CLException { + try (MemorySegment seg = MemorySegment.allocateNative(size * 2)) { + enqueueReadBuffer(mem, true, mem_offset * 2, size * 2, seg, wait, event); + seg.asByteBuffer().order(ByteOrder.nativeOrder()).asShortBuffer().get(buffer, buf_offset, size); + } + } - native public void enqueueReadBuffer(CLBuffer mem, boolean blocking, - long mem_offset, long size, - int[] buffer, long buf_offset, + public void enqueueReadBuffer(CLBuffer mem, boolean blocking, + long mem_offset, int size, + int[] buffer, int buf_offset, CLEventList wait, - CLEventList event) throws CLException; + CLEventList event) throws CLException { + try (MemorySegment seg = MemorySegment.allocateNative(size * 4)) { + enqueueReadBuffer(mem, true, mem_offset * 4, size * 4, seg, wait, event); + seg.asByteBuffer().order(ByteOrder.nativeOrder()).asIntBuffer().get(buffer, buf_offset, size); + } + } - native public void enqueueReadBuffer(CLBuffer mem, boolean blocking, - long mem_offset, long size, - long[] buffer, long buf_offset, + public void enqueueReadBuffer(CLBuffer mem, boolean blocking, + long mem_offset, int size, + long[] buffer, int buf_offset, CLEventList wait, - CLEventList event) throws CLException; + CLEventList event) throws CLException { + try (MemorySegment seg = MemorySegment.allocateNative(size * 8)) { + enqueueReadBuffer(mem, true, mem_offset * 8, size * 8, seg, wait, event); + seg.asByteBuffer().order(ByteOrder.nativeOrder()).asLongBuffer().get(buffer, buf_offset, size); + } + } - native public void enqueueReadBuffer(CLBuffer mem, boolean blocking, - long mem_offset, long size, - float[] buffer, long buf_offset, + public void enqueueReadBuffer(CLBuffer mem, boolean blocking, + long mem_offset, int size, + float[] buffer, int buf_offset, CLEventList wait, - CLEventList event) throws CLException; + CLEventList event) throws CLException { + try (MemorySegment seg = MemorySegment.allocateNative(size * 4)) { + enqueueReadBuffer(mem, true, mem_offset * 4, size * 4, seg, wait, event); + seg.asByteBuffer().order(ByteOrder.nativeOrder()).asFloatBuffer().get(buffer, buf_offset, size); + } + } - native public void enqueueReadBuffer(CLBuffer mem, boolean blocking, - long mem_offset, long size, - double[] buffer, long buf_offset, + public void enqueueReadBuffer(CLBuffer mem, boolean blocking, + long mem_offset, int size, + double[] buffer, int buf_offset, CLEventList wait, - CLEventList event) throws CLException; + CLEventList event) throws CLException { + try (MemorySegment seg = MemorySegment.allocateNative(size * 8)) { + enqueueReadBuffer(mem, true, mem_offset * 8, size * 8, seg, wait, event); + seg.asByteBuffer().order(ByteOrder.nativeOrder()).asDoubleBuffer().get(buffer, buf_offset, size); + } + } + + private void checkBufferRectRange( + long[] buffer_origin, long[] host_origin, long[] region, + long buffer_row_pitch, long buffer_slice_pitch, long host_row_pitch, long host_slice_pitch, + long limit) { + if (buffer_origin.length != 3 + || host_origin.length != 3 + || region.length != 3) + throw new IllegalArgumentException("origin and region must be 3-dimensional"); + + long stride = host_row_pitch == 0 ? region[0] : host_row_pitch; + long slice = host_slice_pitch == 0 ? region[1] * stride : host_slice_pitch; + + if (host_origin[0] + host_origin[1] * stride + host_origin[2] * slice + + region[0] + (region[1]-1) * stride + (region[2]-1) * slice + > limit) + throw new BufferOverflowException(); + } /** * @@ -189,17 +320,89 @@ public class CLCommandQueue extends CLExtendable { * @throws UnsupportedOperationException * @since OpenCL 1.1 */ - public native void enqueueReadBufferRect(CLBuffer mem, boolean blocking, + public void enqueueReadBufferRect(CLBuffer mem, boolean blocking, + long[] buffer_origin, long[] host_origin, long[] region, + long buffer_row_pitch, long buffer_slice_pitch, long host_row_pitch, long host_slice_pitch, + MemorySegment buffer, + CLEventList wait, CLEventList event) throws CLException, UnsupportedOperationException { + checkBufferRectRange( + buffer_origin, host_origin, region, + buffer_row_pitch, buffer_slice_pitch, host_row_pitch, host_slice_pitch, + buffer.byteSize()); + + try (Allocator frame = Memory.stack()) { + EventInfo info = new EventInfo(frame, wait, event); + MemoryAddress cbuffer_origin = toLongV(frame, buffer_origin); + MemoryAddress chost_origin = toLongV(frame, host_origin); + MemoryAddress cregion = toLongV(frame, region); + int res; + + res = clEnqueueReadBufferRect( + addr(), mem.addr(), blocking ? 1 : 0, + cbuffer_origin, chost_origin, cregion, + buffer_row_pitch, + buffer_slice_pitch, + host_row_pitch, + host_slice_pitch, + buffer.baseAddress(), + info.nwait, info.wait, info.event); + + if (res != 0) + throw new CLException(res); + + info.post(event); + } catch (CLException | RuntimeException | Error t) { + throw t; + } catch (Throwable t) { + throw new RuntimeException(t); + } + } + + public void enqueueReadBufferRect(CLBuffer mem, boolean blocking, long[] buffer_origin, long[] host_origin, long[] region, long buffer_row_pitch, long buffer_slice_pitch, long host_row_pitch, long host_slice_pitch, ByteBuffer buffer, - CLEventList waiters, CLEventList events) throws CLException, UnsupportedOperationException; + CLEventList waiters, CLEventList events) throws CLException, UnsupportedOperationException { + + try (MemorySegment seg = MemorySegment.ofByteBuffer(buffer)) { + enqueueReadBufferRect(mem, blocking, + buffer_origin, host_origin, region, + buffer_row_pitch, buffer_slice_pitch, host_row_pitch, host_slice_pitch, + seg, + waiters, events); + } + } - public native void enqueueReadBufferRect(CLBuffer mem, boolean blocking, + public void enqueueReadBufferRect(CLBuffer mem, boolean blocking, long[] buffer_origin, long[] host_origin, long[] region, long buffer_row_pitch, long buffer_slice_pitch, long host_row_pitch, long host_slice_pitch, byte[] buffer, - CLEventList waiters, CLEventList events) throws CLException, UnsupportedOperationException; + CLEventList waiters, CLEventList events) throws CLException, UnsupportedOperationException { + // This allocates only what is required and then copies row by row to the target host_origin. + // yikes this isn't very nice. + long stride = region[0]; + long slice = region[1] * stride; + long size = slice * region[2]; + + try (MemorySegment seg = MemorySegment.allocateNative(size)) { + enqueueReadBufferRect(mem, blocking, + buffer_origin, OFFSET_0x0x0, region, + buffer_row_pitch, buffer_slice_pitch, stride, slice, + seg, + waiters, events); + long host_stride = host_row_pitch == 0 ? region[0] : host_row_pitch; + long host_slice = host_slice_pitch == 0 ? region[1] * host_stride : host_slice_pitch; + long host_offset = host_origin[0] + host_origin[1] * host_stride + host_origin[2] * host_slice; + ByteBuffer bb = seg.asByteBuffer().order(ByteOrder.nativeOrder()); + + for (long z = 0; z < region[2]; z++) { + for (long y = 0; y < region[1]; y++) { + long o = host_offset + y * host_stride + z * host_slice; + bb.get(buffer, (int)o, (int)region[0]); + } + } + } + } public native void enqueueReadBufferRect(CLBuffer mem, boolean blocking, long[] buffer_origin, long[] host_origin, long[] region, @@ -231,47 +434,111 @@ public class CLCommandQueue extends CLExtendable { double[] buffer, CLEventList waiters, CLEventList events) throws CLException, UnsupportedOperationException; - native public void enqueueWriteBuffer(CLBuffer mem, boolean blocking, + public void enqueueWriteBuffer(CLBuffer mem, boolean blocking, long mem_offset, long size, - ByteBuffer buffer, + MemorySegment buffer, CLEventList wait, - CLEventList event) throws CLException; + CLEventList event) throws CLException { + if (size > buffer.byteSize()) + throw new BufferUnderflowException(); + + try (Allocator frame = Memory.stack()) { + EventInfo info = new EventInfo(frame, wait, event); + int res; + + res = clEnqueueWriteBuffer(addr(), mem.addr(), blocking ? 1 : 0, + mem_offset, size, + buffer.baseAddress(), + info.nwait, info.wait, info.event); + if (res != 0) + throw new CLException(res); + + info.post(event); + } catch (CLException | RuntimeException | Error t) { + throw t; + } catch (Throwable t) { + throw new RuntimeException(t); + } + } - native public void enqueueWriteBuffer(CLBuffer mem, boolean blocking, + public void enqueueWriteBuffer(CLBuffer mem, boolean blocking, long mem_offset, long size, - byte[] buffer, long buf_offset, + ByteBuffer buffer, CLEventList wait, - CLEventList event) throws CLException; + CLEventList event) throws CLException { + try (MemorySegment seg = MemorySegment.ofByteBuffer(buffer)) { + enqueueWriteBuffer(mem, blocking, + mem_offset, size, + seg, + wait, event); + } + } - native public void enqueueWriteBuffer(CLBuffer mem, boolean blocking, - long mem_offset, long size, - short[] buffer, long buf_offset, + public void enqueueWriteBuffer(CLBuffer mem, boolean blocking, + long mem_offset, int size, + byte[] buffer, int buf_offset, CLEventList wait, - CLEventList event) throws CLException; + CLEventList event) throws CLException { + try (MemorySegment seg = MemorySegment.allocateNative(size)) { + seg.asByteBuffer().order(ByteOrder.nativeOrder()).put(buffer, buf_offset, size); + enqueueWriteBuffer(mem, true, mem_offset, size, seg, wait, event); + } + } - native public void enqueueWriteBuffer(CLBuffer mem, boolean blocking, - long mem_offset, long size, - int[] buffer, long buf_offset, + public void enqueueWriteBuffer(CLBuffer mem, boolean blocking, + long mem_offset, int size, + short[] buffer, int buf_offset, CLEventList wait, - CLEventList event) throws CLException; + CLEventList event) throws CLException { + try (MemorySegment seg = MemorySegment.allocateNative(size * 2L)) { + seg.asByteBuffer().order(ByteOrder.nativeOrder()).asShortBuffer().put(buffer, buf_offset, size); + enqueueWriteBuffer(mem, true, mem_offset * 2, size * 2L, seg, wait, event); + } + } - native public void enqueueWriteBuffer(CLBuffer mem, boolean blocking, - long mem_offset, long size, - long[] buffer, long buf_offset, + public void enqueueWriteBuffer(CLBuffer mem, boolean blocking, + long mem_offset, int size, + int[] buffer, int buf_offset, CLEventList wait, - CLEventList event) throws CLException; + CLEventList event) throws CLException { + try (MemorySegment seg = MemorySegment.allocateNative(size * 4L)) { + seg.asByteBuffer().order(ByteOrder.nativeOrder()).asIntBuffer().put(buffer, buf_offset, size); + enqueueWriteBuffer(mem, true, mem_offset * 4, size * 4L, seg, wait, event); + } + } - native public void enqueueWriteBuffer(CLBuffer mem, boolean blocking, - long mem_offset, long size, - float[] buffer, long buf_offset, + public void enqueueWriteBuffer(CLBuffer mem, boolean blocking, + long mem_offset, int size, + long[] buffer, int buf_offset, CLEventList wait, - CLEventList event) throws CLException; + CLEventList event) throws CLException { + try (MemorySegment seg = MemorySegment.allocateNative(size * 8L)) { + seg.asByteBuffer().order(ByteOrder.nativeOrder()).asLongBuffer().put(buffer, buf_offset, size); + enqueueWriteBuffer(mem, true, mem_offset * 8, size * 8L, seg, wait, event); + } + } - native public void enqueueWriteBuffer(CLBuffer mem, boolean blocking, - long mem_offset, long size, - double[] buffer, long buf_offset, + public void enqueueWriteBuffer(CLBuffer mem, boolean blocking, + long mem_offset, int size, + float[] buffer, int buf_offset, CLEventList wait, - CLEventList event) throws CLException; + CLEventList event) throws CLException { + try (MemorySegment seg = MemorySegment.allocateNative(size * 4L)) { + seg.asByteBuffer().order(ByteOrder.nativeOrder()).asFloatBuffer().put(buffer, buf_offset, size); + enqueueWriteBuffer(mem, true, mem_offset * 4, size * 4L, seg, wait, event); + } + } + + public void enqueueWriteBuffer(CLBuffer mem, boolean blocking, + long mem_offset, int size, + double[] buffer, int buf_offset, + CLEventList wait, + CLEventList event) throws CLException { + try (MemorySegment seg = MemorySegment.allocateNative(size * 8L)) { + seg.asByteBuffer().order(ByteOrder.nativeOrder()).asDoubleBuffer().put(buffer, buf_offset, size); + enqueueWriteBuffer(mem, true, mem_offset * 8, size * 8L, seg, wait, event); + } + } /** * @@ -291,11 +558,60 @@ public class CLCommandQueue extends CLExtendable { * @throws UnsupportedOperationException * @since OpenCL 1.1 */ - public native void enqueueWriteBufferRect(CLBuffer mem, boolean blocking, + public void enqueueWriteBufferRect(CLBuffer mem, boolean blocking, + long[] buffer_origin, long[] host_origin, long[] region, + long buffer_row_pitch, long buffer_slice_pitch, long host_row_pitch, long host_slice_pitch, + MemorySegment buffer, + CLEventList wait, CLEventList event) throws CLException, UnsupportedOperationException { + + requireAPIVersion(CLPlatform.VERSION_1_1); + + checkBufferRectRange( + buffer_origin, host_origin, region, + buffer_row_pitch, buffer_slice_pitch, host_row_pitch, host_slice_pitch, + buffer.byteSize()); + + try (Allocator frame = Memory.stack()) { + EventInfo info = new EventInfo(frame, wait, event); + MemoryAddress cbuffer_origin = toLongV(frame, buffer_origin); + MemoryAddress chost_origin = toLongV(frame, host_origin); + MemoryAddress cregion = toLongV(frame, region); + int res; + + res = clEnqueueWriteBufferRect( + addr(), mem.addr(), blocking ? 1 : 0, + cbuffer_origin, chost_origin, cregion, + buffer_row_pitch, + buffer_slice_pitch, + host_row_pitch, + host_slice_pitch, + buffer.baseAddress(), + info.nwait, info.wait, info.event); + + if (res != 0) + throw new CLException(res); + + info.post(event); + } catch (CLException | RuntimeException | Error t) { + throw t; + } catch (Throwable t) { + throw new RuntimeException(t); + } + } + + public void enqueueWriteBufferRect(CLBuffer mem, boolean blocking, long[] buffer_origin, long[] host_origin, long[] region, long buffer_row_pitch, long buffer_slice_pitch, long host_row_pitch, long host_slice_pitch, ByteBuffer buffer, - CLEventList waiters, CLEventList events) throws CLException, UnsupportedOperationException; + CLEventList waiters, CLEventList events) throws CLException, UnsupportedOperationException { + try (MemorySegment seg = MemorySegment.ofByteBuffer(buffer)) { + enqueueWriteBufferRect(mem, blocking, + buffer_origin, host_origin, region, + buffer_row_pitch, buffer_slice_pitch, host_row_pitch, host_slice_pitch, + seg, + waiters, events); + } + } public native void enqueueWriteBufferRect(CLBuffer mem, boolean blocking, long[] buffer_origin, long[] host_origin, long[] region, @@ -334,7 +650,10 @@ public class CLCommandQueue extends CLExtendable { CLEventList waiters, CLEventList events) throws CLException, UnsupportedOperationException; /** - * Calls clEnqueueFillBuffer for byte types. + * Calls clEnqueueFillBuffer. + * + * This fills the buffer with a pattern. The offset and size + * is in multiples of the pattern size. * * @param buffer * @param pattern pattern to fill @@ -345,12 +664,75 @@ public class CLCommandQueue extends CLExtendable { * @since OpenCL 1.2 * @throws CLException */ - public native void enqueueFillBuffer(CLBuffer buffer, - byte[] pattern, + public void enqueueFillBuffer(CLBuffer buffer, + MemorySegment pattern, + long offset, + long size, + CLEventList wait, + CLEventList event) throws CLException { + requireAPIVersion(CLPlatform.VERSION_1_2); + try (Allocator frame = Memory.stack()) { + EventInfo info = new EventInfo(frame, wait, event); + int res; + + res = clEnqueueFillBuffer( + addr(), buffer.addr(), + pattern.baseAddress(), pattern.byteSize(), + offset * pattern.byteSize(), + size * pattern.byteSize(), + info.nwait, info.wait, info.event); + + if (res != 0) + throw new CLException(res); + + info.post(event); + } catch (CLException | RuntimeException | Error t) { + throw t; + } catch (Throwable t) { + throw new RuntimeException(t); + } + } + public void enqueueFillBuffer(CLBuffer buffer, + ByteBuffer pattern, long offset, long size, - CLEventList waiters, - CLEventList events) throws CLException; + CLEventList wait, + CLEventList event) throws CLException { + try (MemorySegment seg = MemorySegment.ofByteBuffer(pattern)) { + enqueueFillBuffer(buffer, + pattern, + offset, size, + wait, event); + } + } + + /** + * Calls clEnqueueFillBuffer for byte types. + * + * @param buffer + * @param pattern pattern to fill + * @param offset offset in multiples of the pattern size. + * @param size number of elements in multiples of the pattern size. + * @param waiters + * @param events + * @since OpenCL 1.2 + * @throws CLException + */ + public void enqueueFillBuffer(CLBuffer buffer, + byte[] pattern, + long offset, + long size, + CLEventList wait, + CLEventList event) throws CLException { + try (MemorySegment seg = MemorySegment.allocateNative(pattern.length)) { + MemoryAddress add = seg.baseAddress(); + + for (int i=0;ibuffer copy function, for read or write + */ + private void doImageBuffer(CLImage image, boolean blocking, + long[] origin, + long[] region, + long row_pitch, + long slice_pitch, + MemorySegment buffer, + CLEventList wait, + CLEventList event, + MethodHandle op) throws CLException { + + if (origin.length != 3 + || region.length != 3) + throw new IllegalArgumentException("origin and region must be 3-dimensional"); + + long stride = row_pitch == 0 ? region[0] * image.getElementSize() : row_pitch; + long slice = slice_pitch == 0 ? region[1] * stride : slice_pitch; + + if (buffer.byteSize() < slice * region[2]) + throw new BufferOverflowException(); + + try (Allocator frame = Memory.stack()) { + EventInfo info = new EventInfo(frame, wait, event); + MemoryAddress corigin = toLongV(frame, origin); + MemoryAddress cregion = toLongV(frame, region); + int res; + + res = (int)op.invokeExact( + addr(), image.addr(), blocking ? 1 : 0, + corigin, cregion, + row_pitch, slice_pitch, + buffer.baseAddress(), + info.nwait, info.wait, info.event); + + if (res != 0) + throw new CLException(res); + + info.post(event); + } catch (CLException | RuntimeException | Error t) { + throw t; + } catch (Throwable t) { + throw new RuntimeException(t); + } + } + + private interface CopyAppend { + void apply(int doff, int size); + + default void copy(int w, int h, int d, int stride, int slice) { + for (int z=0;zbuffer copy function, for read or write + * of primitive types. + * This first copies to the exact size required + * and then copies to the target. + */ + private void doImageBufferPrimitive( + CLImage image, boolean blocking, + long[] origin, + long[] region, + long row_pitch, + long slice_pitch, + boolean readMode, + Function writer, + long write_size, + long dshift, + MethodHandle op, + CLEventList wait, + CLEventList event) throws CLException { + // Just transfer the minimum size, then copy to target + long elsize = image.getElementSize(); + + // these sizes are in array elmeents + long stride = row_pitch == 0 ? (region[0] * elsize) >> dshift : row_pitch; + long slice = slice_pitch == 0 ? (region[1] * stride) >> dshift : slice_pitch; + + // Test target size + if (slice * region[2] > write_size) + throw new BufferOverflowException(); + + // these are in bytes + long alloc = (region[0] * region[1] * region[2]) << dshift; + long xstride = region[0] << dshift; + long xslice = xstride * region[1]; + + try (MemorySegment seg = MemorySegment.allocateNative(alloc)) { + if (!readMode) + writer.apply(seg).copy((int)region[0], (int)region[1], (int)region[2],(int)stride, (int)slice); + doImageBuffer(image, blocking, origin, region, xstride, 0, seg, wait, event, op); + if (readMode) + writer.apply(seg).copy((int)region[0], (int)region[1], (int)region[2],(int)stride, (int)slice); + } catch (CLException | RuntimeException | Error t) { + throw t; + } catch (Throwable t) { + throw new RuntimeException(t); + } + } /** * @@ -491,14 +1028,36 @@ public class CLCommandQueue extends CLExtendable { * @param events * @throws CLException */ - public native void enqueueReadImage(CLImage image, boolean blocking, + public void enqueueReadImage(CLImage image, boolean blocking, + long[] origin, + long[] region, + long row_pitch, + long slice_pitch, + MemorySegment buffer, + CLEventList wait, + CLEventList event) throws CLException { + doImageBuffer(image, blocking, origin, region, row_pitch, slice_pitch, buffer, wait, event, clEnqueueReadImage); + } + + /** + * @see #enqueueReadImage(CLImage,boolean,long[],long[],long,long,MemorySegment,CLEventList,CLEventList) + */ + public void enqueueReadImage(CLImage image, boolean blocking, long[] origin, long[] region, long row_pitch, long slice_pitch, ByteBuffer buffer, - CLEventList waiters, - CLEventList events) throws CLException; + CLEventList wait, + CLEventList event) throws CLException { + try (MemorySegment seg = MemorySegment.ofByteBuffer(buffer)) { + enqueueReadImage(image, blocking, + origin, region, + row_pitch, slice_pitch, + seg, + wait, event); + } + } /** * @@ -514,23 +1073,50 @@ public class CLCommandQueue extends CLExtendable { * @param events * @throws CLException */ - public native void enqueueReadImage(CLImage image, boolean blocking, + public void enqueueReadImage(CLImage image, boolean blocking, long[] origin, long[] region, long row_pitch, long slice_pitch, - byte[] buffer, long buff_offset, - CLEventList waiters, - CLEventList events) throws CLException; + byte[] buffer, int buff_offset, + CLEventList wait, + CLEventList event) throws CLException { + + doImageBufferPrimitive(image, blocking, origin, region, row_pitch, slice_pitch, + true, + (seg) -> { + var sb = seg.asByteBuffer(); + return (off, size) -> sb.get(buffer, buff_offset + off, size); + }, + buff_offset - buffer.length, + 0, + clEnqueueReadImage, + wait, event); + } - public native void enqueueReadImage(CLImage image, boolean blocking, + /** + * @see #enqueueReadImage(CLImage,boolean,long[],long[],long,long,byte[],int,CLEventList,CLEventList) + */ + public void enqueueReadImage(CLImage image, boolean blocking, long[] origin, long[] region, long row_pitch, long slice_pitch, - short[] buffer, long buff_offset, - CLEventList waiters, - CLEventList events) throws CLException; + short[] buffer, int buff_offset, + CLEventList wait, + CLEventList event) throws CLException { + + doImageBufferPrimitive(image, blocking, origin, region, row_pitch, slice_pitch, + true, + (seg) -> { + var sb = seg.asByteBuffer().order(ByteOrder.nativeOrder()).asShortBuffer(); + return (off, size) -> sb.get(buffer, buff_offset + off, size); + }, + buff_offset - buffer.length, + 1, + clEnqueueReadImage, + wait, event); + } public native void enqueueReadImage(CLImage image, boolean blocking, long[] origin, @@ -550,14 +1136,25 @@ public class CLCommandQueue extends CLExtendable { CLEventList waiters, CLEventList events) throws CLException; - public native void enqueueReadImage(CLImage image, boolean blocking, + public void enqueueReadImage(CLImage image, boolean blocking, long[] origin, long[] region, long row_pitch, long slice_pitch, - float[] buffer, long buff_offset, - CLEventList waiters, - CLEventList events) throws CLException; + float[] buffer, int buff_offset, + CLEventList wait, + CLEventList event) throws CLException { + doImageBufferPrimitive(image, blocking, origin, region, row_pitch, slice_pitch, + true, + (seg) -> { + var sb = seg.asByteBuffer().order(ByteOrder.nativeOrder()).asFloatBuffer(); + return (off, size) -> sb.get(buffer, buff_offset + off, size); + }, + buff_offset - buffer.length, + 2, + clEnqueueReadImage, + wait, event); + } public native void enqueueReadImage(CLImage image, boolean blocking, long[] origin, @@ -568,23 +1165,54 @@ public class CLCommandQueue extends CLExtendable { CLEventList waiters, CLEventList events) throws CLException; - public native void enqueueWriteImage(CLImage image, boolean blocking, + public void enqueueWriteImage(CLImage image, boolean blocking, + long[] origin, + long[] region, + long row_pitch, + long slice_pitch, + MemorySegment buffer, + CLEventList wait, + CLEventList event) throws CLException { + doImageBuffer(image, blocking, origin, region, row_pitch, slice_pitch, buffer, wait, event, clEnqueueWriteImage); + } + + public void enqueueWriteImage(CLImage image, boolean blocking, long[] origin, long[] region, long row_pitch, long slice_pitch, ByteBuffer buffer, - CLEventList waiters, - CLEventList events) throws CLException; + CLEventList wait, + CLEventList event) throws CLException { + try (MemorySegment seg = MemorySegment.ofByteBuffer(buffer)) { + enqueueWriteImage(image, blocking, + origin, region, + row_pitch, slice_pitch, + seg, + wait, event); + } + } - public native void enqueueWriteImage(CLImage image, boolean blocking, + public void enqueueWriteImage(CLImage image, boolean blocking, long[] origin, long[] region, long row_pitch, long slice_pitch, - byte[] buffer, long buff_offset, - CLEventList waiters, - CLEventList events) throws CLException; + byte[] buffer, int buff_offset, + CLEventList wait, + CLEventList event) throws CLException { + + doImageBufferPrimitive(image, blocking, origin, region, row_pitch, slice_pitch, + false, + (seg) -> { + var sb = seg.asByteBuffer(); + return (off, size) -> sb.put(buffer, buff_offset + off, size); + }, + buff_offset - buffer.length, + 0, + clEnqueueWriteImage, + wait, event); + } public native void enqueueWriteImage(CLImage image, boolean blocking, long[] origin, @@ -613,14 +1241,25 @@ public class CLCommandQueue extends CLExtendable { CLEventList waiters, CLEventList events) throws CLException; - public native void enqueueWriteImage(CLImage image, boolean blocking, + public void enqueueWriteImage(CLImage image, boolean blocking, long[] origin, long[] region, long row_pitch, long slice_pitch, - float[] buffer, long buff_offset, - CLEventList waiters, - CLEventList events) throws CLException; + float[] buffer, int buff_offset, + CLEventList wait, + CLEventList event) throws CLException { + doImageBufferPrimitive(image, blocking, origin, region, row_pitch, slice_pitch, + false, + (seg) -> { + var sb = seg.asByteBuffer().order(ByteOrder.nativeOrder()).asFloatBuffer(); + return (off, size) -> sb.put(buffer, buff_offset + off, size); + }, + buff_offset - buffer.length, + 2, + clEnqueueWriteImage, + wait, event); + } public native void enqueueWriteImage(CLImage image, boolean blocking, long[] origin, @@ -692,25 +1331,163 @@ public class CLCommandQueue extends CLExtendable { CLEventList waiters, CLEventList events) throws CLException; - public native ByteBuffer enqueueMapBuffer(CLBuffer buffer, boolean blocking, - long flags, - long offset, - long size, - CLEventList waiters, - CLEventList events) throws CLException; + static class MapData { + MemoryAddress raw; + ByteBuffer buffer; - public native ByteBuffer enqueueMapImage(CLImage image, boolean blocking, - long flags, - long[] origin, - long[] region, - long[] image_row_pitch, - long[] image_slice_pitch, - CLEventList waiters, - CLEventList events) throws CLException; + public MapData(MemoryAddress p, ByteBuffer buffer) { + this.raw = p; + this.buffer = buffer; + } + } - public native void enqueueUnmapMemObject(CLMemory mem, ByteBuffer mapped, - CLEventList waiters, - CLEventList events) throws CLException; + private final ArrayList maps = new ArrayList<>(); + + private void addMap(MemoryAddress raw, ByteBuffer bb) { + synchronized (maps) { + maps.add(new MapData(raw, bb)); + } + } + + private MemoryAddress getMap(ByteBuffer bb) { + synchronized (maps) { + // Note this can't use a hashtable as ByteBuffer + // hashes on state like position. + for (int i=0;i 0) { + wait = frame.alloca(8 * nwait); + for (int i=0;i call = Native.resolve( + Call_pv_v.stub((MemoryAddress memargs) -> { + int xmem = 0; + + for (int i=0;i new Callback<>(p, kernel)); + + res = clEnqueueNativeKernel(addr(), call.addr(), memstage, nmem * 8, nmem, memstage, memptrs, info.nwait, info.wait, info.event); + + if (res != 0) + throw new CLException(res); + + info.post(events); + } catch (CLException | RuntimeException | Error t) { + throw t; + } catch (Throwable t) { + throw new RuntimeException(t); + } + + } /** * Enqueues a marker point. @@ -785,9 +1682,24 @@ public class CLCommandQueue extends CLExtendable { * @param events * @throws CLException */ - public native void enqueueMarkerWithWaitList( + public void enqueueMarkerWithWaitList( CLEventList waiters, - CLEventList events) throws CLException; + CLEventList events) throws CLException { + try (Allocator frame = Memory.stack()) { + EventInfo info = new EventInfo(frame, waiters, events); + if (haveAPIVersion(CLPlatform.VERSION_1_2)) { + clEnqueueMarkerWithWaitList(addr(), info.nwait, info.wait, info.event); + } else { + clEnqueueWaitForEvents(addr(), info.nwait, info.wait); + clEnqueueMarker(addr(), info.event); + } + info.post(events); + } catch (CLException | RuntimeException | Error t) { + throw t; + } catch (Throwable t) { + throw new RuntimeException(t); + } + } /** * Enqueues a barrier. @@ -800,9 +1712,25 @@ public class CLCommandQueue extends CLExtendable { * @param events * @throws CLException */ - public native void enqueueBarrierWithWaitList( + public void enqueueBarrierWithWaitList( CLEventList waiters, - CLEventList events) throws CLException; + CLEventList events) throws CLException { + try (Allocator frame = Memory.stack()) { + EventInfo info = new EventInfo(frame, waiters, events); + if (haveAPIVersion(CLPlatform.VERSION_1_2)) { + clEnqueueBarrierWithWaitList(addr(), info.nwait, info.wait, info.event); + } else { + clEnqueueWaitForEvents(addr(), info.nwait, info.wait); + clEnqueueBarrier(addr()); + clEnqueueMarker(addr(), info.event); + } + info.post(events); + } catch (CLException | RuntimeException | Error t) { + throw t; + } catch (Throwable t) { + throw new RuntimeException(t); + } + } /** * Call clEnqueueSVMFree(). @@ -1002,11 +1930,11 @@ public class CLCommandQueue extends CLExtendable { } public CLContext getContext() { - return getInfoAny(CTYPE_CONTEXT, CL_QUEUE_CONTEXT); + return getInfoAny(CL_QUEUE_CONTEXT, clGetCommandQueueInfo, CLContext::new); } public CLDevice getDevice() { - return getInfoAny(CTYPE_DEVICE, CL_QUEUE_DEVICE); + return getInfoAny(CL_QUEUE_DEVICE, clGetCommandQueueInfo, CLDevice::new); } public long getProperties() { @@ -1026,26 +1954,26 @@ public class CLCommandQueue extends CLExtendable { return getDevice().platform; } - protected GLSharing getGLSharing() { - return getExtension(GLSharing.class, CLPlatform.cl_khr_gl_sharing); - } + //protected GLSharing getGLSharing() { + // return getExtension(GLSharing.class, CLPlatform.cl_khr_gl_sharing); + //} /* Experimental: Alternative interface to extensions. */ - public void enqueueAcquireGLObjects( - CLMemory[] mem_objects, - CLEventList waiters, - CLEventList events) { - getGLSharing().enqueueAcquireGLObjects(this, mem_objects, waiters, events); - } - - public void enqueueReleaseGLObjects( - CLMemory[] mem_objects, - CLEventList waiters, - CLEventList events) { - getGLSharing().enqueueReleaseGLObjects(this, mem_objects, waiters, events); - } + //public void enqueueAcquireGLObjects( + // CLMemory[] mem_objects, + // CLEventList waiters, + // CLEventList events) { + // getGLSharing().enqueueAcquireGLObjects(this, mem_objects, waiters, events); + //} + + //public void enqueueReleaseGLObjects( + // CLMemory[] mem_objects, + // CLEventList waiters, + // CLEventList events) { + // getGLSharing().enqueueReleaseGLObjects(this, mem_objects, waiters, events); + //} /** * Invoke task.queue for this queue with no event lists. diff --git a/src/notzed.zcl/classes/au/notzed/zcl/CLContext.java b/src/notzed.zcl/classes/au/notzed/zcl/CLContext.java index a2d51c3..34d89d0 100644 --- a/src/notzed.zcl/classes/au/notzed/zcl/CLContext.java +++ b/src/notzed.zcl/classes/au/notzed/zcl/CLContext.java @@ -16,15 +16,27 @@ */ package au.notzed.zcl; -import java.nio.ByteBuffer; import static au.notzed.zcl.CL.*; -import au.notzed.zcl.khr.GLEvent; -import au.notzed.zcl.khr.GLSharing; +import static au.notzed.zcl.CLLib.*; +import jdk.incubator.foreign.*; +import api.Memory; +import api.Allocator; +import api.Native; +import api.Callback; +import java.util.stream.Stream; + +import java.lang.invoke.MethodHandle; + +import java.nio.ByteBuffer; +import java.nio.ByteOrder; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.nio.charset.Charset; +import java.util.function.Function; +import java.util.function.IntFunction; + /** * Interface for cl_context */ @@ -33,24 +45,34 @@ public class CLContext extends CLExtendable { /** * If a notify callback is supplied to createContext() then this is used to track the reference. */ - final CLContextNotify notify; + final Callback notify; /** * Creates an interface for a native pointer of type cl_context. * * @param p Native pointer. */ - public CLContext(long p) { + public CLContext(MemoryAddress p) { super(p); this.notify = null; } - CLContext(long p, CLContextNotify notify) { + CLContext(MemoryAddress p, Callback notify) { super(p); this.notify = notify; } - private native static void release(long p); + static CLContext create(MemoryAddress p) { + return Native.resolve(p, CLContext::new); + } + + private static void release(MemoryAddress p) { + try { + clReleaseContext(p); + } catch (Throwable t) { + t.printStackTrace(); + } + } @Override public String toString() { @@ -65,8 +87,8 @@ public class CLContext extends CLExtendable { } @Override - int getInfoType() { - return TYPE_CONTEXT; + MethodHandle getInfoFunc() { + return clGetContextInfo; } /** @@ -76,7 +98,7 @@ public class CLContext extends CLExtendable { * @return new property */ public static CLContextProperty PLATFORM(CLPlatform platform) { - return new CLContextProperty.TagValue(CL.CL_CONTEXT_PLATFORM, platform.getP()); + return new CLContextProperty.TagValue(CL.CL_CONTEXT_PLATFORM, platform.addr().offset()); } /** @@ -99,7 +121,31 @@ public class CLContext extends CLExtendable { * release() should be called when it is no longer needed. * @throws CLRuntimeException */ - public static native CLContext createContext(CLContextProperty[] properties, CLDevice[] devices, CLContextNotify notify) throws CLRuntimeException; + public static CLContext createContext(CLContextProperty[] properties, CLDevice[] devices, CLContextNotify notify) throws CLRuntimeException { + try (Allocator frame = Memory.stack()) { + MemoryAddress pprops = CLProperty.toNative(frame, properties); + MemoryAddress pdevs = frame.alloca(devices.length * 8); + MemoryAddress pres = frame.alloca(8); + Callback call = CLContextNotify.call(notify); + MemoryAddress cl; + int res; + + for (int i=0;i { @@ -117,7 +163,28 @@ public class CLContext extends CLExtendable { * release() should be called when it is no longer needed. * @throws CLRuntimeException */ - public static native CLContext createContextFromType(CLContextProperty[] properties, long device_type, CLContextNotify notify) throws CLRuntimeException; + public static CLContext createContextFromType(CLContextProperty[] properties, long device_type, CLContextNotify notify) throws CLRuntimeException { + + try (Allocator frame = Memory.stack()) { + MemoryAddress pprops = CLProperty.toNative(frame, properties); + MemoryAddress pres = frame.alloca(8); + MemoryAddress cl; + Callback call = CLContextNotify.call(notify); + int res; + + cl = clCreateContextFromType(pprops, device_type, call.addr(), MemoryAddress.NULL, pres); + res = getInt(pres); + + if (res != 0) + throw new CLRuntimeException(res); + + return Native.resolve(cl, (p) -> new CLContext(p, call)); + } catch (RuntimeException | Error t) { + throw t; + } catch (Throwable t) { + throw new RuntimeException(t); + } + } /** * Calls clCreateCommandQueue. @@ -127,10 +194,27 @@ public class CLContext extends CLExtendable { * @return Newly created command queue.

* release() should be called when it is no longer needed. * @throws CLRuntimeException - * @deprecated as of OpenCL 2.0 + * deprecated as of OpenCL 2.0 */ - @Deprecated - native public CLCommandQueue createCommandQueue(CLDevice dev, long properties) throws CLRuntimeException; + public CLCommandQueue createCommandQueue(CLDevice dev, long properties) throws CLRuntimeException { + try (Allocator frame = Memory.stack()) { + MemoryAddress pres = frame.alloca(8); + MemoryAddress q; + int res; + + q = clCreateCommandQueue(addr(), dev.addr(), properties, pres); + res = getInt(pres); + + if (res != 0) + throw new CLRuntimeException(res); + + return Native.resolve(q, CLCommandQueue::new); + } catch (RuntimeException | Error t) { + throw t; + } catch (Throwable t) { + throw new RuntimeException(t); + } + } /** * Calls clCreateCommandQueueWithProperties. @@ -141,7 +225,29 @@ public class CLContext extends CLExtendable { * @throws CLRuntimeException * @since OpenCL 2.0 */ - native public CLCommandQueue createCommandQueue(CLDevice dev, CLQueueProperty[] properties) throws CLRuntimeException; + public CLCommandQueue createCommandQueue(CLDevice dev, CLQueueProperty[] properties) throws CLRuntimeException { + // Fallback if opencl2 not supported? + requireAPIVersion(CLPlatform.VERSION_2_0); + + try (Allocator frame = Memory.stack()) { + MemoryAddress pprops = CLProperty.toNative(frame, properties); + MemoryAddress pres = frame.alloca(8); + MemoryAddress q; + int res; + + q = clCreateCommandQueueWithProperties(addr(), dev.addr(), pprops, pres); + res = getInt(pres); + + if (res != 0) + throw new CLRuntimeException(res); + + return Native.resolve(q, CLCommandQueue::new); + } catch (RuntimeException | Error t) { + throw t; + } catch (Throwable t) { + throw new RuntimeException(t); + } + } /** * @@ -150,23 +256,105 @@ public class CLContext extends CLExtendable { * @throws CLException * @since OpenCL 2.1 */ - native public void setDefaultDeviceCommandQueue(CLDevice dev, CLCommandQueue q) throws CLException; + public void setDefaultDeviceCommandQueue(CLDevice dev, CLCommandQueue q) throws CLException { + requireAPIVersion(CLPlatform.VERSION_2_1); + try { + int res; + + res = clSetDefaultDeviceCommandQueue(addr(), dev.addr(), q.addr()); + if (res != 0) + throw new CLException(res); + } catch (CLException | RuntimeException | Error t) { + throw t; + } catch (Throwable t) { + throw new RuntimeException(t); + } + } + + /* ********************************************************************** */ + + /** + * Calls clCreateBuffer with an empty host pointer. + * + * @param flags CL_MEM_* flags. + * @param size Size in bytes. + * @throws CLRuntimeException + */ public CLBuffer createBuffer(long flags, long size) throws CLRuntimeException { - return createBuffer(flags, size, null); + return createBuffer(flags, size, (MemorySegment)null); } /** * Calls clCreateBuffer. * + * If flags contains CL_MEM_USE_HOST_PTR then hostp must not + * be null. Currently in this case the CLBuffer must be + * explicitly released() on the caller thread. + * * @param flags CL_MEM_* flags. * @param size Size in bytes. * @param hostp Optional host memory pointer. - * @return Newly allocated buffer.

- * release() should be called when it is no longer needed. + * @return Newly allocated buffer. * @throws CLRuntimeException */ - native public CLBuffer createBuffer(long flags, long size, ByteBuffer hostp) throws CLRuntimeException; + public CLBuffer createBuffer(long flags, long size, MemorySegment hostseg) throws CLRuntimeException { + if (hostseg != null && hostseg.byteSize() < size) + throw new CLRuntimeException(CL_INVALID_HOST_PTR); + + try (Allocator frame = Memory.stack()) { + MemoryAddress pres = frame.alloca(8); + MemoryAddress pbuffer; + int res; + + pbuffer = clCreateBuffer(addr(), flags, size, addr(hostseg), pres); + res = getInt(pres); + + if (res != 0) + throw new CLRuntimeException(res); + + if (hostseg != null && (flags & CL_MEM_USE_HOST_PTR) != 0) + return resolve(pbuffer, (x) -> new CLBuffer(x, hostseg)); + else + return resolve(pbuffer, CLBuffer::new); + } catch (RuntimeException | Error t) { + throw t; + } catch (Throwable t) { + throw new RuntimeException(t); + } + } + + /** + * Calls clCreateBuffer. + * + * If flags contains CL_MEM_USE_HOST_PTR then hostp must not + * be null. Currently the CLBuffer must be explicitly + * released() on the caller thread. + * + * @param flags CL_MEM_* flags. + * @param size Size in bytes. + * @param hostp Optional host memory pointer. + * @return Newly allocated buffer. + * @throws CLRuntimeException + */ + public CLBuffer createBuffer(long flags, long size, ByteBuffer hostp) throws CLRuntimeException { + if (hostp != null) { + MemorySegment hostseg = MemorySegment.ofByteBuffer(hostp); + try { + CLBuffer buffer = createBuffer(flags, size, hostseg); + + if ((flags & CL_MEM_USE_HOST_PTR) != 0) + hostseg = null; + + return buffer; + } finally { + if (hostseg != null) + hostseg.close(); + } + } else { + return createBuffer(flags, size, (MemorySegment)null); + } + } /** * Wraps a full buffer. @@ -192,41 +380,150 @@ public class CLContext extends CLExtendable { * @throws CLRuntimeException if the clCreateBuffer fails, or with CL_INVALID_VALUE if CL_MEM_USE_HOST_PTR is specified in flags. * @throws NullPointerException if hostp is null. */ - native public CLBuffer createBuffer(long flags, byte[] hostp) throws CLRuntimeException; + public CLBuffer createBuffer(long flags, byte[] hostp) throws CLRuntimeException { + if ((flags & CL_MEM_USE_HOST_PTR) != 0) + throw new CLRuntimeException(CL_INVALID_VALUE); + + if (hostp == null) + throw new NullPointerException(); - native public CLBuffer createBuffer(long flags, short[] hostp) throws CLRuntimeException; + // Must copy. + try (MemorySegment mem = MemorySegment.allocateNative(hostp.length, 16)) { + mem.asByteBuffer().order(ByteOrder.nativeOrder()).put(hostp); + return createBuffer(flags, hostp.length, mem); + } + } - native public CLBuffer createBuffer(long flags, int[] hostp) throws CLRuntimeException; + //native public CLBuffer createBuffer(long flags, short[] hostp) throws CLRuntimeException; - native public CLBuffer createBuffer(long flags, float[] hostp) throws CLRuntimeException; + //native public CLBuffer createBuffer(long flags, int[] hostp) throws CLRuntimeException; - native public CLBuffer createBuffer(long flags, double[] hostp) throws CLRuntimeException; + public CLBuffer createBuffer(long flags, float[] hostp) throws CLRuntimeException { + if ((flags & CL_MEM_USE_HOST_PTR) != 0) + throw new CLRuntimeException(CL_INVALID_VALUE); + + if (hostp == null) + throw new NullPointerException(); + + // Must copy. + try (MemorySegment mem = MemorySegment.allocateNative(hostp.length, 16)) { + mem.asByteBuffer().order(ByteOrder.nativeOrder()).asFloatBuffer().put(hostp); + return createBuffer(flags, hostp.length * 4, mem); + } + } + + //native public CLBuffer createBuffer(long flags, double[] hostp) throws CLRuntimeException; + + /* ********************************************************************** */ public CLImage createImage(long flags, CLImageFormat fmt, CLImageDesc desc) throws CLRuntimeException, UnsupportedOperationException { - return createImage(flags, fmt, desc, (ByteBuffer) null); + return createImage(flags, fmt, desc, (MemorySegment) null); } /** - * Calls clCreateImage. + * Calls clCreateImage, or clCreateImageXD on OpenCL 1.1 or less. * * @param flags CL_MEM_* flags. * @param fmt Image format. - * @param desc Image descriptor. For OpenCL 1.2 only CL_MEM_OBJECT_IMAGE2D and CL_MEM_OBJECT_IMAGE3D are allowed. + * @param desc Image descriptor. For OpenCL 1.2, only CL_MEM_OBJECT_IMAGE2D and CL_MEM_OBJECT_IMAGE3D are allowed. * @param hostp * @return Newly allocated image.

* release() should be called when it is no longer needed. * @throws CLRuntimeException * @throws UnsupportedOperationException */ - native public CLImage createImage(long flags, CLImageFormat fmt, CLImageDesc desc, ByteBuffer hostp) throws CLRuntimeException, UnsupportedOperationException; + public CLImage createImage(long flags, CLImageFormat fmt, CLImageDesc desc, MemorySegment hostseg) throws CLRuntimeException, UnsupportedOperationException { + try (Allocator frame = Memory.stack()) { + MemoryAddress cfmt = CLImageFormat.toNative(frame, fmt); + MemoryAddress cres = frame.alloca(8); + MemoryAddress ci; + int res; + + // FIXME: perform range checks + + if (haveAPIVersion(CLPlatform.VERSION_1_2)) { + MemoryAddress cdesc = CLImageDesc.toNative(frame, desc); + + ci = clCreateImage(addr(), flags, cfmt, cdesc, addr(hostseg), cres); + } else { + switch (desc.imageType) { + case CL_MEM_OBJECT_IMAGE2D: + ci = clCreateImage2D(addr(), flags, cfmt, desc.imageWidth, desc.imageHeight, desc.imageRowPitch, addr(hostseg), cres); + break; + case CL_MEM_OBJECT_IMAGE3D: + ci = clCreateImage3D(addr(), flags, cfmt, desc.imageWidth, desc.imageHeight, desc.imageDepth, + desc.imageRowPitch, desc.imageSlicePitch, addr(hostseg), cres); + break; + default: + throw new UnsupportedOperationException("Requires OpenCL 1.2"); + } + } + + res = getInt(cres); + if (res != 0) + throw new CLRuntimeException(res); - native public CLImage createImage(long flags, CLImageFormat fmt, CLImageDesc desc, byte[] hostp) throws CLRuntimeException, UnsupportedOperationException; + if (hostseg != null && (flags & CL_MEM_USE_HOST_PTR) != 0) + return resolve(ci, (x) -> new CLImage(x, hostseg)); + else + return resolve(ci, CLImage::new); + } catch (RuntimeException | Error t) { + throw t; + } catch (Throwable t) { + throw new RuntimeException(t); + } + } + + public CLImage createImage(long flags, CLImageFormat fmt, CLImageDesc desc, ByteBuffer hostp) throws CLRuntimeException, UnsupportedOperationException { + if (hostp != null) { + MemorySegment hostseg = MemorySegment.ofByteBuffer(hostp); + try { + CLImage image = createImage(flags, fmt, desc, hostseg); - native public CLImage createImage(long flags, CLImageFormat fmt, CLImageDesc desc, short[] hostp) throws CLRuntimeException, UnsupportedOperationException; + if ((flags & CL_MEM_USE_HOST_PTR) != 0) + hostseg = null; - native public CLImage createImage(long flags, CLImageFormat fmt, CLImageDesc desc, int[] hostp) throws CLRuntimeException, UnsupportedOperationException; + return image; + } finally { + if (hostseg != null) + hostseg.close(); + } + } else { + return createImage(flags, fmt, desc, (MemorySegment)null); + } + } + + public CLImage createImage(long flags, CLImageFormat fmt, CLImageDesc desc, byte[] hostp) throws CLRuntimeException, UnsupportedOperationException { + if ((flags & CL_MEM_USE_HOST_PTR) != 0) + throw new CLRuntimeException(CL_INVALID_VALUE); + + if (hostp == null) + throw new NullPointerException(); + + // Must copy. + try (MemorySegment mem = MemorySegment.allocateNative(hostp.length, 16)) { + mem.asByteBuffer().order(ByteOrder.nativeOrder()).put(hostp); + return createImage(flags, fmt, desc, mem); + } + } - native public CLImage createImage(long flags, CLImageFormat fmt, CLImageDesc desc, float[] hostp) throws CLRuntimeException, UnsupportedOperationException; + //native public CLImage createImage(long flags, CLImageFormat fmt, CLImageDesc desc, short[] hostp) throws CLRuntimeException, UnsupportedOperationException; + + //native public CLImage createImage(long flags, CLImageFormat fmt, CLImageDesc desc, int[] hostp) throws CLRuntimeException, UnsupportedOperationException; + + public CLImage createImage(long flags, CLImageFormat fmt, CLImageDesc desc, float[] hostp) throws CLRuntimeException, UnsupportedOperationException { + if ((flags & CL_MEM_USE_HOST_PTR) != 0) + throw new CLRuntimeException(CL_INVALID_VALUE); + + if (hostp == null) + throw new NullPointerException(); + + // Must copy. + try (MemorySegment mem = MemorySegment.allocateNative(hostp.length * 4, 16)) { + mem.asByteBuffer().order(ByteOrder.nativeOrder()).asFloatBuffer().put(hostp); + return createImage(flags, fmt, desc, mem); + } + } /** * Calls clCreatePipe @@ -240,7 +537,27 @@ public class CLContext extends CLExtendable { * @throws UnsupportedOperationException * @since OpenCL 2.0 */ - native public CLPipe createPipe(long flags, int packetSize, int maxPackets, CLPipeProperty[] properties) throws CLRuntimeException, UnsupportedOperationException; + public CLPipe createPipe(long flags, int packetSize, int maxPackets, CLPipeProperty[] properties) throws CLRuntimeException, UnsupportedOperationException { + requireAPIVersion(CLPlatform.VERSION_2_0); + + try (Allocator frame = Memory.stack()) { + MemoryAddress cprops = CLProperty.toNative(frame, properties); + MemoryAddress cres = frame.alloca(8); + int res; + MemoryAddress cp; + + cp = clCreatePipe(addr(), flags, packetSize, maxPackets, cprops, cres); + res = getInt(cres); + if (res != 0) + throw new CLRuntimeException(res); + + return resolve(cp, CLPipe::new); + } catch (RuntimeException | Error t) { + throw t; + } catch (Throwable t) { + throw new RuntimeException(t); + } + } /** * Calls clGetSupportedImageFormats. @@ -250,7 +567,33 @@ public class CLContext extends CLExtendable { * @return List of supported image formats. * @throws CLRuntimeException */ - native public CLImageFormat[] getSupportedImageFormats(long flags, int type) throws CLRuntimeException; + public CLImageFormat[] getSupportedImageFormats(long flags, int type) throws CLRuntimeException { + try (Allocator frame = Memory.stack()) { + MemoryAddress cnum = frame.alloca(8); + MemoryAddress list; + int num; + int res; + + res = clGetSupportedImageFormats(addr(), flags, type, 0, MemoryAddress.NULL, cnum); + if (res != 0) + throw new CLRuntimeException(res); + + num = getInt(cnum); + list = frame.alloca(num * 8); + + res = clGetSupportedImageFormats(addr(), flags, type, num, list, cnum); + + CLImageFormat[] out = new CLImageFormat[num]; + for (int i=0;i * release() should be called when it is no longer needed. * @throws CLRuntimeException - * @deprecated as of OpenCL 2.0 + * xdeprecated as of OpenCL 2.0 */ - @Deprecated - native public CLSampler createSampler(boolean norm, int addr_mode, int filter_mode) throws CLRuntimeException; + //@Deprecated + public CLSampler createSampler(boolean norm, int addr_mode, int filter_mode) throws CLRuntimeException { + try (Allocator frame = Memory.stack()) { + MemoryAddress cres = frame.alloca(8); + int res; + MemoryAddress cs; + + cs = clCreateSampler(addr(), norm ? 1 : 0, addr_mode, filter_mode, cres); + res = getInt(cres); + if (res != 0) + throw new CLRuntimeException(res); + + return resolve(cs, CLSampler::new); + } catch (RuntimeException | Error t) { + throw t; + } catch (Throwable t) { + throw new RuntimeException(t); + } + } /** * Calls clCreateSamplerWithProperties @@ -299,7 +663,50 @@ public class CLContext extends CLExtendable { * @throws CLRuntimeException * @since OpenCL 2.0 */ - native public CLSampler createSampler(CLSamplerProperty[] props) throws CLRuntimeException; + public CLSampler createSampler(CLSamplerProperty[] props) throws CLRuntimeException { + // Fallback if opencl2 not supported? + requireAPIVersion(CLPlatform.VERSION_2_0); + + try (Allocator frame = Memory.stack()) { + MemoryAddress cres = frame.alloca(8); + MemoryAddress cprops = CLProperty.toNative(frame, props); + int res; + MemoryAddress cs; + + cs = clCreateSamplerWithProperties(addr(), cprops, cres); + res = getInt(cres); + if (res != 0) + throw new CLRuntimeException(res); + + return resolve(cs, CLSampler::new); + } catch (RuntimeException | Error t) { + throw t; + } catch (Throwable t) { + throw new RuntimeException(t); + } + + } + + static long length(byte[][] strings) { + long len = 0; + for (int i=0;i notify) throws CLException, UnsupportedOperationException; + public CLProgram linkProgram(CLDevice[] devices, String options, CLProgram[] programs, CLNotify notify) throws CLException, UnsupportedOperationException { + requireAPIVersion(CLPlatform.VERSION_1_2); + + try (Allocator frame = Memory.stack(); + Callback> cnotify = CLNotify.call(notify, CLProgram::new)) { + MemoryAddress cdevs = toAddrV(frame, devices); + MemoryAddress coptions = toByteV(frame, options); + MemoryAddress cprogs = toAddrV(frame, programs); + MemoryAddress cret = frame.alloca(8); + MemoryAddress cp; + int res; + + cp = clLinkProgram(addr(), devices.length, cdevs, coptions, programs.length, cprogs, cnotify.addr(), MemoryAddress.NULL, cret); + + res = getInt(cret); + if (res != 0) + throw new CLException(res); + + return resolve(cp, CLProgram::new); + } catch (CLException | RuntimeException | Error t) { + throw t; + } catch (Throwable t) { + throw new RuntimeException(t); + } + } /** * Calls clCreateUserEvent. @@ -389,7 +933,27 @@ public class CLContext extends CLExtendable { * @throws CLRuntimeException * @since OpenCL 1.1 */ - native public CLEvent createUserEvent() throws CLRuntimeException; + public CLEvent createUserEvent() throws CLException { + requireAPIVersion(CLPlatform.VERSION_1_1); + + try (Allocator frame = Memory.stack()) { + MemoryAddress cret = frame.alloca(8); + MemoryAddress ce; + int res; + + ce = clCreateUserEvent(addr(), cret); + + res = getInt(cret); + if (res != 0) + throw new CLException(res); + + return resolve(ce, CLEvent::new); + } catch (CLException | RuntimeException | Error t) { + throw t; + } catch (Throwable t) { + throw new RuntimeException(t); + } + } /** * gets CL_CONTEXT_NUM_DEVICES. @@ -406,7 +970,7 @@ public class CLContext extends CLExtendable { * @return List of devices. */ public CLDevice[] getDevices() { - return getInfoAnyV(CTYPE_DEVICE, CL_CONTEXT_DEVICES); + return getInfoAnyV(CL_CONTEXT_DEVICES, clGetContextInfo, CLDevice::new, CLDevice[]::new); } /** @@ -414,45 +978,48 @@ public class CLContext extends CLExtendable { * * @return List of properties used at create time. */ - public native CLContextProperty[] getProperties(); + public CLContextProperty[] getProperties() { + return getInfoPropertyV(CL_CONTEXT_PROPERTIES, clGetContextInfo, CLContextProperty.TagValue::new, CLContextProperty[]::new); + } @Override protected CLPlatform initPlatform() { return getDevices()[0].platform; } - protected GLSharing getGLSharing() { - return getExtension(GLSharing.class, CLPlatform.cl_khr_gl_sharing); - } + //protected GLSharing getGLSharing() { + // return getExtension(GLSharing.class, CLPlatform.cl_khr_gl_sharing); + //} - protected GLEvent getGLEvent() { - return getExtension(GLEvent.class, CLPlatform.cl_khr_gl_event); - } + //protected GLEvent getGLEvent() { + // return getExtension(GLEvent.class, CLPlatform.cl_khr_gl_event); + //} /* Experimental: extension interface mechanism */ - public CLBuffer createFromGLBuffer( - long flags, - int bufobj) { - return getGLSharing().createFromGLBuffer(this, flags, bufobj); - } - public CLImage createFromGLTexture( - long flags /* flags */, - int target /* target */, - int miplevel /* miplevel */, - int texture /* texture */) { - return getGLSharing().createFromGLTexture(this, flags, target, miplevel, texture); - } + // public CLBuffer createFromGLBuffer( + // long flags, + // int bufobj) { + // return getGLSharing().createFromGLBuffer(this, flags, bufobj); + // } - public CLImage createFromGLRenderbuffer( - long flags /* flags */, - int renderbuffer /* renderbuffer */) { - return getGLSharing().createFromGLRenderbuffer(this, flags, renderbuffer); - } + // public CLImage createFromGLTexture( + // long flags /* flags */, + // int target /* target */, + // int miplevel /* miplevel */, + // int texture /* texture */) { + // return getGLSharing().createFromGLTexture(this, flags, target, miplevel, texture); + // } - public CLEvent createEventFromGLsync(long glsync) { - return getGLEvent().clCreateEventFromGLsync(this, glsync); - } + // public CLImage createFromGLRenderbuffer( + // long flags /* flags */, + // int renderbuffer /* renderbuffer */) { + // return getGLSharing().createFromGLRenderbuffer(this, flags, renderbuffer); + // } + + // public CLEvent createEventFromGLsync(long glsync) { + // return getGLEvent().clCreateEventFromGLsync(this, glsync); + // } } diff --git a/src/notzed.zcl/classes/au/notzed/zcl/CLContextNotify.java b/src/notzed.zcl/classes/au/notzed/zcl/CLContextNotify.java index 8c3a304..e8f18f7 100644 --- a/src/notzed.zcl/classes/au/notzed/zcl/CLContextNotify.java +++ b/src/notzed.zcl/classes/au/notzed/zcl/CLContextNotify.java @@ -17,6 +17,12 @@ package au.notzed.zcl; import java.nio.ByteBuffer; +import java.util.function.Function; +import jdk.incubator.foreign.MemoryAddress; +import jdk.incubator.foreign.MemorySegment; +import api.Native; +import api.Callback; +import api.Memory; /** * Callback for CLContext.createContext*() @@ -25,4 +31,19 @@ public interface CLContextNotify { public void notify(String what, ByteBuffer error_info); + @SuppressWarnings("unchecked") + static Callback call(CLContextNotify notify) { + if (notify != null) { + return Native.resolve( + Call_pBpvJpv_v.stub((cwhat, cinfo, cinfolen, dummy) -> { + MemorySegment seg = Memory.ofNative(cinfo, cinfolen); + notify.notify(Native.toString(cwhat), seg.asByteBuffer()); + }), + (p) -> new Callback<>(p, notify)); + } else { + return Callback.NULL; + } + } + + } diff --git a/src/notzed.zcl/classes/au/notzed/zcl/CLDevice.java b/src/notzed.zcl/classes/au/notzed/zcl/CLDevice.java index 37dc9fb..f6e474c 100644 --- a/src/notzed.zcl/classes/au/notzed/zcl/CLDevice.java +++ b/src/notzed.zcl/classes/au/notzed/zcl/CLDevice.java @@ -16,7 +16,12 @@ */ package au.notzed.zcl; +import api.Native; +import java.lang.invoke.MethodHandle; +import java.util.function.Function; +import jdk.incubator.foreign.*; import static au.notzed.zcl.CL.*; +import static au.notzed.zcl.CLLib.*; /** * Interface for cl_device_id. @@ -28,11 +33,18 @@ public class CLDevice extends CLExtendable { * * @param p Native pointer. */ - public CLDevice(long p) { + public CLDevice(MemoryAddress p) { super(p); } - private native static void release(long p); + private static void release(MemoryAddress p) { + try { + clReleaseDevice(p); + } catch (Throwable t) { + } + } + + //private native static void release(long p); @Override public String toString() { @@ -40,8 +52,8 @@ public class CLDevice extends CLExtendable { } @Override - int getInfoType() { - return TYPE_DEVICE; + MethodHandle getInfoFunc() { + return clGetDeviceInfo; } @Override @@ -55,7 +67,7 @@ public class CLDevice extends CLExtendable { * @param times { device_timestamp, host_timestamp } * @since OpenCL 2.1 */ - public native void getDeviceAndHostTimer(long[] times); + //public native void getDeviceAndHostTimer(long[] times); /** * Gets device view of host clock. @@ -63,7 +75,7 @@ public class CLDevice extends CLExtendable { * @return host_timestamp. * @since OpenCN 2.1 */ - public native long getHostTimer(); + //public native long getHostTimer(); /** * Create a property representing CL_DEVICE_PARTITION_EQUALLY. @@ -107,7 +119,7 @@ public class CLDevice extends CLExtendable { * @throws CLException * @since OpenCL 1.2 */ - public native CLDevice[] createSubDevices(CLDeviceProperty[] properties, int num_devices) throws CLException, UnsupportedOperationException; + //public native CLDevice[] createSubDevices(CLDeviceProperty[] properties, int num_devices) throws CLException, UnsupportedOperationException; /** * get CL_DEVICE_TYPE @@ -349,7 +361,7 @@ public class CLDevice extends CLExtendable { } public CLPlatform getPlatform() { - return getInfoAny(CTYPE_PLATFORM, CL_DEVICE_PLATFORM); + return getInfoAny(CL_DEVICE_PLATFORM, clGetDeviceInfo, CLPlatform::new); } public String getName() { @@ -389,22 +401,22 @@ public class CLDevice extends CLExtendable { } public CLDevice getParentDevice() { - return getInfoAny(CTYPE_DEVICE, CL_DEVICE_PARENT_DEVICE); + return getInfoAny(CL_DEVICE_PARENT_DEVICE, clGetDeviceInfo, CLDevice::new); } public int getPartitionMaxSubDevices() { return getInfoInt(CL_DEVICE_PARTITION_MAX_SUB_DEVICES); } - public native CLDeviceProperty[] getPartitionProperties(); + //public native CLDeviceProperty[] getPartitionProperties(); public long getPartitionAffinityDomain() { return getInfoLong(CL_DEVICE_PARTITION_AFFINITY_DOMAIN); } - public native CLDeviceProperty[] getPartitionType(); + //public native CLDeviceProperty[] getPartitionType(); - public static CLDevice[] newArray(int n) { - return new CLDevice[n]; - } + //public static CLDevice[] newArray(int n) { + // return new CLDevice[n]; + //} } diff --git a/src/notzed.zcl/classes/au/notzed/zcl/CLDeviceProperty.java b/src/notzed.zcl/classes/au/notzed/zcl/CLDeviceProperty.java index 4d1d0b4..f3f1afb 100644 --- a/src/notzed.zcl/classes/au/notzed/zcl/CLDeviceProperty.java +++ b/src/notzed.zcl/classes/au/notzed/zcl/CLDeviceProperty.java @@ -16,6 +16,9 @@ */ package au.notzed.zcl; +import api.Native; +import jdk.incubator.foreign.MemoryAddress; + /** * Properties for CLDevice sub-device creation. * @@ -62,6 +65,14 @@ public interface CLDeviceProperty extends CLProperty { dst[o++] = CL.CL_DEVICE_PARTITION_BY_COUNTS_LIST_END; return o; } + + public int toLong(MemoryAddress dst, int o) { + Native.setLong(dst, o++, CL.CL_DEVICE_PARTITION_BY_COUNTS); + for (int c : counts) + Native.setLong(dst, o++, c); + Native.setLong(dst, o++, CL.CL_DEVICE_PARTITION_BY_COUNTS_LIST_END); + return o; + } } } diff --git a/src/notzed.zcl/classes/au/notzed/zcl/CLEvent.java b/src/notzed.zcl/classes/au/notzed/zcl/CLEvent.java index f8dcb60..6e63126 100644 --- a/src/notzed.zcl/classes/au/notzed/zcl/CLEvent.java +++ b/src/notzed.zcl/classes/au/notzed/zcl/CLEvent.java @@ -16,27 +16,53 @@ */ package au.notzed.zcl; +import jdk.incubator.foreign.*; import static au.notzed.zcl.CL.*; +import static au.notzed.zcl.CLLib.*; +import api.Native; +import api.Callback; +import java.lang.invoke.MethodHandle; /** * Interface for cl_event. */ public class CLEvent extends CLObject { + /** + * This is used to retain a reference for any callback set + */ + Callback callback; + /** * Create an interface for a native pointer of type cl_event. * * @param p Native pointer. */ - public CLEvent(long p) { + public CLEvent(MemoryAddress p) { super(p); } - private native static void release(long p); + public static CLEvent create(MemoryAddress p) { + return Native.resolve(p, CLEvent::new); + } + + private static void release(MemoryAddress p) { + try { + System.err.printf("** release event %016x\n", api.Memory.toLong(p)); + clReleaseEvent(p); + } catch (Throwable t) { + } + } + + public void release() { + Native.release(callback); + callback = null; + super.release(); + } @Override - int getInfoType() { - return TYPE_EVENT; + MethodHandle getInfoFunc() { + return clGetEventInfo; } /** @@ -48,7 +74,20 @@ public class CLEvent extends CLObject { * @throws CLRuntimeException * @since OpenCL 1.1 */ - public native void setUserEventStatus(int status) throws CLRuntimeException; + public void setUserEventStatus(int status) throws CLRuntimeException { + // avoid platform lookup for costs + //requiredAPIVersion(CLPlatform.VERSION_1_1); + try { + int res = clSetUserEventStatus(addr(), status); + + if (res != 0) + throw new CLRuntimeException(res); + } catch (RuntimeException | Error t) { + throw t; + } catch (Throwable t) { + throw new RuntimeException(t); + } + } /** * Call clSetEventCallback(type, notify). @@ -58,7 +97,28 @@ public class CLEvent extends CLObject { * @throws CLRuntimeException * @since OpenCL 1.1 */ - public native void setEventCallback(int type, CLEventNotify notify) throws CLRuntimeException; + public void setEventCallback(int type, CLEventNotify notify) throws CLRuntimeException { + //requiredAPIVersion(CLPlatform.VERSION_1_1); + + Native.release(callback); + + if (notify != null) { + callback = CLEventNotify.call(notify); + + try { + int res = clSetEventCallback(addr(), type, callback.addr(), MemoryAddress.NULL); + + if (res != 0) + throw new CLRuntimeException(res); + } catch (RuntimeException | Error t) { + throw t; + } catch (Throwable t) { + throw new RuntimeException(t); + } + } else { + callback = null; + } + } /** * Get CL_EVENT_COMMAND_QUEUE. @@ -68,7 +128,7 @@ public class CLEvent extends CLObject { * @return */ public CLCommandQueue getCommandQueue() { - return getInfoAny(CTYPE_COMMAND_QUEUE, CL_EVENT_COMMAND_QUEUE); + return getInfoAny(CL_EVENT_COMMAND_QUEUE, clGetEventInfo, CLCommandQueue::new); } /** @@ -79,7 +139,7 @@ public class CLEvent extends CLObject { * @return */ public CLContext getContext() { - return getInfoAny(CTYPE_CONTEXT, CL_EVENT_CONTEXT); + return getInfoAny(CL_EVENT_CONTEXT, clGetEventInfo, CLContext::new); } /** @@ -103,22 +163,22 @@ public class CLEvent extends CLObject { } public long getProfilingCommandQueued() { - return getInfoLong(TYPE_EVENT_PROFILING, CL_PROFILING_COMMAND_QUEUED); + return getInfoLong(CL_PROFILING_COMMAND_QUEUED, clGetEventProfilingInfo); } public long getProfilingCommandSubmit() { - return getInfoLong(TYPE_EVENT_PROFILING, CL_PROFILING_COMMAND_SUBMIT); + return getInfoLong(CL_PROFILING_COMMAND_SUBMIT, clGetEventProfilingInfo); } public long getProfilingCommandStart() { - return getInfoLong(TYPE_EVENT_PROFILING, CL_PROFILING_COMMAND_START); + return getInfoLong(CL_PROFILING_COMMAND_START, clGetEventProfilingInfo); } public long getProfilingCommandEnd() { - return getInfoLong(TYPE_EVENT_PROFILING, CL_PROFILING_COMMAND_END); + return getInfoLong(CL_PROFILING_COMMAND_END, clGetEventProfilingInfo); } public long getProfilingCommandComplete() { - return getInfoLong(TYPE_EVENT_PROFILING, CL_PROFILING_COMMAND_COMPLETE); + return getInfoLong(CL_PROFILING_COMMAND_COMPLETE, clGetEventProfilingInfo); } } diff --git a/src/notzed.zcl/classes/au/notzed/zcl/CLEventList.java b/src/notzed.zcl/classes/au/notzed/zcl/CLEventList.java index 96f6c5d..bb38677 100644 --- a/src/notzed.zcl/classes/au/notzed/zcl/CLEventList.java +++ b/src/notzed.zcl/classes/au/notzed/zcl/CLEventList.java @@ -16,6 +16,12 @@ */ package au.notzed.zcl; +import jdk.incubator.foreign.MemoryAddress; +import api.Memory; +import api.Allocator; +import api.Native; +import static au.notzed.zcl.CLLib.*; + /** * Manages a list of cl_events. *

@@ -37,10 +43,6 @@ package au.notzed.zcl; */ public class CLEventList { - /** - * C-accessible copy of jevets[i].p - */ - final long[] events; /** * Event references. */ @@ -53,7 +55,6 @@ public class CLEventList { * @param capacity Sets the event list capacity. This */ public CLEventList(int capacity) { - this.events = new long[capacity]; this.jevents = new CLEvent[capacity]; } @@ -65,7 +66,6 @@ public class CLEventList { public void reset() { for (int i = 0; i < index; i++) { jevents[i] = null; - events[i] = 0; } index = 0; } @@ -86,19 +86,9 @@ public class CLEventList { * @param event */ public void add(CLEvent event) { - events[index] = event.getP(); jevents[index++] = event; } - /** - * Interface for JNI to add an event after a successful enqueue operation. - * - * @param eid - */ - private void add(long eid) { - add(CLObject.resolve(CLEvent.class, eid)); - } - /** * Get the number of active events. * @@ -108,10 +98,38 @@ public class CLEventList { return index; } + static MemoryAddress toWaitList(Allocator frame, CLEventList list) { + if (list != null) { + MemoryAddress addr = frame.alloca(list.index * 8); + + for (int i=0;i 0) { + try (Allocator frame = Memory.stack()) { + MemoryAddress events = toWaitList(frame, this); + int res; + + res = clWaitForEvents(size(), events); + if (res != 0) + throw new CLException(res); + } catch (CLException | RuntimeException | Error t) { + throw t; + } catch (Throwable t) { + throw new RuntimeException(t); + } + } + } } diff --git a/src/notzed.zcl/classes/au/notzed/zcl/CLEventNotify.java b/src/notzed.zcl/classes/au/notzed/zcl/CLEventNotify.java index 1c793a1..95331d1 100644 --- a/src/notzed.zcl/classes/au/notzed/zcl/CLEventNotify.java +++ b/src/notzed.zcl/classes/au/notzed/zcl/CLEventNotify.java @@ -16,9 +16,13 @@ */ package au.notzed.zcl; +import api.Callback; +import api.Native; + /** * Callback for CLEvent. */ +@FunctionalInterface public interface CLEventNotify { /** @@ -28,4 +32,15 @@ public interface CLEventNotify { * @param status status. */ public void notify(CLEvent event, int status); + + @SuppressWarnings("unchecked") + static Callback call(CLEventNotify notify) { + if (notify != null) { + return Native.resolve( + Call_pLIpv_v.stub((cevent, status, dummy) -> notify.notify(Native.resolve(cevent, CLEvent::new), status)), + (p) -> new Callback<>(p, notify)); + } else { + return Callback.NULL; + } + } } diff --git a/src/notzed.zcl/classes/au/notzed/zcl/CLException.java b/src/notzed.zcl/classes/au/notzed/zcl/CLException.java index fccafe9..fd6a922 100644 --- a/src/notzed.zcl/classes/au/notzed/zcl/CLException.java +++ b/src/notzed.zcl/classes/au/notzed/zcl/CLException.java @@ -1,183 +1,13 @@ -/** - * ***************************************************************************** - * Copyright (c) 2008 - 2012 The Khronos Group Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and/or associated documentation files (the "Materials"), to - * deal in the Materials without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Materials, and to permit persons to whom the Materials are - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Materials. - * - * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS IN - * THE MATERIALS. - * **************************************************************************** - */ + package au.notzed.zcl; -/** - * Exception for OpenCL error values. - */ public class CLException extends Exception { + int res; - int id; - - public CLException(int id) { - this.id = id; - } - - /** - * Get the error code. - * - * @return OpenCL error code. - * @see #codeToError - */ - public int getID() { - return id; + public CLException() { } - @Override - public String getMessage() { - return String.format("Error (%d): '%s'", id, codeToError(id)); - } - - /** - * Convert the error code to a description. - * - * @param code - * @return - */ - public static String codeToError(int code) { - switch (code) { - case CL.CL_SUCCESS: - return "CL_SUCCESS"; - case CL.CL_DEVICE_NOT_FOUND: - return "CL_DEVICE_NOT_FOUND"; - case CL.CL_DEVICE_NOT_AVAILABLE: - return "CL_DEVICE_NOT_AVAILABLE"; - case CL.CL_COMPILER_NOT_AVAILABLE: - return "CL_COMPILER_NOT_AVAILABLE"; - case CL.CL_MEM_OBJECT_ALLOCATION_FAILURE: - return "CL_MEM_OBJECT_ALLOCATION_FAILURE"; - case CL.CL_OUT_OF_RESOURCES: - return "CL_OUT_OF_RESOURCES"; - case CL.CL_OUT_OF_HOST_MEMORY: - return "CL_OUT_OF_HOST_MEMORY"; - case CL.CL_PROFILING_INFO_NOT_AVAILABLE: - return "CL_PROFILING_INFO_NOT_AVAILABLE"; - case CL.CL_MEM_COPY_OVERLAP: - return "CL_MEM_COPY_OVERLAP"; - case CL.CL_IMAGE_FORMAT_MISMATCH: - return "CL_IMAGE_FORMAT_MISMATCH"; - case CL.CL_IMAGE_FORMAT_NOT_SUPPORTED: - return "CL_IMAGE_FORMAT_NOT_SUPPORTED"; - case CL.CL_BUILD_PROGRAM_FAILURE: - return "CL_BUILD_PROGRAM_FAILURE"; - case CL.CL_MAP_FAILURE: - return "CL_MAP_FAILURE"; - case CL.CL_MISALIGNED_SUB_BUFFER_OFFSET: - return "CL_MISALIGNED_SUB_BUFFER_OFFSET"; - case CL.CL_EXEC_STATUS_ERROR_FOR_EVENTS_IN_WAIT_LIST: - return "CL_EXEC_STATUS_ERROR_FOR_EVENTS_IN_WAIT_LIST"; - case CL.CL_COMPILE_PROGRAM_FAILURE: - return "CL_COMPILE_PROGRAM_FAILURE"; - case CL.CL_LINKER_NOT_AVAILABLE: - return "CL_LINKER_NOT_AVAILABLE"; - case CL.CL_LINK_PROGRAM_FAILURE: - return "CL_LINK_PROGRAM_FAILURE"; - case CL.CL_DEVICE_PARTITION_FAILED: - return "CL_DEVICE_PARTITION_FAILED"; - case CL.CL_KERNEL_ARG_INFO_NOT_AVAILABLE: - return "CL_KERNEL_ARG_INFO_NOT_AVAILABLE"; - - case CL.CL_INVALID_VALUE: - return "CL_INVALID_VALUE"; - case CL.CL_INVALID_DEVICE_TYPE: - return "CL_INVALID_DEVICE_TYPE"; - case CL.CL_INVALID_PLATFORM: - return "CL_INVALID_PLATFORM"; - case CL.CL_INVALID_DEVICE: - return "CL_INVALID_DEVICE"; - case CL.CL_INVALID_CONTEXT: - return "CL_INVALID_CONTEXT"; - case CL.CL_INVALID_QUEUE_PROPERTIES: - return "CL_INVALID_QUEUE_PROPERTIES"; - case CL.CL_INVALID_COMMAND_QUEUE: - return "CL_INVALID_COMMAND_QUEUE"; - case CL.CL_INVALID_HOST_PTR: - return "CL_INVALID_HOST_PTR"; - case CL.CL_INVALID_MEM_OBJECT: - return "CL_INVALID_MEM_OBJECT"; - case CL.CL_INVALID_IMAGE_FORMAT_DESCRIPTOR: - return "CL_INVALID_IMAGE_FORMAT_DESCRIPTOR"; - case CL.CL_INVALID_IMAGE_SIZE: - return "CL_INVALID_IMAGE_SIZE"; - case CL.CL_INVALID_SAMPLER: - return "CL_INVALID_SAMPLER"; - case CL.CL_INVALID_BINARY: - return "CL_INVALID_BINARY"; - case CL.CL_INVALID_BUILD_OPTIONS: - return "CL_INVALID_BUILD_OPTIONS"; - case CL.CL_INVALID_PROGRAM: - return "CL_INVALID_PROGRAM"; - case CL.CL_INVALID_PROGRAM_EXECUTABLE: - return "CL_INVALID_PROGRAM_EXECUTABLE"; - case CL.CL_INVALID_KERNEL_NAME: - return "CL_INVALID_KERNEL_NAME"; - case CL.CL_INVALID_KERNEL_DEFINITION: - return "CL_INVALID_KERNEL_DEFINITION"; - case CL.CL_INVALID_KERNEL: - return "CL_INVALID_KERNEL"; - case CL.CL_INVALID_ARG_INDEX: - return "CL_INVALID_ARG_INDEX"; - case CL.CL_INVALID_ARG_VALUE: - return "CL_INVALID_ARG_VALUE"; - case CL.CL_INVALID_ARG_SIZE: - return "CL_INVALID_ARG_SIZE"; - case CL.CL_INVALID_KERNEL_ARGS: - return "CL_INVALID_KERNEL_ARGS"; - case CL.CL_INVALID_WORK_DIMENSION: - return "CL_INVALID_WORK_DIMENSION"; - case CL.CL_INVALID_WORK_GROUP_SIZE: - return "CL_INVALID_WORK_GROUP_SIZE"; - case CL.CL_INVALID_WORK_ITEM_SIZE: - return "CL_INVALID_WORK_ITEM_SIZE"; - case CL.CL_INVALID_GLOBAL_OFFSET: - return "CL_INVALID_GLOBAL_OFFSET"; - case CL.CL_INVALID_EVENT_WAIT_LIST: - return "CL_INVALID_EVENT_WAIT_LIST"; - case CL.CL_INVALID_EVENT: - return "CL_INVALID_EVENT"; - case CL.CL_INVALID_OPERATION: - return "CL_INVALID_OPERATION"; - case CL.CL_INVALID_GL_OBJECT: - return "CL_INVALID_GL_OBJECT"; - case CL.CL_INVALID_BUFFER_SIZE: - return "CL_INVALID_BUFFER_SIZE"; - case CL.CL_INVALID_MIP_LEVEL: - return "CL_INVALID_MIP_LEVEL"; - case CL.CL_INVALID_GLOBAL_WORK_SIZE: - return "CL_INVALID_GLOBAL_WORK_SIZE"; - case CL.CL_INVALID_PROPERTY: - return "CL_INVALID_PROPERTY"; - case CL.CL_INVALID_IMAGE_DESCRIPTOR: - return "CL_INVALID_IMAGE_DESCRIPTOR"; - case CL.CL_INVALID_COMPILER_OPTIONS: - return "CL_INVALID_COMPILER_OPTIONS"; - case CL.CL_INVALID_LINKER_OPTIONS: - return "CL_INVALID_LINKER_OPTIONS"; - case CL.CL_INVALID_DEVICE_PARTITION_COUNT: - return "CL_INVALID_DEVICE_PARTITION_COUNT"; - default: - return "Unknown error"; - } + public CLException(int res) { + this.res = res; } } diff --git a/src/notzed.zcl/classes/au/notzed/zcl/CLExtendable.java b/src/notzed.zcl/classes/au/notzed/zcl/CLExtendable.java index 85e073e..6686295 100644 --- a/src/notzed.zcl/classes/au/notzed/zcl/CLExtendable.java +++ b/src/notzed.zcl/classes/au/notzed/zcl/CLExtendable.java @@ -16,6 +16,8 @@ */ package au.notzed.zcl; +import jdk.incubator.foreign.MemoryAddress; + /** * Extendable object. These keep track of the platform and api revision to be * able to lookup extension pointers efficiently. @@ -28,7 +30,7 @@ public abstract class CLExtendable extends CLObject { */ final int apiVersion; - public CLExtendable(long p) { + public CLExtendable(MemoryAddress p) { super(p); platform = initPlatform(); @@ -51,6 +53,15 @@ public abstract class CLExtendable extends CLObject { return apiVersion; } + public void requireAPIVersion(int version) throws UnsupportedOperationException { + if (apiVersion < version) + throw new UnsupportedOperationException("Requires version " + ((apiVersion >> 8) & 0xff) + "." + (apiVersion & 0xff)); + } + + public boolean haveAPIVersion(int version) { + return apiVersion >= version; + } + /** * Retrieve an extension interface for this object.Used by implementors of * CLExtenable. @@ -61,6 +72,7 @@ public abstract class CLExtendable extends CLObject { * @return */ protected T getExtension(Class klass, int id) { - return platform.getExtension(klass, id); + //return platform.getExtension(klass, id); + return null; } } diff --git a/src/notzed.zcl/classes/au/notzed/zcl/CLExtension.java b/src/notzed.zcl/classes/au/notzed/zcl/CLExtension.java index 16e4520..e4e165e 100644 --- a/src/notzed.zcl/classes/au/notzed/zcl/CLExtension.java +++ b/src/notzed.zcl/classes/au/notzed/zcl/CLExtension.java @@ -16,6 +16,9 @@ */ package au.notzed.zcl; +import jdk.incubator.foreign.MemoryAddress; +import java.lang.invoke.MethodHandle; + /** * Experimental code for extension support. *

@@ -30,15 +33,15 @@ package au.notzed.zcl; */ public abstract class CLExtension extends CLObject { - protected CLExtension(long p) { + protected CLExtension(MemoryAddress p) { super(p); } public abstract String getName(); @Override - int getInfoType() { + MethodHandle getInfoFunc() { throw new UnsupportedOperationException(); } - + } diff --git a/src/notzed.zcl/classes/au/notzed/zcl/CLImage.java b/src/notzed.zcl/classes/au/notzed/zcl/CLImage.java index b4117fb..60d4509 100644 --- a/src/notzed.zcl/classes/au/notzed/zcl/CLImage.java +++ b/src/notzed.zcl/classes/au/notzed/zcl/CLImage.java @@ -17,7 +17,13 @@ package au.notzed.zcl; import static au.notzed.zcl.CL.*; +import static au.notzed.zcl.CLLib.*; +import jdk.incubator.foreign.*; +import api.Native; + +//import static au.au.notzed.zcl.CL.*; import java.nio.ByteBuffer; +import java.lang.invoke.MethodHandle; /** * Interface for cl_image. @@ -31,21 +37,28 @@ public class CLImage extends CLMemory { * image object. * * @param p Native pointer. + * @param seg A segment backing the image on the host. */ - public CLImage(long p) { - super(p); + public CLImage(MemoryAddress p) { + this(p, null); + } + + public CLImage(MemoryAddress p, MemorySegment seg) { + super(p, seg); } - static void release(long p) { + static void release(MemoryAddress p) { CLMemory.release(p); } @Override - int getInfoType() { - return TYPE_IMAGE; + MethodHandle getInfoFunc() { + return clGetImageInfo; } - public native CLImageFormat getFormat(); + public CLImageFormat getFormat() { + return getInfoJava(CL_IMAGE_BUFFER, clGetImageInfo, CLImageFormat::fromNative); + } public long getElementSize() { return getInfoSizeT(CL_IMAGE_ELEMENT_SIZE); @@ -76,7 +89,7 @@ public class CLImage extends CLMemory { } public CLBuffer getBuffer() { - return getInfoAny(CTYPE_BUFFER, CL_IMAGE_BUFFER); + return getInfoAny(CL_IMAGE_BUFFER, clGetImageInfo, CLBuffer::new); } public int getNumMipLevels() { @@ -89,7 +102,7 @@ public class CLImage extends CLMemory { @Override public String toString() { - return String.format("[%s: %dx%dx%d 0x%x]", getClass().getSimpleName(), getWidth(), getHeight(), getDepth(), getP()); + return String.format("[%s: %dx%dx%d 0x%x]", getClass().getSimpleName(), getWidth(), getHeight(), getDepth(), addr().offset()); } /** diff --git a/src/notzed.zcl/classes/au/notzed/zcl/CLImageDesc.java b/src/notzed.zcl/classes/au/notzed/zcl/CLImageDesc.java index aacc985..f12e299 100644 --- a/src/notzed.zcl/classes/au/notzed/zcl/CLImageDesc.java +++ b/src/notzed.zcl/classes/au/notzed/zcl/CLImageDesc.java @@ -16,26 +16,36 @@ */ package au.notzed.zcl; +import jdk.incubator.foreign.*; +import api.Native; +import api.Allocator; + /** * Holder for cl_image_desc equivalent. + *

panama notes

+ To maintain compatability with the + * previous api this remains as a simple pojo and marshalling is + * done as required. +

+This also means it doesn't have to deal with allocation and deallocation and so on. */ public class CLImageDesc { public int imageType; - public int imageWidth; - public int imageHeight; - public int imageDepth; - public int imageArraySize; - public int imageRowPitch; - public int imageSlicePitch; - public int numMipLevels; - public int numSamples; + public long imageWidth; + public long imageHeight; + public long imageDepth; + public long imageArraySize; + public long imageRowPitch; + public long imageSlicePitch; + public long numMipLevels; + public long numSamples; public CLMemory memObject; public CLImageDesc() { } - public CLImageDesc(int imageType, int imageWidth, int imageHeight, int imageDepth, int imageArraySize, int imageRowPitch, int imageSlicePitch, int numMipLevels, int numSamples, CLMemory memObject) { + public CLImageDesc(int imageType, long imageWidth, long imageHeight, long imageDepth, long imageArraySize, long imageRowPitch, long imageSlicePitch, long numMipLevels, long numSamples, CLMemory memObject) { this.imageType = imageType; this.imageWidth = imageWidth; this.imageHeight = imageHeight; @@ -70,4 +80,35 @@ public class CLImageDesc { public static CLImageDesc create2D(int w, int h, int count) { return new CLImageDesc(CL.CL_MEM_OBJECT_IMAGE2D_ARRAY, w, h, 1, count, 0, 0, 0, 0, null); } + + + /* + * This is just hand-rolled for now. I'm not really sure how to approach it + * since these are just going to be used temporarily + */ + public static MemoryAddress toNative(Allocator frame, CLImageDesc d) { + MemoryAddress addr = frame.alloca(sizeof); + + Native.setInt(addr, d.imageType); + Native.setLong(addr, 1, d.imageWidth); + Native.setLong(addr, 2, d.imageHeight); + Native.setLong(addr, 3, d.imageDepth); + Native.setLong(addr, 4, d.imageArraySize); + Native.setLong(addr, 5, d.imageRowPitch); + Native.setLong(addr, 6, d.imageSlicePitch); + Native.setLong(addr, 7, d.numMipLevels); + Native.setLong(addr, 8, d.numSamples); + Native.setAddr(addr, 9, Native.addr(d.memObject)); + + return addr; + } + + public static CLImageFormat fromNative(MemoryAddress addr) { + return new CLImageFormat(Native.getInt(addr), Native.getInt(addr, 1)); + } + + public static final long sizeof = 72; + + public static MemoryLayout layout() { return Native.parseStruct("[u32(image_type)x32u64(image_width)u64(image_height)u64(image_depth)u64(image_array_size)u64(image_row_pitch)u64(image_slice_pitch)u32(num_mip_levels)u32(num_samples)u64(buffer):${_cl_mem}u64(mem_object):${_cl_mem}]"); } + } diff --git a/src/notzed.zcl/classes/au/notzed/zcl/CLImageFormat.java b/src/notzed.zcl/classes/au/notzed/zcl/CLImageFormat.java index d870024..f419bc6 100644 --- a/src/notzed.zcl/classes/au/notzed/zcl/CLImageFormat.java +++ b/src/notzed.zcl/classes/au/notzed/zcl/CLImageFormat.java @@ -16,8 +16,20 @@ */ package au.notzed.zcl; +import jdk.incubator.foreign.*; +import api.Native; +import api.Allocator; + /** * Holder for cl_image_format equivalent. + * + *

panama notes

+ To maintain compatability with the + * previous api this remains as a simple pojo and marshalling is + * done as required. +

+This also means it doesn't have to deal with allocation and deallocation and so on. + */ public class CLImageFormat { @@ -80,4 +92,26 @@ public class CLImageFormat { getChannelOrder(), getChannelDataType()); } + /* + * This is just hand-rolled for now. I'm not really sure how to approach it + * since these are just going to be used temporarily + */ + static MemoryAddress toNative(Allocator frame, CLImageFormat fmt) { + MemoryAddress addr = frame.alloca(2*4); + + Native.setInt(addr, fmt.channelOrder); + Native.setInt(addr, 1, fmt.channelDataType); + + return addr; + } + + static CLImageFormat fromNative(MemoryAddress addr) { + return new CLImageFormat(Native.getInt(addr), Native.getInt(addr, 1)); + } + + static CLImageFormat fromNative(MemorySegment addr) { + return fromNative(addr.baseAddress()); + } + + static MemoryLayout layout() { return Native.parseStruct("[u32(image_channel_order)u32(image_channel_data_type)]"); } } diff --git a/src/notzed.zcl/classes/au/notzed/zcl/CLKernel.java b/src/notzed.zcl/classes/au/notzed/zcl/CLKernel.java index 899e206..aaade1e 100644 --- a/src/notzed.zcl/classes/au/notzed/zcl/CLKernel.java +++ b/src/notzed.zcl/classes/au/notzed/zcl/CLKernel.java @@ -16,9 +16,16 @@ */ package au.notzed.zcl; -import java.nio.Buffer; import static au.notzed.zcl.CL.*; +import static au.notzed.zcl.CLLib.*; +import jdk.incubator.foreign.*; +import api.Native; +import api.Allocator; +import api.Memory; + +import java.nio.Buffer; import java.nio.ByteBuffer; +import java.lang.invoke.MethodHandle; /** * Interface for cl_kernel. @@ -33,15 +40,24 @@ public class CLKernel extends CLObject { * * @param p Native pointer. */ - public CLKernel(long p) { + CLKernel(MemoryAddress p) { super(p); } - private native static void release(long p); + static CLKernel create(MemoryAddress p) { + return Native.resolve(p, CLKernel::new); + } + + private static void release(MemoryAddress p) { + try { + clReleaseKernel(p); + } catch (Throwable t) { + } + } @Override - int getInfoType() { - return TYPE_KERNEL; + MethodHandle getInfoFunc() { + return clGetKernelInfo; } /** @@ -51,7 +67,32 @@ public class CLKernel extends CLObject { * @throws CLRuntimeException * @since OpenCL 2.1 */ - public native CLKernel cloneKernel() throws CLRuntimeException; + public CLKernel cloneKernel() throws CLRuntimeException { + if (clCloneKernel != null) { + // ?? + } + throw new UnsupportedOperationException(); + } + + /** + * Calls clGetKernelArg. + * pval is a pointer to the value. + */ + private void setKernelArg(int index, long size, MemoryAddress pval) { + try { + int res; + + res = clSetKernelArg(addr(), index, size, pval); + + if (res != 0) + throw new CLRuntimeException(res); + } catch (CLRuntimeException t) { + // oh joy + throw t; + } catch (Throwable t) { + throw new RuntimeException(t); + } + } /** * Calls clSetKernelArg with the arguments. @@ -62,7 +103,7 @@ public class CLKernel extends CLObject { * ignored. May be null to setArg the size of a local scope parameter. * @param offset Offset in buffer. */ - public native void setArg(int index, long size, Buffer buffer, long offset); + //public native void setArg(int index, long size, Buffer buffer, long offset); /** * Set the size of a parameter that is of a local scope. @@ -71,7 +112,7 @@ public class CLKernel extends CLObject { * @param size The size to reserve in bytes. */ public void setArgLDS(int index, long size) { - setArg(index, size, null, 0); + setKernelArg(index, size, MemoryAddress.NULL); } /** @@ -80,7 +121,14 @@ public class CLKernel extends CLObject { * @param index * @param o */ - public native void setArg(int index, CLObject o); + public void setArg(int index, CLObject o) { + try (Allocator frame = Memory.stack()) { + MemoryAddress pval = frame.alloca(8); + + setAddr(pval, o.addr()); + setKernelArg(index, 8, pval); + } + } /** * Set a byte-valued argument. Equates to OpenCL types char, unsigned char, @@ -89,7 +137,14 @@ public class CLKernel extends CLObject { * @param index * @param val */ - public native void setArg(int index, byte val); + public void setArg(int index, byte val) { + try (Allocator frame = Memory.stack()) { + MemoryAddress pval = frame.alloca(8); + + setByte(pval, val); + setKernelArg(index, 1, pval); + } + } /** * Set a short-valued argument. Equates to OpenCL types short, unsigned @@ -98,7 +153,14 @@ public class CLKernel extends CLObject { * @param index * @param val */ - public native void setArg(int index, short val); + public void setArg(int index, short val) { + try (Allocator frame = Memory.stack()) { + MemoryAddress pval = frame.alloca(8); + + setShort(pval, val); + setKernelArg(index, 2, pval); + } + } /** * Set an integer-valued argument. Equates to OpenCL types int, unsigned @@ -107,7 +169,14 @@ public class CLKernel extends CLObject { * @param index * @param val */ - public native void setArg(int index, int val); + public void setArg(int index, int val) { + try (Allocator frame = Memory.stack()) { + MemoryAddress pval = frame.alloca(8); + + setInt(pval, val); + setKernelArg(index, 4, pval); + } + } /** * Set a long-valued argument. Equates (somewhat conveniently) to the OpenCL @@ -116,7 +185,14 @@ public class CLKernel extends CLObject { * @param index * @param val */ - public native void setArg(int index, long val); + public void setArg(int index, long val) { + try (Allocator frame = Memory.stack()) { + MemoryAddress pval = frame.alloca(8); + + setLong(pval, val); + setKernelArg(index, 8, pval); + } + } /** * Set a float-valued argument. @@ -124,7 +200,14 @@ public class CLKernel extends CLObject { * @param index * @param val */ - public native void setArg(int index, float val); + public void setArg(int index, float val) { + try (Allocator frame = Memory.stack()) { + MemoryAddress pval = frame.alloca(8); + + setFloat(pval, val); + setKernelArg(index, 4, pval); + } + } /** * Set a double-valued argument. @@ -132,7 +215,15 @@ public class CLKernel extends CLObject { * @param index * @param val */ - public native void setArg(int index, double val); + public void setArg(int index, double val) { + try (Allocator frame = Memory.stack()) { + MemoryAddress pval = frame.alloca(8); + + setDouble(pval, val); + setKernelArg(index, 8, pval); + } + } + /** * Set SVM argument. @@ -140,7 +231,9 @@ public class CLKernel extends CLObject { * @param index * @param svm MUST have been allocated using CLContext.SVMAlloc(). */ - public native void setArg(int index, ByteBuffer svm); + public void setArg(int index, ByteBuffer svm) { + throw new UnsupportedOperationException("not yet"); + } /** * Set a multi-element byte argument. This may be used to setArg vector @@ -149,7 +242,15 @@ public class CLKernel extends CLObject { * @param index * @param val */ - public native void setArg(int index, byte... val); + public void setArg(int index, byte... val) { + try (Allocator frame = Memory.stack()) { + MemoryAddress pval = frame.alloca(val.length); + + for (int i=0;i T getWorkGroupInfoAny(CLDevice dev, int otype, int param_name) throws CLRuntimeException; - - native T getWorkGroupInfoAnyV(CLDevice dev, int otype, int param_name) throws CLRuntimeException; - /** * gets CL_KERNEL_GLOBAL_WORK_SIZE * @@ -266,58 +402,56 @@ public class CLKernel extends CLObject { * @return */ public long[] getGlobalWorkSize(CLDevice device) { - return getWorkGroupInfoAnyV(device, CTYPE_SIZE_T, CL_KERNEL_GLOBAL_WORK_SIZE); + return getInfoLongV(device, CL_KERNEL_GLOBAL_WORK_SIZE, clGetKernelWorkGroupInfo); } - public long getWorkGroupSize(CLDevice device) { - return getWorkGroupInfoAny(device, CTYPE_SIZE_T, CL_KERNEL_WORK_GROUP_SIZE); + public long getWorkGroupSize(CLDevice device) { + return getInfoSizeT(device, CL_KERNEL_WORK_GROUP_SIZE, clGetKernelWorkGroupInfo); } public long[] getCompileWorkGroupSize(CLDevice device) { - return getWorkGroupInfoAnyV(device, CTYPE_SIZE_T, CL_KERNEL_COMPILE_WORK_GROUP_SIZE); + return getInfoLongV(device, CL_KERNEL_COMPILE_WORK_GROUP_SIZE, clGetKernelWorkGroupInfo); } public long getLocalMemSize(CLDevice device) { - return getWorkGroupInfoAny(device, CTYPE_LONG, CL_KERNEL_LOCAL_MEM_SIZE); + return getInfoSizeT(device, CL_KERNEL_LOCAL_MEM_SIZE, clGetKernelWorkGroupInfo); } public long getPreferredWorkGroupSizeMultiple(CLDevice device) { - return getWorkGroupInfoAny(device, CTYPE_SIZE_T, CL_KERNEL_PREFERRED_WORK_GROUP_SIZE_MULTIPLE); + return getInfoSizeT(device, CL_KERNEL_PREFERRED_WORK_GROUP_SIZE_MULTIPLE, clGetKernelWorkGroupInfo); } public long getPrivateMemSize(CLDevice device) { - return getWorkGroupInfoAny(device, CTYPE_SIZE_T, CL_KERNEL_PRIVATE_MEM_SIZE); + return getInfoSizeT(device, CL_KERNEL_PRIVATE_MEM_SIZE, clGetKernelWorkGroupInfo); } - /* cl_kernel_sub_group_info */ - // this assumes all size_t's atm. - native T getSubGroupInfoAny(CLDevice dev, int otype, int param_name, long[] input) throws CLRuntimeException; - - native T getSubGroupInfoAnyV(CLDevice dev, int otype, int param_name, long[] input) throws CLRuntimeException; - /** * @since OpenCL 2.1 */ public long getMaxSubGroupSizeForNDRange(CLDevice device, long[] range) { - return getSubGroupInfoAny(device, CTYPE_SIZE_T, CL_KERNEL_MAX_SUB_GROUP_SIZE_FOR_NDRANGE, range); + // wrong, these all need to pass a range too + //return getInfoSizeT(CL_KERNEL_MAX_SUB_GROUP_SIZE_FOR_NDRANGE, device, clGetKernelSubGroupInfo); + throw new UnsupportedOperationException(); } /** * @since OpenCL 2.1 */ public long getSubGroupCountForNDRange(CLDevice device, long[] range) { - return getSubGroupInfoAny(device, CTYPE_SIZE_T, CL_KERNEL_SUB_GROUP_COUNT_FOR_NDRANGE, range); + //return getInfoSizeT(CL_KERNEL_SUB_GROUP_COUNT_FOR_NDRANGE, device, clGetKernelSubGroupInfo); + throw new UnsupportedOperationException(); } - /** - * @since OpenCL 2.1 - */ - public long[] getLocalSizeForSubGroupCount(CLDevice device, long count) { - return getSubGroupInfoAnyV(device, CTYPE_SIZE_T, CL_KERNEL_LOCAL_SIZE_FOR_SUB_GROUP_COUNT, new long[]{count}); - } + // /** + // * @since OpenCL 2.1 + // */ + // public long[] getLocalSizeForSubGroupCount(CLDevice device, long count) { + // return getSubGroupInfoAnyV(device, CTYPE_SIZE_T, CL_KERNEL_LOCAL_SIZE_FOR_SUB_GROUP_COUNT, new long[]{count}); + // } public long getMaxNumSubGroups(CLDevice device) { - return getSubGroupInfoAny(device, CTYPE_SIZE_T, CL_KERNEL_SUB_GROUP_COUNT_FOR_NDRANGE, null); + throw new UnsupportedOperationException(); + //return getInfoSizeT(CL_KERNEL_MAX_NUM_SUB_GROUPS, device, clGetKernelSubGroupInfo); } /* cl_kernel_exec_info */ @@ -330,11 +464,6 @@ public class CLKernel extends CLObject { */ public final static int CL_KERNEL_EXEC_INFO_SVM_FINE_GRAIN_SYSTEM = 0x11B7; - /* cl_kernel_arg_info */ - native T getArgInfoAny(int index, int otype, int param_name) throws CLRuntimeException; - - native T getArgInfoAnyV(int index, int otype, int param_name) throws CLRuntimeException; - /** * gets CL_KERNEL_ARG_ADDRESS_QUALIFIER. * @@ -344,7 +473,7 @@ public class CLKernel extends CLObject { * @since OpenCL 1.2 */ public int getArgAddressQualifier(int index) throws UnsupportedOperationException { - return getArgInfoAny(index, CTYPE_INT, CL_KERNEL_ARG_ADDRESS_QUALIFIER); + return getInfoInt(index, CL_KERNEL_ARG_ADDRESS_QUALIFIER, clGetKernelArgInfo); } /** @@ -356,7 +485,7 @@ public class CLKernel extends CLObject { * @since OpenCL 1.2 */ public int getArgAccessQualifier(int index) throws UnsupportedOperationException { - return getArgInfoAny(index, CTYPE_INT, CL_KERNEL_ARG_ACCESS_QUALIFIER); + return getInfoInt(index, CL_KERNEL_ARG_ACCESS_QUALIFIER, clGetKernelArgInfo); } /** @@ -368,7 +497,7 @@ public class CLKernel extends CLObject { * @since OpenCL 1.2 */ public String getArgTypeName(int index) throws UnsupportedOperationException { - return fromInfoString(getArgInfoAnyV(index, CTYPE_BYTE, CL_KERNEL_ARG_TYPE_NAME)); + return getInfoString(index, CL_KERNEL_ARG_TYPE_NAME, clGetKernelArgInfo); } /** @@ -380,7 +509,7 @@ public class CLKernel extends CLObject { * @since OpenCL 1.2 */ public long getArgTypeQualifier(int index) throws UnsupportedOperationException { - return getArgInfoAny(index, CTYPE_LONG, CL_KERNEL_ARG_TYPE_QUALIFIER); + return getInfoLong(index, CL_KERNEL_ARG_TYPE_QUALIFIER, clGetKernelArgInfo); } /** @@ -392,6 +521,6 @@ public class CLKernel extends CLObject { * @since OpenCL 1.2 */ public String getArgName(int index) throws UnsupportedOperationException { - return fromInfoString(getArgInfoAnyV(index, CTYPE_BYTE, CL_KERNEL_ARG_NAME)); + return getInfoString(index, CL_KERNEL_ARG_NAME, clGetKernelArgInfo); } } diff --git a/src/notzed.zcl/classes/au/notzed/zcl/CLMemory.java b/src/notzed.zcl/classes/au/notzed/zcl/CLMemory.java index c4bd264..0a2923b 100644 --- a/src/notzed.zcl/classes/au/notzed/zcl/CLMemory.java +++ b/src/notzed.zcl/classes/au/notzed/zcl/CLMemory.java @@ -16,9 +16,19 @@ */ package au.notzed.zcl; -import java.nio.ByteBuffer; import static au.notzed.zcl.CL.*; +import static au.notzed.zcl.CLLib.*; +import jdk.incubator.foreign.*; +import api.Native; +import api.Callback; +import api.Memory; +import api.Allocator; +import java.lang.invoke.MethodHandle; + +import java.nio.ByteBuffer; +//import static au.au.notzed.zcl.CL.*; import java.nio.ByteOrder; +import jdk.incubator.foreign.*; /** * Interface for cl_mem. @@ -58,11 +68,81 @@ import java.nio.ByteOrder; */ public abstract class CLMemory extends CLObject { - CLMemory(long p) { + /** + * If use USE_HOST_PTR was used then this keeps track of the + * host ptr reference both to avoid java freeing it and so it + * can be retrieved later. + */ + MemorySegment seg; + + /** + * If set, retain reference for lifetime of memory. + */ + Callback> destroyCallback; + + CLMemory(MemoryAddress p, MemorySegment seg) { super(p); + + this.seg = seg; } - native static void release(long p); + @Override + MethodHandle getInfoFunc() { + return clGetMemObjectInfo; + } + + public static CLMemory create(MemoryAddress p) { + if (p.offset() == 0) + return null; + + // This is basically a workaround so that setMemObjectDestructorCallback passes + // the right type without changing the api or using reflection. + // Probably better solutions. + + try (Allocator a = Memory.stack()) { + MemoryAddress addr = getInfo(p, CL_MEM_TYPE, clGetMemObjectInfo, a, 4); + int type = getInt(addr); + + switch (type) { + case CL_MEM_OBJECT_BUFFER: + return Native.resolve(p, CLBuffer::new); + case CL_MEM_OBJECT_IMAGE2D: + case CL_MEM_OBJECT_IMAGE3D: + case CL_MEM_OBJECT_IMAGE2D_ARRAY: + case CL_MEM_OBJECT_IMAGE1D: + case CL_MEM_OBJECT_IMAGE1D_ARRAY: + case CL_MEM_OBJECT_IMAGE1D_BUFFER: + return Native.resolve(p, CLImage::new); + case CL_MEM_OBJECT_PIPE: + return Native.resolve(p, CLPipe::new); + default: + throw new UnsupportedOperationException(); + } + } + } + + static void release(MemoryAddress p) { + // note: no way to free the hostSegment, even if we could + System.out.println("*** release clmemory"); + try { + clReleaseMemObject(p); + } catch (Throwable t) { + } + } + + /** + * If CL_MEM_USE_HOST_PTR was used at creation then this must + * be invoked to avoid a memory leak. It also must be invoked + * on the original thread of creation. + */ + @Override + public void release() { + if (seg != null) { + seg.close(); + seg = null; + } + super.release(); + } /** * Call clSetMemObjectDestructorCallback. @@ -72,14 +152,32 @@ public abstract class CLMemory extends CLObject { * @throws UnsupportedOperationException * @since OpenCL 1.1 */ - public native void setMemObjectDestructorCallback(CLNotify notify) throws CLException, UnsupportedOperationException; + public void setMemObjectDestructorCallback(CLNotify notify) throws CLException, UnsupportedOperationException { + //a bit costly perhaps + getContext().requireAPIVersion(CLPlatform.VERSION_1_1); - @Override - int getInfoType() { - return TYPE_MEM_OBJECT; + Native.release(destroyCallback); + if (notify != null) { + destroyCallback = CLNotify.call(notify, CLMemory::create); + + try { + int res = clSetMemObjectDestructorCallback(addr(), destroyCallback.addr(), MemoryAddress.NULL); + if (res != 0) + throw new CLException(res); + } catch (RuntimeException | Error t) { + throw t; + } catch (Throwable t) { + throw new RuntimeException(t); + } + } else { + destroyCallback = null; + } } - public long getType() { + /** + * Get CL_MEM_TYPE + */ + public int getType() { return getInfoInt(CL_MEM_TYPE); } @@ -104,9 +202,15 @@ public abstract class CLMemory extends CLObject { /** * Get CL_MEM_HOST_PTR. * + * This recreates a bytebuffer from the memory segment used + * at creation time. It is always in native order. * @return */ - public native ByteBuffer getHostPtr() throws CLRuntimeException; + public ByteBuffer getHostPtr() throws CLRuntimeException { + return seg != null + ? seg.asByteBuffer().order(ByteOrder.nativeOrder()) + : null; + } /** * Get CL_MEM_CONTEXT. @@ -114,7 +218,7 @@ public abstract class CLMemory extends CLObject { * @return An interface to the context this memory was created on. */ public CLContext getContext() { - return getInfoAny(CTYPE_CONTEXT, CL_MEM_CONTEXT); + return getInfoAny(CL_MEM_CONTEXT, clGetMemObjectInfo, CLContext::new); } /** @@ -123,7 +227,7 @@ public abstract class CLMemory extends CLObject { * @return */ public CLBuffer getAssociatedMemObject() { - return getInfoAny(CTYPE_BUFFER, CL_MEM_ASSOCIATED_MEMOBJECT); + return getInfoAny(CL_MEM_ASSOCIATED_MEMOBJECT, clGetMemObjectInfo, CLBuffer::new); } /** @@ -197,28 +301,28 @@ public abstract class CLMemory extends CLObject { } } - public static CLTask ofAcquireGL(CLMemory... mems) { - return (CLCommandQueue q, CLEventList waiters, CLEventList events) -> { - q.enqueueAcquireGLObjects(mems, waiters, events); - }; - } + //public static CLTask ofAcquireGL(CLMemory... mems) { + // return (CLCommandQueue q, CLEventList waiters, CLEventList events) -> { + // q.enqueueAcquireGLObjects(mems, waiters, events); + // }; + //} - public static CLTask ofReleaseGL(CLMemory... mems) { - return (CLCommandQueue q, CLEventList waiters, CLEventList events) -> { - q.enqueueReleaseGLObjects(mems, waiters, events); - }; - } + //public static CLTask ofReleaseGL(CLMemory... mems) { + // return (CLCommandQueue q, CLEventList waiters, CLEventList events) -> { + // q.enqueueReleaseGLObjects(mems, waiters, events); + // }; + //} /* Experimental: extensions/gl */ - public CLTask ofAcquireGL() { - return ofAcquireGL(this); - } + //public CLTask ofAcquireGL() { + // return ofAcquireGL(this); + //} - public CLTask ofReleaseGL() { - return ofReleaseGL(this); - } + //public CLTask ofReleaseGL() { + // return ofReleaseGL(this); + //} /* Experimental half stuff diff --git a/src/notzed.zcl/classes/au/notzed/zcl/CLNotify.java b/src/notzed.zcl/classes/au/notzed/zcl/CLNotify.java index 94b912c..ceb6f8d 100644 --- a/src/notzed.zcl/classes/au/notzed/zcl/CLNotify.java +++ b/src/notzed.zcl/classes/au/notzed/zcl/CLNotify.java @@ -16,11 +16,28 @@ */ package au.notzed.zcl; +import java.util.function.Function; +import jdk.incubator.foreign.MemoryAddress; +import api.Native; +import api.Callback; + /** * Generic notify routine. * @param Type of source object. */ +@FunctionalInterface public interface CLNotify { public void notify(T source); + + @SuppressWarnings("unchecked") + static Callback> call(CLNotify notify, Function create) { + if (notify != null) { + return Native.resolve( + Call_pLpv_v.stub((co, dummy) -> notify.notify(Native.resolve(co, create))), + (p) -> new Callback<>(p, notify)); + } else { + return Callback.NULL; + } + } } diff --git a/src/notzed.zcl/classes/au/notzed/zcl/CLObject.java b/src/notzed.zcl/classes/au/notzed/zcl/CLObject.java index 284c82a..a7eb75d 100644 --- a/src/notzed.zcl/classes/au/notzed/zcl/CLObject.java +++ b/src/notzed.zcl/classes/au/notzed/zcl/CLObject.java @@ -16,7 +16,16 @@ */ package au.notzed.zcl; -import au.notzed.nativez.NativeZ; +import java.lang.invoke.MethodHandle; +import java.util.function.Function; +import java.util.function.IntFunction; +import java.util.function.BiFunction; +import jdk.incubator.foreign.*; +import api.Native; +import api.Allocator; +import api.Memory; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; /** * Base class for all OpenCL types which can be represented as objects - i.e. @@ -39,16 +48,12 @@ import au.notzed.nativez.NativeZ; * Memory management is explicit and objects must be released when no longer * needed. */ -public abstract class CLObject extends NativeZ { +public abstract class CLObject extends Native { - protected CLObject(long p) { + protected CLObject(MemoryAddress p) { super(p); } - static { - System.loadLibrary("zcl"); - } - // These are not really public - for access by extensions public static final int CTYPE_PLATFORM = 0; public static final int CTYPE_DEVICE = 1; @@ -98,42 +103,286 @@ public abstract class CLObject extends NativeZ { final static int TYPE_EVENT_PROFILING = 14; final static int TYPE_KERNEL_SUB_GROUP = 15; - /** - * A generic get info type for GetInfo() qeries that take 5 arguments. - * - * @param type type code for 'this', or the query that applies to this. - * @param param_name name of value being queried. - * @param otype output type - * @return result, primitive types are boxed. - * @throws CLRuntimeException - */ - native T getInfoAny(int type, int otype, int param_name) throws CLRuntimeException; + // new 5-param version + // this one is static so it can be accessed at creation time + protected static MemoryAddress getInfo(MemoryAddress self, int id, MethodHandle getInfo, Allocator frame, long size) throws CLRuntimeException { + try { + MemoryAddress addr = frame.alloca(size); + int res; - T getInfoAny(int otype, int param_name) throws CLRuntimeException { - return getInfoAny(getInfoType(), otype, param_name); + res = (int)getInfo.invokeExact(self, id, size, addr, MemoryAddress.NULL); + if (res != 0) + throw new CLRuntimeException(res); + + return addr; + } catch (RuntimeException | Error t) { + throw t; + } catch (Throwable t) { + throw new RuntimeException(t); + } } - /** - * A generic get info type for GetInfo() qeries that take 5 arguments and - * returns an array. - * - * @param type type code for 'this', or the query that applies to this. - * @param param_name name of value being queried. - * @param otype output type - * @return result array type. - * @throws CLRuntimeException - */ - native T getInfoAnyV(int type, int otype, int param_name) throws CLRuntimeException; - T getInfoAnyV(int otype, int param_name) throws CLRuntimeException { - return getInfoAnyV(getInfoType(), otype, param_name); + protected int getInfoInt(int id, MethodHandle getInfo) { + try (Allocator a = Memory.stack()) { + return getInt(getInfo(addr(), id, getInfo, a, 4)); + } + } + + protected long getInfoLong(int id, MethodHandle getInfo) { + try (Allocator a = Memory.stack()) { + return getLong(getInfo(addr(), id, getInfo, a, 8)); + } + } + + protected long getInfoSizeT(int id, MethodHandle getInfo) { + return getInfoLong(id, getInfo); + } + + protected T getInfoAny(int id, MethodHandle getInfo, Function create) { + try (Allocator a = Memory.stack()) { + return Native.resolve(getAddr(getInfo(addr(), id, getInfo, a, 8)), create); + } + } + + protected T getInfoJava(int id, MethodHandle getInfo, Function create) { + try (Allocator a = Memory.stack()) { + return create.apply(getAddr(getInfo(addr(), id, getInfo, a, 8))); + } + } + + // new 5-param version for get any + protected MemorySegment getInfoAny(int id, MethodHandle getInfo, Allocator a) throws CLRuntimeException { + try { + MemoryAddress sizep = a.alloca(8); + MemorySegment valp; + long size; + int res; + + res = (int)getInfo.invokeExact(addr(), id, 0L, MemoryAddress.NULL, sizep); + + size = getLong(sizep); + valp = a.allocs(size); + + res = (int)getInfo.invokeExact(addr(), id, size, valp.baseAddress(), sizep); + + if (res != 0) + throw new CLRuntimeException(res); + + return valp; + } catch (RuntimeException | Error t) { + throw t; + } catch (Throwable t) { + throw new RuntimeException(t); + } + } + + protected byte[] getInfoByteV(int id, MethodHandle getInfo) { + try (Allocator a = Memory.stack()) { + return getInfoAny(id, getInfo, a).toByteArray(); + } + } + + protected String getInfoString(int id, MethodHandle getInfo) { + try (Allocator a = Memory.stack()) { + return infoToString(getInfoAny(id, getInfo, a)); + } + } + + protected T[] getInfoPropertyV(int id, MethodHandle getInfo, BiFunction create, IntFunction createArray) { + try (Allocator a = Memory.stack()) { + return CLProperty.fromNative(getInfoAny(id, getInfo, a), create, createArray); + } + } + + protected long[] getInfoLongV(int id, MethodHandle getInfo) { + try (Allocator a = Memory.stack()) { + return Native.toLongV(getInfoAny(id, getInfo, a)); + } + } + + protected T[] getInfoAnyV(int id, MethodHandle getInfo, Function create, IntFunction createArray) { + try (Allocator a = Memory.stack()) { + return Native.toObjectV(getInfoAny(id, getInfo, a), create, createArray); + } catch (RuntimeException | Error t) { + throw t; + } catch (Throwable t) { + throw new RuntimeException(t); + } + } + + // new 6-param version + protected MemoryAddress getInfo(T ctx, int id, MethodHandle getInfo, Allocator a, long size) throws CLRuntimeException { + try { + MemoryAddress addr = a.alloca(size); + int res; + + res = (int)getInfo.invokeExact(addr(), ctx.addr(), id, size, addr, MemoryAddress.NULL); + if (res != 0) + throw new CLRuntimeException(res); + + return addr; + } catch (RuntimeException | Error t) { + throw t; + } catch (Throwable t) { + throw new RuntimeException(t); + } + } + + protected int getInfoInt(T ctx, int id, MethodHandle getInfo) { + try (Allocator a = Memory.stack()) { + return getInt(getInfo(ctx, id, getInfo, a, 4)); + } + } + + protected long getInfoLong(T ctx, int id, MethodHandle getInfo) { + try (Allocator a = Memory.stack()) { + return getLong(getInfo(ctx, id, getInfo, a, 8)); + } } - native long getInfoLong(int type, int param_name) throws CLRuntimeException; + protected long getInfoSizeT(T ctx, int id, MethodHandle getInfo) { + return getInfoLong(ctx, id, getInfo); + } + + // new 6-param get-any + protected MemorySegment getInfoAny(T ctx, int id, MethodHandle getInfo, Allocator a) throws CLRuntimeException { + try { + MemoryAddress sizep = a.alloca(8); + MemorySegment valp; + long size; + int res; + + res = (int)getInfo.invokeExact(addr(), ctx.addr(), id, 0L, MemoryAddress.NULL, sizep); + + size = getLong(sizep); + valp = a.allocs(size); + + res = (int)getInfo.invokeExact(addr(), ctx.addr(), id, size, valp.baseAddress(), sizep); + + if (res != 0) + throw new CLRuntimeException(res); + + return valp; + } catch (RuntimeException | Error x) { + throw x; + } catch (Throwable x) { + throw new RuntimeException(x); + } + } + + protected byte[] getInfoByteV(T ctx, int id, MethodHandle getInfo) { + try (Allocator a = Memory.stack()) { + MemorySegment seg = getInfoAny(ctx, id, getInfo, a); + return seg.toByteArray(); + } + } + + // clGet*Info includes terminating 0 + static String infoToString(MemorySegment seg) { + if (false) { + MemoryAddress valp = seg.baseAddress(); + byte[] val = new byte[(int)(seg.byteSize()-1)]; + + for (int i=0;i String getInfoString(T ctx, int id, MethodHandle getInfo) { + try (Allocator a = Memory.stack()) { + MemorySegment seg = getInfoAny(ctx, id, getInfo, a); + return infoToString(seg); + } + } + + protected long[] getInfoLongV(T ctx, int id, MethodHandle getInfo) { + try (Allocator a = Memory.stack()) { + MemorySegment valp = getInfoAny(ctx, id, getInfo, a); + MemoryAddress val = valp.baseAddress(); + int len = (int)(valp.byteSize() >>> 3); + long[] list = new long[len]; + + for (int i=0;i extends CLMemory { * * @param p Native pointer. */ - public CLPipe(long p) { - super(p); + public CLPipe(MemoryAddress p) { + this(p, null); } - static void release(long p) { - CLMemory.release(p); + public CLPipe(MemoryAddress p, MemorySegment seg) { + super(p, seg); } @Override - int getInfoType() { - return TYPE_PIPE; + MethodHandle getInfoFunc() { + return clGetPipeInfo; + } + + static void release(MemoryAddress p) { + CLMemory.release(p); } public int getPacketSize() { diff --git a/src/notzed.zcl/classes/au/notzed/zcl/CLPlatform.java b/src/notzed.zcl/classes/au/notzed/zcl/CLPlatform.java index 001b037..be8dcb1 100644 --- a/src/notzed.zcl/classes/au/notzed/zcl/CLPlatform.java +++ b/src/notzed.zcl/classes/au/notzed/zcl/CLPlatform.java @@ -17,8 +17,17 @@ package au.notzed.zcl; import static au.notzed.zcl.CL.*; -import au.notzed.zcl.khr.GLSharing; +import static au.notzed.zcl.CLLib.*; +//import au.notzed.zcl.khr.GLSharing; import java.util.function.ToDoubleFunction; +import jdk.incubator.foreign.*; +import api.Native; +import api.Memory; +import api.Allocator; + +// hack test +import java.lang.invoke.*; +import jdk.incubator.foreign.unsafe.ForeignUnsafe; /** * Interface for cl_platform_id @@ -39,7 +48,7 @@ public class CLPlatform extends CLObject { * * @param p Native pointer. */ - public CLPlatform(long p) { + public CLPlatform(MemoryAddress p) { super(p); String v = getVersion(); @@ -54,7 +63,14 @@ public class CLPlatform extends CLObject { } } - private native static void release(long p); + private static void release(MemoryAddress p) { + // noop + } + + @Override + public void release() { + // noop + } @Override public String toString() { @@ -62,8 +78,8 @@ public class CLPlatform extends CLObject { } @Override - int getInfoType() { - return TYPE_PLATFORM; + MethodHandle getInfoFunc() { + return clGetPlatformInfo; } /** @@ -72,7 +88,25 @@ public class CLPlatform extends CLObject { * @return List of all available platforms. * @throws CLRuntimeException */ - public static native CLPlatform[] getPlatforms() throws CLRuntimeException; + public static CLPlatform[] getPlatforms() /*throws CLRuntimeException*/ { + try (Allocator frame = Memory.stack()) { + MemoryAddress lenp = frame.alloca(8); + MemoryAddress list; + int len; + int res; + + res = (int)clGetPlatformIDs.invokeExact(0, MemoryAddress.NULL, lenp); + + len = Native.getInt(lenp); + list = frame.alloca(8 * len); + + res = (int)clGetPlatformIDs.invokeExact(len, list, lenp); + + return toObjectV(list, new CLPlatform[len], CLPlatform::new); + } catch (Throwable t) { + throw new RuntimeException(t); + } + } /** * Calls clGetDeviceIDs. @@ -83,7 +117,29 @@ public class CLPlatform extends CLObject { * @return List of matching devices in this platform. * @throws CLRuntimeException */ - public native CLDevice[] getDevices(long type) throws CLRuntimeException; + public CLDevice []getDevices(long type) /*throws CLRuntimeException*/ { + try (Allocator frame = Memory.stack()) { + MemoryAddress lenp = frame.alloca(8); + MemoryAddress list; + int res, len; + + res = (int)clGetDeviceIDs.invokeExact(addr(), type, 0, MemoryAddress.NULL, lenp); + + if (res == CL_DEVICE_NOT_FOUND) + return new CLDevice[0]; + else if (res != 0) + throw new CLRuntimeException(res); + + len = Native.getInt(lenp); + list = frame.alloca(len * 8); + + res = (int)clGetDeviceIDs.invokeExact(addr(), type, len, list, lenp); + + return toObjectV(list, new CLDevice[len], CLDevice::new); + } catch (Throwable t) { + throw new RuntimeException(); + } + } /** * Find the 'best' device using supplied statistic. @@ -129,7 +185,7 @@ public class CLPlatform extends CLObject { * * @throws CLRuntimeException */ - public native void unloadPlatformCompiler() throws CLRuntimeException; + //public native void unloadPlatformCompiler() throws CLRuntimeException; /** * get CL_PLATFORM_PROFILE. @@ -190,18 +246,18 @@ public class CLPlatform extends CLObject { *

* Extensions are bound to platforms. */ - final CLExtension[] extensions = new CLExtension[2]; + //final CLExtension[] extensions = new CLExtension[2]; - native CLExtension createExtension(int extension); // throws something + //native CLExtension createExtension(int extension); // throws something - public T getExtension(Class klass, int id) { - synchronized (extensions) { - if (extensions[id] == null) { - extensions[id] = createExtension(id); - } - return klass.cast(extensions[id]); - } - } + //public T getExtension(Class klass, int id) { + // synchronized (extensions) { + // if (extensions[id] == null) { + // extensions[id] = createExtension(id); + // } + // return klass.cast(extensions[id]); + // } + //} /** * Retrieve an extension by name. @@ -211,14 +267,13 @@ public class CLPlatform extends CLObject { * @param name * @return */ - public T getExtension(Class klass, String name) { - switch (name) { - case GLSharing.NAME: - return getExtension(klass, cl_khr_gl_sharing); - case au.notzed.zcl.khr.GLEvent.NAME: - return getExtension(klass, cl_khr_gl_event); - } - return null; - } - + //public T getExtension(Class klass, String name) { + // switch (name) { + // case GLSharing.NAME: + // return getExtension(klass, cl_khr_gl_sharing); + // case au.notzed.zcl.khr.GLEvent.NAME: + // return getExtension(klass, cl_khr_gl_event); + // } + // return null; + //} } diff --git a/src/notzed.zcl/classes/au/notzed/zcl/CLProgram.java b/src/notzed.zcl/classes/au/notzed/zcl/CLProgram.java index 44da93d..43b97a0 100644 --- a/src/notzed.zcl/classes/au/notzed/zcl/CLProgram.java +++ b/src/notzed.zcl/classes/au/notzed/zcl/CLProgram.java @@ -17,6 +17,14 @@ package au.notzed.zcl; import static au.notzed.zcl.CL.*; +import static au.notzed.zcl.CLLib.*; +import jdk.incubator.foreign.*; +import api.Native; +import api.Memory; +import api.Allocator; +import api.Callback; +import java.lang.invoke.MethodHandle; +import java.util.stream.LongStream; /** * Interface for cl_program. @@ -28,15 +36,25 @@ public class CLProgram extends CLObject { * * @param p Native pointer. */ - public CLProgram(long p) { + CLProgram(MemoryAddress p) { super(p); } - private native static void release(long p); + public static CLProgram create(MemoryAddress p) { + return Native.resolve(p, CLProgram::new); + } + + private static void release(MemoryAddress p) { + try { + clReleaseProgram(p); + } catch (Throwable t) { + t.printStackTrace(); + } + } @Override - int getInfoType() { - return TYPE_PROGRAM; + MethodHandle getInfoFunc() { + return clGetProgramInfo; } /** @@ -47,7 +65,22 @@ public class CLProgram extends CLObject { * @param notify Notification callback. * @throws CLException */ - public native void buildProgram(CLDevice[] devices, String options, CLNotify notify) throws CLException; + public void buildProgram(CLDevice[] devices, String options, CLNotify notify) throws CLException { + try (Allocator frame = Memory.stack(); + Callback> call = CLNotify.call(notify, CLProgram::new)) { + MemoryAddress pdevs = toAddrV(frame, devices); + MemoryAddress poptions = toByteV(frame, options); + int res; + + res = clBuildProgram(addr(), devices.length, pdevs, poptions, call.addr(), MemoryAddress.NULL); + if (res != 0) + throw new CLException(res); + } catch (CLException | RuntimeException | Error t) { + throw t; + } catch (Throwable t) { + throw new RuntimeException(t); + } + } public void buildProgram(CLDevice[] devices, String options) throws CLException { CLNotify notify = (CLProgram source) -> { @@ -81,7 +114,35 @@ public class CLProgram extends CLObject { * @throws UnsupportedOperationException * @since OpenCL 1.2 */ - public native void compileProgram(CLDevice[] devices, String options, CLProgram[] headers, String[] header_names, CLNotify notify) throws CLException, UnsupportedOperationException; + public void compileProgram(CLDevice[] devices, String options, CLProgram[] headers, String[] header_names, CLNotify notify) throws CLException, UnsupportedOperationException { + int nheaders = 0; + if (headers != null && header_names != null) { + if (headers.length != header_names.length) + throw new IllegalArgumentException(); + nheaders = headers.length; + } else if (headers != null || header_names != null) { + throw new IllegalArgumentException(); + } + + try (Allocator frame = Memory.stack(); + Callback> call = CLNotify.call(notify, CLProgram::new)) { + MemoryAddress cdevs = toAddrV(frame, devices); + MemoryAddress coptions = toByteV(frame, options); + MemoryAddress cheaders = toAddrV(frame, headers); + MemoryAddress cnames = Native.toAddrV(frame, header_names); + MemoryAddress cres = frame.alloca(8); + int res; + MemoryAddress ck; + + res = clCompileProgram(addr(), devices.length, cdevs, coptions, nheaders, cheaders, cnames, call.addr(), MemoryAddress.NULL); + if (res != 0) + throw new CLException(res); + } catch (CLException | RuntimeException | Error t) { + throw t; + } catch (Throwable t) { + throw new RuntimeException(t); + } + } /** * Call clCreateKernel. @@ -91,18 +152,54 @@ public class CLProgram extends CLObject { * longer needed. * @throws CLRuntimeException */ - public native CLKernel createKernel(String name) throws CLRuntimeException; + public CLKernel createKernel(String name) throws CLException { + try (Allocator frame = Memory.stack()) { + MemoryAddress pres = frame.alloca(8); + MemoryAddress pname = toByteV(frame, name); + int res; + MemoryAddress ck; + + ck = clCreateKernel(addr(), pname, pres); + res = getInt(pres); + if (res != 0) + throw new CLException(res); + return resolve(ck, CLKernel::new); + } catch (CLException | RuntimeException | Error t) { + throw t; + } catch (Throwable t) { + throw new RuntimeException(t); + } + } /** * Call clCreateKernelsInProgram. * - * @return Number of kernels created. + * @return kernels created * @throws CLRuntimeException */ - public native CLKernel[] createKernelsInProgram() throws CLRuntimeException; + public CLKernel[] createKernelsInProgram() throws CLRuntimeException { + int size = getNumKernels(); + + try (api.Allocator a = api.Memory.stack()) { + MemoryAddress csize = a.alloca(8); + MemoryAddress ckern = a.alloca(8 * size); + int res; + + res = clCreateKernelsInProgram(addr(), size, ckern, csize); + if (res != 0) + throw new CLRuntimeException(); + + size = getInt(csize); + return Native.toObjectV(ckern, new CLKernel[size], CLKernel::new); + } catch (RuntimeException | Error t) { + throw t; + } catch (Throwable t) { + throw new RuntimeException(t); + } + } public CLContext getContext() { - return getInfoAny(CTYPE_CONTEXT, CL_PROGRAM_CONTEXT); + return getInfoAny(CL_PROGRAM_CONTEXT, clGetProgramInfo, CLContext::new); } public int getNumDevices() { @@ -110,7 +207,7 @@ public class CLProgram extends CLObject { } public CLDevice[] getDevices() { - return getInfoAnyV(CTYPE_DEVICE, CL_PROGRAM_DEVICES); + return getInfoAnyV(CL_PROGRAM_DEVICES, clGetProgramInfo, CLDevice::new, CLDevice[]::new); } public String getSource() { @@ -118,14 +215,43 @@ public class CLProgram extends CLObject { } /* This is unnecessary since getBinaries() is the only thing that needs it - public long[] getBinarySizes() { - long[] sizes = new long[getNumDevices()]; + public long[] getBinarySizes() { } + */ + + public byte[][] getBinaries() { + long[] sizes = getInfoSizeTA(CL_PROGRAM_BINARY_SIZES); + long size = LongStream.of(sizes).sum(); + + try (api.Allocator a = api.Memory.stack(); + MemorySegment seg = MemorySegment.allocateNative(size)) { + MemoryAddress data = seg.baseAddress(); + MemoryAddress cptrs = a.alloca(size * 8); + long off = 0; + int res; + + for (int i=0;i T getBuildInfoAny(CLDevice dev, int otype, int param_name) throws CLRuntimeException; - - native T getBuildInfoAnyV(CLDevice dev, int otype, int param_name) throws CLRuntimeException; - public int getBuildStatus(CLDevice device) { - return getBuildInfoAny(device, CTYPE_INT, CL_PROGRAM_BUILD_STATUS); + return getInfoInt(device, CL_PROGRAM_BUILD_STATUS, clGetProgramBuildInfo); } public String getBuildOptions(CLDevice device) { - return fromInfoString(getBuildInfoAnyV(device, CTYPE_BYTE, CL_PROGRAM_BUILD_OPTIONS)); + return getInfoString(device, CL_PROGRAM_BUILD_OPTIONS, clGetProgramBuildInfo); } public String getBuildLog(CLDevice device) { - return fromInfoString(getBuildInfoAnyV(device, CTYPE_BYTE, CL_PROGRAM_BUILD_LOG)); + return getInfoString(device, CL_PROGRAM_BUILD_LOG, clGetProgramBuildInfo); } public int getBinaryType(CLDevice device) { - return getBuildInfoAny(device, CTYPE_INT, CL_PROGRAM_BINARY_TYPE); + return getInfoInt(device, CL_PROGRAM_BINARY_TYPE, clGetProgramBuildInfo); } - } diff --git a/src/notzed.zcl/classes/au/notzed/zcl/CLProperty.java b/src/notzed.zcl/classes/au/notzed/zcl/CLProperty.java index ef03c45..02e1906 100644 --- a/src/notzed.zcl/classes/au/notzed/zcl/CLProperty.java +++ b/src/notzed.zcl/classes/au/notzed/zcl/CLProperty.java @@ -16,12 +16,23 @@ */ package au.notzed.zcl; +import api.Native; + +import static au.notzed.zcl.CL.*; + +import api.Allocator; +import jdk.incubator.foreign.MemoryAddress; +import jdk.incubator.foreign.MemorySegment; +import java.util.function.BiFunction; +import java.util.function.IntFunction; +import java.util.ArrayList; + /** * All property arrays implement this interface. */ public interface CLProperty { - public abstract int getSize(); + int getSize(); /** * Encode this property as an integer array. @@ -30,7 +41,7 @@ public interface CLProperty { * @param o offset * @return updated o (o + getSize()) */ - public abstract int toInt(int dst[], int o); + int toInt(int dst[], int o); /** * Encode this property as a long array. @@ -39,7 +50,9 @@ public interface CLProperty { * @param o offset * @return updated o (o + getSize()) */ - public abstract int toLong(long dst[], int o); + int toLong(long dst[], int o); + + int toLong(MemoryAddress addr, int i); /** * A simple tag/value property type. @@ -73,6 +86,16 @@ public interface CLProperty { return o; } + public int toLong(MemoryAddress dst, int o) { + Native.setLong(dst, o++, tag); + Native.setLong(dst, o++, value); + return o; + } + + public String toString() { + return String.format("[%s: %08x=%08x]", + getClass().getName(), tag, value); + } } /** @@ -81,11 +104,11 @@ public interface CLProperty { * @param props * @return */ - static int getSize(Object[] props) { + static int getSize(T[] props) { int size = 0; - for (Object p : props) { - size += ((CLProperty) p).getSize(); - } + + for (CLProperty p : props) + size += p.getSize(); return size + 1; } @@ -96,6 +119,7 @@ public interface CLProperty { * @param props * @return */ + /* public static int[] toInt(Object[] props) { int[] dst = new int[getSize(props)]; int o = 0; @@ -109,13 +133,14 @@ public interface CLProperty { return dst; } - + */ /** * Convert to 64-bit intptr_t array. A terminating 0L is included. * * @param props * @return */ + /* public static long[] toLong(Object[] props) { long[] dst = new long[getSize(props)]; int o = 0; @@ -129,4 +154,57 @@ public interface CLProperty { return dst; } + */ + /* + public static Pointer toLong(T[] properties) { + if (properties != null && properties.length > 0) { + Pointer props = Pointer.alloc(getSize(properties), 8, Long.class); + int o = 0; + + for (CLProperty p : properties) + o = p.toLong(props, o); + props.set(o, 0L); + + return props; + } else { + return Pointer.NULL; + } + }*/ + + public static MemoryAddress toNative(Allocator frame, T[] properties) { + if (properties != null && properties.length > 0) { + MemoryAddress addr = frame.alloca(getSize(properties) * 8); + int i = 0; + + for (CLProperty p: properties) + i = p.toLong(addr, i); + Native.setLong(addr, i, 0L); + return addr; + } else { + MemoryAddress addr = frame.alloca(8); + Native.setLong(addr, 0L); + return addr; + + //return MemoryAddress.NULL; + } + } + + public static T[] fromNative(MemorySegment seg, BiFunction create, IntFunction createArray) { + MemoryAddress add = seg.baseAddress(); + ArrayList list = new ArrayList<>(); + long tag; + + for (int i = 0;(tag = Native.getLong(add, i++)) != 0;) { + // HACK: this needs some other mechanism, just hardcode each for now + if (tag == CL_DEVICE_PARTITION_BY_COUNTS) { + throw new UnsupportedOperationException(); + } else { + long value = Native.getLong(add, i++); + + list.add(create.apply(tag, value)); + } + } + + return list.toArray(createArray); + } } diff --git a/src/notzed.zcl/classes/au/notzed/zcl/CLRuntimeException.java b/src/notzed.zcl/classes/au/notzed/zcl/CLRuntimeException.java index 1a6a088..f3a54d2 100644 --- a/src/notzed.zcl/classes/au/notzed/zcl/CLRuntimeException.java +++ b/src/notzed.zcl/classes/au/notzed/zcl/CLRuntimeException.java @@ -1,46 +1,16 @@ -/* - * Copyright (C) 2014 Michael Zucchi - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package au.notzed.zcl; -import static au.notzed.zcl.CLException.codeToError; +package au.notzed.zcl; -/** - * An exception that is likely to occur from a more serious error such as out of - * memory. - */ public class CLRuntimeException extends RuntimeException { - - private final int id; - - /** - * - * @param id - */ - public CLRuntimeException(int id) { - this.id = id; + int err; + public CLRuntimeException() { } - - public int getID() { - return id; + public CLRuntimeException(int err) { + this.err = err; } @Override public String getMessage() { - return String.format("Error (%d): '%s'", id, codeToError(id)); + return "cl_error(" + err + ")"; } - } diff --git a/src/notzed.zcl/classes/au/notzed/zcl/CLSampler.java b/src/notzed.zcl/classes/au/notzed/zcl/CLSampler.java index 1133e15..cacbbb7 100644 --- a/src/notzed.zcl/classes/au/notzed/zcl/CLSampler.java +++ b/src/notzed.zcl/classes/au/notzed/zcl/CLSampler.java @@ -17,6 +17,10 @@ package au.notzed.zcl; import static au.notzed.zcl.CL.*; +import static au.notzed.zcl.CLLib.*; +import jdk.incubator.foreign.*; +import api.Native; +import java.lang.invoke.MethodHandle; /** * Interface for cl_sampler. @@ -28,19 +32,38 @@ public class CLSampler extends CLObject { * * @param p Native pointer. */ - public CLSampler(long p) { + public CLSampler(MemoryAddress p) { super(p); } - private native static void release(long p); - @Override - int getInfoType() { - return TYPE_SAMPLER; + MethodHandle getInfoFunc() { + return clGetSamplerInfo; + } + + private static void release(MemoryAddress p) { + try { + clReleaseSampler(p); + } catch (Throwable t) { + t.printStackTrace(); + } + } + + public static CLSamplerProperty NORMALIZED_COORDS(boolean enable) { + return new CLSamplerProperty.TagValue(CL_SAMPLER_NORMALIZED_COORDS, enable ? 1 : 0); } + public static CLSamplerProperty ADDRESSING_MODE(int mode) { + return new CLSamplerProperty.TagValue(CL_SAMPLER_ADDRESSING_MODE, mode); + } + + public static CLSamplerProperty FILTER_MODE(int mode) { + return new CLSamplerProperty.TagValue(CL_SAMPLER_FILTER_MODE, mode); + } + + public CLContext getContext() { - return getInfoAny(CTYPE_CONTEXT, CL_SAMPLER_CONTEXT); + return getInfoAny(CL_SAMPLER_CONTEXT, clGetSamplerInfo, CLContext::new); } public boolean getNormalisedCoords() { diff --git a/src/notzed.zcl/classes/au/notzed/zcl/khr/GLEvent.java b/src/notzed.zcl/classes/au/notzed/zcl/khr/GLEvent.java index ffa2599..449da72 100644 --- a/src/notzed.zcl/classes/au/notzed/zcl/khr/GLEvent.java +++ b/src/notzed.zcl/classes/au/notzed/zcl/khr/GLEvent.java @@ -20,12 +20,14 @@ import au.notzed.zcl.CLContext; import au.notzed.zcl.CLEvent; import au.notzed.zcl.CLExtension; +import jdk.incubator.foreign.MemoryAddress; + /** * cl_khr_gl_sharing extension interface. */ public class GLEvent extends CLExtension { - public GLEvent(long p) { + public GLEvent(MemoryAddress p) { super(p); } diff --git a/src/notzed.zcl/classes/au/notzed/zcl/khr/GLSharing.java b/src/notzed.zcl/classes/au/notzed/zcl/khr/GLSharing.java index 1bb988c..665d19b 100644 --- a/src/notzed.zcl/classes/au/notzed/zcl/khr/GLSharing.java +++ b/src/notzed.zcl/classes/au/notzed/zcl/khr/GLSharing.java @@ -28,12 +28,14 @@ import au.notzed.zcl.CLMemory; import au.notzed.zcl.CLObject; import au.notzed.zcl.CLRuntimeException; +import jdk.incubator.foreign.MemoryAddress; + /** * cl_khr_gl_sharing extension interface. */ public class GLSharing extends CLExtension { - public GLSharing(long p) { + public GLSharing(MemoryAddress p) { super(p); } diff --git a/src/notzed.zcl/classes/module-info.java b/src/notzed.zcl/classes/module-info.java index e83a880..67454d8 100644 --- a/src/notzed.zcl/classes/module-info.java +++ b/src/notzed.zcl/classes/module-info.java @@ -17,11 +17,8 @@ * along with this program. If not, see . */ module notzed.zcl { - requires java.logging; - requires notzed.nativez; - + requires jdk.incubator.foreign; + exports au.notzed.zcl; - exports au.notzed.zcl.khr; - - opens au.notzed.zcl to notzed.nativez; + //exports au.notzed.zcl.khr; } diff --git a/src/notzed.zcl/gen/export-defines b/src/notzed.zcl/gen/export-defines new file mode 100755 index 0000000..fbd92bc --- /dev/null +++ b/src/notzed.zcl/gen/export-defines @@ -0,0 +1,44 @@ +#!/usr/bin/perl + +# the gcc plugin can't get to defines, this extracts the opencl ones + +$ignore = qr/CL_VERSION_.*/; + +$src = shift; + +open (my $in,"<$src") || die ("Unable to open $src\n"); + +print <) { + next if (/$ignore/); + + my $line = $_; + + $line =~ s@/\*.*\*/@@; + + if ($line =~ m/^\#define\s+(\w*)\s+(.+)/) { + my $name = $1; + my $value = $2; + + if ($last =~ m@^/*\* (.*) \*/@) { + print "\t".$last; + } + + if ($line =~ m/deprecated/) { + print "\t\@Deprecated\n"; + } + print "\tpublic static final int $name = $value;\n"; + } + $last = $_; +} + +print < $@ || rm -f $@ + +$(addprefix $(notzed.zcl_genjavadir)/,$(notzed.zcl_generated)): $(generate_api) $(opencl_pm) + perl $(generate_api) \ + -d $(notzed.zcl_genjavadir) \ + -t au.notzed.zcl \ + -r _cl_platform_id=CLPlatform \ + -r _cl_device_id=CLDevice \ + -r _cl_context=CLContext \ + -r _cl_command_queue=CLCommandQueue \ + -r _cl_program=CLProgram \ + -r _cl_kernel=CLKernel \ + -r _cl_event=CLEvent \ + -r _cl_mem=CLMemory \ + -r _cl_sampler=CLSampler \ + -r _cl_image_desc=CLImageDesc \ + -r _cl_image_format=CLImageFormat \ + --raw-calls \ + -c CLLib -lOpenCL --func-file src/notzed.zcl/gen/opencl.txt \ + ./$(opencl_pm) diff --git a/src/notzed.zcl/gen/generate-api b/src/notzed.zcl/gen/generate-api new file mode 100755 index 0000000..ca3d95f --- /dev/null +++ b/src/notzed.zcl/gen/generate-api @@ -0,0 +1,1418 @@ +#!/usr/bin/perl + +# This is a massive fucking mess. +# It's got a lot of historical baggage and not all options will work. +# Will be cleaned up later, most of it isn't required. + +# replace a datatype with another, do not generate any code for it +# -r name=new + +@matchStruct = (); +$meta = ""; +# @classes = ( { name => 'class', match => [ func-pattern, ... ], match_file => [ file, ... ], enum => [ enum-pattern, ... ], enum_file => [ file, ...] } ) +@classes = (); +%class = (); +$output = "."; +# map call signatures to a class name +%callMap = (); +$package = ""; +# don't output types, replace their name +%replace = (); +# calls take raw types and throw Throwable +$rawCalls = 0; +# calls visited by all output types +%usedCalls = (); + +while (@ARGV) { + my $cmd = shift(@ARGV); + + if ($cmd eq "-f") { + my $v = shift(@ARGV); + push @{$class{match}}, qr/$v/; + } elsif ($cmd eq "--func-file") { + my $file = shift(@ARGV); + + push @{$class{match_file}}, $file; + push @{$class{match}}, readMatchFile($file); + } elsif ($cmd eq "-e") { + my $v = shift(@ARGV); + push @{$class{enum}}, qr/$v/; + } elsif ($cmd eq "--enum-file") { + my $file = shift(@ARGV); + push @{$class{enum_file}}, $file; + push @{$class{enum}}, readMatchFile($file); + } elsif ($cmd eq "-s") { + my $v = shift(@ARGV); + push @matchStruct, qr/$v/; + } elsif ($cmd eq "--struct-file") { + my $file = shift(@ARGV); + push @matchStruct, readMatchFile($file); + } elsif ($cmd eq "-r") { + my $v = shift(@ARGV); + + $v =~ m/(.*)=(.*)/; + $replace{$1} = $2; + } elsif ($cmd eq "--raw-calls") { + $rawCalls = 1; + } elsif ($cmd eq "-t") { + $package = shift(@ARGV); + } elsif ($cmd eq "-c") { + my %new = ( + name => shift(@ARGV), + match => [], + match_file => [], + enum => [], + enum_file => [], + libs => []); + push @classes, \%new; + %class = %new; + #print "new:\n".Dumper(\%class); + } elsif ($cmd =~ m/^-l(.*)/) { + push @{$class{libs}}, $1; + } elsif ($cmd eq "-d") { + $output = shift(@ARGV); + } elsif ($cmd eq "--enclosing-type") { + $enclosingType = shift(@ARGV); + } else { + $meta = $cmd; + } +} + +$importPointer = "import api.Native.Pointer;" if (!$rawCalls); + +use Data::Dumper; + +require $meta; + +# box types for primitives +%map_box = ( + "long" => "Long", + "int" => "Integer", + "short" => "Short", + "char" => "Character", + "float" => "Float", + "double" => "Double", + "byte" => "Byte", + "void" => "Void" + ); + +sub readMatchFile { + my $path = shift @_; + my @lines = (); + + open(my $f,"<$path"); + while (<$f>) { + chop; + next if m/^#/; + + #push @lines, qr/\^$_\$/; + push @lines, $_; + } + close($f); + + my $all = join ('|', @lines); + + return qr/^($all)$/; +} + +sub camelCase { + my $name = shift @_; + + $name =~ s/_(.)/uc($1)/eg; + + return $name; +} + +sub StudlyCaps { + my $name = shift @_; + + # hack, or good spot for it? + return $replace{$name} if $replace{$name}; + + $name =~ s/^(.)/uc($1)/e; + $name =~ s/_(.)/uc($1)/eg; + + return $name; +} + + +sub structSignature { + my %struct = %{shift(@_)}; + my $union = shift(@_); + my $sig = ""; + my @fields = @{$struct{fields}}; + my $offset = 0; + + my $inbf = 0; + my $bfoffset = 0; + my $bfstart = 0; + my $bfsig = ""; + + for $fi (@fields) { + my %field = %{$fi}; + my $off = $field{offset}; + + # bitfields, this only handles 1x u64 bitfield section + # They need to: align to u32/u64 + # Group fields into one full u32/u64 + # TODO: check alignment @ start? + # TODO: clean up and complete + # TODO: bitfields in unions are probably broken + if ($field{ctype} eq 'bitfield') { + if ($inbf) { + if ($off - $offset) { + $bfsig .= "x"; + $bfsig .= ($off - $offset); + } + $bfsig .= $field{type}; + $bfsig .= "($field{name})"; + $offset = $off + $field{size}; + } else { + $inbf = 1; + $bfsig = $field{type}; + $bfsig .= "($field{name})"; + $offset = $off + $field{size}; + $bfstart = $field{offset}; + } + + if ($union) { + $inbf = 0; + + if (($offset - $bfstart) == 32) { + $bfsig = "u32=[$bfsig]"; + } elsif (($offset - $bfstart) < 32) { + $bfsig .= "x"; + $bfsig .= 32 - ($offset - $bfstart); + $offset = $bfstart + 32; + $bfsig = "u32=[$bfsig]"; + } elsif (($offset - $bfstart) == 64) { + $bfsig = "u64=[$bfsig]"; + } elsif (($offset - $bfstart) < 64) { + $bfsig .= "x"; + $bfsig .= 64 - ($offset - $bfstart); + $offset = $bfstart + 64; + $bfsig = "u64=[$bfsig]"; + } + + $sig .= $bfsig; + $sig .= "|" if ($union && $fi != @fields[$#fields]); + } + next; + } elsif ($inbf) { + if (($offset - $bfstart) == 32) { + $bfsig = "u32=[$bfsig]"; + } elsif (($offset - $bfstart) < 32) { + $bfsig .= "x"; + $bfsig .= 32 - ($offset - $bfstart); + $offset = $bfstart + 32; + $bfsig = "u32=[$bfsig]"; + } elsif (($offset - $bfstart) == 64) { + $bfsig = "u64=[$bfsig]"; + } elsif (($offset - $bfstart) < 64) { + $bfsig .= "x"; + $bfsig .= 64 - ($offset - $bfstart); + $offset = $bfstart + 64; + $bfsig = "u64=[$bfsig]"; + } + $sig .= $bfsig; + $inbf = 0; + } + + # skip to next offset if necessary + if ($off > $offset) { + $sig .= "x"; + $sig .= ($off - $offset); + } + $offset = $off + $field{size}; + + # normal field processing + if ($field{deref}) { + my $deref = $field{deref}; + + # HACK: function -> Void + # if ($field{debug} eq 'function') { + # $sig .= "u64($field{name}):v"; + # } els + if ($deref =~ m/^(u\d\d)(:.*)/) { + $sig .= "$1($field{name})$2"; + } else { + $sig .= "$deref($field{name})"; + } + } else { + if ($field{type} =~ m/(struct|union):(.*)/) { + $sig .= "\${$2}"; + } elsif ($field{type} =~ m/([iuf])(\d+)/) { + $sig .= $1; + $sig .= $2; + } elsif ($field{type} eq 'void') { + $sig .= "v"; + } elsif ($field{type} eq 'enum') { + # FIXME: set type in compiler + $sig .= "u32"; + } + + $sig .= "($field{name})"; + } + + $sig .= "|" if ($union && $fi != @fields[$#fields]); + } + + # finish any trailing bitfield + # TODO: cleanup + if ($inbf) { + if (($offset - $bfstart) == 32) { + $bfsig = "u32=[$bfsig]"; + } elsif (($offset - $bfstart) < 32) { + $bfsig .= "x"; + $bfsig .= 32 - ($offset - $bfstart); + $offset = $bfstart + 32; + $bfsig = "u32=[$bfsig]"; + } elsif (($offset - $bfstart) == 64) { + $bfsig = "u64=[$bfsig]"; + } elsif (($offset - $bfstart) < 64) { + $bfsig .= "x"; + $bfsig .= 64 - ($offset - $bfstart); + $offset = $bfstart + 64; + $bfsig = "u64=[$bfsig]"; + } + #$bfsig .= "]"; + $sig .= $bfsig; + } + + return "[".$sig."]"; +} + +sub funcSignature { + my %func = %{shift(@_)}; + my $sig = ""; + my @params = @{$func{arguments}}; + + for $pi (@params) { + my %param = %{$pi}; + + if ($param{deref}) { + # HACK: function to void + if ($param{debug} eq "function") { + $sig .= "u64:v"; + } else { + $sig .= $param{deref}; + } + } else { + if ($param{type} =~ m/struct:(.*)/) { + $sig .= "\${$1}"; + } elsif ($param{type} =~ m/([iuf])(\d*)/) { + $sig .= $1; + $sig .= $2; + } elsif ($param{type} eq "void") { + $sig .= "v"; + } + } + } + + my %result = %{$func{result}}; + my $ret = ""; + + if ($result{deref}) { + $ret .= $result{deref}; + } else { + if ($result{type} =~ m/^struct:(.*)/) { + $ret .= "\${$1}"; + } elsif ($result{type} =~ m/^([iuf])(\d+)/) { + $ret .= $1; + $ret .= $2; + } elsif ($result{type} eq "void") { + $ret .= "v"; + } + } + + return "($sig)$ret"; +} + +sub deref { + my $type = shift @_; + my $ref = shift @_; + + while ($ref) { + if ($ref =~ m/\[\d*(.*)\]/) { + my $sub = deref($type, $1); + + return "Array<$sub>"; + } elsif ($ref =~ m/^u64:\$/) { + # ignore penultimate pointer? + last; + } elsif ($ref =~ m/^u64:(.*)/) { + $type = "Pointer<$type>"; + $ref = $1; + } else { + last; + } + } + return $type; +} + +sub typeToJava { + my %param = %{shift(@_)}; + my $type = $param{type}; + my $ref = $param{deref}; + + if ($type =~ m/^struct:(.*)/) { + $type = $replace{$1} ? $replace{$1} : StudlyCaps($1); + } elsif ($type =~ m/call:/) { + # this re-writes ref to remove one pointer-to as the Callback absorbs it. + $type = "Callback<".$callMap{$type}.">"; + $type || die ("No mapping for type ".Dumper(\%param)); + $ref =~ s/^u(32|64)://; + } elsif ($type =~ m/^enum:(.*)/) { + # TODO: other enum options + $type = "int"; + } elsif ($type eq "void") { + $type = "void"; + } elsif ($type =~ m/^([iu])(\d*)/) { + my $sign = $1; + my $size = $2; + + if ($size <= 8) { + $type = "byte"; + } elsif ($size <= 16) { + if ($sign eq "i") { + $type = "short"; + } else { + $type = "char"; + } + } elsif ($size <= 32) { + $type = "int"; + } else { + $type = "long"; + } + } elsif ($type =~ m/^[f](\d*)$/) { + my $size = $1; + + if ($size == 32) { + $type = "float"; + } elsif ($size == 64) { + $type = "double"; + } + } + + if ($ref) { + $type = $map_box{$type} if ($map_box{$type}); + $type = deref($type, $ref); + } + + return $type; +} + +sub typeToRaw { + my %param = %{shift(@_)}; + my $type = $param{type}; + my $ref = $param{deref}; + + my $type = typeToJava(\%param); + + if ($ref =~ m/^u64:/) { + return "MemoryAddress"; + } elsif ($type =~ m/^(struct|union):/) { + return "MemorySegment"; + } else { + return $type; + } + + # hackity hack +# if ($type =~ "(Pointer|Array|Callback)") { +# return "MemoryAddress"; +# } elsif ($type =~ m/^[A-Z]/) { +# return "MemorySegment"; +# } else { +# return $type; +# } +} + +sub testMatch { + my $name = shift @_; + + if (@_) { + for $pat (@_) { + if ($name =~ /$pat/) { + return 1; + } + } + return 0; + } else { + return 1; + } +} + +# find all matching structures and then all that they require +sub findStructs { + my %all = %{shift @_}; + my @match = @_; + my @stack = grep { + my %e = %{$all{$_}}; + $e{type} =~ m/(struct|union)/ && !$replace{$e{name}} && testMatch($e{name}, @match); + } keys %all; + my %visit = (); + + while (@stack) { + my $test = shift @stack; + + if (!$visit{$test}) { + my %struct = %{$all{$test}}; + + $visit{$test} = 1; + + if (%struct) { + print "class: $struct{name}\n"; + # find all types this one uses + for $f (@{$struct{fields}}) { + my %field = %{$f}; + + if ($field{type} =~ m/^(struct|union):(.*)/) { + if (!$replace{$1} && !$set{$field{type}}) { + $set{$field{type}} = $all{$field{type}}; + push @stack, $field{type}; + } + } + } + } else { + # this is an anon type, typically used for handles + $test =~ m/^(struct|union):(.*)/; + if (!$replace{$2}) { + print " anon: $2\n"; + my %rec = ( + type => 'struct', + name => $2, + size => 0 + ); + $data{$test} = \%rec; + } + } + } + } + return grep { !$replace{$_} } keys(%visit); +} + +sub findDefinition { + my %all = %{shift @_}; + my $type = shift @_; + my @match = @_; + my @stack = grep { + my %e = %{$all{$_}}; + $e{type} eq $type && testMatch($e{name}, @match); + } keys %all; + + return @stack; +} + +sub arrayInfo { + my $ref = shift @_; + my %info = ( + dims => [], + ); + + print "array $ref\n"; + while ($ref =~ m/^\[(\d*)(.*)\]$/) { + push @{$info{dims}}, $1; + $ref = $2; + print "dim $1 -, '$2'\n"; + } + $info{deref} = $ref; + + return %info; +} + +# ###################################################################### + +# setup section + +# find all classes used by functions +my %roots = (); +for $c (@classes) { + my %class = %{$c}; + my @libs = @{$class{libs}}; + my @match = @{$class{match}}; + + for $k (findDefinition(\%data, 'func', @match)) { + my %func = %{$data{$k}}; + my @params = @{$func{arguments}}; + + for $pi (@params) { + my %param = %{$pi}; + + if ($param{type} =~ m/^(struct|union):(.*)/) { + $roots{$2} = 1; + } + } + + my %result = %{$func{result}}; + + if ($result{type} =~ m/^(struct|union):(.*)/) { + $roots{$2} = 1; + } + } +} + +# add roots for any types used by calls +# FIXME: only include ones used elsewhere +for $k (grep { $_ =~ m/^call:/n } keys %data) { + my %func = %{$data{$k}}; + my @params = @{$func{arguments}}; + + for $pi (@params) { + my %param = %{$pi}; + + if ($param{type} =~ m/^(struct|union):(.*)/) { + $roots{$2} = 1; + } + } + + my %result = %{$func{result}}; + + if ($result{type} =~ m/^(struct|union):(.*)/) { + $roots{$2} = 1; + } +} + +# Create anonymous structs for anything missing +for $k (keys %roots) { + my $s = 'struct:'.$k; + my $u = 'union:'.$k; + + if (!$data{$u} && !$data{$s} && !$replace{$k}) { + print " xanon: $s\n"; + my %rec = ( + type => 'struct', + name => $k, + size => 0 + ); + $data{$s} = \%rec; + } +} + +$all = join ('|', keys %roots); +if ($all) { + push @matchStruct, qr/^($all)$/; +} +#print "structures:\n"; +#print Dumper(@matchStruct); + +# make a map for all callbacks (call: type) to generated names +for $c (grep { $_ =~ m/^call:/n } keys %data) { + my $name = $c; + + #print "$c\n"; + # enum maybe to int? + + $name =~ s/^call:/Call/; + if ($rawCalls) { + $name =~ s/\$\{([^\}]*)\}/L/g; + } else { + while ($name =~ m/\$\{([^\}]*)\}/) { + my $x = $1; + if ($replace{$x}) { + $x = $replace{$x}; + } else { + $x = StudlyCaps($x); + } + $name =~ s/\$\{([^\}]*)\}/L$x/; + } + } + $name =~ s/[ui](64|32):/p/g; + $name =~ s/[ui]64/J/g; + $name =~ s/[ui]32/I/g; + $name =~ s/[ui]8/B/g; + $name =~ s/f32/F/g; + $name =~ s/f64/D/g; + $name =~ s/[\[\]\(\)]/_/g; + + $callMap{$c} = "$name"; +} + +#print "call mappings\n"; +#print Dumper(\%callMap); + +# ###################################################################### +# Start output +my $dst; + +use File::Basename; +use File::Path qw(make_path); + +if ($package ne "") { + $packagePrefix = $package."."; +} + +if ($enclosingType) { + my $classname = $packagePrefix.$enclosingType; + + $classname =~ s@\.@/@g; + + my $path = $output."/".$classname.".java"; + my $dir = dirname($path); + my $class = basename($path, ".java"); + + print "path $path\n"; + print "dirname $dir\n"; + + make_path($dir); + open ($dst, ">$path"); + + if ($package ne "") { + print $dst "package $package;\n"; + } + + print $dst <$path"); + $classname =~ s@\.@/@g; + + my $path = $output."/".$classname.".java"; + my $dir = dirname($path); + my $class = basename($path, ".java"); + make_path($dir); + open ($dst, ">$path"); + + if ($package ne "") { + print $dst "package $package;\n"; + } + print $dst <> 3; + my $addr = $offset ? "addr().addOffset($offset)" : 'addr()'; + + my $size = %{$data{$field{type}}}{size} >> 3; + + print $dst "\tpublic $ltype get$cc() {\n"; + print $dst "\t\treturn $ltype.create(Native.getAddr($addr, $size));\n"; + print $dst "\t}\n"; + + print $dst "\tpublic void set$cc($ltype v) {\n"; + print $dst "\t\tNative.setAddr($addr, v.addr());\n"; + print $dst "\t}\n"; + } + } elsif ($field{deref} =~ m/^u64:u64:\$/) { + # pointer-to-pointer-to? + if ($field{type} =~ m/^(struct|union):(.*)/) { + my $ltype = StudlyCaps($2); + my $offset = $field{offset} >> 3; + my $addr = $offset ? "addr().addOffset($offset)" : 'addr()'; + + my $size = %{$data{$field{type}}}{size} >> 3; + + print $dst "\tpublic $type get$cc() {\n"; + print $dst "\t\treturn Native.Pointer.ofAddress($addr, $size, $ltype"."::new);\n"; + print $dst "\t}\n"; + + print $dst "\tpublic void set$cc($type v) {\n"; + print $dst "\t\tNative.setAddr($addr, v.addr());\n"; + print $dst "\t}\n"; + } + } elsif ($field{ctype} eq 'bitfield') { + my $alsr = $field{type} =~ m/^u/ ? '>>>' : '>>'; + my $lshift = $field{size} <= 32 ? 5 : 6; + my $lbits = 1 << $lshift; + my $type = $lbits == 32 ? 'int' : 'long'; + my $ltype = $lbits == 32 ? 'Int' : 'Long'; + + my $offset = ($field{offset} >> ($lshift)) * ($lbits / 8); + my $addr = $offset ? "addr().addOffset($offset)" : 'addr()'; + my $shift = $field{offset} & ($lbits-1); + my $width = $field{size}; + my $upshift = ($lbits-$width-$shift); + my $downshift = ($lbits-$width); + my $mask = sprintf("0x%x", ((1 << $width) - 1) << $shift); + + print $dst "\tpublic $type get$cc() {\n"; + print $dst "\t\treturn (($type)Native.get$ltype($addr)) << $upshift $alsr $downshift;\n"; + print $dst "\t}\n"; + + print $dst "\tpublic void set$cc($type v) {\n"; + print $dst "\t\tMemoryAddress addr = $addr;\n"; + print $dst "\t\tNative.set$ltype(addr, ((($type)Native.get$ltype(addr)) & ~$mask) | ((v << $shift) & $mask));\n"; + print $dst "\t}\n"; + } elsif ($field{type} =~ m/^(struct|union):/) { + # embedded struct + } elsif ($field{type} =~ m/^call:/) { + # call, function? + print $dst "// call? $type $cc\n"; + my $offset = $field{offset} >> 3; + my $addr = $offset ? "addr().addOffset($offset)" : 'addr()'; + my $ltype = $type; + + $type =~ s/Callback<(.*)>/$1/; + + print $dst "\tprivate Pointer<$type> $cc;\n"; + + print $dst "\tpublic void set$cc($type v) {\n"; + print $dst "\t\tif ($cc != null) $cc.close();\n"; + print $dst "\t\tNative.setAddr($addr, ($cc = $type.call(v)).addr());\n"; + print $dst "\t}\n"; + } else { + my $offset = $field{offset} >> 3; + my $addr = $offset ? "addr().addOffset($offset)" : 'addr()'; + my $ltype = $type; + + $ltype =~ s/^(.)/uc($1)/e; + + die("non-byte offset=$offset ".Dumper(\%field)) if ($field{offset} & 7); + + print $dst "\tpublic $type get$cc() {\n"; + print $dst "\t\treturn Native.get$ltype($addr);\n"; + print $dst "\t}\n"; + + print $dst "\tpublic void set$cc($type v) {\n"; + print $dst "\t\tNative.set$ltype($addr, v);\n"; + print $dst "\t}\n"; + } + } + + my $byteSize = $struct{size} >> 3; + print $dst "\tpublic static final long sizeof = $byteSize;\n"; + + # TODO: optional just call new() + print $dst "\tpublic static $name create(MemoryAddress p) {\n"; + print $dst "\t\treturn Native.resolve(p, $name"."::new);\n"; + print $dst "\t}\n"; + + print $dst "\tpublic static $name alloc() {\n"; + print $dst "\t\treturn $name.create(MemorySegment.allocateNative(sizeof).baseAddress());\n"; + print $dst "\t}\n"; + print $dst "\tpublic static Pointer<$name> alloc(int n) {\n"; + print $dst "\t\treturn Pointer.alloc(n, sizeof, $name"."::new);\n"; + print $dst "\t}\n"; + + if ($struct{type} eq "union") { + print $dst "\tpublic static MemoryLayout layout() { return Native.parseUnion(\"$signature\"); }\n"; + } else { + print $dst "\tpublic static MemoryLayout layout() { return Native.parseStruct(\"$signature\"); }\n"; + } + + print $dst "}\n"; + + if (!$enclosingType) { + close($dst); + } +} + +# ###################################################################### +# Dump classes for library linkage +for $c (@classes) { + my %class = %{$c}; + my @libs = @{$class{libs}}; + my @match = @{$class{match}}; + + if (!$enclosingType) { + my $classname = $packagePrefix.$class{name}; + + open ($dst, ">$path"); + $classname =~ s@\.@/@g; + + my $path = $output."/".$classname.".java"; + my $dir = dirname($path); + my $class = basename($path, ".java"); + make_path($dir); + open ($dst, ">$path"); + + if ($package ne "") { + print $dst "package $package;\n"; + } + print $dst < 32) + } + + print $dst "\n\t// enum $enum{name}\n"; + for $vi (@values) { + my %value = %{$vi}; + + if (!$visited{$value{label}}) { + #print $dst "\tpublic static final $type $value{label} = ($type)$value{value};\n"; + print $dst "\tpublic static final $type $value{label} = $value{value};\n"; + $visited{$value{label}} = 1; + } + } + } + + # find all 'call:' types used by any included function + for $k (sort(findDefinition(\%data, 'func', @match))) { + my %func = %{$data{$k}}; + my @params = @{$func{arguments}}; + my %res = %{$func{result}}; + + for $pi (@params) { + my %param = %{$pi}; + + if ($param{type} =~ m/^call:/) { + $usedCalls{$param{type}} = 1; + } + } + if ($result{type} =~ m/^call:/) { + $usedCalls{$result{type}} = 1; + } + } + + # function handles + #print "class $class{name} -> match:\n".Dumper(\@match); + + for $k (sort(findDefinition(\%data, 'func', @match))) { + my %func = %{$data{$k}}; + my @params = @{$func{arguments}}; + my $signature = funcSignature(\%func); + my $name = ($func{name}); + + print $dst "\tfinal static MethodHandle $name;\n"; + } + + # function handle init + print $dst "\tstatic {\n"; + print $dst "\t\tLibraryLookup[] libs = Native.loadLibraries(libraries);\n"; + + for $k (sort(findDefinition(\%data, 'func', @match))) { + my %func = %{$data{$k}}; + my @params = @{$func{arguments}}; + my $signature = funcSignature(\%func); + my $name = ($func{name}); + + print $dst "\t\t$name = Native.downcallHandle(libs, \"$name\", \"$signature\");\n"; + } + print $dst "\t}\n"; + + # function handle invocation + if ($rawCalls) { + for $k (sort(findDefinition(\%data, 'func', @match))) { + my %func = %{$data{$k}}; + my @params = @{$func{arguments}}; + my $signature = funcSignature(\%func); + my $name = ($func{name}); + my %res = %{$func{result}}; + my $result = typeToRaw(\%res); + + print $dst "\tpublic static $result $name("; + + for $pi (@params) { + my %param = %{$pi}; + my $type = typeToRaw($pi); + + print $dst "$type $param{name}"; + print $dst ", " if ($pi != $params[$#params]); + } + + print $dst ") throws Throwable {\n"; + if ($result ne "void") { + print $dst "return ($result)"; + } + print $dst "$name.invokeExact("; + for $pi (@params) { + my %param = %{$pi}; + + print $dst "$param{name}"; + print $dst ", " if ($pi != $params[$#params]); + } + print $dst ");\n"; + print $dst "\t}\n\n"; + } + print $dst "}\n"; + } else { + for $k (sort(findDefinition(\%data, 'func', @match))) { + my %func = %{$data{$k}}; + my @params = @{$func{arguments}}; + my $signature = funcSignature(\%func); + my $name = ($func{name}); + my %res = %{$func{result}}; + my $result = typeToJava(\%{$func{result}}); + + print $dst "\tpublic static $result $name("; + + for $pi (@params) { + my %param = %{$pi}; + my $type = typeToJava($pi); + + $type =~ s/Callback/Pointer/; + + # HACK + $type =~ s/Pointer/Pointer/; + + print $dst "$type $param{name}"; + print $dst ", " if ($pi != $params[$#params]); + } + + print $dst ") {\n"; + # see also call below + print $dst "\t\ttry {\n"; + print $dst "\t\t\t"; + if ($res{type} =~ m/(struct|union)/n) { + if ($res{deref}) { + print $dst "MemoryAddress add = (MemoryAddress)"; + } else { + print $dst "MemorySegment seg = (MemorySegment)"; + } + } elsif ($result ne "void") { + print $dst "return ($result)"; + } + print $dst "$name.invokeExact("; + for $pi (@params) { + my %param = %{$pi}; + + print $dst "$param{name}"; + if ($param{deref}) { + print $dst ".addr()"; + } elsif ($param{type} =~ m/^struct|union/) { + print $dst ".addr().segment()"; + } + print $dst ", " if ($pi != $params[$#params]); + } + print $dst ");\n"; + if ($res{type} =~ m/(struct|union)/n) { + if ($res{deref}) { + print $dst "\t\t\treturn $result.create(add);\n"; + } else { + print $dst "\t\t\treturn $result.create(seg.baseAddress());\n"; + } + } + print $dst "\t\t}\n"; + print $dst "\t\tcatch (Throwable t) { throw new RuntimeException(t); }\n"; + print $dst "\t}\n\n"; + } + + print $dst "}\n"; + } + + if (!$enclosingType) { + close($dst); + } +} + +# ###################################################################### +# Dump callbacks +# TODO: only those used by classes and functions that were exported +# TODO: yeah this is a total total fucking shitshow + +if ($rawCalls) { + for $c (grep { $usedCalls{$_} } keys %callMap) { + my %call = %{$data{$c}}; + my $name = $callMap{$c}; + my @params = @{$call{arguments}}; + my %res = %{$call{result}}; + my $result = typeToRaw(\%res); + my $signature = funcSignature(\%call); + + if (!$enclosingType) { + my $classname = $packagePrefix.$name; + + open ($dst, ">$path"); + $classname =~ s@\.@/@g; + + my $path = $output."/".$classname.".java"; + my $dir = dirname($path); + my $class = basename($path, ".java"); + make_path($dir); + open ($dst, ">$path"); + + if ($package ne "") { + print $dst "package $package;\n"; + } + print $dst < "; + if ($result ne "void") { + print $dst "($result)"; + } + print $dst "func.invokeExact("; + for $pi (@params) { + my %param = %{$pi}; + + print $dst "$param{name}"; + print $dst ", " if ($pi != $params[$#params]); + } + print $dst ");\n"; + print $dst "\t}\n"; + + # upcall ############################################################## + # ?? + + print $dst "\tstatic MemoryAddress stub($name call) {\n"; + print $dst "\t\treturn Native.upcallStub(MethodHandles.lookup(), call, \"$signature\");\n"; + print $dst "\t}\n"; + + # # the raw interface as expected by the native code + # my $rawresult = typeToRaw(\%res); + # print $dst "\tpublic interface $rawName {\n"; + # # fixme raw result + # print $dst "\t\tpublic $rawresult fn("; + + # for $pi (@params) { + # my %param = %{$pi}; + # my $type = typeToRaw($pi); + + # print $dst "$type $param{name}"; + # print $dst ", " if ($pi != $params[$#params]); + # } + + # print $dst ");\n"; + # print $dst "\t}\n"; + + # print $dst "\tstatic public Pointer<$name> call($name v) {\n"; + # print $dst "\t\t$rawName func = ("; + # for $pi (@params) { + # my %param = %{$pi}; + # my $type = typeToRaw($pi); + + # print $dst "$type $param{name}"; + # print $dst ", " if ($pi != $params[$#params]); + # } + # print $dst ") -> {\n"; + # print $dst "\t\t\t"; + # if ($rawresult ne "void") { + # print $dst "return "; + # } + # print $dst "v.fn("; + # for $pi (@params) { + # my %param = %{$pi}; + # my $type = typeToJava($pi); + # my $rawtype = typeToRaw($pi); + + # print "type ='$type'\n"; + # if ($type =~ m/^Pointer<[^>]*>$/) { + # print $dst "Pointer.ofAddress($param{name})"; + # } elsif ($type eq "Pointer>") { + # print $dst "Pointer.ofAddressP($param{name})"; + # } elsif ($rawtype eq "MemoryAddress") { + # print $dst "$type.create($param{name})"; + # } elsif ($rawtype eq "MemorySegment") { + # print $dst "$type.create($param{name}.baseAddress())"; + # } else { + # print $dst "$param{name}"; + # } + # print $dst ", " if ($pi != $params[$#params]); + # } + # print $dst ")"; + # if ($rawresult eq "MemoryAddress") { + # print $dst ".addr()"; + # } elsif ($rawresult eq "MemorySegment") { + # print $dst ".addr().segment()"; + # } + # print $dst ";\n"; + + # print $dst "\t\t};\n"; + # print $dst "\t\treturn Native.Pointer.ofCallback(MethodHandles.lookup(), v, func, \"$signature\");\n"; + # print $dst "\t}\n"; + + print $dst "}\n"; + + if (!$enclosingType) { + close($dst); + } + } +} else { + for $c (keys %callMap) { + my %call = %{$data{$c}}; + my $name = $callMap{$c}; + my @params = @{$call{arguments}}; + my %res = %{$call{result}}; + my $result = typeToJava(\%{$call{result}}); + my $signature = funcSignature(\%call); + + if (!$enclosingType) { + my $classname = $packagePrefix.$name; + + open ($dst, ">$path"); + $classname =~ s@\.@/@g; + + my $path = $output."/".$classname.".java"; + my $dir = dirname($path); + my $class = basename($path, ".java"); + make_path($dir); + open ($dst, ">$path"); + + if ($package ne "") { + print $dst "package $package;\n"; + } + print $dst < {\n"; + print $dst "\t\t\ttry {\n"; + print $dst "\t\t\t\t"; + if (!$res{deref} && $res{type} =~ m/(struct|union)/n) { + print $dst "MemorySegment seg = (MemorySegment)"; + } elsif ($result ne "void") { + print $dst "return ($result)"; + } + print $dst "func.invokeExact("; + for $pi (@params) { + my %param = %{$pi}; + + print $dst "$param{name}"; + if ($param{deref}) { + print $dst ".addr()"; + } elsif ($param{type} =~ m/^struct|union/) { + print $dst ".addr().segment()"; + } + print $dst ", " if ($pi != $params[$#params]); + } + print $dst ");\n"; + if (!$res{deref} && $res{type} =~ m/(struct|union)/n) { + print $dst "\t\t\t\treturn $result.create(seg.baseAddress());\n"; + } + print $dst "\t\t\t} catch (Throwable t) { throw new RuntimeException(t); }\n"; + print $dst "\t\t};\n"; + print $dst "\t}\n"; + + # upcall ############################################################## + # the raw interface as expected by the native code + my $rawName = $name.'Raw'; + my $rawresult = typeToRaw(\%res); + print $dst "\tpublic interface $rawName {\n"; + # fixme raw result + print $dst "\t\tpublic $rawresult fn("; + + for $pi (@params) { + my %param = %{$pi}; + my $type = typeToRaw($pi); + + print $dst "$type $param{name}"; + print $dst ", " if ($pi != $params[$#params]); + } + + print $dst ");\n"; + print $dst "\t}\n"; + + print $dst "\tstatic public Pointer<$name> call($name v) {\n"; + print $dst "\t\t$rawName func = ("; + for $pi (@params) { + my %param = %{$pi}; + my $type = typeToRaw($pi); + + print $dst "$type $param{name}"; + print $dst ", " if ($pi != $params[$#params]); + } + print $dst ") -> {\n"; + print $dst "\t\t\t"; + if ($rawresult ne "void") { + print $dst "return "; + } + print $dst "v.fn("; + for $pi (@params) { + my %param = %{$pi}; + my $type = typeToJava($pi); + my $rawtype = typeToRaw($pi); + + print "type ='$type'\n"; + if ($type =~ m/^Pointer<[^>]*>$/) { + print $dst "Pointer.ofAddress($param{name})"; + } elsif ($type eq "Pointer>") { + print $dst "Pointer.ofAddressP($param{name})"; + } elsif ($rawtype eq "MemoryAddress") { + print $dst "$type.create($param{name})"; + } elsif ($rawtype eq "MemorySegment") { + print $dst "$type.create($param{name}.baseAddress())"; + } else { + print $dst "$param{name}"; + } + print $dst ", " if ($pi != $params[$#params]); + } + print $dst ")"; + if ($rawresult eq "MemoryAddress") { + print $dst ".addr()"; + } elsif ($rawresult eq "MemorySegment") { + print $dst ".addr().segment()"; + } + print $dst ";\n"; + + print $dst "\t\t};\n"; + print $dst "\t\treturn Native.Pointer.ofCallback(MethodHandles.lookup(), v, func, \"$signature\");\n"; + print $dst "\t}\n"; + + print $dst "}\n"; + + if (!$enclosingType) { + close($dst); + } + } +} + +# Finish off +if ($enclosingType) { + print $dst "}\n"; + close($dst); +} diff --git a/src/notzed.zcl/gen/opencl.pm b/src/notzed.zcl/gen/opencl.pm new file mode 100644 index 0000000..2908010 --- /dev/null +++ b/src/notzed.zcl/gen/opencl.pm @@ -0,0 +1,2301 @@ + +# Note that this was generated by a gcc plugin +# it grabs a lot of junk that just gets ignored by the generator + +%data = ( +'func:__ctype_get_mb_cur_max' => { name => '__ctype_get_mb_cur_max', type => 'func', + result => { ctype => 'long unsigned int', type => 'u64', }, + arguments => [ +]}, +'func:atof' => { name => 'atof', type => 'func', + result => { ctype => 'double', type => 'f64', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:i8', ctype => 'char', type => 'i8',}, +]}, +'func:atoi' => { name => 'atoi', type => 'func', + result => { ctype => 'int', type => 'i32', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:i8', ctype => 'char', type => 'i8',}, +]}, +'func:atol' => { name => 'atol', type => 'func', + result => { ctype => 'long int', type => 'i64', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:i8', ctype => 'char', type => 'i8',}, +]}, +'func:atoll' => { name => 'atoll', type => 'func', + result => { ctype => 'long long int', type => 'i64', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:i8', ctype => 'char', type => 'i8',}, +]}, +'func:strtod' => { name => 'strtod', type => 'func', + result => { ctype => 'double', type => 'f64', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:i8', ctype => 'char', type => 'i8',}, + { size => 64, name => 'arg_1', deref => 'u64:u64:i8', ctype => 'char', type => 'i8',}, +]}, +'func:strtof' => { name => 'strtof', type => 'func', + result => { ctype => 'float', type => 'f32', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:i8', ctype => 'char', type => 'i8',}, + { size => 64, name => 'arg_1', deref => 'u64:u64:i8', ctype => 'char', type => 'i8',}, +]}, +'func:strtold' => { name => 'strtold', type => 'func', + result => { ctype => 'long double', type => 'f128', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:i8', ctype => 'char', type => 'i8',}, + { size => 64, name => 'arg_1', deref => 'u64:u64:i8', ctype => 'char', type => 'i8',}, +]}, +'func:strtol' => { name => 'strtol', type => 'func', + result => { ctype => 'long int', type => 'i64', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:i8', ctype => 'char', type => 'i8',}, + { size => 64, name => 'arg_1', deref => 'u64:u64:i8', ctype => 'char', type => 'i8',}, + { size => 32, name => 'arg_2', ctype => 'int', type => 'i32',}, +]}, +'func:strtoul' => { name => 'strtoul', type => 'func', + result => { ctype => 'long unsigned int', type => 'u64', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:i8', ctype => 'char', type => 'i8',}, + { size => 64, name => 'arg_1', deref => 'u64:u64:i8', ctype => 'char', type => 'i8',}, + { size => 32, name => 'arg_2', ctype => 'int', type => 'i32',}, +]}, +'func:strtoq' => { name => 'strtoq', type => 'func', + result => { ctype => 'long long int', type => 'i64', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:i8', ctype => 'char', type => 'i8',}, + { size => 64, name => 'arg_1', deref => 'u64:u64:i8', ctype => 'char', type => 'i8',}, + { size => 32, name => 'arg_2', ctype => 'int', type => 'i32',}, +]}, +'func:strtouq' => { name => 'strtouq', type => 'func', + result => { ctype => 'long long unsigned int', type => 'u64', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:i8', ctype => 'char', type => 'i8',}, + { size => 64, name => 'arg_1', deref => 'u64:u64:i8', ctype => 'char', type => 'i8',}, + { size => 32, name => 'arg_2', ctype => 'int', type => 'i32',}, +]}, +'func:strtoll' => { name => 'strtoll', type => 'func', + result => { ctype => 'long long int', type => 'i64', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:i8', ctype => 'char', type => 'i8',}, + { size => 64, name => 'arg_1', deref => 'u64:u64:i8', ctype => 'char', type => 'i8',}, + { size => 32, name => 'arg_2', ctype => 'int', type => 'i32',}, +]}, +'func:strtoull' => { name => 'strtoull', type => 'func', + result => { ctype => 'long long unsigned int', type => 'u64', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:i8', ctype => 'char', type => 'i8',}, + { size => 64, name => 'arg_1', deref => 'u64:u64:i8', ctype => 'char', type => 'i8',}, + { size => 32, name => 'arg_2', ctype => 'int', type => 'i32',}, +]}, +'func:l64a' => { name => 'l64a', type => 'func', + result => { deref => 'u64:i8', ctype => 'char', type => 'i8', }, + arguments => [ + { size => 64, name => 'arg_0', ctype => 'long int', type => 'i64',}, +]}, +'func:a64l' => { name => 'a64l', type => 'func', + result => { ctype => 'long int', type => 'i64', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:i8', ctype => 'char', type => 'i8',}, +]}, +'struct:timeval' => { name => 'timeval', type => 'struct', size => 128, fields => [ + { name => 'tv_sec', size => 64, offset => 0, ctype => 'long int', type => 'i64',}, + { name => 'tv_usec', size => 64, offset => 64, ctype => 'long int', type => 'i64',}, +]}, +'struct:timespec' => { name => 'timespec', type => 'struct', size => 128, fields => [ + { name => 'tv_sec', size => 64, offset => 0, ctype => 'long int', type => 'i64',}, + { name => 'tv_nsec', size => 64, offset => 64, ctype => 'long int', type => 'i64',}, +]}, +'func:select' => { name => 'select', type => 'func', + result => { ctype => 'int', type => 'i32', }, + arguments => [ + { size => 32, name => 'arg_0', ctype => 'int', type => 'i32',}, + { size => 64, name => 'arg_1', deref => 'u64:${fd_set}', type => 'struct:fd_set',}, + { size => 64, name => 'arg_2', deref => 'u64:${fd_set}', type => 'struct:fd_set',}, + { size => 64, name => 'arg_3', deref => 'u64:${fd_set}', type => 'struct:fd_set',}, + { size => 64, name => 'arg_4', deref => 'u64:${timeval}', type => 'struct:timeval',}, +]}, +'func:pselect' => { name => 'pselect', type => 'func', + result => { ctype => 'int', type => 'i32', }, + arguments => [ + { size => 32, name => 'arg_0', ctype => 'int', type => 'i32',}, + { size => 64, name => 'arg_1', deref => 'u64:${fd_set}', type => 'struct:fd_set',}, + { size => 64, name => 'arg_2', deref => 'u64:${fd_set}', type => 'struct:fd_set',}, + { size => 64, name => 'arg_3', deref => 'u64:${fd_set}', type => 'struct:fd_set',}, + { size => 64, name => 'arg_4', deref => 'u64:${timespec}', type => 'struct:timespec',}, + { size => 64, name => 'arg_5', deref => 'u64:${__sigset_t}', type => 'struct:__sigset_t',}, +]}, +'struct:__pthread_rwlock_arch_t' => { name => '__pthread_rwlock_arch_t', type => 'struct', size => 448, fields => [ + { name => '__readers', size => 32, offset => 0, ctype => 'unsigned int', type => 'u32',}, + { name => '__writers', size => 32, offset => 32, ctype => 'unsigned int', type => 'u32',}, + { name => '__wrphase_futex', size => 32, offset => 64, ctype => 'unsigned int', type => 'u32',}, + { name => '__writers_futex', size => 32, offset => 96, ctype => 'unsigned int', type => 'u32',}, + { name => '__pad3', size => 32, offset => 128, ctype => 'unsigned int', type => 'u32',}, + { name => '__pad4', size => 32, offset => 160, ctype => 'unsigned int', type => 'u32',}, + { name => '__cur_writer', size => 32, offset => 192, ctype => 'int', type => 'i32',}, + { name => '__shared', size => 32, offset => 224, ctype => 'int', type => 'i32',}, + { name => '__rwelision', size => 8, offset => 256, ctype => 'signed char', type => 'i8',}, + { name => '__pad1', size => 56, offset => 264, deref => '[7u8]', ctype => 'unsigned char', type => 'u8',}, + { name => '__pad2', size => 64, offset => 320, ctype => 'long unsigned int', type => 'u64',}, + { name => '__flags', size => 32, offset => 384, ctype => 'unsigned int', type => 'u32',}, +]}, +'struct:__pthread_internal_list' => { name => '__pthread_internal_list', type => 'struct', size => 128, fields => [ + { name => '__prev', size => 64, offset => 0, deref => 'u64:${__pthread_internal_list}', type => 'struct:__pthread_internal_list',}, + { name => '__next', size => 64, offset => 64, deref => 'u64:${__pthread_internal_list}', type => 'struct:__pthread_internal_list',}, +]}, +'struct:__pthread_mutex_s' => { name => '__pthread_mutex_s', type => 'struct', size => 320, fields => [ + { name => '__lock', size => 32, offset => 0, ctype => 'int', type => 'i32',}, + { name => '__count', size => 32, offset => 32, ctype => 'unsigned int', type => 'u32',}, + { name => '__owner', size => 32, offset => 64, ctype => 'int', type => 'i32',}, + { name => '__nusers', size => 32, offset => 96, ctype => 'unsigned int', type => 'u32',}, + { name => '__kind', size => 32, offset => 128, ctype => 'int', type => 'i32',}, + { name => '__spins', size => 16, offset => 160, ctype => 'short int', type => 'i16',}, + { name => '__elision', size => 16, offset => 176, ctype => 'short int', type => 'i16',}, + { name => '__list', size => 128, offset => 192, type => 'struct:__pthread_internal_list',}, +]}, +'struct:__pthread_cond_s' => { name => '__pthread_cond_s', type => 'struct', size => 384, fields => [ + { name => '__wseq', size => 64, offset => 0, ctype => 'long long unsigned int', type => 'u64',}, + { name => '__wseq32', size => 64, offset => 0, type => 'struct:__pthread_cond_s___wseq32',}, + { name => '__g1_start', size => 64, offset => 64, ctype => 'long long unsigned int', type => 'u64',}, + { name => '__g1_start32', size => 64, offset => 64, type => 'struct:__pthread_cond_s___g1_start32',}, + { name => '__g_refs', size => 64, offset => 128, deref => '[2u32]', ctype => 'unsigned int', type => 'u32',}, + { name => '__g_size', size => 64, offset => 192, deref => '[2u32]', ctype => 'unsigned int', type => 'u32',}, + { name => '__g1_orig_size', size => 32, offset => 256, ctype => 'unsigned int', type => 'u32',}, + { name => '__wrefs', size => 32, offset => 288, ctype => 'unsigned int', type => 'u32',}, + { name => '__g_signals', size => 64, offset => 320, deref => '[2u32]', ctype => 'unsigned int', type => 'u32',}, +]}, +'union:pthread_attr_t' => { name => 'pthread_attr_t', type => 'union', size => 448, fields => [ + { name => '__size', size => 448, offset => 0, deref => '[56i8]', ctype => 'char', type => 'i8',}, + { name => '__align', size => 64, offset => 0, ctype => 'long int', type => 'i64',}, +]}, +'func:random' => { name => 'random', type => 'func', + result => { ctype => 'long int', type => 'i64', }, + arguments => [ +]}, +'func:srandom' => { name => 'srandom', type => 'func', + result => { type => 'void', }, + arguments => [ + { size => 32, name => 'arg_0', ctype => 'unsigned int', type => 'u32',}, +]}, +'func:initstate' => { name => 'initstate', type => 'func', + result => { deref => 'u64:i8', ctype => 'char', type => 'i8', }, + arguments => [ + { size => 32, name => 'arg_0', ctype => 'unsigned int', type => 'u32',}, + { size => 64, name => 'arg_1', deref => 'u64:i8', ctype => 'char', type => 'i8',}, + { size => 64, name => 'arg_2', ctype => 'long unsigned int', type => 'u64',}, +]}, +'func:setstate' => { name => 'setstate', type => 'func', + result => { deref => 'u64:i8', ctype => 'char', type => 'i8', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:i8', ctype => 'char', type => 'i8',}, +]}, +'struct:random_data' => { name => 'random_data', type => 'struct', size => 384, fields => [ + { name => 'fptr', size => 64, offset => 0, deref => 'u64:i32', ctype => 'int', type => 'i32',}, + { name => 'rptr', size => 64, offset => 64, deref => 'u64:i32', ctype => 'int', type => 'i32',}, + { name => 'state', size => 64, offset => 128, deref => 'u64:i32', ctype => 'int', type => 'i32',}, + { name => 'rand_type', size => 32, offset => 192, ctype => 'int', type => 'i32',}, + { name => 'rand_deg', size => 32, offset => 224, ctype => 'int', type => 'i32',}, + { name => 'rand_sep', size => 32, offset => 256, ctype => 'int', type => 'i32',}, + { name => 'end_ptr', size => 64, offset => 320, deref => 'u64:i32', ctype => 'int', type => 'i32',}, +]}, +'func:random_r' => { name => 'random_r', type => 'func', + result => { ctype => 'int', type => 'i32', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:${random_data}', type => 'struct:random_data',}, + { size => 64, name => 'arg_1', deref => 'u64:i32', ctype => 'int', type => 'i32',}, +]}, +'func:srandom_r' => { name => 'srandom_r', type => 'func', + result => { ctype => 'int', type => 'i32', }, + arguments => [ + { size => 32, name => 'arg_0', ctype => 'unsigned int', type => 'u32',}, + { size => 64, name => 'arg_1', deref => 'u64:${random_data}', type => 'struct:random_data',}, +]}, +'func:initstate_r' => { name => 'initstate_r', type => 'func', + result => { ctype => 'int', type => 'i32', }, + arguments => [ + { size => 32, name => 'arg_0', ctype => 'unsigned int', type => 'u32',}, + { size => 64, name => 'arg_1', deref => 'u64:i8', ctype => 'char', type => 'i8',}, + { size => 64, name => 'arg_2', ctype => 'long unsigned int', type => 'u64',}, + { size => 64, name => 'arg_3', deref => 'u64:${random_data}', type => 'struct:random_data',}, +]}, +'func:setstate_r' => { name => 'setstate_r', type => 'func', + result => { ctype => 'int', type => 'i32', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:i8', ctype => 'char', type => 'i8',}, + { size => 64, name => 'arg_1', deref => 'u64:${random_data}', type => 'struct:random_data',}, +]}, +'func:rand' => { name => 'rand', type => 'func', + result => { ctype => 'int', type => 'i32', }, + arguments => [ +]}, +'func:srand' => { name => 'srand', type => 'func', + result => { type => 'void', }, + arguments => [ + { size => 32, name => 'arg_0', ctype => 'unsigned int', type => 'u32',}, +]}, +'func:rand_r' => { name => 'rand_r', type => 'func', + result => { ctype => 'int', type => 'i32', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:u32', ctype => 'unsigned int', type => 'u32',}, +]}, +'func:drand48' => { name => 'drand48', type => 'func', + result => { ctype => 'double', type => 'f64', }, + arguments => [ +]}, +'func:erand48' => { name => 'erand48', type => 'func', + result => { ctype => 'double', type => 'f64', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:u16', ctype => 'short unsigned int', type => 'u16',}, +]}, +'func:lrand48' => { name => 'lrand48', type => 'func', + result => { ctype => 'long int', type => 'i64', }, + arguments => [ +]}, +'func:nrand48' => { name => 'nrand48', type => 'func', + result => { ctype => 'long int', type => 'i64', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:u16', ctype => 'short unsigned int', type => 'u16',}, +]}, +'func:mrand48' => { name => 'mrand48', type => 'func', + result => { ctype => 'long int', type => 'i64', }, + arguments => [ +]}, +'func:jrand48' => { name => 'jrand48', type => 'func', + result => { ctype => 'long int', type => 'i64', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:u16', ctype => 'short unsigned int', type => 'u16',}, +]}, +'func:srand48' => { name => 'srand48', type => 'func', + result => { type => 'void', }, + arguments => [ + { size => 64, name => 'arg_0', ctype => 'long int', type => 'i64',}, +]}, +'func:seed48' => { name => 'seed48', type => 'func', + result => { deref => 'u64:u16', ctype => 'short unsigned int', type => 'u16', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:u16', ctype => 'short unsigned int', type => 'u16',}, +]}, +'func:lcong48' => { name => 'lcong48', type => 'func', + result => { type => 'void', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:u16', ctype => 'short unsigned int', type => 'u16',}, +]}, +'struct:drand48_data' => { name => 'drand48_data', type => 'struct', size => 192, fields => [ + { name => '__x', size => 48, offset => 0, deref => '[3u16]', ctype => 'short unsigned int', type => 'u16',}, + { name => '__old_x', size => 48, offset => 48, deref => '[3u16]', ctype => 'short unsigned int', type => 'u16',}, + { name => '__c', size => 16, offset => 96, ctype => 'short unsigned int', type => 'u16',}, + { name => '__init', size => 16, offset => 112, ctype => 'short unsigned int', type => 'u16',}, + { name => '__a', size => 64, offset => 128, ctype => 'long long unsigned int', type => 'u64',}, +]}, +'func:drand48_r' => { name => 'drand48_r', type => 'func', + result => { ctype => 'int', type => 'i32', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:${drand48_data}', type => 'struct:drand48_data',}, + { size => 64, name => 'arg_1', deref => 'u64:f64', ctype => 'double', type => 'f64',}, +]}, +'func:erand48_r' => { name => 'erand48_r', type => 'func', + result => { ctype => 'int', type => 'i32', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:u16', ctype => 'short unsigned int', type => 'u16',}, + { size => 64, name => 'arg_1', deref => 'u64:${drand48_data}', type => 'struct:drand48_data',}, + { size => 64, name => 'arg_2', deref => 'u64:f64', ctype => 'double', type => 'f64',}, +]}, +'func:lrand48_r' => { name => 'lrand48_r', type => 'func', + result => { ctype => 'int', type => 'i32', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:${drand48_data}', type => 'struct:drand48_data',}, + { size => 64, name => 'arg_1', deref => 'u64:i64', ctype => 'long int', type => 'i64',}, +]}, +'func:nrand48_r' => { name => 'nrand48_r', type => 'func', + result => { ctype => 'int', type => 'i32', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:u16', ctype => 'short unsigned int', type => 'u16',}, + { size => 64, name => 'arg_1', deref => 'u64:${drand48_data}', type => 'struct:drand48_data',}, + { size => 64, name => 'arg_2', deref => 'u64:i64', ctype => 'long int', type => 'i64',}, +]}, +'func:mrand48_r' => { name => 'mrand48_r', type => 'func', + result => { ctype => 'int', type => 'i32', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:${drand48_data}', type => 'struct:drand48_data',}, + { size => 64, name => 'arg_1', deref => 'u64:i64', ctype => 'long int', type => 'i64',}, +]}, +'func:jrand48_r' => { name => 'jrand48_r', type => 'func', + result => { ctype => 'int', type => 'i32', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:u16', ctype => 'short unsigned int', type => 'u16',}, + { size => 64, name => 'arg_1', deref => 'u64:${drand48_data}', type => 'struct:drand48_data',}, + { size => 64, name => 'arg_2', deref => 'u64:i64', ctype => 'long int', type => 'i64',}, +]}, +'func:srand48_r' => { name => 'srand48_r', type => 'func', + result => { ctype => 'int', type => 'i32', }, + arguments => [ + { size => 64, name => 'arg_0', ctype => 'long int', type => 'i64',}, + { size => 64, name => 'arg_1', deref => 'u64:${drand48_data}', type => 'struct:drand48_data',}, +]}, +'func:seed48_r' => { name => 'seed48_r', type => 'func', + result => { ctype => 'int', type => 'i32', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:u16', ctype => 'short unsigned int', type => 'u16',}, + { size => 64, name => 'arg_1', deref => 'u64:${drand48_data}', type => 'struct:drand48_data',}, +]}, +'func:lcong48_r' => { name => 'lcong48_r', type => 'func', + result => { ctype => 'int', type => 'i32', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:u16', ctype => 'short unsigned int', type => 'u16',}, + { size => 64, name => 'arg_1', deref => 'u64:${drand48_data}', type => 'struct:drand48_data',}, +]}, +'func:malloc' => { name => 'malloc', type => 'func', + result => { deref => 'u64:v', type => 'void', }, + arguments => [ + { size => 64, name => 'arg_0', ctype => 'long unsigned int', type => 'u64',}, +]}, +'func:calloc' => { name => 'calloc', type => 'func', + result => { deref => 'u64:v', type => 'void', }, + arguments => [ + { size => 64, name => 'arg_0', ctype => 'long unsigned int', type => 'u64',}, + { size => 64, name => 'arg_1', ctype => 'long unsigned int', type => 'u64',}, +]}, +'func:realloc' => { name => 'realloc', type => 'func', + result => { deref => 'u64:v', type => 'void', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:v', type => 'void',}, + { size => 64, name => 'arg_1', ctype => 'long unsigned int', type => 'u64',}, +]}, +'func:reallocarray' => { name => 'reallocarray', type => 'func', + result => { deref => 'u64:v', type => 'void', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:v', type => 'void',}, + { size => 64, name => 'arg_1', ctype => 'long unsigned int', type => 'u64',}, + { size => 64, name => 'arg_2', ctype => 'long unsigned int', type => 'u64',}, +]}, +'func:free' => { name => 'free', type => 'func', + result => { type => 'void', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:v', type => 'void',}, +]}, +'func:alloca' => { name => 'alloca', type => 'func', + result => { deref => 'u64:v', type => 'void', }, + arguments => [ + { size => 64, name => 'arg_0', ctype => 'long unsigned int', type => 'u64',}, +]}, +'func:valloc' => { name => 'valloc', type => 'func', + result => { deref => 'u64:v', type => 'void', }, + arguments => [ + { size => 64, name => 'arg_0', ctype => 'long unsigned int', type => 'u64',}, +]}, +'func:posix_memalign' => { name => 'posix_memalign', type => 'func', + result => { ctype => 'int', type => 'i32', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:u64:v', type => 'void',}, + { size => 64, name => 'arg_1', ctype => 'long unsigned int', type => 'u64',}, + { size => 64, name => 'arg_2', ctype => 'long unsigned int', type => 'u64',}, +]}, +'func:aligned_alloc' => { name => 'aligned_alloc', type => 'func', + result => { deref => 'u64:v', type => 'void', }, + arguments => [ + { size => 64, name => 'arg_0', ctype => 'long unsigned int', type => 'u64',}, + { size => 64, name => 'arg_1', ctype => 'long unsigned int', type => 'u64',}, +]}, +'func:abort' => { name => 'abort', type => 'func', + result => { type => 'void', }, + arguments => [ +]}, +'func:atexit' => { name => 'atexit', type => 'func', + result => { ctype => 'int', type => 'i32', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:()v', type => 'call:()v', }, +]}, +'func:at_quick_exit' => { name => 'at_quick_exit', type => 'func', + result => { ctype => 'int', type => 'i32', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:()v', type => 'call:()v', }, +]}, +'func:on_exit' => { name => 'on_exit', type => 'func', + result => { ctype => 'int', type => 'i32', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:(i32u64:v)v', type => 'call:(i32u64:v)v', }, + { size => 64, name => 'arg_1', deref => 'u64:v', type => 'void',}, +]}, +'func:exit' => { name => 'exit', type => 'func', + result => { type => 'void', }, + arguments => [ + { size => 32, name => 'arg_0', ctype => 'int', type => 'i32',}, +]}, +'func:quick_exit' => { name => 'quick_exit', type => 'func', + result => { type => 'void', }, + arguments => [ + { size => 32, name => 'arg_0', ctype => 'int', type => 'i32',}, +]}, +'func:_Exit' => { name => '_Exit', type => 'func', + result => { type => 'void', }, + arguments => [ + { size => 32, name => 'arg_0', ctype => 'int', type => 'i32',}, +]}, +'func:getenv' => { name => 'getenv', type => 'func', + result => { deref => 'u64:i8', ctype => 'char', type => 'i8', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:i8', ctype => 'char', type => 'i8',}, +]}, +'func:putenv' => { name => 'putenv', type => 'func', + result => { ctype => 'int', type => 'i32', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:i8', ctype => 'char', type => 'i8',}, +]}, +'func:setenv' => { name => 'setenv', type => 'func', + result => { ctype => 'int', type => 'i32', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:i8', ctype => 'char', type => 'i8',}, + { size => 64, name => 'arg_1', deref => 'u64:i8', ctype => 'char', type => 'i8',}, + { size => 32, name => 'arg_2', ctype => 'int', type => 'i32',}, +]}, +'func:unsetenv' => { name => 'unsetenv', type => 'func', + result => { ctype => 'int', type => 'i32', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:i8', ctype => 'char', type => 'i8',}, +]}, +'func:clearenv' => { name => 'clearenv', type => 'func', + result => { ctype => 'int', type => 'i32', }, + arguments => [ +]}, +'func:mktemp' => { name => 'mktemp', type => 'func', + result => { deref => 'u64:i8', ctype => 'char', type => 'i8', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:i8', ctype => 'char', type => 'i8',}, +]}, +'func:mkstemp' => { name => 'mkstemp', type => 'func', + result => { ctype => 'int', type => 'i32', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:i8', ctype => 'char', type => 'i8',}, +]}, +'func:mkstemps' => { name => 'mkstemps', type => 'func', + result => { ctype => 'int', type => 'i32', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:i8', ctype => 'char', type => 'i8',}, + { size => 32, name => 'arg_1', ctype => 'int', type => 'i32',}, +]}, +'func:mkdtemp' => { name => 'mkdtemp', type => 'func', + result => { deref => 'u64:i8', ctype => 'char', type => 'i8', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:i8', ctype => 'char', type => 'i8',}, +]}, +'func:system' => { name => 'system', type => 'func', + result => { ctype => 'int', type => 'i32', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:i8', ctype => 'char', type => 'i8',}, +]}, +'func:realpath' => { name => 'realpath', type => 'func', + result => { deref => 'u64:i8', ctype => 'char', type => 'i8', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:i8', ctype => 'char', type => 'i8',}, + { size => 64, name => 'arg_1', deref => 'u64:i8', ctype => 'char', type => 'i8',}, +]}, +'call:__compar_fn_t' => { name => '__compar_fn_t', deref => 'u64:(u64:vu64:v)i32', + result => { ctype => 'int', type => 'i32', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:v', type => 'void',}, + { size => 64, name => 'arg_1', deref => 'u64:v', type => 'void',}, +]}, +'func:bsearch' => { name => 'bsearch', type => 'func', + result => { deref => 'u64:v', type => 'void', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:v', type => 'void',}, + { size => 64, name => 'arg_1', deref => 'u64:v', type => 'void',}, + { size => 64, name => 'arg_2', ctype => 'long unsigned int', type => 'u64',}, + { size => 64, name => 'arg_3', ctype => 'long unsigned int', type => 'u64',}, + { size => 64, name => 'arg_4', deref => 'u64:(u64:vu64:v)i32', type => 'call:(u64:vu64:v)i32', }, +]}, +'func:qsort' => { name => 'qsort', type => 'func', + result => { type => 'void', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:v', type => 'void',}, + { size => 64, name => 'arg_1', ctype => 'long unsigned int', type => 'u64',}, + { size => 64, name => 'arg_2', ctype => 'long unsigned int', type => 'u64',}, + { size => 64, name => 'arg_3', deref => 'u64:(u64:vu64:v)i32', type => 'call:(u64:vu64:v)i32', }, +]}, +'func:abs' => { name => 'abs', type => 'func', + result => { ctype => 'int', type => 'i32', }, + arguments => [ + { size => 32, name => 'arg_0', ctype => 'int', type => 'i32',}, +]}, +'func:labs' => { name => 'labs', type => 'func', + result => { ctype => 'long int', type => 'i64', }, + arguments => [ + { size => 64, name => 'arg_0', ctype => 'long int', type => 'i64',}, +]}, +'func:llabs' => { name => 'llabs', type => 'func', + result => { ctype => 'long long int', type => 'i64', }, + arguments => [ + { size => 64, name => 'arg_0', ctype => 'long long int', type => 'i64',}, +]}, +'func:div' => { name => 'div', type => 'func', + result => { type => 'struct:div_t', }, + arguments => [ + { size => 32, name => 'arg_0', ctype => 'int', type => 'i32',}, + { size => 32, name => 'arg_1', ctype => 'int', type => 'i32',}, +]}, +'func:ldiv' => { name => 'ldiv', type => 'func', + result => { type => 'struct:ldiv_t', }, + arguments => [ + { size => 64, name => 'arg_0', ctype => 'long int', type => 'i64',}, + { size => 64, name => 'arg_1', ctype => 'long int', type => 'i64',}, +]}, +'func:lldiv' => { name => 'lldiv', type => 'func', + result => { type => 'struct:lldiv_t', }, + arguments => [ + { size => 64, name => 'arg_0', ctype => 'long long int', type => 'i64',}, + { size => 64, name => 'arg_1', ctype => 'long long int', type => 'i64',}, +]}, +'func:ecvt' => { name => 'ecvt', type => 'func', + result => { deref => 'u64:i8', ctype => 'char', type => 'i8', }, + arguments => [ + { size => 64, name => 'arg_0', ctype => 'double', type => 'f64',}, + { size => 32, name => 'arg_1', ctype => 'int', type => 'i32',}, + { size => 64, name => 'arg_2', deref => 'u64:i32', ctype => 'int', type => 'i32',}, + { size => 64, name => 'arg_3', deref => 'u64:i32', ctype => 'int', type => 'i32',}, +]}, +'func:fcvt' => { name => 'fcvt', type => 'func', + result => { deref => 'u64:i8', ctype => 'char', type => 'i8', }, + arguments => [ + { size => 64, name => 'arg_0', ctype => 'double', type => 'f64',}, + { size => 32, name => 'arg_1', ctype => 'int', type => 'i32',}, + { size => 64, name => 'arg_2', deref => 'u64:i32', ctype => 'int', type => 'i32',}, + { size => 64, name => 'arg_3', deref => 'u64:i32', ctype => 'int', type => 'i32',}, +]}, +'func:gcvt' => { name => 'gcvt', type => 'func', + result => { deref => 'u64:i8', ctype => 'char', type => 'i8', }, + arguments => [ + { size => 64, name => 'arg_0', ctype => 'double', type => 'f64',}, + { size => 32, name => 'arg_1', ctype => 'int', type => 'i32',}, + { size => 64, name => 'arg_2', deref => 'u64:i8', ctype => 'char', type => 'i8',}, +]}, +'func:qecvt' => { name => 'qecvt', type => 'func', + result => { deref => 'u64:i8', ctype => 'char', type => 'i8', }, + arguments => [ + { size => 128, name => 'arg_0', ctype => 'long double', type => 'f128',}, + { size => 32, name => 'arg_1', ctype => 'int', type => 'i32',}, + { size => 64, name => 'arg_2', deref => 'u64:i32', ctype => 'int', type => 'i32',}, + { size => 64, name => 'arg_3', deref => 'u64:i32', ctype => 'int', type => 'i32',}, +]}, +'func:qfcvt' => { name => 'qfcvt', type => 'func', + result => { deref => 'u64:i8', ctype => 'char', type => 'i8', }, + arguments => [ + { size => 128, name => 'arg_0', ctype => 'long double', type => 'f128',}, + { size => 32, name => 'arg_1', ctype => 'int', type => 'i32',}, + { size => 64, name => 'arg_2', deref => 'u64:i32', ctype => 'int', type => 'i32',}, + { size => 64, name => 'arg_3', deref => 'u64:i32', ctype => 'int', type => 'i32',}, +]}, +'func:qgcvt' => { name => 'qgcvt', type => 'func', + result => { deref => 'u64:i8', ctype => 'char', type => 'i8', }, + arguments => [ + { size => 128, name => 'arg_0', ctype => 'long double', type => 'f128',}, + { size => 32, name => 'arg_1', ctype => 'int', type => 'i32',}, + { size => 64, name => 'arg_2', deref => 'u64:i8', ctype => 'char', type => 'i8',}, +]}, +'func:ecvt_r' => { name => 'ecvt_r', type => 'func', + result => { ctype => 'int', type => 'i32', }, + arguments => [ + { size => 64, name => 'arg_0', ctype => 'double', type => 'f64',}, + { size => 32, name => 'arg_1', ctype => 'int', type => 'i32',}, + { size => 64, name => 'arg_2', deref => 'u64:i32', ctype => 'int', type => 'i32',}, + { size => 64, name => 'arg_3', deref => 'u64:i32', ctype => 'int', type => 'i32',}, + { size => 64, name => 'arg_4', deref => 'u64:i8', ctype => 'char', type => 'i8',}, + { size => 64, name => 'arg_5', ctype => 'long unsigned int', type => 'u64',}, +]}, +'func:fcvt_r' => { name => 'fcvt_r', type => 'func', + result => { ctype => 'int', type => 'i32', }, + arguments => [ + { size => 64, name => 'arg_0', ctype => 'double', type => 'f64',}, + { size => 32, name => 'arg_1', ctype => 'int', type => 'i32',}, + { size => 64, name => 'arg_2', deref => 'u64:i32', ctype => 'int', type => 'i32',}, + { size => 64, name => 'arg_3', deref => 'u64:i32', ctype => 'int', type => 'i32',}, + { size => 64, name => 'arg_4', deref => 'u64:i8', ctype => 'char', type => 'i8',}, + { size => 64, name => 'arg_5', ctype => 'long unsigned int', type => 'u64',}, +]}, +'func:qecvt_r' => { name => 'qecvt_r', type => 'func', + result => { ctype => 'int', type => 'i32', }, + arguments => [ + { size => 128, name => 'arg_0', ctype => 'long double', type => 'f128',}, + { size => 32, name => 'arg_1', ctype => 'int', type => 'i32',}, + { size => 64, name => 'arg_2', deref => 'u64:i32', ctype => 'int', type => 'i32',}, + { size => 64, name => 'arg_3', deref => 'u64:i32', ctype => 'int', type => 'i32',}, + { size => 64, name => 'arg_4', deref => 'u64:i8', ctype => 'char', type => 'i8',}, + { size => 64, name => 'arg_5', ctype => 'long unsigned int', type => 'u64',}, +]}, +'func:qfcvt_r' => { name => 'qfcvt_r', type => 'func', + result => { ctype => 'int', type => 'i32', }, + arguments => [ + { size => 128, name => 'arg_0', ctype => 'long double', type => 'f128',}, + { size => 32, name => 'arg_1', ctype => 'int', type => 'i32',}, + { size => 64, name => 'arg_2', deref => 'u64:i32', ctype => 'int', type => 'i32',}, + { size => 64, name => 'arg_3', deref => 'u64:i32', ctype => 'int', type => 'i32',}, + { size => 64, name => 'arg_4', deref => 'u64:i8', ctype => 'char', type => 'i8',}, + { size => 64, name => 'arg_5', ctype => 'long unsigned int', type => 'u64',}, +]}, +'func:mblen' => { name => 'mblen', type => 'func', + result => { ctype => 'int', type => 'i32', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:i8', ctype => 'char', type => 'i8',}, + { size => 64, name => 'arg_1', ctype => 'long unsigned int', type => 'u64',}, +]}, +'func:mbtowc' => { name => 'mbtowc', type => 'func', + result => { ctype => 'int', type => 'i32', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:i32', ctype => 'int', type => 'i32',}, + { size => 64, name => 'arg_1', deref => 'u64:i8', ctype => 'char', type => 'i8',}, + { size => 64, name => 'arg_2', ctype => 'long unsigned int', type => 'u64',}, +]}, +'func:wctomb' => { name => 'wctomb', type => 'func', + result => { ctype => 'int', type => 'i32', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:i8', ctype => 'char', type => 'i8',}, + { size => 32, name => 'arg_1', ctype => 'int', type => 'i32',}, +]}, +'func:mbstowcs' => { name => 'mbstowcs', type => 'func', + result => { ctype => 'long unsigned int', type => 'u64', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:i32', ctype => 'int', type => 'i32',}, + { size => 64, name => 'arg_1', deref => 'u64:i8', ctype => 'char', type => 'i8',}, + { size => 64, name => 'arg_2', ctype => 'long unsigned int', type => 'u64',}, +]}, +'func:wcstombs' => { name => 'wcstombs', type => 'func', + result => { ctype => 'long unsigned int', type => 'u64', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:i8', ctype => 'char', type => 'i8',}, + { size => 64, name => 'arg_1', deref => 'u64:i32', ctype => 'int', type => 'i32',}, + { size => 64, name => 'arg_2', ctype => 'long unsigned int', type => 'u64',}, +]}, +'func:rpmatch' => { name => 'rpmatch', type => 'func', + result => { ctype => 'int', type => 'i32', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:i8', ctype => 'char', type => 'i8',}, +]}, +'func:getsubopt' => { name => 'getsubopt', type => 'func', + result => { ctype => 'int', type => 'i32', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:u64:i8', ctype => 'char', type => 'i8',}, + { size => 64, name => 'arg_1', deref => 'u64:u64:i8', ctype => 'char', type => 'i8',}, + { size => 64, name => 'arg_2', deref => 'u64:u64:i8', ctype => 'char', type => 'i8',}, +]}, +'func:getloadavg' => { name => 'getloadavg', type => 'func', + result => { ctype => 'int', type => 'i32', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:f64', ctype => 'double', type => 'f64',}, + { size => 32, name => 'arg_1', ctype => 'int', type => 'i32',}, +]}, +'enum:_mm_hint' => { name => '_mm_hint', type => 'enum', size => 32, value_type => 'u32', values => [ + { label => '_MM_HINT_ET0', value => '7' }, + { label => '_MM_HINT_ET1', value => '6' }, + { label => '_MM_HINT_T0', value => '3' }, + { label => '_MM_HINT_T1', value => '2' }, + { label => '_MM_HINT_T2', value => '1' }, + { label => '_MM_HINT_NTA', value => '0' }, +]}, +'struct:_cl_image_format' => { name => '_cl_image_format', type => 'struct', size => 64, fields => [ + { name => 'image_channel_order', size => 32, offset => 0, ctype => 'unsigned int', type => 'u32',}, + { name => 'image_channel_data_type', size => 32, offset => 32, ctype => 'unsigned int', type => 'u32',}, +]}, +'struct:_cl_image_desc' => { name => '_cl_image_desc', type => 'struct', size => 576, fields => [ + { name => 'image_type', size => 32, offset => 0, ctype => 'unsigned int', type => 'u32',}, + { name => 'image_width', size => 64, offset => 64, ctype => 'long unsigned int', type => 'u64',}, + { name => 'image_height', size => 64, offset => 128, ctype => 'long unsigned int', type => 'u64',}, + { name => 'image_depth', size => 64, offset => 192, ctype => 'long unsigned int', type => 'u64',}, + { name => 'image_array_size', size => 64, offset => 256, ctype => 'long unsigned int', type => 'u64',}, + { name => 'image_row_pitch', size => 64, offset => 320, ctype => 'long unsigned int', type => 'u64',}, + { name => 'image_slice_pitch', size => 64, offset => 384, ctype => 'long unsigned int', type => 'u64',}, + { name => 'num_mip_levels', size => 32, offset => 448, ctype => 'unsigned int', type => 'u32',}, + { name => 'num_samples', size => 32, offset => 480, ctype => 'unsigned int', type => 'u32',}, + { name => 'buffer', size => 64, offset => 512, deref => 'u64:${_cl_mem}', type => 'struct:_cl_mem',}, + { name => 'mem_object', size => 64, offset => 512, deref => 'u64:${_cl_mem}', type => 'struct:_cl_mem',}, +]}, +'struct:_cl_buffer_region' => { name => '_cl_buffer_region', type => 'struct', size => 128, fields => [ + { name => 'origin', size => 64, offset => 0, ctype => 'long unsigned int', type => 'u64',}, + { name => 'size', size => 64, offset => 64, ctype => 'long unsigned int', type => 'u64',}, +]}, +'func:clGetPlatformIDs' => { name => 'clGetPlatformIDs', type => 'func', + result => { ctype => 'int', type => 'i32', }, + arguments => [ + { size => 32, name => 'arg_0', ctype => 'unsigned int', type => 'u32',}, + { size => 64, name => 'arg_1', deref => 'u64:u64:${_cl_platform_id}', type => 'struct:_cl_platform_id',}, + { size => 64, name => 'arg_2', deref => 'u64:u32', ctype => 'unsigned int', type => 'u32',}, +]}, +'func:clGetPlatformInfo' => { name => 'clGetPlatformInfo', type => 'func', + result => { ctype => 'int', type => 'i32', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:${_cl_platform_id}', type => 'struct:_cl_platform_id',}, + { size => 32, name => 'arg_1', ctype => 'unsigned int', type => 'u32',}, + { size => 64, name => 'arg_2', ctype => 'long unsigned int', type => 'u64',}, + { size => 64, name => 'arg_3', deref => 'u64:v', type => 'void',}, + { size => 64, name => 'arg_4', deref => 'u64:u64', ctype => 'long unsigned int', type => 'u64',}, +]}, +'func:clGetDeviceIDs' => { name => 'clGetDeviceIDs', type => 'func', + result => { ctype => 'int', type => 'i32', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:${_cl_platform_id}', type => 'struct:_cl_platform_id',}, + { size => 64, name => 'arg_1', ctype => 'long unsigned int', type => 'u64',}, + { size => 32, name => 'arg_2', ctype => 'unsigned int', type => 'u32',}, + { size => 64, name => 'arg_3', deref => 'u64:u64:${_cl_device_id}', type => 'struct:_cl_device_id',}, + { size => 64, name => 'arg_4', deref => 'u64:u32', ctype => 'unsigned int', type => 'u32',}, +]}, +'func:clGetDeviceInfo' => { name => 'clGetDeviceInfo', type => 'func', + result => { ctype => 'int', type => 'i32', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:${_cl_device_id}', type => 'struct:_cl_device_id',}, + { size => 32, name => 'arg_1', ctype => 'unsigned int', type => 'u32',}, + { size => 64, name => 'arg_2', ctype => 'long unsigned int', type => 'u64',}, + { size => 64, name => 'arg_3', deref => 'u64:v', type => 'void',}, + { size => 64, name => 'arg_4', deref => 'u64:u64', ctype => 'long unsigned int', type => 'u64',}, +]}, +'func:clCreateSubDevices' => { name => 'clCreateSubDevices', type => 'func', + result => { ctype => 'int', type => 'i32', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:${_cl_device_id}', type => 'struct:_cl_device_id',}, + { size => 64, name => 'arg_1', deref => 'u64:i64', ctype => 'long int', type => 'i64',}, + { size => 32, name => 'arg_2', ctype => 'unsigned int', type => 'u32',}, + { size => 64, name => 'arg_3', deref => 'u64:u64:${_cl_device_id}', type => 'struct:_cl_device_id',}, + { size => 64, name => 'arg_4', deref => 'u64:u32', ctype => 'unsigned int', type => 'u32',}, +]}, +'func:clRetainDevice' => { name => 'clRetainDevice', type => 'func', + result => { ctype => 'int', type => 'i32', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:${_cl_device_id}', type => 'struct:_cl_device_id',}, +]}, +'func:clReleaseDevice' => { name => 'clReleaseDevice', type => 'func', + result => { ctype => 'int', type => 'i32', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:${_cl_device_id}', type => 'struct:_cl_device_id',}, +]}, +'func:clSetDefaultDeviceCommandQueue' => { name => 'clSetDefaultDeviceCommandQueue', type => 'func', + result => { ctype => 'int', type => 'i32', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:${_cl_context}', type => 'struct:_cl_context',}, + { size => 64, name => 'arg_1', deref => 'u64:${_cl_device_id}', type => 'struct:_cl_device_id',}, + { size => 64, name => 'arg_2', deref => 'u64:${_cl_command_queue}', type => 'struct:_cl_command_queue',}, +]}, +'func:clGetDeviceAndHostTimer' => { name => 'clGetDeviceAndHostTimer', type => 'func', + result => { ctype => 'int', type => 'i32', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:${_cl_device_id}', type => 'struct:_cl_device_id',}, + { size => 64, name => 'arg_1', deref => 'u64:u64', ctype => 'long unsigned int', type => 'u64',}, + { size => 64, name => 'arg_2', deref => 'u64:u64', ctype => 'long unsigned int', type => 'u64',}, +]}, +'func:clGetHostTimer' => { name => 'clGetHostTimer', type => 'func', + result => { ctype => 'int', type => 'i32', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:${_cl_device_id}', type => 'struct:_cl_device_id',}, + { size => 64, name => 'arg_1', deref => 'u64:u64', ctype => 'long unsigned int', type => 'u64',}, +]}, +'func:clCreateContext' => { name => 'clCreateContext', type => 'func', + result => { deref => 'u64:${_cl_context}', type => 'struct:_cl_context', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:i64', ctype => 'long int', type => 'i64',}, + { size => 32, name => 'arg_1', ctype => 'unsigned int', type => 'u32',}, + { size => 64, name => 'arg_2', deref => 'u64:u64:${_cl_device_id}', type => 'struct:_cl_device_id',}, + { size => 64, name => 'arg_3', deref => 'u64:(u64:i8u64:vu64u64:v)v', type => 'call:(u64:i8u64:vu64u64:v)v', }, + { size => 64, name => 'arg_4', deref => 'u64:v', type => 'void',}, + { size => 64, name => 'arg_5', deref => 'u64:i32', ctype => 'int', type => 'i32',}, +]}, +'func:clCreateContextFromType' => { name => 'clCreateContextFromType', type => 'func', + result => { deref => 'u64:${_cl_context}', type => 'struct:_cl_context', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:i64', ctype => 'long int', type => 'i64',}, + { size => 64, name => 'arg_1', ctype => 'long unsigned int', type => 'u64',}, + { size => 64, name => 'arg_2', deref => 'u64:(u64:i8u64:vu64u64:v)v', type => 'call:(u64:i8u64:vu64u64:v)v', }, + { size => 64, name => 'arg_3', deref => 'u64:v', type => 'void',}, + { size => 64, name => 'arg_4', deref => 'u64:i32', ctype => 'int', type => 'i32',}, +]}, +'func:clRetainContext' => { name => 'clRetainContext', type => 'func', + result => { ctype => 'int', type => 'i32', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:${_cl_context}', type => 'struct:_cl_context',}, +]}, +'func:clReleaseContext' => { name => 'clReleaseContext', type => 'func', + result => { ctype => 'int', type => 'i32', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:${_cl_context}', type => 'struct:_cl_context',}, +]}, +'func:clGetContextInfo' => { name => 'clGetContextInfo', type => 'func', + result => { ctype => 'int', type => 'i32', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:${_cl_context}', type => 'struct:_cl_context',}, + { size => 32, name => 'arg_1', ctype => 'unsigned int', type => 'u32',}, + { size => 64, name => 'arg_2', ctype => 'long unsigned int', type => 'u64',}, + { size => 64, name => 'arg_3', deref => 'u64:v', type => 'void',}, + { size => 64, name => 'arg_4', deref => 'u64:u64', ctype => 'long unsigned int', type => 'u64',}, +]}, +'func:clCreateCommandQueueWithProperties' => { name => 'clCreateCommandQueueWithProperties', type => 'func', + result => { deref => 'u64:${_cl_command_queue}', type => 'struct:_cl_command_queue', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:${_cl_context}', type => 'struct:_cl_context',}, + { size => 64, name => 'arg_1', deref => 'u64:${_cl_device_id}', type => 'struct:_cl_device_id',}, + { size => 64, name => 'arg_2', deref => 'u64:u64', ctype => 'long unsigned int', type => 'u64',}, + { size => 64, name => 'arg_3', deref => 'u64:i32', ctype => 'int', type => 'i32',}, +]}, +'func:clRetainCommandQueue' => { name => 'clRetainCommandQueue', type => 'func', + result => { ctype => 'int', type => 'i32', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:${_cl_command_queue}', type => 'struct:_cl_command_queue',}, +]}, +'func:clReleaseCommandQueue' => { name => 'clReleaseCommandQueue', type => 'func', + result => { ctype => 'int', type => 'i32', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:${_cl_command_queue}', type => 'struct:_cl_command_queue',}, +]}, +'func:clGetCommandQueueInfo' => { name => 'clGetCommandQueueInfo', type => 'func', + result => { ctype => 'int', type => 'i32', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:${_cl_command_queue}', type => 'struct:_cl_command_queue',}, + { size => 32, name => 'arg_1', ctype => 'unsigned int', type => 'u32',}, + { size => 64, name => 'arg_2', ctype => 'long unsigned int', type => 'u64',}, + { size => 64, name => 'arg_3', deref => 'u64:v', type => 'void',}, + { size => 64, name => 'arg_4', deref => 'u64:u64', ctype => 'long unsigned int', type => 'u64',}, +]}, +'func:clCreateBuffer' => { name => 'clCreateBuffer', type => 'func', + result => { deref => 'u64:${_cl_mem}', type => 'struct:_cl_mem', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:${_cl_context}', type => 'struct:_cl_context',}, + { size => 64, name => 'arg_1', ctype => 'long unsigned int', type => 'u64',}, + { size => 64, name => 'arg_2', ctype => 'long unsigned int', type => 'u64',}, + { size => 64, name => 'arg_3', deref => 'u64:v', type => 'void',}, + { size => 64, name => 'arg_4', deref => 'u64:i32', ctype => 'int', type => 'i32',}, +]}, +'func:clCreateSubBuffer' => { name => 'clCreateSubBuffer', type => 'func', + result => { deref => 'u64:${_cl_mem}', type => 'struct:_cl_mem', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:${_cl_mem}', type => 'struct:_cl_mem',}, + { size => 64, name => 'arg_1', ctype => 'long unsigned int', type => 'u64',}, + { size => 32, name => 'arg_2', ctype => 'unsigned int', type => 'u32',}, + { size => 64, name => 'arg_3', deref => 'u64:v', type => 'void',}, + { size => 64, name => 'arg_4', deref => 'u64:i32', ctype => 'int', type => 'i32',}, +]}, +'func:clCreateImage' => { name => 'clCreateImage', type => 'func', + result => { deref => 'u64:${_cl_mem}', type => 'struct:_cl_mem', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:${_cl_context}', type => 'struct:_cl_context',}, + { size => 64, name => 'arg_1', ctype => 'long unsigned int', type => 'u64',}, + { size => 64, name => 'arg_2', deref => 'u64:${_cl_image_format}', type => 'struct:_cl_image_format',}, + { size => 64, name => 'arg_3', deref => 'u64:${_cl_image_desc}', type => 'struct:_cl_image_desc',}, + { size => 64, name => 'arg_4', deref => 'u64:v', type => 'void',}, + { size => 64, name => 'arg_5', deref => 'u64:i32', ctype => 'int', type => 'i32',}, +]}, +'func:clCreatePipe' => { name => 'clCreatePipe', type => 'func', + result => { deref => 'u64:${_cl_mem}', type => 'struct:_cl_mem', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:${_cl_context}', type => 'struct:_cl_context',}, + { size => 64, name => 'arg_1', ctype => 'long unsigned int', type => 'u64',}, + { size => 32, name => 'arg_2', ctype => 'unsigned int', type => 'u32',}, + { size => 32, name => 'arg_3', ctype => 'unsigned int', type => 'u32',}, + { size => 64, name => 'arg_4', deref => 'u64:i64', ctype => 'long int', type => 'i64',}, + { size => 64, name => 'arg_5', deref => 'u64:i32', ctype => 'int', type => 'i32',}, +]}, +'func:clRetainMemObject' => { name => 'clRetainMemObject', type => 'func', + result => { ctype => 'int', type => 'i32', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:${_cl_mem}', type => 'struct:_cl_mem',}, +]}, +'func:clReleaseMemObject' => { name => 'clReleaseMemObject', type => 'func', + result => { ctype => 'int', type => 'i32', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:${_cl_mem}', type => 'struct:_cl_mem',}, +]}, +'func:clGetSupportedImageFormats' => { name => 'clGetSupportedImageFormats', type => 'func', + result => { ctype => 'int', type => 'i32', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:${_cl_context}', type => 'struct:_cl_context',}, + { size => 64, name => 'arg_1', ctype => 'long unsigned int', type => 'u64',}, + { size => 32, name => 'arg_2', ctype => 'unsigned int', type => 'u32',}, + { size => 32, name => 'arg_3', ctype => 'unsigned int', type => 'u32',}, + { size => 64, name => 'arg_4', deref => 'u64:${_cl_image_format}', type => 'struct:_cl_image_format',}, + { size => 64, name => 'arg_5', deref => 'u64:u32', ctype => 'unsigned int', type => 'u32',}, +]}, +'func:clGetMemObjectInfo' => { name => 'clGetMemObjectInfo', type => 'func', + result => { ctype => 'int', type => 'i32', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:${_cl_mem}', type => 'struct:_cl_mem',}, + { size => 32, name => 'arg_1', ctype => 'unsigned int', type => 'u32',}, + { size => 64, name => 'arg_2', ctype => 'long unsigned int', type => 'u64',}, + { size => 64, name => 'arg_3', deref => 'u64:v', type => 'void',}, + { size => 64, name => 'arg_4', deref => 'u64:u64', ctype => 'long unsigned int', type => 'u64',}, +]}, +'func:clGetImageInfo' => { name => 'clGetImageInfo', type => 'func', + result => { ctype => 'int', type => 'i32', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:${_cl_mem}', type => 'struct:_cl_mem',}, + { size => 32, name => 'arg_1', ctype => 'unsigned int', type => 'u32',}, + { size => 64, name => 'arg_2', ctype => 'long unsigned int', type => 'u64',}, + { size => 64, name => 'arg_3', deref => 'u64:v', type => 'void',}, + { size => 64, name => 'arg_4', deref => 'u64:u64', ctype => 'long unsigned int', type => 'u64',}, +]}, +'func:clGetPipeInfo' => { name => 'clGetPipeInfo', type => 'func', + result => { ctype => 'int', type => 'i32', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:${_cl_mem}', type => 'struct:_cl_mem',}, + { size => 32, name => 'arg_1', ctype => 'unsigned int', type => 'u32',}, + { size => 64, name => 'arg_2', ctype => 'long unsigned int', type => 'u64',}, + { size => 64, name => 'arg_3', deref => 'u64:v', type => 'void',}, + { size => 64, name => 'arg_4', deref => 'u64:u64', ctype => 'long unsigned int', type => 'u64',}, +]}, +'func:clSetMemObjectDestructorCallback' => { name => 'clSetMemObjectDestructorCallback', type => 'func', + result => { ctype => 'int', type => 'i32', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:${_cl_mem}', type => 'struct:_cl_mem',}, + { size => 64, name => 'arg_1', deref => 'u64:(u64:${_cl_mem}u64:v)v', type => 'call:(u64:${_cl_mem}u64:v)v', }, + { size => 64, name => 'arg_2', deref => 'u64:v', type => 'void',}, +]}, +'func:clSVMAlloc' => { name => 'clSVMAlloc', type => 'func', + result => { deref => 'u64:v', type => 'void', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:${_cl_context}', type => 'struct:_cl_context',}, + { size => 64, name => 'arg_1', ctype => 'long unsigned int', type => 'u64',}, + { size => 64, name => 'arg_2', ctype => 'long unsigned int', type => 'u64',}, + { size => 32, name => 'arg_3', ctype => 'unsigned int', type => 'u32',}, +]}, +'func:clSVMFree' => { name => 'clSVMFree', type => 'func', + result => { type => 'void', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:${_cl_context}', type => 'struct:_cl_context',}, + { size => 64, name => 'arg_1', deref => 'u64:v', type => 'void',}, +]}, +'func:clCreateSamplerWithProperties' => { name => 'clCreateSamplerWithProperties', type => 'func', + result => { deref => 'u64:${_cl_sampler}', type => 'struct:_cl_sampler', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:${_cl_context}', type => 'struct:_cl_context',}, + { size => 64, name => 'arg_1', deref => 'u64:u64', ctype => 'long unsigned int', type => 'u64',}, + { size => 64, name => 'arg_2', deref => 'u64:i32', ctype => 'int', type => 'i32',}, +]}, +'func:clRetainSampler' => { name => 'clRetainSampler', type => 'func', + result => { ctype => 'int', type => 'i32', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:${_cl_sampler}', type => 'struct:_cl_sampler',}, +]}, +'func:clReleaseSampler' => { name => 'clReleaseSampler', type => 'func', + result => { ctype => 'int', type => 'i32', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:${_cl_sampler}', type => 'struct:_cl_sampler',}, +]}, +'func:clGetSamplerInfo' => { name => 'clGetSamplerInfo', type => 'func', + result => { ctype => 'int', type => 'i32', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:${_cl_sampler}', type => 'struct:_cl_sampler',}, + { size => 32, name => 'arg_1', ctype => 'unsigned int', type => 'u32',}, + { size => 64, name => 'arg_2', ctype => 'long unsigned int', type => 'u64',}, + { size => 64, name => 'arg_3', deref => 'u64:v', type => 'void',}, + { size => 64, name => 'arg_4', deref => 'u64:u64', ctype => 'long unsigned int', type => 'u64',}, +]}, +'func:clCreateProgramWithSource' => { name => 'clCreateProgramWithSource', type => 'func', + result => { deref => 'u64:${_cl_program}', type => 'struct:_cl_program', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:${_cl_context}', type => 'struct:_cl_context',}, + { size => 32, name => 'arg_1', ctype => 'unsigned int', type => 'u32',}, + { size => 64, name => 'arg_2', deref => 'u64:u64:i8', ctype => 'char', type => 'i8',}, + { size => 64, name => 'arg_3', deref => 'u64:u64', ctype => 'long unsigned int', type => 'u64',}, + { size => 64, name => 'arg_4', deref => 'u64:i32', ctype => 'int', type => 'i32',}, +]}, +'func:clCreateProgramWithBinary' => { name => 'clCreateProgramWithBinary', type => 'func', + result => { deref => 'u64:${_cl_program}', type => 'struct:_cl_program', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:${_cl_context}', type => 'struct:_cl_context',}, + { size => 32, name => 'arg_1', ctype => 'unsigned int', type => 'u32',}, + { size => 64, name => 'arg_2', deref => 'u64:u64:${_cl_device_id}', type => 'struct:_cl_device_id',}, + { size => 64, name => 'arg_3', deref => 'u64:u64', ctype => 'long unsigned int', type => 'u64',}, + { size => 64, name => 'arg_4', deref => 'u64:u64:u8', ctype => 'unsigned char', type => 'u8',}, + { size => 64, name => 'arg_5', deref => 'u64:i32', ctype => 'int', type => 'i32',}, + { size => 64, name => 'arg_6', deref => 'u64:i32', ctype => 'int', type => 'i32',}, +]}, +'func:clCreateProgramWithBuiltInKernels' => { name => 'clCreateProgramWithBuiltInKernels', type => 'func', + result => { deref => 'u64:${_cl_program}', type => 'struct:_cl_program', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:${_cl_context}', type => 'struct:_cl_context',}, + { size => 32, name => 'arg_1', ctype => 'unsigned int', type => 'u32',}, + { size => 64, name => 'arg_2', deref => 'u64:u64:${_cl_device_id}', type => 'struct:_cl_device_id',}, + { size => 64, name => 'arg_3', deref => 'u64:i8', ctype => 'char', type => 'i8',}, + { size => 64, name => 'arg_4', deref => 'u64:i32', ctype => 'int', type => 'i32',}, +]}, +'func:clCreateProgramWithIL' => { name => 'clCreateProgramWithIL', type => 'func', + result => { deref => 'u64:${_cl_program}', type => 'struct:_cl_program', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:${_cl_context}', type => 'struct:_cl_context',}, + { size => 64, name => 'arg_1', deref => 'u64:v', type => 'void',}, + { size => 64, name => 'arg_2', ctype => 'long unsigned int', type => 'u64',}, + { size => 64, name => 'arg_3', deref => 'u64:i32', ctype => 'int', type => 'i32',}, +]}, +'func:clRetainProgram' => { name => 'clRetainProgram', type => 'func', + result => { ctype => 'int', type => 'i32', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:${_cl_program}', type => 'struct:_cl_program',}, +]}, +'func:clReleaseProgram' => { name => 'clReleaseProgram', type => 'func', + result => { ctype => 'int', type => 'i32', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:${_cl_program}', type => 'struct:_cl_program',}, +]}, +'func:clBuildProgram' => { name => 'clBuildProgram', type => 'func', + result => { ctype => 'int', type => 'i32', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:${_cl_program}', type => 'struct:_cl_program',}, + { size => 32, name => 'arg_1', ctype => 'unsigned int', type => 'u32',}, + { size => 64, name => 'arg_2', deref => 'u64:u64:${_cl_device_id}', type => 'struct:_cl_device_id',}, + { size => 64, name => 'arg_3', deref => 'u64:i8', ctype => 'char', type => 'i8',}, + { size => 64, name => 'arg_4', deref => 'u64:(u64:${_cl_program}u64:v)v', type => 'call:(u64:${_cl_program}u64:v)v', }, + { size => 64, name => 'arg_5', deref => 'u64:v', type => 'void',}, +]}, +'func:clCompileProgram' => { name => 'clCompileProgram', type => 'func', + result => { ctype => 'int', type => 'i32', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:${_cl_program}', type => 'struct:_cl_program',}, + { size => 32, name => 'arg_1', ctype => 'unsigned int', type => 'u32',}, + { size => 64, name => 'arg_2', deref => 'u64:u64:${_cl_device_id}', type => 'struct:_cl_device_id',}, + { size => 64, name => 'arg_3', deref => 'u64:i8', ctype => 'char', type => 'i8',}, + { size => 32, name => 'arg_4', ctype => 'unsigned int', type => 'u32',}, + { size => 64, name => 'arg_5', deref => 'u64:u64:${_cl_program}', type => 'struct:_cl_program',}, + { size => 64, name => 'arg_6', deref => 'u64:u64:i8', ctype => 'char', type => 'i8',}, + { size => 64, name => 'arg_7', deref => 'u64:(u64:${_cl_program}u64:v)v', type => 'call:(u64:${_cl_program}u64:v)v', }, + { size => 64, name => 'arg_8', deref => 'u64:v', type => 'void',}, +]}, +'func:clLinkProgram' => { name => 'clLinkProgram', type => 'func', + result => { deref => 'u64:${_cl_program}', type => 'struct:_cl_program', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:${_cl_context}', type => 'struct:_cl_context',}, + { size => 32, name => 'arg_1', ctype => 'unsigned int', type => 'u32',}, + { size => 64, name => 'arg_2', deref => 'u64:u64:${_cl_device_id}', type => 'struct:_cl_device_id',}, + { size => 64, name => 'arg_3', deref => 'u64:i8', ctype => 'char', type => 'i8',}, + { size => 32, name => 'arg_4', ctype => 'unsigned int', type => 'u32',}, + { size => 64, name => 'arg_5', deref => 'u64:u64:${_cl_program}', type => 'struct:_cl_program',}, + { size => 64, name => 'arg_6', deref => 'u64:(u64:${_cl_program}u64:v)v', type => 'call:(u64:${_cl_program}u64:v)v', }, + { size => 64, name => 'arg_7', deref => 'u64:v', type => 'void',}, + { size => 64, name => 'arg_8', deref => 'u64:i32', ctype => 'int', type => 'i32',}, +]}, +'func:clUnloadPlatformCompiler' => { name => 'clUnloadPlatformCompiler', type => 'func', + result => { ctype => 'int', type => 'i32', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:${_cl_platform_id}', type => 'struct:_cl_platform_id',}, +]}, +'func:clGetProgramInfo' => { name => 'clGetProgramInfo', type => 'func', + result => { ctype => 'int', type => 'i32', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:${_cl_program}', type => 'struct:_cl_program',}, + { size => 32, name => 'arg_1', ctype => 'unsigned int', type => 'u32',}, + { size => 64, name => 'arg_2', ctype => 'long unsigned int', type => 'u64',}, + { size => 64, name => 'arg_3', deref => 'u64:v', type => 'void',}, + { size => 64, name => 'arg_4', deref => 'u64:u64', ctype => 'long unsigned int', type => 'u64',}, +]}, +'func:clGetProgramBuildInfo' => { name => 'clGetProgramBuildInfo', type => 'func', + result => { ctype => 'int', type => 'i32', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:${_cl_program}', type => 'struct:_cl_program',}, + { size => 64, name => 'arg_1', deref => 'u64:${_cl_device_id}', type => 'struct:_cl_device_id',}, + { size => 32, name => 'arg_2', ctype => 'unsigned int', type => 'u32',}, + { size => 64, name => 'arg_3', ctype => 'long unsigned int', type => 'u64',}, + { size => 64, name => 'arg_4', deref => 'u64:v', type => 'void',}, + { size => 64, name => 'arg_5', deref => 'u64:u64', ctype => 'long unsigned int', type => 'u64',}, +]}, +'func:clCreateKernel' => { name => 'clCreateKernel', type => 'func', + result => { deref => 'u64:${_cl_kernel}', type => 'struct:_cl_kernel', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:${_cl_program}', type => 'struct:_cl_program',}, + { size => 64, name => 'arg_1', deref => 'u64:i8', ctype => 'char', type => 'i8',}, + { size => 64, name => 'arg_2', deref => 'u64:i32', ctype => 'int', type => 'i32',}, +]}, +'func:clCreateKernelsInProgram' => { name => 'clCreateKernelsInProgram', type => 'func', + result => { ctype => 'int', type => 'i32', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:${_cl_program}', type => 'struct:_cl_program',}, + { size => 32, name => 'arg_1', ctype => 'unsigned int', type => 'u32',}, + { size => 64, name => 'arg_2', deref => 'u64:u64:${_cl_kernel}', type => 'struct:_cl_kernel',}, + { size => 64, name => 'arg_3', deref => 'u64:u32', ctype => 'unsigned int', type => 'u32',}, +]}, +'func:clCloneKernel' => { name => 'clCloneKernel', type => 'func', + result => { deref => 'u64:${_cl_kernel}', type => 'struct:_cl_kernel', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:${_cl_kernel}', type => 'struct:_cl_kernel',}, + { size => 64, name => 'arg_1', deref => 'u64:i32', ctype => 'int', type => 'i32',}, +]}, +'func:clRetainKernel' => { name => 'clRetainKernel', type => 'func', + result => { ctype => 'int', type => 'i32', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:${_cl_kernel}', type => 'struct:_cl_kernel',}, +]}, +'func:clReleaseKernel' => { name => 'clReleaseKernel', type => 'func', + result => { ctype => 'int', type => 'i32', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:${_cl_kernel}', type => 'struct:_cl_kernel',}, +]}, +'func:clSetKernelArg' => { name => 'clSetKernelArg', type => 'func', + result => { ctype => 'int', type => 'i32', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:${_cl_kernel}', type => 'struct:_cl_kernel',}, + { size => 32, name => 'arg_1', ctype => 'unsigned int', type => 'u32',}, + { size => 64, name => 'arg_2', ctype => 'long unsigned int', type => 'u64',}, + { size => 64, name => 'arg_3', deref => 'u64:v', type => 'void',}, +]}, +'func:clSetKernelArgSVMPointer' => { name => 'clSetKernelArgSVMPointer', type => 'func', + result => { ctype => 'int', type => 'i32', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:${_cl_kernel}', type => 'struct:_cl_kernel',}, + { size => 32, name => 'arg_1', ctype => 'unsigned int', type => 'u32',}, + { size => 64, name => 'arg_2', deref => 'u64:v', type => 'void',}, +]}, +'func:clSetKernelExecInfo' => { name => 'clSetKernelExecInfo', type => 'func', + result => { ctype => 'int', type => 'i32', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:${_cl_kernel}', type => 'struct:_cl_kernel',}, + { size => 32, name => 'arg_1', ctype => 'unsigned int', type => 'u32',}, + { size => 64, name => 'arg_2', ctype => 'long unsigned int', type => 'u64',}, + { size => 64, name => 'arg_3', deref => 'u64:v', type => 'void',}, +]}, +'func:clGetKernelInfo' => { name => 'clGetKernelInfo', type => 'func', + result => { ctype => 'int', type => 'i32', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:${_cl_kernel}', type => 'struct:_cl_kernel',}, + { size => 32, name => 'arg_1', ctype => 'unsigned int', type => 'u32',}, + { size => 64, name => 'arg_2', ctype => 'long unsigned int', type => 'u64',}, + { size => 64, name => 'arg_3', deref => 'u64:v', type => 'void',}, + { size => 64, name => 'arg_4', deref => 'u64:u64', ctype => 'long unsigned int', type => 'u64',}, +]}, +'func:clGetKernelArgInfo' => { name => 'clGetKernelArgInfo', type => 'func', + result => { ctype => 'int', type => 'i32', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:${_cl_kernel}', type => 'struct:_cl_kernel',}, + { size => 32, name => 'arg_1', ctype => 'unsigned int', type => 'u32',}, + { size => 32, name => 'arg_2', ctype => 'unsigned int', type => 'u32',}, + { size => 64, name => 'arg_3', ctype => 'long unsigned int', type => 'u64',}, + { size => 64, name => 'arg_4', deref => 'u64:v', type => 'void',}, + { size => 64, name => 'arg_5', deref => 'u64:u64', ctype => 'long unsigned int', type => 'u64',}, +]}, +'func:clGetKernelWorkGroupInfo' => { name => 'clGetKernelWorkGroupInfo', type => 'func', + result => { ctype => 'int', type => 'i32', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:${_cl_kernel}', type => 'struct:_cl_kernel',}, + { size => 64, name => 'arg_1', deref => 'u64:${_cl_device_id}', type => 'struct:_cl_device_id',}, + { size => 32, name => 'arg_2', ctype => 'unsigned int', type => 'u32',}, + { size => 64, name => 'arg_3', ctype => 'long unsigned int', type => 'u64',}, + { size => 64, name => 'arg_4', deref => 'u64:v', type => 'void',}, + { size => 64, name => 'arg_5', deref => 'u64:u64', ctype => 'long unsigned int', type => 'u64',}, +]}, +'func:clGetKernelSubGroupInfo' => { name => 'clGetKernelSubGroupInfo', type => 'func', + result => { ctype => 'int', type => 'i32', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:${_cl_kernel}', type => 'struct:_cl_kernel',}, + { size => 64, name => 'arg_1', deref => 'u64:${_cl_device_id}', type => 'struct:_cl_device_id',}, + { size => 32, name => 'arg_2', ctype => 'unsigned int', type => 'u32',}, + { size => 64, name => 'arg_3', ctype => 'long unsigned int', type => 'u64',}, + { size => 64, name => 'arg_4', deref => 'u64:v', type => 'void',}, + { size => 64, name => 'arg_5', ctype => 'long unsigned int', type => 'u64',}, + { size => 64, name => 'arg_6', deref => 'u64:v', type => 'void',}, + { size => 64, name => 'arg_7', deref => 'u64:u64', ctype => 'long unsigned int', type => 'u64',}, +]}, +'func:clWaitForEvents' => { name => 'clWaitForEvents', type => 'func', + result => { ctype => 'int', type => 'i32', }, + arguments => [ + { size => 32, name => 'arg_0', ctype => 'unsigned int', type => 'u32',}, + { size => 64, name => 'arg_1', deref => 'u64:u64:${_cl_event}', type => 'struct:_cl_event',}, +]}, +'func:clGetEventInfo' => { name => 'clGetEventInfo', type => 'func', + result => { ctype => 'int', type => 'i32', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:${_cl_event}', type => 'struct:_cl_event',}, + { size => 32, name => 'arg_1', ctype => 'unsigned int', type => 'u32',}, + { size => 64, name => 'arg_2', ctype => 'long unsigned int', type => 'u64',}, + { size => 64, name => 'arg_3', deref => 'u64:v', type => 'void',}, + { size => 64, name => 'arg_4', deref => 'u64:u64', ctype => 'long unsigned int', type => 'u64',}, +]}, +'func:clCreateUserEvent' => { name => 'clCreateUserEvent', type => 'func', + result => { deref => 'u64:${_cl_event}', type => 'struct:_cl_event', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:${_cl_context}', type => 'struct:_cl_context',}, + { size => 64, name => 'arg_1', deref => 'u64:i32', ctype => 'int', type => 'i32',}, +]}, +'func:clRetainEvent' => { name => 'clRetainEvent', type => 'func', + result => { ctype => 'int', type => 'i32', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:${_cl_event}', type => 'struct:_cl_event',}, +]}, +'func:clReleaseEvent' => { name => 'clReleaseEvent', type => 'func', + result => { ctype => 'int', type => 'i32', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:${_cl_event}', type => 'struct:_cl_event',}, +]}, +'func:clSetUserEventStatus' => { name => 'clSetUserEventStatus', type => 'func', + result => { ctype => 'int', type => 'i32', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:${_cl_event}', type => 'struct:_cl_event',}, + { size => 32, name => 'arg_1', ctype => 'int', type => 'i32',}, +]}, +'func:clSetEventCallback' => { name => 'clSetEventCallback', type => 'func', + result => { ctype => 'int', type => 'i32', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:${_cl_event}', type => 'struct:_cl_event',}, + { size => 32, name => 'arg_1', ctype => 'int', type => 'i32',}, + { size => 64, name => 'arg_2', deref => 'u64:(u64:${_cl_event}i32u64:v)v', type => 'call:(u64:${_cl_event}i32u64:v)v', }, + { size => 64, name => 'arg_3', deref => 'u64:v', type => 'void',}, +]}, +'func:clGetEventProfilingInfo' => { name => 'clGetEventProfilingInfo', type => 'func', + result => { ctype => 'int', type => 'i32', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:${_cl_event}', type => 'struct:_cl_event',}, + { size => 32, name => 'arg_1', ctype => 'unsigned int', type => 'u32',}, + { size => 64, name => 'arg_2', ctype => 'long unsigned int', type => 'u64',}, + { size => 64, name => 'arg_3', deref => 'u64:v', type => 'void',}, + { size => 64, name => 'arg_4', deref => 'u64:u64', ctype => 'long unsigned int', type => 'u64',}, +]}, +'func:clFlush' => { name => 'clFlush', type => 'func', + result => { ctype => 'int', type => 'i32', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:${_cl_command_queue}', type => 'struct:_cl_command_queue',}, +]}, +'func:clFinish' => { name => 'clFinish', type => 'func', + result => { ctype => 'int', type => 'i32', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:${_cl_command_queue}', type => 'struct:_cl_command_queue',}, +]}, +'func:clEnqueueReadBuffer' => { name => 'clEnqueueReadBuffer', type => 'func', + result => { ctype => 'int', type => 'i32', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:${_cl_command_queue}', type => 'struct:_cl_command_queue',}, + { size => 64, name => 'arg_1', deref => 'u64:${_cl_mem}', type => 'struct:_cl_mem',}, + { size => 32, name => 'arg_2', ctype => 'unsigned int', type => 'u32',}, + { size => 64, name => 'arg_3', ctype => 'long unsigned int', type => 'u64',}, + { size => 64, name => 'arg_4', ctype => 'long unsigned int', type => 'u64',}, + { size => 64, name => 'arg_5', deref => 'u64:v', type => 'void',}, + { size => 32, name => 'arg_6', ctype => 'unsigned int', type => 'u32',}, + { size => 64, name => 'arg_7', deref => 'u64:u64:${_cl_event}', type => 'struct:_cl_event',}, + { size => 64, name => 'arg_8', deref => 'u64:u64:${_cl_event}', type => 'struct:_cl_event',}, +]}, +'func:clEnqueueReadBufferRect' => { name => 'clEnqueueReadBufferRect', type => 'func', + result => { ctype => 'int', type => 'i32', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:${_cl_command_queue}', type => 'struct:_cl_command_queue',}, + { size => 64, name => 'arg_1', deref => 'u64:${_cl_mem}', type => 'struct:_cl_mem',}, + { size => 32, name => 'arg_2', ctype => 'unsigned int', type => 'u32',}, + { size => 64, name => 'arg_3', deref => 'u64:u64', ctype => 'long unsigned int', type => 'u64',}, + { size => 64, name => 'arg_4', deref => 'u64:u64', ctype => 'long unsigned int', type => 'u64',}, + { size => 64, name => 'arg_5', deref => 'u64:u64', ctype => 'long unsigned int', type => 'u64',}, + { size => 64, name => 'arg_6', ctype => 'long unsigned int', type => 'u64',}, + { size => 64, name => 'arg_7', ctype => 'long unsigned int', type => 'u64',}, + { size => 64, name => 'arg_8', ctype => 'long unsigned int', type => 'u64',}, + { size => 64, name => 'arg_9', ctype => 'long unsigned int', type => 'u64',}, + { size => 64, name => 'arg_10', deref => 'u64:v', type => 'void',}, + { size => 32, name => 'arg_11', ctype => 'unsigned int', type => 'u32',}, + { size => 64, name => 'arg_12', deref => 'u64:u64:${_cl_event}', type => 'struct:_cl_event',}, + { size => 64, name => 'arg_13', deref => 'u64:u64:${_cl_event}', type => 'struct:_cl_event',}, +]}, +'func:clEnqueueWriteBuffer' => { name => 'clEnqueueWriteBuffer', type => 'func', + result => { ctype => 'int', type => 'i32', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:${_cl_command_queue}', type => 'struct:_cl_command_queue',}, + { size => 64, name => 'arg_1', deref => 'u64:${_cl_mem}', type => 'struct:_cl_mem',}, + { size => 32, name => 'arg_2', ctype => 'unsigned int', type => 'u32',}, + { size => 64, name => 'arg_3', ctype => 'long unsigned int', type => 'u64',}, + { size => 64, name => 'arg_4', ctype => 'long unsigned int', type => 'u64',}, + { size => 64, name => 'arg_5', deref => 'u64:v', type => 'void',}, + { size => 32, name => 'arg_6', ctype => 'unsigned int', type => 'u32',}, + { size => 64, name => 'arg_7', deref => 'u64:u64:${_cl_event}', type => 'struct:_cl_event',}, + { size => 64, name => 'arg_8', deref => 'u64:u64:${_cl_event}', type => 'struct:_cl_event',}, +]}, +'func:clEnqueueWriteBufferRect' => { name => 'clEnqueueWriteBufferRect', type => 'func', + result => { ctype => 'int', type => 'i32', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:${_cl_command_queue}', type => 'struct:_cl_command_queue',}, + { size => 64, name => 'arg_1', deref => 'u64:${_cl_mem}', type => 'struct:_cl_mem',}, + { size => 32, name => 'arg_2', ctype => 'unsigned int', type => 'u32',}, + { size => 64, name => 'arg_3', deref => 'u64:u64', ctype => 'long unsigned int', type => 'u64',}, + { size => 64, name => 'arg_4', deref => 'u64:u64', ctype => 'long unsigned int', type => 'u64',}, + { size => 64, name => 'arg_5', deref => 'u64:u64', ctype => 'long unsigned int', type => 'u64',}, + { size => 64, name => 'arg_6', ctype => 'long unsigned int', type => 'u64',}, + { size => 64, name => 'arg_7', ctype => 'long unsigned int', type => 'u64',}, + { size => 64, name => 'arg_8', ctype => 'long unsigned int', type => 'u64',}, + { size => 64, name => 'arg_9', ctype => 'long unsigned int', type => 'u64',}, + { size => 64, name => 'arg_10', deref => 'u64:v', type => 'void',}, + { size => 32, name => 'arg_11', ctype => 'unsigned int', type => 'u32',}, + { size => 64, name => 'arg_12', deref => 'u64:u64:${_cl_event}', type => 'struct:_cl_event',}, + { size => 64, name => 'arg_13', deref => 'u64:u64:${_cl_event}', type => 'struct:_cl_event',}, +]}, +'func:clEnqueueFillBuffer' => { name => 'clEnqueueFillBuffer', type => 'func', + result => { ctype => 'int', type => 'i32', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:${_cl_command_queue}', type => 'struct:_cl_command_queue',}, + { size => 64, name => 'arg_1', deref => 'u64:${_cl_mem}', type => 'struct:_cl_mem',}, + { size => 64, name => 'arg_2', deref => 'u64:v', type => 'void',}, + { size => 64, name => 'arg_3', ctype => 'long unsigned int', type => 'u64',}, + { size => 64, name => 'arg_4', ctype => 'long unsigned int', type => 'u64',}, + { size => 64, name => 'arg_5', ctype => 'long unsigned int', type => 'u64',}, + { size => 32, name => 'arg_6', ctype => 'unsigned int', type => 'u32',}, + { size => 64, name => 'arg_7', deref => 'u64:u64:${_cl_event}', type => 'struct:_cl_event',}, + { size => 64, name => 'arg_8', deref => 'u64:u64:${_cl_event}', type => 'struct:_cl_event',}, +]}, +'func:clEnqueueCopyBuffer' => { name => 'clEnqueueCopyBuffer', type => 'func', + result => { ctype => 'int', type => 'i32', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:${_cl_command_queue}', type => 'struct:_cl_command_queue',}, + { size => 64, name => 'arg_1', deref => 'u64:${_cl_mem}', type => 'struct:_cl_mem',}, + { size => 64, name => 'arg_2', deref => 'u64:${_cl_mem}', type => 'struct:_cl_mem',}, + { size => 64, name => 'arg_3', ctype => 'long unsigned int', type => 'u64',}, + { size => 64, name => 'arg_4', ctype => 'long unsigned int', type => 'u64',}, + { size => 64, name => 'arg_5', ctype => 'long unsigned int', type => 'u64',}, + { size => 32, name => 'arg_6', ctype => 'unsigned int', type => 'u32',}, + { size => 64, name => 'arg_7', deref => 'u64:u64:${_cl_event}', type => 'struct:_cl_event',}, + { size => 64, name => 'arg_8', deref => 'u64:u64:${_cl_event}', type => 'struct:_cl_event',}, +]}, +'func:clEnqueueCopyBufferRect' => { name => 'clEnqueueCopyBufferRect', type => 'func', + result => { ctype => 'int', type => 'i32', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:${_cl_command_queue}', type => 'struct:_cl_command_queue',}, + { size => 64, name => 'arg_1', deref => 'u64:${_cl_mem}', type => 'struct:_cl_mem',}, + { size => 64, name => 'arg_2', deref => 'u64:${_cl_mem}', type => 'struct:_cl_mem',}, + { size => 64, name => 'arg_3', deref => 'u64:u64', ctype => 'long unsigned int', type => 'u64',}, + { size => 64, name => 'arg_4', deref => 'u64:u64', ctype => 'long unsigned int', type => 'u64',}, + { size => 64, name => 'arg_5', deref => 'u64:u64', ctype => 'long unsigned int', type => 'u64',}, + { size => 64, name => 'arg_6', ctype => 'long unsigned int', type => 'u64',}, + { size => 64, name => 'arg_7', ctype => 'long unsigned int', type => 'u64',}, + { size => 64, name => 'arg_8', ctype => 'long unsigned int', type => 'u64',}, + { size => 64, name => 'arg_9', ctype => 'long unsigned int', type => 'u64',}, + { size => 32, name => 'arg_10', ctype => 'unsigned int', type => 'u32',}, + { size => 64, name => 'arg_11', deref => 'u64:u64:${_cl_event}', type => 'struct:_cl_event',}, + { size => 64, name => 'arg_12', deref => 'u64:u64:${_cl_event}', type => 'struct:_cl_event',}, +]}, +'func:clEnqueueReadImage' => { name => 'clEnqueueReadImage', type => 'func', + result => { ctype => 'int', type => 'i32', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:${_cl_command_queue}', type => 'struct:_cl_command_queue',}, + { size => 64, name => 'arg_1', deref => 'u64:${_cl_mem}', type => 'struct:_cl_mem',}, + { size => 32, name => 'arg_2', ctype => 'unsigned int', type => 'u32',}, + { size => 64, name => 'arg_3', deref => 'u64:u64', ctype => 'long unsigned int', type => 'u64',}, + { size => 64, name => 'arg_4', deref => 'u64:u64', ctype => 'long unsigned int', type => 'u64',}, + { size => 64, name => 'arg_5', ctype => 'long unsigned int', type => 'u64',}, + { size => 64, name => 'arg_6', ctype => 'long unsigned int', type => 'u64',}, + { size => 64, name => 'arg_7', deref => 'u64:v', type => 'void',}, + { size => 32, name => 'arg_8', ctype => 'unsigned int', type => 'u32',}, + { size => 64, name => 'arg_9', deref => 'u64:u64:${_cl_event}', type => 'struct:_cl_event',}, + { size => 64, name => 'arg_10', deref => 'u64:u64:${_cl_event}', type => 'struct:_cl_event',}, +]}, +'func:clEnqueueWriteImage' => { name => 'clEnqueueWriteImage', type => 'func', + result => { ctype => 'int', type => 'i32', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:${_cl_command_queue}', type => 'struct:_cl_command_queue',}, + { size => 64, name => 'arg_1', deref => 'u64:${_cl_mem}', type => 'struct:_cl_mem',}, + { size => 32, name => 'arg_2', ctype => 'unsigned int', type => 'u32',}, + { size => 64, name => 'arg_3', deref => 'u64:u64', ctype => 'long unsigned int', type => 'u64',}, + { size => 64, name => 'arg_4', deref => 'u64:u64', ctype => 'long unsigned int', type => 'u64',}, + { size => 64, name => 'arg_5', ctype => 'long unsigned int', type => 'u64',}, + { size => 64, name => 'arg_6', ctype => 'long unsigned int', type => 'u64',}, + { size => 64, name => 'arg_7', deref => 'u64:v', type => 'void',}, + { size => 32, name => 'arg_8', ctype => 'unsigned int', type => 'u32',}, + { size => 64, name => 'arg_9', deref => 'u64:u64:${_cl_event}', type => 'struct:_cl_event',}, + { size => 64, name => 'arg_10', deref => 'u64:u64:${_cl_event}', type => 'struct:_cl_event',}, +]}, +'func:clEnqueueFillImage' => { name => 'clEnqueueFillImage', type => 'func', + result => { ctype => 'int', type => 'i32', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:${_cl_command_queue}', type => 'struct:_cl_command_queue',}, + { size => 64, name => 'arg_1', deref => 'u64:${_cl_mem}', type => 'struct:_cl_mem',}, + { size => 64, name => 'arg_2', deref => 'u64:v', type => 'void',}, + { size => 64, name => 'arg_3', deref => 'u64:u64', ctype => 'long unsigned int', type => 'u64',}, + { size => 64, name => 'arg_4', deref => 'u64:u64', ctype => 'long unsigned int', type => 'u64',}, + { size => 32, name => 'arg_5', ctype => 'unsigned int', type => 'u32',}, + { size => 64, name => 'arg_6', deref => 'u64:u64:${_cl_event}', type => 'struct:_cl_event',}, + { size => 64, name => 'arg_7', deref => 'u64:u64:${_cl_event}', type => 'struct:_cl_event',}, +]}, +'func:clEnqueueCopyImage' => { name => 'clEnqueueCopyImage', type => 'func', + result => { ctype => 'int', type => 'i32', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:${_cl_command_queue}', type => 'struct:_cl_command_queue',}, + { size => 64, name => 'arg_1', deref => 'u64:${_cl_mem}', type => 'struct:_cl_mem',}, + { size => 64, name => 'arg_2', deref => 'u64:${_cl_mem}', type => 'struct:_cl_mem',}, + { size => 64, name => 'arg_3', deref => 'u64:u64', ctype => 'long unsigned int', type => 'u64',}, + { size => 64, name => 'arg_4', deref => 'u64:u64', ctype => 'long unsigned int', type => 'u64',}, + { size => 64, name => 'arg_5', deref => 'u64:u64', ctype => 'long unsigned int', type => 'u64',}, + { size => 32, name => 'arg_6', ctype => 'unsigned int', type => 'u32',}, + { size => 64, name => 'arg_7', deref => 'u64:u64:${_cl_event}', type => 'struct:_cl_event',}, + { size => 64, name => 'arg_8', deref => 'u64:u64:${_cl_event}', type => 'struct:_cl_event',}, +]}, +'func:clEnqueueCopyImageToBuffer' => { name => 'clEnqueueCopyImageToBuffer', type => 'func', + result => { ctype => 'int', type => 'i32', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:${_cl_command_queue}', type => 'struct:_cl_command_queue',}, + { size => 64, name => 'arg_1', deref => 'u64:${_cl_mem}', type => 'struct:_cl_mem',}, + { size => 64, name => 'arg_2', deref => 'u64:${_cl_mem}', type => 'struct:_cl_mem',}, + { size => 64, name => 'arg_3', deref => 'u64:u64', ctype => 'long unsigned int', type => 'u64',}, + { size => 64, name => 'arg_4', deref => 'u64:u64', ctype => 'long unsigned int', type => 'u64',}, + { size => 64, name => 'arg_5', ctype => 'long unsigned int', type => 'u64',}, + { size => 32, name => 'arg_6', ctype => 'unsigned int', type => 'u32',}, + { size => 64, name => 'arg_7', deref => 'u64:u64:${_cl_event}', type => 'struct:_cl_event',}, + { size => 64, name => 'arg_8', deref => 'u64:u64:${_cl_event}', type => 'struct:_cl_event',}, +]}, +'func:clEnqueueCopyBufferToImage' => { name => 'clEnqueueCopyBufferToImage', type => 'func', + result => { ctype => 'int', type => 'i32', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:${_cl_command_queue}', type => 'struct:_cl_command_queue',}, + { size => 64, name => 'arg_1', deref => 'u64:${_cl_mem}', type => 'struct:_cl_mem',}, + { size => 64, name => 'arg_2', deref => 'u64:${_cl_mem}', type => 'struct:_cl_mem',}, + { size => 64, name => 'arg_3', ctype => 'long unsigned int', type => 'u64',}, + { size => 64, name => 'arg_4', deref => 'u64:u64', ctype => 'long unsigned int', type => 'u64',}, + { size => 64, name => 'arg_5', deref => 'u64:u64', ctype => 'long unsigned int', type => 'u64',}, + { size => 32, name => 'arg_6', ctype => 'unsigned int', type => 'u32',}, + { size => 64, name => 'arg_7', deref => 'u64:u64:${_cl_event}', type => 'struct:_cl_event',}, + { size => 64, name => 'arg_8', deref => 'u64:u64:${_cl_event}', type => 'struct:_cl_event',}, +]}, +'func:clEnqueueMapBuffer' => { name => 'clEnqueueMapBuffer', type => 'func', + result => { deref => 'u64:v', type => 'void', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:${_cl_command_queue}', type => 'struct:_cl_command_queue',}, + { size => 64, name => 'arg_1', deref => 'u64:${_cl_mem}', type => 'struct:_cl_mem',}, + { size => 32, name => 'arg_2', ctype => 'unsigned int', type => 'u32',}, + { size => 64, name => 'arg_3', ctype => 'long unsigned int', type => 'u64',}, + { size => 64, name => 'arg_4', ctype => 'long unsigned int', type => 'u64',}, + { size => 64, name => 'arg_5', ctype => 'long unsigned int', type => 'u64',}, + { size => 32, name => 'arg_6', ctype => 'unsigned int', type => 'u32',}, + { size => 64, name => 'arg_7', deref => 'u64:u64:${_cl_event}', type => 'struct:_cl_event',}, + { size => 64, name => 'arg_8', deref => 'u64:u64:${_cl_event}', type => 'struct:_cl_event',}, + { size => 64, name => 'arg_9', deref => 'u64:i32', ctype => 'int', type => 'i32',}, +]}, +'func:clEnqueueMapImage' => { name => 'clEnqueueMapImage', type => 'func', + result => { deref => 'u64:v', type => 'void', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:${_cl_command_queue}', type => 'struct:_cl_command_queue',}, + { size => 64, name => 'arg_1', deref => 'u64:${_cl_mem}', type => 'struct:_cl_mem',}, + { size => 32, name => 'arg_2', ctype => 'unsigned int', type => 'u32',}, + { size => 64, name => 'arg_3', ctype => 'long unsigned int', type => 'u64',}, + { size => 64, name => 'arg_4', deref => 'u64:u64', ctype => 'long unsigned int', type => 'u64',}, + { size => 64, name => 'arg_5', deref => 'u64:u64', ctype => 'long unsigned int', type => 'u64',}, + { size => 64, name => 'arg_6', deref => 'u64:u64', ctype => 'long unsigned int', type => 'u64',}, + { size => 64, name => 'arg_7', deref => 'u64:u64', ctype => 'long unsigned int', type => 'u64',}, + { size => 32, name => 'arg_8', ctype => 'unsigned int', type => 'u32',}, + { size => 64, name => 'arg_9', deref => 'u64:u64:${_cl_event}', type => 'struct:_cl_event',}, + { size => 64, name => 'arg_10', deref => 'u64:u64:${_cl_event}', type => 'struct:_cl_event',}, + { size => 64, name => 'arg_11', deref => 'u64:i32', ctype => 'int', type => 'i32',}, +]}, +'func:clEnqueueUnmapMemObject' => { name => 'clEnqueueUnmapMemObject', type => 'func', + result => { ctype => 'int', type => 'i32', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:${_cl_command_queue}', type => 'struct:_cl_command_queue',}, + { size => 64, name => 'arg_1', deref => 'u64:${_cl_mem}', type => 'struct:_cl_mem',}, + { size => 64, name => 'arg_2', deref => 'u64:v', type => 'void',}, + { size => 32, name => 'arg_3', ctype => 'unsigned int', type => 'u32',}, + { size => 64, name => 'arg_4', deref => 'u64:u64:${_cl_event}', type => 'struct:_cl_event',}, + { size => 64, name => 'arg_5', deref => 'u64:u64:${_cl_event}', type => 'struct:_cl_event',}, +]}, +'func:clEnqueueMigrateMemObjects' => { name => 'clEnqueueMigrateMemObjects', type => 'func', + result => { ctype => 'int', type => 'i32', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:${_cl_command_queue}', type => 'struct:_cl_command_queue',}, + { size => 32, name => 'arg_1', ctype => 'unsigned int', type => 'u32',}, + { size => 64, name => 'arg_2', deref => 'u64:u64:${_cl_mem}', type => 'struct:_cl_mem',}, + { size => 64, name => 'arg_3', ctype => 'long unsigned int', type => 'u64',}, + { size => 32, name => 'arg_4', ctype => 'unsigned int', type => 'u32',}, + { size => 64, name => 'arg_5', deref => 'u64:u64:${_cl_event}', type => 'struct:_cl_event',}, + { size => 64, name => 'arg_6', deref => 'u64:u64:${_cl_event}', type => 'struct:_cl_event',}, +]}, +'func:clEnqueueNDRangeKernel' => { name => 'clEnqueueNDRangeKernel', type => 'func', + result => { ctype => 'int', type => 'i32', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:${_cl_command_queue}', type => 'struct:_cl_command_queue',}, + { size => 64, name => 'arg_1', deref => 'u64:${_cl_kernel}', type => 'struct:_cl_kernel',}, + { size => 32, name => 'arg_2', ctype => 'unsigned int', type => 'u32',}, + { size => 64, name => 'arg_3', deref => 'u64:u64', ctype => 'long unsigned int', type => 'u64',}, + { size => 64, name => 'arg_4', deref => 'u64:u64', ctype => 'long unsigned int', type => 'u64',}, + { size => 64, name => 'arg_5', deref => 'u64:u64', ctype => 'long unsigned int', type => 'u64',}, + { size => 32, name => 'arg_6', ctype => 'unsigned int', type => 'u32',}, + { size => 64, name => 'arg_7', deref => 'u64:u64:${_cl_event}', type => 'struct:_cl_event',}, + { size => 64, name => 'arg_8', deref => 'u64:u64:${_cl_event}', type => 'struct:_cl_event',}, +]}, +'func:clEnqueueNativeKernel' => { name => 'clEnqueueNativeKernel', type => 'func', + result => { ctype => 'int', type => 'i32', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:${_cl_command_queue}', type => 'struct:_cl_command_queue',}, + { size => 64, name => 'arg_1', deref => 'u64:(u64:v)v', type => 'call:(u64:v)v', }, + { size => 64, name => 'arg_2', deref => 'u64:v', type => 'void',}, + { size => 64, name => 'arg_3', ctype => 'long unsigned int', type => 'u64',}, + { size => 32, name => 'arg_4', ctype => 'unsigned int', type => 'u32',}, + { size => 64, name => 'arg_5', deref => 'u64:u64:${_cl_mem}', type => 'struct:_cl_mem',}, + { size => 64, name => 'arg_6', deref => 'u64:u64:v', type => 'void',}, + { size => 32, name => 'arg_7', ctype => 'unsigned int', type => 'u32',}, + { size => 64, name => 'arg_8', deref => 'u64:u64:${_cl_event}', type => 'struct:_cl_event',}, + { size => 64, name => 'arg_9', deref => 'u64:u64:${_cl_event}', type => 'struct:_cl_event',}, +]}, +'func:clEnqueueMarkerWithWaitList' => { name => 'clEnqueueMarkerWithWaitList', type => 'func', + result => { ctype => 'int', type => 'i32', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:${_cl_command_queue}', type => 'struct:_cl_command_queue',}, + { size => 32, name => 'arg_1', ctype => 'unsigned int', type => 'u32',}, + { size => 64, name => 'arg_2', deref => 'u64:u64:${_cl_event}', type => 'struct:_cl_event',}, + { size => 64, name => 'arg_3', deref => 'u64:u64:${_cl_event}', type => 'struct:_cl_event',}, +]}, +'func:clEnqueueBarrierWithWaitList' => { name => 'clEnqueueBarrierWithWaitList', type => 'func', + result => { ctype => 'int', type => 'i32', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:${_cl_command_queue}', type => 'struct:_cl_command_queue',}, + { size => 32, name => 'arg_1', ctype => 'unsigned int', type => 'u32',}, + { size => 64, name => 'arg_2', deref => 'u64:u64:${_cl_event}', type => 'struct:_cl_event',}, + { size => 64, name => 'arg_3', deref => 'u64:u64:${_cl_event}', type => 'struct:_cl_event',}, +]}, +'func:clEnqueueSVMFree' => { name => 'clEnqueueSVMFree', type => 'func', + result => { ctype => 'int', type => 'i32', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:${_cl_command_queue}', type => 'struct:_cl_command_queue',}, + { size => 32, name => 'arg_1', ctype => 'unsigned int', type => 'u32',}, + { size => 64, name => 'arg_2', deref => 'u64:u64:v', type => 'void',}, + { size => 64, name => 'arg_3', deref => 'u64:(u64:${_cl_command_queue}u32u64:u64:vu64:v)v', type => 'call:(u64:${_cl_command_queue}u32u64:u64:vu64:v)v', }, + { size => 64, name => 'arg_4', deref => 'u64:v', type => 'void',}, + { size => 32, name => 'arg_5', ctype => 'unsigned int', type => 'u32',}, + { size => 64, name => 'arg_6', deref => 'u64:u64:${_cl_event}', type => 'struct:_cl_event',}, + { size => 64, name => 'arg_7', deref => 'u64:u64:${_cl_event}', type => 'struct:_cl_event',}, +]}, +'func:clEnqueueSVMMemcpy' => { name => 'clEnqueueSVMMemcpy', type => 'func', + result => { ctype => 'int', type => 'i32', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:${_cl_command_queue}', type => 'struct:_cl_command_queue',}, + { size => 32, name => 'arg_1', ctype => 'unsigned int', type => 'u32',}, + { size => 64, name => 'arg_2', deref => 'u64:v', type => 'void',}, + { size => 64, name => 'arg_3', deref => 'u64:v', type => 'void',}, + { size => 64, name => 'arg_4', ctype => 'long unsigned int', type => 'u64',}, + { size => 32, name => 'arg_5', ctype => 'unsigned int', type => 'u32',}, + { size => 64, name => 'arg_6', deref => 'u64:u64:${_cl_event}', type => 'struct:_cl_event',}, + { size => 64, name => 'arg_7', deref => 'u64:u64:${_cl_event}', type => 'struct:_cl_event',}, +]}, +'func:clEnqueueSVMMemFill' => { name => 'clEnqueueSVMMemFill', type => 'func', + result => { ctype => 'int', type => 'i32', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:${_cl_command_queue}', type => 'struct:_cl_command_queue',}, + { size => 64, name => 'arg_1', deref => 'u64:v', type => 'void',}, + { size => 64, name => 'arg_2', deref => 'u64:v', type => 'void',}, + { size => 64, name => 'arg_3', ctype => 'long unsigned int', type => 'u64',}, + { size => 64, name => 'arg_4', ctype => 'long unsigned int', type => 'u64',}, + { size => 32, name => 'arg_5', ctype => 'unsigned int', type => 'u32',}, + { size => 64, name => 'arg_6', deref => 'u64:u64:${_cl_event}', type => 'struct:_cl_event',}, + { size => 64, name => 'arg_7', deref => 'u64:u64:${_cl_event}', type => 'struct:_cl_event',}, +]}, +'func:clEnqueueSVMMap' => { name => 'clEnqueueSVMMap', type => 'func', + result => { ctype => 'int', type => 'i32', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:${_cl_command_queue}', type => 'struct:_cl_command_queue',}, + { size => 32, name => 'arg_1', ctype => 'unsigned int', type => 'u32',}, + { size => 64, name => 'arg_2', ctype => 'long unsigned int', type => 'u64',}, + { size => 64, name => 'arg_3', deref => 'u64:v', type => 'void',}, + { size => 64, name => 'arg_4', ctype => 'long unsigned int', type => 'u64',}, + { size => 32, name => 'arg_5', ctype => 'unsigned int', type => 'u32',}, + { size => 64, name => 'arg_6', deref => 'u64:u64:${_cl_event}', type => 'struct:_cl_event',}, + { size => 64, name => 'arg_7', deref => 'u64:u64:${_cl_event}', type => 'struct:_cl_event',}, +]}, +'func:clEnqueueSVMUnmap' => { name => 'clEnqueueSVMUnmap', type => 'func', + result => { ctype => 'int', type => 'i32', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:${_cl_command_queue}', type => 'struct:_cl_command_queue',}, + { size => 64, name => 'arg_1', deref => 'u64:v', type => 'void',}, + { size => 32, name => 'arg_2', ctype => 'unsigned int', type => 'u32',}, + { size => 64, name => 'arg_3', deref => 'u64:u64:${_cl_event}', type => 'struct:_cl_event',}, + { size => 64, name => 'arg_4', deref => 'u64:u64:${_cl_event}', type => 'struct:_cl_event',}, +]}, +'func:clEnqueueSVMMigrateMem' => { name => 'clEnqueueSVMMigrateMem', type => 'func', + result => { ctype => 'int', type => 'i32', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:${_cl_command_queue}', type => 'struct:_cl_command_queue',}, + { size => 32, name => 'arg_1', ctype => 'unsigned int', type => 'u32',}, + { size => 64, name => 'arg_2', deref => 'u64:u64:v', type => 'void',}, + { size => 64, name => 'arg_3', deref => 'u64:u64', ctype => 'long unsigned int', type => 'u64',}, + { size => 64, name => 'arg_4', ctype => 'long unsigned int', type => 'u64',}, + { size => 32, name => 'arg_5', ctype => 'unsigned int', type => 'u32',}, + { size => 64, name => 'arg_6', deref => 'u64:u64:${_cl_event}', type => 'struct:_cl_event',}, + { size => 64, name => 'arg_7', deref => 'u64:u64:${_cl_event}', type => 'struct:_cl_event',}, +]}, +'func:clGetExtensionFunctionAddressForPlatform' => { name => 'clGetExtensionFunctionAddressForPlatform', type => 'func', + result => { deref => 'u64:v', type => 'void', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:${_cl_platform_id}', type => 'struct:_cl_platform_id',}, + { size => 64, name => 'arg_1', deref => 'u64:i8', ctype => 'char', type => 'i8',}, +]}, +'func:clCreateImage2D' => { name => 'clCreateImage2D', type => 'func', + result => { deref => 'u64:${_cl_mem}', type => 'struct:_cl_mem', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:${_cl_context}', type => 'struct:_cl_context',}, + { size => 64, name => 'arg_1', ctype => 'long unsigned int', type => 'u64',}, + { size => 64, name => 'arg_2', deref => 'u64:${_cl_image_format}', type => 'struct:_cl_image_format',}, + { size => 64, name => 'arg_3', ctype => 'long unsigned int', type => 'u64',}, + { size => 64, name => 'arg_4', ctype => 'long unsigned int', type => 'u64',}, + { size => 64, name => 'arg_5', ctype => 'long unsigned int', type => 'u64',}, + { size => 64, name => 'arg_6', deref => 'u64:v', type => 'void',}, + { size => 64, name => 'arg_7', deref => 'u64:i32', ctype => 'int', type => 'i32',}, +]}, +'func:clCreateImage3D' => { name => 'clCreateImage3D', type => 'func', + result => { deref => 'u64:${_cl_mem}', type => 'struct:_cl_mem', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:${_cl_context}', type => 'struct:_cl_context',}, + { size => 64, name => 'arg_1', ctype => 'long unsigned int', type => 'u64',}, + { size => 64, name => 'arg_2', deref => 'u64:${_cl_image_format}', type => 'struct:_cl_image_format',}, + { size => 64, name => 'arg_3', ctype => 'long unsigned int', type => 'u64',}, + { size => 64, name => 'arg_4', ctype => 'long unsigned int', type => 'u64',}, + { size => 64, name => 'arg_5', ctype => 'long unsigned int', type => 'u64',}, + { size => 64, name => 'arg_6', ctype => 'long unsigned int', type => 'u64',}, + { size => 64, name => 'arg_7', ctype => 'long unsigned int', type => 'u64',}, + { size => 64, name => 'arg_8', deref => 'u64:v', type => 'void',}, + { size => 64, name => 'arg_9', deref => 'u64:i32', ctype => 'int', type => 'i32',}, +]}, +'func:clEnqueueMarker' => { name => 'clEnqueueMarker', type => 'func', + result => { ctype => 'int', type => 'i32', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:${_cl_command_queue}', type => 'struct:_cl_command_queue',}, + { size => 64, name => 'arg_1', deref => 'u64:u64:${_cl_event}', type => 'struct:_cl_event',}, +]}, +'func:clEnqueueWaitForEvents' => { name => 'clEnqueueWaitForEvents', type => 'func', + result => { ctype => 'int', type => 'i32', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:${_cl_command_queue}', type => 'struct:_cl_command_queue',}, + { size => 32, name => 'arg_1', ctype => 'unsigned int', type => 'u32',}, + { size => 64, name => 'arg_2', deref => 'u64:u64:${_cl_event}', type => 'struct:_cl_event',}, +]}, +'func:clEnqueueBarrier' => { name => 'clEnqueueBarrier', type => 'func', + result => { ctype => 'int', type => 'i32', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:${_cl_command_queue}', type => 'struct:_cl_command_queue',}, +]}, +'func:clUnloadCompiler' => { name => 'clUnloadCompiler', type => 'func', + result => { ctype => 'int', type => 'i32', }, + arguments => [ +]}, +'func:clGetExtensionFunctionAddress' => { name => 'clGetExtensionFunctionAddress', type => 'func', + result => { deref => 'u64:v', type => 'void', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:i8', ctype => 'char', type => 'i8',}, +]}, +'func:clCreateCommandQueue' => { name => 'clCreateCommandQueue', type => 'func', + result => { deref => 'u64:${_cl_command_queue}', type => 'struct:_cl_command_queue', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:${_cl_context}', type => 'struct:_cl_context',}, + { size => 64, name => 'arg_1', deref => 'u64:${_cl_device_id}', type => 'struct:_cl_device_id',}, + { size => 64, name => 'arg_2', ctype => 'long unsigned int', type => 'u64',}, + { size => 64, name => 'arg_3', deref => 'u64:i32', ctype => 'int', type => 'i32',}, +]}, +'func:clCreateSampler' => { name => 'clCreateSampler', type => 'func', + result => { deref => 'u64:${_cl_sampler}', type => 'struct:_cl_sampler', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:${_cl_context}', type => 'struct:_cl_context',}, + { size => 32, name => 'arg_1', ctype => 'unsigned int', type => 'u32',}, + { size => 32, name => 'arg_2', ctype => 'unsigned int', type => 'u32',}, + { size => 32, name => 'arg_3', ctype => 'unsigned int', type => 'u32',}, + { size => 64, name => 'arg_4', deref => 'u64:i32', ctype => 'int', type => 'i32',}, +]}, +'func:clEnqueueTask' => { name => 'clEnqueueTask', type => 'func', + result => { ctype => 'int', type => 'i32', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:${_cl_command_queue}', type => 'struct:_cl_command_queue',}, + { size => 64, name => 'arg_1', deref => 'u64:${_cl_kernel}', type => 'struct:_cl_kernel',}, + { size => 32, name => 'arg_2', ctype => 'unsigned int', type => 'u32',}, + { size => 64, name => 'arg_3', deref => 'u64:u64:${_cl_event}', type => 'struct:_cl_event',}, + { size => 64, name => 'arg_4', deref => 'u64:u64:${_cl_event}', type => 'struct:_cl_event',}, +]}, +'struct:__pthread_cond_s___wseq32' => { name => '__pthread_cond_s___wseq32', type => 'struct', size => 64, fields => [ + { name => '__low', size => 32, offset => 0, ctype => 'unsigned int', type => 'u32',}, + { name => '__high', size => 32, offset => 32, ctype => 'unsigned int', type => 'u32',}, +]}, +'struct:__pthread_cond_s___g1_start32' => { name => '__pthread_cond_s___g1_start32', type => 'struct', size => 64, fields => [ + { name => '__low', size => 32, offset => 0, ctype => 'unsigned int', type => 'u32',}, + { name => '__high', size => 32, offset => 32, ctype => 'unsigned int', type => 'u32',}, +]}, +'call:()v' => { name => '()v', type => 'call', + result => { type => 'void', }, + arguments => [ +]}, +'call:(i32u64:v)v' => { name => '(i32u64:v)v', type => 'call', + result => { type => 'void', }, + arguments => [ + { size => 32, name => 'arg_0', ctype => 'int', type => 'i32',}, + { size => 64, name => 'arg_1', deref => 'u64:v', type => 'void',}, +]}, +'call:(u64:vu64:v)i32' => { name => '(u64:vu64:v)i32', type => 'call', + result => { ctype => 'int', type => 'i32', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:v', type => 'void',}, + { size => 64, name => 'arg_1', deref => 'u64:v', type => 'void',}, +]}, +'call:(u64:i8u64:vu64u64:v)v' => { name => '(u64:i8u64:vu64u64:v)v', type => 'call', + result => { type => 'void', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:i8', ctype => 'char', type => 'i8',}, + { size => 64, name => 'arg_1', deref => 'u64:v', type => 'void',}, + { size => 64, name => 'arg_2', ctype => 'long unsigned int', type => 'u64',}, + { size => 64, name => 'arg_3', deref => 'u64:v', type => 'void',}, +]}, +'call:(u64:${_cl_mem}u64:v)v' => { name => '(u64:${_cl_mem}u64:v)v', type => 'call', + result => { type => 'void', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:${_cl_mem}', type => 'struct:_cl_mem',}, + { size => 64, name => 'arg_1', deref => 'u64:v', type => 'void',}, +]}, +'call:(u64:${_cl_program}u64:v)v' => { name => '(u64:${_cl_program}u64:v)v', type => 'call', + result => { type => 'void', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:${_cl_program}', type => 'struct:_cl_program',}, + { size => 64, name => 'arg_1', deref => 'u64:v', type => 'void',}, +]}, +'call:(u64:${_cl_event}i32u64:v)v' => { name => '(u64:${_cl_event}i32u64:v)v', type => 'call', + result => { type => 'void', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:${_cl_event}', type => 'struct:_cl_event',}, + { size => 32, name => 'arg_1', ctype => 'int', type => 'i32',}, + { size => 64, name => 'arg_2', deref => 'u64:v', type => 'void',}, +]}, +'call:(u64:v)v' => { name => '(u64:v)v', type => 'call', + result => { type => 'void', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:v', type => 'void',}, +]}, +'call:(u64:${_cl_command_queue}u32u64:u64:vu64:v)v' => { name => '(u64:${_cl_command_queue}u32u64:u64:vu64:v)v', type => 'call', + result => { type => 'void', }, + arguments => [ + { size => 64, name => 'arg_0', deref => 'u64:${_cl_command_queue}', type => 'struct:_cl_command_queue',}, + { size => 32, name => 'arg_1', ctype => 'unsigned int', type => 'u32',}, + { size => 64, name => 'arg_2', deref => 'u64:u64:v', type => 'void',}, + { size => 64, name => 'arg_3', deref => 'u64:v', type => 'void',}, +]}, +# dumped structs: +# __u_char +# __u_short +# __u_int +# __u_long +# __int8_t +# __uint8_t +# __int16_t +# __uint16_t +# __int32_t +# __uint32_t +# __int64_t +# __uint64_t +# __int_least8_t +# __uint_least8_t +# __int_least16_t +# __uint_least16_t +# __int_least32_t +# __uint_least32_t +# __int_least64_t +# __uint_least64_t +# __quad_t +# __u_quad_t +# __intmax_t +# __uintmax_t +# __dev_t +# __uid_t +# __gid_t +# __ino_t +# __ino64_t +# __mode_t +# __nlink_t +# __off_t +# __off64_t +# __pid_t +# __fsid_t +# __clock_t +# __rlim_t +# __rlim64_t +# __id_t +# __time_t +# __useconds_t +# __suseconds_t +# __daddr_t +# __key_t +# __clockid_t +# __timer_t +# __blksize_t +# __blkcnt_t +# __blkcnt64_t +# __fsblkcnt_t +# __fsblkcnt64_t +# __fsfilcnt_t +# __fsfilcnt64_t +# __fsword_t +# __ssize_t +# __syscall_slong_t +# __syscall_ulong_t +# __loff_t +# __caddr_t +# __intptr_t +# __socklen_t +# __sig_atomic_t +# int8_t +# int16_t +# int32_t +# int64_t +# uint8_t +# uint16_t +# uint32_t +# uint64_t +# int_least8_t +# int_least16_t +# int_least32_t +# int_least64_t +# uint_least8_t +# uint_least16_t +# uint_least32_t +# uint_least64_t +# int_fast8_t +# int_fast16_t +# int_fast32_t +# int_fast64_t +# uint_fast8_t +# uint_fast16_t +# uint_fast32_t +# uint_fast64_t +# intptr_t +# uintptr_t +# intmax_t +# uintmax_t +# cl_char +# cl_uchar +# cl_short +# cl_ushort +# cl_int +# cl_uint +# cl_long +# cl_ulong +# cl_half +# cl_float +# cl_double +# ptrdiff_t +# size_t +# wchar_t +# max_align_t +# cl_GLuint +# cl_GLint +# cl_GLenum +# __m64 +# __m64_u +# __v2si +# __v4hi +# __v8qi +# __v1di +# __v2sf +# div_t +# ldiv_t +# lldiv_t +# __ctype_get_mb_cur_max +# atof +# atoi +# atol +# atoll +# strtod +# strtof +# strtold +# strtol +# strtoul +# strtoq +# strtouq +# strtoll +# strtoull +# l64a +# a64l +# u_char +# u_short +# u_int +# u_long +# quad_t +# u_quad_t +# fsid_t +# loff_t +# ino_t +# dev_t +# gid_t +# mode_t +# nlink_t +# uid_t +# off_t +# pid_t +# id_t +# ssize_t +# daddr_t +# caddr_t +# key_t +# clock_t +# clockid_t +# time_t +# timer_t +# ulong +# ushort +# uint +# u_int8_t +# u_int16_t +# u_int32_t +# u_int64_t +# register_t +# __sigset_t +# sigset_t +# timeval +# timespec +# suseconds_t +# __fd_mask +# fd_set +# fd_mask +# select +# pselect +# blksize_t +# blkcnt_t +# fsblkcnt_t +# fsfilcnt_t +# __pthread_rwlock_arch_t +# __pthread_internal_list +# __pthread_list_t +# __pthread_mutex_s +# __pthread_cond_s +# pthread_t +# pthread_mutexattr_t +# pthread_condattr_t +# pthread_key_t +# pthread_once_t +# pthread_attr_t +# pthread_mutex_t +# pthread_cond_t +# pthread_rwlock_t +# pthread_rwlockattr_t +# pthread_spinlock_t +# pthread_barrier_t +# pthread_barrierattr_t +# random +# srandom +# initstate +# setstate +# random_data +# random_r +# srandom_r +# initstate_r +# setstate_r +# rand +# srand +# rand_r +# drand48 +# erand48 +# lrand48 +# nrand48 +# mrand48 +# jrand48 +# srand48 +# seed48 +# lcong48 +# drand48_data +# drand48_r +# erand48_r +# lrand48_r +# nrand48_r +# mrand48_r +# jrand48_r +# srand48_r +# seed48_r +# lcong48_r +# malloc +# calloc +# realloc +# reallocarray +# free +# alloca +# valloc +# posix_memalign +# aligned_alloc +# abort +# atexit +# at_quick_exit +# on_exit +# exit +# quick_exit +# _Exit +# getenv +# putenv +# setenv +# unsetenv +# clearenv +# mktemp +# mkstemp +# mkstemps +# mkdtemp +# system +# realpath +# __compar_fn_t +# bsearch +# qsort +# abs +# labs +# llabs +# div +# ldiv +# lldiv +# ecvt +# fcvt +# gcvt +# qecvt +# qfcvt +# qgcvt +# ecvt_r +# fcvt_r +# qecvt_r +# qfcvt_r +# mblen +# mbtowc +# wctomb +# mbstowcs +# wcstombs +# rpmatch +# getsubopt +# getloadavg +# _mm_hint +# __m128 +# __m128_u +# __v4sf +# __v2df +# __v2di +# __v2du +# __v4si +# __v4su +# __v8hi +# __v8hu +# __v16qi +# __v16qs +# __v16qu +# __m128i +# __m128d +# __m128i_u +# __m128d_u +# __cl_float4 +# __cl_uchar16 +# __cl_char16 +# __cl_ushort8 +# __cl_short8 +# __cl_uint4 +# __cl_int4 +# __cl_ulong2 +# __cl_long2 +# __cl_double2 +# __cl_uchar8 +# __cl_char8 +# __cl_ushort4 +# __cl_short4 +# __cl_uint2 +# __cl_int2 +# __cl_ulong1 +# __cl_long1 +# __cl_float2 +# cl_char2 +# cl_char4 +# cl_char3 +# cl_char8 +# cl_char16 +# cl_uchar2 +# cl_uchar4 +# cl_uchar3 +# cl_uchar8 +# cl_uchar16 +# cl_short2 +# cl_short4 +# cl_short3 +# cl_short8 +# cl_short16 +# cl_ushort2 +# cl_ushort4 +# cl_ushort3 +# cl_ushort8 +# cl_ushort16 +# cl_int2 +# cl_int4 +# cl_int3 +# cl_int8 +# cl_int16 +# cl_uint2 +# cl_uint4 +# cl_uint3 +# cl_uint8 +# cl_uint16 +# cl_long2 +# cl_long4 +# cl_long3 +# cl_long8 +# cl_long16 +# cl_ulong2 +# cl_ulong4 +# cl_ulong3 +# cl_ulong8 +# cl_ulong16 +# cl_float2 +# cl_float4 +# cl_float3 +# cl_float8 +# cl_float16 +# cl_double2 +# cl_double4 +# cl_double3 +# cl_double8 +# cl_double16 +# cl_platform_id +# cl_device_id +# cl_context +# cl_command_queue +# cl_mem +# cl_program +# cl_kernel +# cl_event +# cl_sampler +# cl_bool +# cl_bitfield +# cl_device_type +# cl_platform_info +# cl_device_info +# cl_device_fp_config +# cl_device_mem_cache_type +# cl_device_local_mem_type +# cl_device_exec_capabilities +# cl_device_svm_capabilities +# cl_command_queue_properties +# cl_device_partition_property +# cl_device_affinity_domain +# cl_context_properties +# cl_context_info +# cl_queue_properties +# cl_command_queue_info +# cl_channel_order +# cl_channel_type +# cl_mem_flags +# cl_svm_mem_flags +# cl_mem_object_type +# cl_mem_info +# cl_mem_migration_flags +# cl_image_info +# cl_buffer_create_type +# cl_addressing_mode +# cl_filter_mode +# cl_sampler_info +# cl_map_flags +# cl_pipe_properties +# cl_pipe_info +# cl_program_info +# cl_program_build_info +# cl_program_binary_type +# cl_build_status +# cl_kernel_info +# cl_kernel_arg_info +# cl_kernel_arg_address_qualifier +# cl_kernel_arg_access_qualifier +# cl_kernel_arg_type_qualifier +# cl_kernel_work_group_info +# cl_kernel_sub_group_info +# cl_event_info +# cl_command_type +# cl_profiling_info +# cl_sampler_properties +# cl_kernel_exec_info +# _cl_image_format +# cl_image_format +# _cl_image_desc +# cl_image_desc +# _cl_buffer_region +# cl_buffer_region +# clGetPlatformIDs +# clGetPlatformInfo +# clGetDeviceIDs +# clGetDeviceInfo +# clCreateSubDevices +# clRetainDevice +# clReleaseDevice +# clSetDefaultDeviceCommandQueue +# clGetDeviceAndHostTimer +# clGetHostTimer +# clCreateContext +# clCreateContextFromType +# clRetainContext +# clReleaseContext +# clGetContextInfo +# clCreateCommandQueueWithProperties +# clRetainCommandQueue +# clReleaseCommandQueue +# clGetCommandQueueInfo +# clCreateBuffer +# clCreateSubBuffer +# clCreateImage +# clCreatePipe +# clRetainMemObject +# clReleaseMemObject +# clGetSupportedImageFormats +# clGetMemObjectInfo +# clGetImageInfo +# clGetPipeInfo +# clSetMemObjectDestructorCallback +# clSVMAlloc +# clSVMFree +# clCreateSamplerWithProperties +# clRetainSampler +# clReleaseSampler +# clGetSamplerInfo +# clCreateProgramWithSource +# clCreateProgramWithBinary +# clCreateProgramWithBuiltInKernels +# clCreateProgramWithIL +# clRetainProgram +# clReleaseProgram +# clBuildProgram +# clCompileProgram +# clLinkProgram +# clUnloadPlatformCompiler +# clGetProgramInfo +# clGetProgramBuildInfo +# clCreateKernel +# clCreateKernelsInProgram +# clCloneKernel +# clRetainKernel +# clReleaseKernel +# clSetKernelArg +# clSetKernelArgSVMPointer +# clSetKernelExecInfo +# clGetKernelInfo +# clGetKernelArgInfo +# clGetKernelWorkGroupInfo +# clGetKernelSubGroupInfo +# clWaitForEvents +# clGetEventInfo +# clCreateUserEvent +# clRetainEvent +# clReleaseEvent +# clSetUserEventStatus +# clSetEventCallback +# clGetEventProfilingInfo +# clFlush +# clFinish +# clEnqueueReadBuffer +# clEnqueueReadBufferRect +# clEnqueueWriteBuffer +# clEnqueueWriteBufferRect +# clEnqueueFillBuffer +# clEnqueueCopyBuffer +# clEnqueueCopyBufferRect +# clEnqueueReadImage +# clEnqueueWriteImage +# clEnqueueFillImage +# clEnqueueCopyImage +# clEnqueueCopyImageToBuffer +# clEnqueueCopyBufferToImage +# clEnqueueMapBuffer +# clEnqueueMapImage +# clEnqueueUnmapMemObject +# clEnqueueMigrateMemObjects +# clEnqueueNDRangeKernel +# clEnqueueNativeKernel +# clEnqueueMarkerWithWaitList +# clEnqueueBarrierWithWaitList +# clEnqueueSVMFree +# clEnqueueSVMMemcpy +# clEnqueueSVMMemFill +# clEnqueueSVMMap +# clEnqueueSVMUnmap +# clEnqueueSVMMigrateMem +# clGetExtensionFunctionAddressForPlatform +# clCreateImage2D +# clCreateImage3D +# clEnqueueMarker +# clEnqueueWaitForEvents +# clEnqueueBarrier +# clUnloadCompiler +# clGetExtensionFunctionAddress +# clCreateCommandQueue +# clCreateSampler +# clEnqueueTask +# __pthread_cond_s___wseq32 +# __pthread_cond_s___g1_start32 +# ()v +# (i32u64:v)v +# (u64:vu64:v)i32 +# (u64:i8u64:vu64u64:v)v +# (u64:${_cl_mem}u64:v)v +# (u64:${_cl_program}u64:v)v +# (u64:${_cl_event}i32u64:v)v +# (u64:v)v +# (u64:${_cl_command_queue}u32u64:u64:vu64:v)v +); diff --git a/src/notzed.zcl/gen/opencl.txt b/src/notzed.zcl/gen/opencl.txt new file mode 100644 index 0000000..fa360b3 --- /dev/null +++ b/src/notzed.zcl/gen/opencl.txt @@ -0,0 +1,108 @@ +clGetPlatformIDs +clGetPlatformInfo +clGetDeviceIDs +clGetDeviceInfo +clCreateSubDevices +clRetainDevice +clReleaseDevice +clSetDefaultDeviceCommandQueue +clGetDeviceAndHostTimer +clGetHostTimer +clCreateContext +clCreateContextFromType +clRetainContext +clReleaseContext +clGetContextInfo +clCreateCommandQueueWithProperties +clRetainCommandQueue +clReleaseCommandQueue +clGetCommandQueueInfo +clCreateBuffer +clCreateSubBuffer +clCreateImage +clCreatePipe +clRetainMemObject +clReleaseMemObject +clGetSupportedImageFormats +clGetMemObjectInfo +clGetImageInfo +clGetPipeInfo +clSetMemObjectDestructorCallback +clSVMAlloc +clSVMFree +clCreateSamplerWithProperties +clRetainSampler +clReleaseSampler +clGetSamplerInfo +clCreateProgramWithSource +clCreateProgramWithBinary +clCreateProgramWithBuiltInKernels +clCreateProgramWithIL +clRetainProgram +clReleaseProgram +clBuildProgram +clCompileProgram +clLinkProgram +clUnloadPlatformCompiler +clGetProgramInfo +clGetProgramBuildInfo +clCreateKernel +clCreateKernelsInProgram +clCloneKernel +clRetainKernel +clReleaseKernel +clSetKernelArg +clSetKernelArgSVMPointer +clSetKernelExecInfo +clGetKernelInfo +clGetKernelArgInfo +clGetKernelWorkGroupInfo +clGetKernelSubGroupInfo +clWaitForEvents +clGetEventInfo +clCreateUserEvent +clRetainEvent +clReleaseEvent +clSetUserEventStatus +clSetEventCallback +clGetEventProfilingInfo +clFlush +clFinish +clEnqueueReadBuffer +clEnqueueReadBufferRect +clEnqueueWriteBuffer +clEnqueueWriteBufferRect +clEnqueueFillBuffer +clEnqueueCopyBuffer +clEnqueueCopyBufferRect +clEnqueueReadImage +clEnqueueWriteImage +clEnqueueFillImage +clEnqueueCopyImage +clEnqueueCopyImageToBuffer +clEnqueueCopyBufferToImage +clEnqueueMapBuffer +clEnqueueMapImage +clEnqueueUnmapMemObject +clEnqueueMigrateMemObjects +clEnqueueNDRangeKernel +clEnqueueNativeKernel +clEnqueueMarkerWithWaitList +clEnqueueBarrierWithWaitList +clEnqueueSVMFree +clEnqueueSVMMemcpy +clEnqueueSVMMemFill +clEnqueueSVMMap +clEnqueueSVMUnmap +clEnqueueSVMMigrateMem +clGetExtensionFunctionAddressForPlatform +clCreateImage2D +clCreateImage3D +clEnqueueMarker +clEnqueueWaitForEvents +clEnqueueBarrier +clUnloadCompiler +clGetExtensionFunctionAddress +clCreateCommandQueue +clCreateSampler +clEnqueueTask diff --git a/src/notzed.zcl/jni/include/CL/cl.h b/src/notzed.zcl/include/CL/cl.h similarity index 100% rename from src/notzed.zcl/jni/include/CL/cl.h rename to src/notzed.zcl/include/CL/cl.h diff --git a/src/notzed.zcl/jni/include/CL/cl_d3d10.h b/src/notzed.zcl/include/CL/cl_d3d10.h similarity index 100% rename from src/notzed.zcl/jni/include/CL/cl_d3d10.h rename to src/notzed.zcl/include/CL/cl_d3d10.h diff --git a/src/notzed.zcl/jni/include/CL/cl_d3d11.h b/src/notzed.zcl/include/CL/cl_d3d11.h similarity index 100% rename from src/notzed.zcl/jni/include/CL/cl_d3d11.h rename to src/notzed.zcl/include/CL/cl_d3d11.h diff --git a/src/notzed.zcl/jni/include/CL/cl_dx9_media_sharing.h b/src/notzed.zcl/include/CL/cl_dx9_media_sharing.h similarity index 100% rename from src/notzed.zcl/jni/include/CL/cl_dx9_media_sharing.h rename to src/notzed.zcl/include/CL/cl_dx9_media_sharing.h diff --git a/src/notzed.zcl/jni/include/CL/cl_egl.h b/src/notzed.zcl/include/CL/cl_egl.h similarity index 100% rename from src/notzed.zcl/jni/include/CL/cl_egl.h rename to src/notzed.zcl/include/CL/cl_egl.h diff --git a/src/notzed.zcl/jni/include/CL/cl_ext.h b/src/notzed.zcl/include/CL/cl_ext.h similarity index 100% rename from src/notzed.zcl/jni/include/CL/cl_ext.h rename to src/notzed.zcl/include/CL/cl_ext.h diff --git a/src/notzed.zcl/jni/include/CL/cl_gl.h b/src/notzed.zcl/include/CL/cl_gl.h similarity index 100% rename from src/notzed.zcl/jni/include/CL/cl_gl.h rename to src/notzed.zcl/include/CL/cl_gl.h diff --git a/src/notzed.zcl/jni/include/CL/cl_gl_ext.h b/src/notzed.zcl/include/CL/cl_gl_ext.h similarity index 100% rename from src/notzed.zcl/jni/include/CL/cl_gl_ext.h rename to src/notzed.zcl/include/CL/cl_gl_ext.h diff --git a/src/notzed.zcl/jni/include/CL/cl_platform.h b/src/notzed.zcl/include/CL/cl_platform.h similarity index 100% rename from src/notzed.zcl/jni/include/CL/cl_platform.h rename to src/notzed.zcl/include/CL/cl_platform.h diff --git a/src/notzed.zcl/jni/include/CL/opencl.h b/src/notzed.zcl/include/CL/opencl.h similarity index 100% rename from src/notzed.zcl/jni/include/CL/opencl.h rename to src/notzed.zcl/include/CL/opencl.h diff --git a/src/notzed.zcl/jni/jni.make b/src/notzed.zcl/jni/jni.make deleted file mode 100644 index 611bab7..0000000 --- a/src/notzed.zcl/jni/jni.make +++ /dev/null @@ -1,41 +0,0 @@ -# Copyright (C) 2015,2019 Michael Zucchi - -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. - -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -notzed.zcl_JNI_LIBRARIES=zcl - -linux-amd64_zcl_SOURCES = zcl-init-so.c -linux-amd64_zcl_LDLIBS = -L$(NATIVEZ_HOME)/lib -lnativez -dl - -windows-amd64_zcl_SOURCES = zcl-init-dll.c -windows-amd64_zcl_LDLIBS = -L$(NATIVEZ_HOME)/bin -lnativez - -zcl_SOURCES=zcl-jni.c \ - zcl-khr-gl-event.c \ - zcl-khr-gl-sharing.c \ - $($(TARGET)_zcl_SOURCES) - -zcl_CPPFLAGS=-Isrc/notzed.zcl/jni/include \ - -I$(notzed.zcl_jnidir) \ - -Wno-deprecated-declarations \ - -I$(NATIVEZ_HOME)/include - -zcl_LDLIBS=$($(TARGET)_zcl_LDLIBS) -zcl_DEFS=zcl-jni.def - -$(addprefix $(notzed.zcl_objdir)/,$(zcl_SOURCES:.c=.o)): bin/include/notzed.zcl/zcl-functions.h -bin/include/notzed.zcl/zcl-functions.h: src/notzed.zcl/jni/include/CL/cl.h src/notzed.zcl/jni/zcl-generate - @install -d $(@D) - src/notzed.zcl/jni/zcl-generate $< > $@.tmp - install -C $@.tmp $@ diff --git a/src/notzed.zcl/jni/zcl-extension.h b/src/notzed.zcl/jni/zcl-extension.h deleted file mode 100644 index dc49b67..0000000 --- a/src/notzed.zcl/jni/zcl-extension.h +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright (C) 2015 Michael Zucchi - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -/* - Common definitions. - Header file for extension handlers. - */ -#ifndef ZCL_EXTENSION_H -#define ZCL_EXTENSION_H - -jobject createExtension(JNIEnv *env, void *p, const char *className); - -jobject createExtension_cl_khr_gl_sharing(JNIEnv *env, cl_platform_id platform); -jobject createExtension_cl_khr_gl_event(JNIEnv *env, cl_platform_id platform); - -void *getExtensionAddress(cl_platform_id platform, const char *func); - -/* Utility functions */ -/* Convert property array to array, result must be freed if not null */ -void *fromPropertyArray(JNIEnv *env, jobjectArray jpropArray); - -/* CLObjects */ -jobject toCLObject(JNIEnv *env, int, void *p); -jobject toCLObjectArray(JNIEnv *env, int ctype, size_t count, void **ptrs); -int fromObjectArray(JNIEnv *env, jobjectArray jobjects, void **dst, int size); -jobject toArray(JNIEnv *env, int ctype, size_t size, void *value); -jobject toObject(JNIEnv *env, int ctype, size_t size, void *value); - -/* Exceptions */ - -#define THROW_ERROR_RET(res, ret) if (res != CL_SUCCESS) { throwCLException(env, res); return ret; } -#define THROW_ERROR(res) if (res != CL_SUCCESS) { throwCLException(env, res); return; } - -#define THROW_RTERROR_RET(res, ret) if (res != CL_SUCCESS) { throwCLRuntimeException(env, res); return ret; } -#define THROW_RTERROR(res) if (res != CL_SUCCESS) { throwCLRuntimeException(env, res); return; } - -#define C2J(x) ((jlong)(uintptr_t)(x)) -#define J2C(x) ((void *)(uintptr_t)(x)) - -void throwCLException(JNIEnv *env, jint id); -void throwCLRuntimeException(JNIEnv *env, jint id); -void throwException(JNIEnv *env, const char *type, const char *msg); -void throwUnsupportedOperation(JNIEnv *env, const char *fail); - -#define THROW_UNSUPPORTED_RET(fn, fail, ret) do { if (!fn) { throwUnsupportedOperation(env, fail); return ret; } } while (0) -#define THROW_UNSUPPORTED(fn, fail) do { if (!fn) { throwUnsupportedOperation(env, fail); return; } } while (0) - -/* Events */ - -#define EVENTS_MAX 28 - -struct events_info { - cl_int wait_count; - cl_event *waitersp; - cl_event *eventp; - - cl_event waiters[EVENTS_MAX]; - cl_event event; -}; - -int events_init(JNIEnv *env, struct events_info *einfo, jobject jwaiters, jobject jevents); -int events_post(JNIEnv *env, struct events_info *einfo, jobject jevents); - -/* Entry point for dynamic loader init & submodules, return 0 on success */ -int init_dynamic(JNIEnv *env); - -#endif diff --git a/src/notzed.zcl/jni/zcl-generate b/src/notzed.zcl/jni/zcl-generate deleted file mode 100755 index fc0de43..0000000 --- a/src/notzed.zcl/jni/zcl-generate +++ /dev/null @@ -1,100 +0,0 @@ -#!/usr/bin/perl - -# Copyright (C) 2015 Michael Zucchi - -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. - -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -# -# Compiles cl.h into function types and useful tables -# -# Fortunately cl.h is very strictly formatted so this is a simple task. -# - -# $1 == cl header files -$cl_h = $ARGV[0]; - -@fn = (); -%fnproto = {}; -$fnprefix = {}; -$fnsuffix = {}; - -open (H, "$cl_h") || die ("Can't open"); -while () { - if (m/^extern (CL_API_ENTRY.*)/) { - $start = $1; - $proto = ""; - while () { - chop($_); - $proto .= $_." "; - last if (m/;/); - } - - $proto =~ s@/\*.*?\*/@@g; - $proto =~ s@ +@ @g; - - if ($proto =~ m/^(\w+)(\(.*)/) { - $f = $1; - - push @fn, $f; - $fnprefix{$f} = $start; - $fnsuffix{$f} = $2; - } - } -} - -print "#ifndef _ZCL_FUNCIONS_H\n"; -print "/* Autogenerated by zcl-generate from $cl_h */\n\n"; -print "// Function types\n"; -for $f (@fn) { - print "typedef $fnprefix{$f} (*$f"."_fn) $fnsuffix{$f}\n"; -} - -print "#define zcl_fn_SIZEOF ".($#fn + 1)."\n"; - -print "#ifdef ZCL_DL_TABLE\n"; -print "// Entry point names\n"; -print "const char const * zcl_fn[] = {\n"; -for $f (@fn) { - print "\t\"$f\",\n"; -} -print "};\n"; -print "// Entry point addresses\n"; -print "const void *zcl_fp[zcl_fn_SIZEOF];\n"; -print "#else\n"; -print "// Entry point names\n"; -print "extern const char const * zcl_fn[zcl_fn_SIZEOF];\n"; -print "// Entry point addresses\n"; -print "extern const void *zcl_fp[zcl_fn_SIZEOF];\n"; -print "#endif\n"; - -print "// Invoke Macros\n"; -$i = 0; -for $f (@fn) { - print "#define $f (($f"."_fn)zcl_fp[$i])\n"; - $i++; -} - -print "// Checking macros\n"; -$i = 0; -for $f (@fn) { - $prefix = $fnprefix{$f}; - $suffix = $fnsuffix{$f}; - - print "#define CHECK_$f() (zcl_fp[$i])\n"; - print "#define FAIL_$f() do { if (!zcl_check_fn(env, $i)) return; } while (0)\n"; - print "#define FAIL_".$f."_RET(r) do { if (!zcl_check_fn(env, $i)) return (r); } while (0)\n"; - $i++; -} - -print "#endif /* _ZCL_FUNCTIONS_H */\n"; diff --git a/src/notzed.zcl/jni/zcl-init-dll.c b/src/notzed.zcl/jni/zcl-init-dll.c deleted file mode 100644 index 1a9a10e..0000000 --- a/src/notzed.zcl/jni/zcl-init-dll.c +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (C) 2015 Michael Zucchi - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -/* - shared library init for mingwin - */ - -#include - -#include -#include - -#include "zcl-extension.h" - -#define ZCL_DL_TABLE 1 -#include "zcl-functions.h" - -static void *lib_opencl; - -int init_dynamic(JNIEnv *env) { - lib_opencl = LoadLibrary("OpenCL.dll"); - - if (lib_opencl) { - for (int i=0;i. - */ - -#include -#ifdef HAVE_ALLOCA_H -#include -#endif -#ifdef HAVE_MALLOC_H -#include -#endif - -#include -#include "nativez.h" - -#include "au_notzed_zcl_CLBuffer.h" -#include "au_notzed_zcl_CLCommandQueue.h" -#include "au_notzed_zcl_CLContext.h" -#include "au_notzed_zcl_CLDevice.h" -#include "au_notzed_zcl_CLEvent.h" -#include "au_notzed_zcl_CLEventList.h" -#include "au_notzed_zcl_CLImage.h" -#include "au_notzed_zcl_CLKernel.h" -#include "au_notzed_zcl_CLMemory.h" -#include "au_notzed_zcl_CLObject.h" -#include "au_notzed_zcl_CLPlatform.h" -#include "au_notzed_zcl_CLProgram.h" - -#include - -#include "zcl-extension.h" -#include "zcl-functions.h" -#include "zcl-jni.h" - -// "real" version isn't what cl.h reports -#ifdef VERSION_IS_1_0 -#undef CL_VERSION_1_1 -#endif - -/** - * Primitive array transfers can only be blocking on OpenCL 1.0 - * - * Note however that for simplicity all primtiive array operations are blocking. - */ -#ifdef CL_VERSION_1_1 -#define PRIMITIVE_BLOCKING(x) 1 // x -#else -#define PRIMITIVE_BLOCKING(x) 1 -#endif - -#ifndef CL_VERSION_1_2 -typedef struct _cl_image_desc { - cl_mem_object_type image_type; - size_t image_width; - size_t image_height; - size_t image_depth; - size_t image_array_size; - size_t image_row_pitch; - size_t image_slice_pitch; - cl_uint num_mip_levels; - cl_uint num_samples; - cl_mem buffer; -} cl_image_desc; -#endif - -/* ********************************************************************** */ -/* Helpers */ - -#define D(x) //x; fflush(stdout) - -typedef void (JNICALL *getArrayRegion_t)(JNIEnv *env, jarray array, jsize start, jsize len, void *buf); -typedef void (JNICALL *setArrayRegion_t)(JNIEnv *env, jarray array, jsize start, jsize len, const void *buf); - -typedef void (JNICALL *getArrayRect_t)(JNIEnv *env, jarray array, jsize start, size_t region[3], jlong row_pitch, jlong slice_pitch, void *buf); -typedef void (JNICALL *setArrayRect_t)(JNIEnv *env, jarray array, jsize start, size_t region[3], jlong row_pitch, jlong slice_pitch, void *buf); - -// read or write -typedef void (JNICALL *copyRegion_t)(JNIEnv *env, jarray array, jsize start, jsize len, void *buf); - -// Read/write functions follow the same pattern, use it to reuse some code -typedef CL_API_ENTRY cl_int CL_API_CALL -(*enqueueReadWriteBuffer_t)(cl_command_queue /* command_queue */, - cl_mem /* buffer */, - cl_bool /* blocking_read */, - size_t /* offset */, - size_t /* size */, - void * /* ptr */, - cl_uint /* num_events_in_wait_list */, - const cl_event * /* event_wait_list */, - cl_event * /* event */); - -typedef CL_API_ENTRY cl_int CL_API_CALL -(*enqueueReadWriteBufferRect_t)(cl_command_queue /* command_queue */, - cl_mem /* buffer */, - cl_bool /* blocking_read */, - const size_t * /* buffer_offset */, - const size_t * /* host_offset */, - const size_t * /* region */, - size_t /* buffer_row_pitch */, - size_t /* buffer_slice_pitch */, - size_t /* host_row_pitch */, - size_t /* host_slice_pitch */, - void * /* ptr */, - cl_uint /* num_events_in_wait_list */, - const cl_event * /* event_wait_list */, - cl_event * /* event */); - -typedef CL_API_ENTRY cl_int CL_API_CALL -(*enqueueReadWriteImage_t)(cl_command_queue /* command_queue */, - cl_mem /* image */, - cl_bool /* blocking_read */, - const size_t * /* origin[3] */, - const size_t * /* region[3] */, - size_t /* row_pitch */, - size_t /* slice_pitch */, - void * /* ptr */, - cl_uint /* num_events_in_wait_list */, - const cl_event * /* event_wait_list */, - cl_event * /* event */); - - -static const char * const names[au_notzed_zcl_CLObject_CTYPE_SIZEOF] = { - "CLPlatform", - "CLDevice", - "CLContext", - "CLCommandQueue", - "CLPipe", - "CLBuffer", - "CLImage", - "CLSampler", - "CLProgram", - "CLKernel", - "CLEvent" -}; - -size_t const ctype_sizes[] = { - sizeof(void *), - sizeof(void *), - sizeof(void *), - sizeof(void *), - sizeof(void *), - sizeof(void *), - sizeof(void *), - sizeof(void *), - sizeof(void *), - sizeof(void *), - sizeof(void *), - 0, // reserves - 0, - 0, - 0, - 0, - sizeof(size_t), - 1, // byte - 2, // short - 4, // int - 8, // long - 4, // float - 8, // double -}; - -static JavaVM *vm; - -static jclass classid[au_notzed_zcl_CLObject_CTYPE_SIZEOF]; - -/* special constructor for handling notify */ -static jmethodID CLContext_new_pn; -/* special constructor for handling buffer */ -static jmethodID CLBuffer_new_jb; - -static int debug_sync = 0; - -/* ********************************************************************** */ - -jint JNI_OnLoad(JavaVM *vmi, void *reserved) { - jclass jc; - char name[64]; - JNIEnv *env; - - D(printf("libclz.so: OnLoad()\n")); - - /* Save VM - required for callbacks from threads */ - vm = vmi; - - if ((*vmi)->GetEnv(vmi, (void *)&env, JNI_VERSION_1_4) < 0) - return 0; - - /* Lookup and save all the class / method / field handles */ - for (int i=0;iFindClass(env, name); - if (jc == NULL) { - fprintf(stderr, "class not found: %s\n", name); - return 0; - } - - classid[i] = jc = (*env)->NewGlobalRef(env, jc); - } - - CLContext_new_pn = (*env)->GetMethodID(env, classid[au_notzed_zcl_CLObject_CTYPE_CONTEXT], "", "(JLau/notzed/zcl/CLContextNotify;)V"); - CLBuffer_new_jb = (*env)->GetMethodID(env, classid[au_notzed_zcl_CLObject_CTYPE_BUFFER], "", "(JLjava/nio/ByteBuffer;)V"); - - if (nativez_OnLoad(vmi, env) - || init_dynamic(env) - || nativez_ResolveReferences(env, java_names, &java) != 0) - return 0; - - char *s = getenv("ZCL_SYNC"); - if (s) - debug_sync = atoi(s); - - return JNI_VERSION_1_4; -} - -static int zcl_check_fn(JNIEnv *env, int fid) { - int ok = zcl_fp[fid] != NULL; - - if (!ok) - throwException(env, "java/lang/UnsupportedOperationException", zcl_fn[fid]); - - return ok; -} - -void throwCLException(JNIEnv *env, jint id) { - jclass jc = (*env)->FindClass(env, "au/notzed/zcl/CLException"); - jmethodID new_i = (*env)->GetMethodID(env, jc, "", "(I)V"); - jobject ex = (*env)->NewObject(env, jc, new_i, id); - - (*env)->Throw(env, ex); -} - -void throwCLRuntimeException(JNIEnv *env, jint id) { - jclass jc = (*env)->FindClass(env, "au/notzed/zcl/CLRuntimeException"); - jmethodID new_i = (*env)->GetMethodID(env, jc, "", "(I)V"); - jobject ex = (*env)->NewObject(env, jc, new_i, id); - - (*env)->Throw(env, ex); -} - -void throwException(JNIEnv *env, const char *type, const char *msg) { - jclass jc = (*env)->FindClass(env, type); - - if (jc) - (*env)->ThrowNew(env, jc, msg); -} - -void throwUnsupportedOperation(JNIEnv *env, const char *fail) { - throwException(env, "java/lang/UnsupportedOperationException", fail); -} - -#define GETP(env, o) NativeZ_getP(env, o) - -static int check_p(JNIEnv *env, jobject src, void **dst, const char *fail) { - if (!src) { - throwException(env, "java/lang/NullPointerException", fail); - return 1; - } - - *dst = GETP(env, src); - - return 0; -} - -#define GET_P(env, jval, val, ret, error) do { if (check_p(env, jval, (void **)&val, error)) return ret; } while (0) - -static int check_array_min(JNIEnv *env, jobject src, jsize min, const char *fail) { - jsize size; - - if (!src) { - throwException(env, "java/lang/NullPointerException", fail); - return 1; - } - - size = (*env)->GetArrayLength(env, src); - if (size < min) { - throwException(env, "java/lang/ArrayIndexOutOfBoundsException", fail); - return 1; - } - - return 0; -} - -#define CHECK_ARRAY_MIN(env, jval, min, ret, error) do { if (check_array_min(env, jval, min, error)) return ret; } while (0) - -static int check_null(JNIEnv *env, jobject jo, const char *fail) { - if (!jo) { - throwException(env, "java/lang/NullPointerException", fail); - return 1; - } - return 0; -} - -#define CHECK_NULL(env, jo, ret, error) do { if (check_null(env, jo, error)) return ret; } while (0) - -int fromObjectArray(JNIEnv *env, jobjectArray jobjects, void **dst, int size) { - for (int i=0;iGetObjectArrayElement(env, jobjects, i); - - dst[i] = GETP(env, jo); - } - - return 0; -} - -jobject toCLObject(JNIEnv *env, int id, void *p) { - if (id < au_notzed_zcl_CLObject_CTYPE_SIZEOF) { - return NativeZ_resolve(env, classid[id], p); - } else { - throwCLRuntimeException(env, CL_INVALID_VALUE); - return NULL; - } -} - -/* unified object instantiator for CLObject and boxed primitive types */ -jobject toObject(JNIEnv *env, int ctype, size_t size, void *value) { - jobject jres = NULL; - jvalue jarg; - - switch (ctype) { - //case au_notzed_zcl_CLObject_CTYPE_BYTE: - case au_notzed_zcl_CLObject_CTYPE_INT: - jarg.i = ((cl_int *)value)[0]; - jres = (*env)->CallStaticObjectMethodA(env, Integer_classid, Integer_valueOf_i, &jarg); - break; - case au_notzed_zcl_CLObject_CTYPE_LONG: - jarg.j = ((cl_long *)value)[0]; - jres = (*env)->CallStaticObjectMethodA(env, Long_classid, Long_valueOf_j, &jarg); - break; - case au_notzed_zcl_CLObject_CTYPE_SIZE_T: - jarg.j = ((size_t *)value)[0]; - jres = (*env)->CallStaticObjectMethodA(env, Long_classid, Long_valueOf_j, &jarg); - break; - default: - jres = toCLObject(env, ctype, ((void **)value)[0]); - break; - } - - return jres; -} - -jobject toCLObjectArray(JNIEnv *env, int ctype, size_t count, void **ptrs) { - jobject jvalue = NULL; - - if (ctype < au_notzed_zcl_CLObject_CTYPE_SIZEOF) { - jvalue = (*env)->NewObjectArray(env, count, classid[ctype], NULL); - if (jvalue) { - for (int i=0;iSetObjectArrayElement(env, jvalue, i, o); - } - } - } else { - throwCLRuntimeException(env, CL_INVALID_VALUE); - } - - return jvalue; -} - -/* unified array builder based on CTYPE* defines */ -jobject toArray(JNIEnv *env, int ctype, size_t size, void *value) { - jobject jvalue = NULL; - int count; - - switch (ctype) { - case au_notzed_zcl_CLObject_CTYPE_BYTE: - count = size; - jvalue = (*env)->NewByteArray(env, count); - if (jvalue) - (*env)->SetByteArrayRegion(env, jvalue, 0, count, (jbyte *)value); - break; - case au_notzed_zcl_CLObject_CTYPE_INT: - count = size / sizeof(cl_int); - jvalue = (*env)->NewIntArray(env, count); - if (jvalue) - (*env)->SetIntArrayRegion(env, jvalue, 0, count, (jint *)value); - break; - case au_notzed_zcl_CLObject_CTYPE_LONG: - count = size / sizeof(cl_long); - jvalue = (*env)->NewLongArray(env, count); - if (jvalue) - (*env)->SetLongArrayRegion(env, jvalue, 0, count, (jlong *)value); - break; - case au_notzed_zcl_CLObject_CTYPE_SIZE_T: - count = size / sizeof(size_t); - jvalue = (*env)->NewLongArray(env, count); - if (jvalue) { - if (sizeof(size_t) == sizeof(jlong)) { - (*env)->SetLongArrayRegion(env, jvalue, 0, count, (jlong *)value); - } else { - jlong *tmp = alloca(count * sizeof(*tmp)); - size_t *data = value; - - for (int i=0;iSetLongArrayRegion(env, jvalue, 0, count, (jlong *)tmp); - } - } - break; - default: - jvalue = toCLObjectArray(env, ctype, size / sizeof(void *), value); - break; - } - - return jvalue; -} - -/* Convert a tag/value property array to a primitive array */ -void *fromPropertyArray(JNIEnv *env, jobjectArray jpropArray) { -#if UINTPTR_MAX == 0xffffffffU - jint *res = NULL; - - if (jpropArray) { - jvalue jargs = { .l = jpropArray }; - jlongArray ptmp = (*env)->CallStaticObjectMethodA(env, CLProperty_classid, CLProperty_toInt__l, &jargs); - - if (!(*env)->ExceptionCheck(env)) { - jint plen = (*env)->GetArrayLength(env, ptmp); - res = malloc(sizeof(*res) * plen); - if (res) - (*env)->GetIntArrayRegion(env, ptmp, 0, plen, res); - else - throwException(env, "java/lang/OutOfMemoryError", "Allocating propery list"); - } - } - return res; -#else - jlong *res = NULL; - - if (jpropArray) { - jvalue jargs = { .l = jpropArray }; - jlongArray ptmp = (*env)->CallStaticObjectMethodA(env, CLProperty_classid, CLProperty_toLong__l, &jargs); - - if (!(*env)->ExceptionCheck(env)) { - jint plen = (*env)->GetArrayLength(env, ptmp); - res = malloc(sizeof(*res) * plen); - if (res) - (*env)->GetLongArrayRegion(env, ptmp, 0, plen, res); - else - throwException(env, "java/lang/OutOfMemoryError", "Allocating property list"); - } - } - return res; - -#endif -} - -/** - * Convert a jlongArray to a size_t * - */ -static void getSizeTA(JNIEnv *env, jlongArray jsrc, size_t *dst, size_t count) { - memset(dst, 0, sizeof(*dst) * count); - if (jsrc) { - if (sizeof(size_t) == sizeof(jlong)) - (*env)->GetLongArrayRegion(env, jsrc, 0, count, (jlong *)dst); - else { - jlong *jdst = alloca(sizeof(*jdst) * count); - (*env)->GetLongArrayRegion(env, jsrc, 0, count, jdst); - for (int i=0;iGetIntField(env, jo, CLExtendable_apiVersion); -} - -static int checkAPIVersion(JNIEnv *env, jobject jo, jint version) { - return getAPIVersion(env, jo) >= version; -} - -/* ********************************************************************** */ - -/* - Some helper code to manage the mess of dealing with CLEventList for - waiting and event output. - - The primary task is to copy the CLEventList.events list for the 'waiters' - object to a local cl_event array, and after-the-event to invoke - CLEventList.add() if an event must be recorded as output. - - See any of the CLCommandQueue.enqueue*() functions for how it's used. - - To avoid the overhead of malloc and the need for alloca() in the callee - waiters[] is fixed in size, but that could be changed here. - */ -int events_init(JNIEnv *env, struct events_info *einfo, jobject jwaiters, jobject jevents) { - if (jwaiters) { - int count = (*env)->GetIntField(env, jwaiters, CLEventList_index); - jlongArray jwaitlist = (*env)->GetObjectField(env, jwaiters, CLEventList_events); - - if (count > EVENTS_MAX) { - throwException(env, "java/lang/ArrayIndexOutOfBoundsException", "Waiting list exceeds internal limit"); - return -1; - } - - einfo->wait_count = count; - einfo->waitersp = &einfo->waiters[0]; - - if (sizeof(cl_event) == sizeof(jlong)) { - (*env)->GetLongArrayRegion(env, jwaitlist, 0, count, (jlong *)&einfo->waiters[0]); - } else { - jlong *levents = alloca(count * sizeof(*levents)); - (*env)->GetLongArrayRegion(env, jwaitlist, 0, count, levents); - for (int i=0;iwaiters[i] = (cl_event)(uintptr_t)levents[i]; - } - } else { - einfo->wait_count = 0; - einfo->waitersp = NULL; - } - - if (jevents) - einfo->eventp = &einfo->event; - else - einfo->eventp = NULL; - - return 0; -} - -int events_post(JNIEnv *env, struct events_info *einfo, jobject jevents) { - if (jevents) { - jvalue arg = { .j = (uintptr_t)einfo->event }; - - (*env)->CallVoidMethodA(env, jevents, CLEventList_add_j, &arg); - } - - return 0; -} - -/* ********************************************************************** */ -/* Build/compile/link notify handler */ - -struct build_notify_info { - cl_program prog; - jobject jprog; - jobject jnotify; -}; - -static struct build_notify_info *build_notify_alloc(JNIEnv *env, cl_program prog, jobject jprog, jobject jnotify) { - struct build_notify_info *data = malloc(sizeof(*data)); - - if (!data) { - throwException(env, "java/lang/OutOfMemoryError", "Allocating hook data"); - return NULL; - } - - data->prog = prog; - data->jnotify = (*env)->NewGlobalRef(env, jnotify); - data->jprog = jprog ? (*env)->NewGlobalRef(env, jprog) : NULL; - - - return data; -} - -static void build_notify_hook(cl_program prog, void *data) { - struct build_notify_info *info = data; - JNIEnv *env; - - D(printf("build notify()\n")); - - if (!(env = nativez_AttachCurrentThreadAsDaemon())) { - // NB: can't do anything here - fprintf(stderr, "Unable to attach java environment\n"); - free(data); - return; - } - - if (!info->jprog) { - /* For linking, this is the first time we've seen the program */ - jvalue arg = { .l = toCLObject(env, au_notzed_zcl_CLObject_CTYPE_PROGRAM, prog) }; - - (*env)->CallVoidMethodA(env, info->jnotify, CLNotify_notify_l, &arg); - } else if (info->prog == prog) { - jvalue arg = { .l = info->jprog }; - - (*env)->CallVoidMethodA(env, info->jnotify, CLNotify_notify_l, &arg); - } else { - fprintf(stderr, "build_notify_hook given wrong cl_program\n"); - } - - (*env)->DeleteGlobalRef(env, info->jnotify); - if (info->jprog) - (*env)->DeleteGlobalRef(env, info->jprog); - - free(info); -} - -/* ********************************************************************** */ - -/* APIs */ - -/* ********************************************************************** */ - -/* CLObject */ - -/* - To cut-down on significant API baggage the getInfo, retain, and - release methods are implemented in an object-oriented way using - using a manual type specifier. - - Some info queries have target-specific variants. - */ - - -JNIEXPORT void JNICALL Java_au_notzed_zcl_CLSampler_release -(JNIEnv *env, jclass jc, jlong jp) { - cl_int res; - FAIL_clReleaseSampler(); - res = clReleaseSampler((cl_sampler)jp); - if (res != CL_SUCCESS) - throwCLRuntimeException(env, res); -} - -JNIEXPORT void JNICALL Java_au_notzed_zcl_CLProgram_release -(JNIEnv *env, jclass jc, jlong jp) { - cl_int res; - FAIL_clReleaseProgram(); - res = clReleaseProgram((cl_program)jp); - if (res != CL_SUCCESS) - throwCLRuntimeException(env, res); -} - -/* */ - -static int getInfo(JNIEnv *env, void *jid, jint type, jint param, size_t size, void *val, void *size_ret) { - switch (type) { - case au_notzed_zcl_CLObject_TYPE_PLATFORM: - FAIL_clGetPlatformInfo_RET(-1); - return clGetPlatformInfo((cl_platform_id)jid, param, size, val, size_ret); - case au_notzed_zcl_CLObject_TYPE_DEVICE: - FAIL_clGetDeviceInfo_RET(-1); - return clGetDeviceInfo((cl_device_id)jid, param, size, val, size_ret); - case au_notzed_zcl_CLObject_TYPE_CONTEXT: - FAIL_clGetContextInfo_RET(-1); - return clGetContextInfo((cl_context)jid, param, size, val, size_ret); - case au_notzed_zcl_CLObject_TYPE_COMMAND_QUEUE: - FAIL_clGetCommandQueueInfo_RET(-1); - return clGetCommandQueueInfo((cl_command_queue)jid, param, size, val, size_ret); - case au_notzed_zcl_CLObject_TYPE_MEM_OBJECT: - FAIL_clGetMemObjectInfo_RET(-1); - return clGetMemObjectInfo((cl_mem)jid, param, size, val, size_ret); - case au_notzed_zcl_CLObject_TYPE_IMAGE: - FAIL_clGetImageInfo_RET(-1); - return clGetImageInfo((cl_mem)jid, param, size, val, size_ret); - case au_notzed_zcl_CLObject_TYPE_PIPE: -#ifdef CL_VERSION_2_0 - FAIL_clGetPipeInfo_RET(-1); - return clGetPipeInfo((cl_mem)jid, param, size, val, size_ret); -#else - return CL_INVALID_OPERATION; -#endif - case au_notzed_zcl_CLObject_TYPE_SAMPLER: - FAIL_clGetSamplerInfo_RET(-1); - return clGetSamplerInfo((cl_sampler)jid, param, size, val, size_ret); - case au_notzed_zcl_CLObject_TYPE_PROGRAM: - FAIL_clGetProgramInfo_RET(-1); - return clGetProgramInfo((cl_program)jid, param, size, val, size_ret); - case au_notzed_zcl_CLObject_TYPE_KERNEL: - FAIL_clGetKernelInfo_RET(-1); - return clGetKernelInfo((cl_kernel)jid, param, size, val, size_ret); - case au_notzed_zcl_CLObject_TYPE_EVENT: - FAIL_clGetEventInfo_RET(-1); - return clGetEventInfo((cl_event)jid, param, size, val, size_ret); - case au_notzed_zcl_CLObject_TYPE_EVENT_PROFILING: - FAIL_clGetEventProfilingInfo_RET(-1); - return clGetEventProfilingInfo((cl_event)jid, param, size, val, size_ret); - default: - return CL_INVALID_VALUE; - } -} - -JNIEXPORT jobject JNICALL Java_au_notzed_zcl_CLObject_getInfoAny -(JNIEnv *env, jobject jid, jint type, int otype, jint param) { - void *jp = GETP(env, jid); - void *value; - size_t size = ctype_sizes[otype]; - cl_int res; - - value = alloca(size); - res = getInfo(env, jp, type, param, size, value, NULL); - THROW_RTERROR_RET(res, NULL); - - return toObject(env, otype, size, value); -} - -JNIEXPORT jint JNICALL Java_au_notzed_zcl_CLObject_getInfoInt -(JNIEnv *env, jobject jid, jint type, jint param) { - void *jp = GETP(env, jid); - cl_int res; - jint value; - - res = getInfo(env, jp, type, param, sizeof(value), &value, NULL); - THROW_RTERROR_RET(res, 0); - - return value; -} - -JNIEXPORT jlong JNICALL Java_au_notzed_zcl_CLObject_getInfoLong -(JNIEnv *env, jobject jid, jint type, jint param) { - void *jp = GETP(env, jid); - cl_int res; - jlong value; - - res = getInfo(env, jp, type, param, sizeof(value), &value, NULL); - THROW_RTERROR_RET(res, 0); - - return value; -} - -JNIEXPORT jlong JNICALL Java_au_notzed_zcl_CLObject_getInfoSizeT -(JNIEnv *env, jobject jid, jint type, jint param) { - void *jp = GETP(env, jid); - cl_int res; - size_t value; - - res = getInfo(env, jp, type, param, sizeof(value), &value, NULL); - THROW_RTERROR_RET(res, 0); - - return value; -} - -JNIEXPORT jobject JNICALL Java_au_notzed_zcl_CLObject_getInfoAnyV -(JNIEnv *env, jobject jid, jint type, int otype, jint param) { - void *jp = GETP(env, jid); - void *value; - size_t size; - cl_int res; - - res = getInfo(env, jp, type, param, 0, NULL, &size); - THROW_RTERROR_RET(res, NULL); - - value = alloca(size); - - res = getInfo(env, jp, type, param, size, value, NULL); - THROW_RTERROR_RET(res, NULL); - - return toArray(env, otype, size, value); -} - -/* - Query a property list and convert it to an array. - - Most properties are simple tag+value pairs but not all so this must - handle those specifically. -*/ -static jobjectArray getInfoProperties -(JNIEnv *env, jobject jsrc, jint type, jint param, jclass array_classid, jclass new_classid, jmethodID new_tagvalue) { - void *src = GETP(env, jsrc); - intptr_t *props; - cl_int res; - size_t size; - int count, limit; - jobjectArray jprops; - - res = getInfo(env, src, type, param, 0, NULL, &size); - THROW_RTERROR_RET(res, NULL); - - if (size == 0) - return (*env)->NewObjectArray(env, 0, array_classid, NULL); - - props = alloca(size); - res = getInfo(env, src, type, param, size, props, &size); - THROW_RTERROR_RET(res, NULL); - - limit = size / sizeof(*props); - count = 0; - for (int i=0;i < limit && props[i];) { - intptr_t p = props[i]; - - count += 1; - - switch (p) { - case CL_DEVICE_PARTITION_BY_COUNTS: - i++; - while (props[i] != CL_DEVICE_PARTITION_BY_COUNTS_LIST_END) - i++; - break; - default: - i += 2; - break; - } - } - - jprops = (*env)->NewObjectArray(env, count, array_classid, NULL); - if (!jprops) - return NULL; - - for (int i=0, j=0;iNewIntArray(env, ccount); - - for (int k=0;kSetIntArrayRegion(env, jcounts, 0, ccount, counts); - - jo = (*env)->NewObject(env, - CLDeviceProperty_PartitionByCounts_classid, - CLDeviceProperty_PartitionByCounts_new__i, - jcounts); - break; - } - default: - jo = (*env)->NewObject(env, new_classid, new_tagvalue, - (jlong)props[i], - (jlong)props[i+1]); - i += 2; - break; - } - - (*env)->SetObjectArrayElement(env, jprops, j, jo); - } - - return jprops; -} - -JNIEXPORT void JNICALL Java_au_notzed_zcl_CLObject_retain -(JNIEnv *env, jobject jid, jint type) { - void *jp = GETP(env, jid); - cl_int res = CL_INVALID_VALUE; - - switch (type) { - case au_notzed_zcl_CLObject_TYPE_PLATFORM: - return; - case au_notzed_zcl_CLObject_TYPE_DEVICE: -#ifdef CL_VERSION_1_2 - if (CHECK_clRetainDevice()) - res = clRetainDevice((cl_device_id)jp); - else - return; - break; -#else - return; -#endif - case au_notzed_zcl_CLObject_TYPE_CONTEXT: - FAIL_clRetainContext(); - res = clRetainContext((cl_context)jp); - break; - case au_notzed_zcl_CLObject_TYPE_COMMAND_QUEUE: - FAIL_clRetainCommandQueue(); - res = clRetainCommandQueue((cl_command_queue)jp); - break; - case au_notzed_zcl_CLObject_TYPE_MEM_OBJECT: - case au_notzed_zcl_CLObject_TYPE_IMAGE: - case au_notzed_zcl_CLObject_TYPE_PIPE: - FAIL_clRetainMemObject(); - res = clRetainMemObject((cl_mem)jp); - break; - case au_notzed_zcl_CLObject_TYPE_SAMPLER: - FAIL_clRetainSampler(); - res = clRetainSampler((cl_sampler)jp); - break; - case au_notzed_zcl_CLObject_TYPE_PROGRAM: - FAIL_clRetainProgram(); - res = clRetainProgram((cl_program)jp); - break; - case au_notzed_zcl_CLObject_TYPE_KERNEL: - FAIL_clRetainKernel(); - res = clRetainKernel((cl_kernel)jp); - break; - case au_notzed_zcl_CLObject_TYPE_KERNEL_WORK_GROUP: - break; - case au_notzed_zcl_CLObject_TYPE_EVENT: - FAIL_clRetainEvent(); - res = clRetainEvent((cl_event)jp); - break; - case au_notzed_zcl_CLObject_TYPE_EVENT_PROFILING: - break; - } - - if (res != CL_SUCCESS) { - throwCLException(env, res); - return; - } -} - -/* ********************************************************************** */ -/* CLPlatform */ - -JNIEXPORT void JNICALL Java_au_notzed_zcl_CLPlatform_release -(JNIEnv *env, jclass jc, jlong jp) { - // NOOP -} - -JNIEXPORT jobjectArray JNICALL Java_au_notzed_zcl_CLPlatform_getPlatforms -(JNIEnv *env, jclass jc) { - FAIL_clGetPlatformIDs_RET(NULL); - - cl_platform_id *platforms; - cl_int res; - cl_uint count; - - res = clGetPlatformIDs(0, NULL, &count); - THROW_RTERROR_RET(res, NULL); - - platforms = alloca(sizeof(*platforms) * count); - - res = clGetPlatformIDs(count, platforms, NULL); - THROW_RTERROR_RET(res, NULL); - - return toCLObjectArray(env, au_notzed_zcl_CLObject_CTYPE_PLATFORM, count, (void **)platforms); -} - -JNIEXPORT jobjectArray JNICALL Java_au_notzed_zcl_CLPlatform_getDevices -(JNIEnv *env, jobject jplatform, jlong type) { - cl_platform_id platform = GETP(env, jplatform); - cl_device_id *devices; - cl_uint count; - cl_int res; - - res = clGetDeviceIDs(platform, type, 0, NULL, &count); - if (res == CL_DEVICE_NOT_FOUND) - return toCLObjectArray(env, au_notzed_zcl_CLObject_CTYPE_DEVICE, 0, NULL); - - THROW_RTERROR_RET(res, NULL); - - devices = alloca(sizeof(devices[0]) * count); - - res = clGetDeviceIDs(platform, type, count, devices, NULL); - THROW_RTERROR_RET(res, NULL); - - return toCLObjectArray(env, au_notzed_zcl_CLObject_CTYPE_DEVICE, count, (void **)devices); -} - -JNIEXPORT void JNICALL Java_au_notzed_zcl_CLPlatform_unloadPlatformCompiler -(JNIEnv *env, jobject jplatform) { -#ifdef CL_VERSION_1_2 - if (CHECK_clUnloadPlatformCompiler()) { - cl_platform_id platform = GETP(env, jplatform); - cl_int res; - - res = clUnloadPlatformCompiler(platform); - THROW_RTERROR(res); - } else { - cl_int res; - - res = clUnloadCompiler(); - THROW_RTERROR(res); - } -#else - cl_int res; - - res = clUnloadCompiler(); - THROW_RTERROR(res); -#endif -} - -/* ********************************************************************** */ -/* CLPlatform - CLExtension(s) */ -#include - -jobject createExtension(JNIEnv *env, void *p, const char *className) { - jclass jc = (*env)->FindClass(env, className); - if (jc == NULL) - return NULL; - - return NativeZ_create(env, jc, p); -} - -void *getExtensionAddress(cl_platform_id platform, const char *func) { -#ifdef CL_VERSION_1_2 - if (CHECK_clGetExtensionFunctionAddressForPlatform()) - return clGetExtensionFunctionAddressForPlatform(platform, func); -#endif - if (CHECK_clGetExtensionFunctionAddress()) - return clGetExtensionFunctionAddress(func); - else - return NULL; -} - -JNIEXPORT jobject JNICALL Java_au_notzed_zcl_CLPlatform_createExtension -(JNIEnv *env, jobject jplatform, jint extensionid) { - cl_platform_id platform = GETP(env, jplatform); - - switch (extensionid) { - case au_notzed_zcl_CLPlatform_cl_khr_gl_sharing: - return createExtension_cl_khr_gl_sharing(env, platform); - case au_notzed_zcl_CLPlatform_cl_khr_gl_event: - return createExtension_cl_khr_gl_event(env, platform); - } - - // throws unknownextension? - throwUnsupportedOperation(env, "Unknown extension number"); - return NULL; -} - -/* ********************************************************************** */ -/* CLDevice */ - -JNIEXPORT void JNICALL Java_au_notzed_zcl_CLDevice_release -(JNIEnv *env, jclass jc, jlong jp) { - // NOOP -} - -JNIEXPORT void JNICALL Java_au_notzed_zcl_CLDevice_getDeviceAndHostTimer -(JNIEnv *env, jobject jdevice, jlongArray jdst) { -#ifdef CL_VERSION_2_1 - if (checkAPIVersion(env, jdevice, au_notzed_zcl_CLPlatform_VERSION_2_1)) { - FAIL_clGetDeviceAndHostTimer(); - - cl_device_id device = GETP(env, jdevice); - cl_int res; - cl_ulong ts[2]; - - res = clGetDeviceAndHostTimer(device, &ts[0], &ts[1]); - THROW_RTERROR(res); - - (*env)->SetLongArrayRegion(env, jdst, 0, 2, (jlong *)ts); - } else -#endif - throwException(env, "java/lang/UnsupportedOperationException", "Requires OpenCL 2.1"); -} - -JNIEXPORT jlong JNICALL Java_au_notzed_zcl_CLDevice_getHostTimer -(JNIEnv *env, jobject jdevice) { -#ifdef CL_VERSION_2_1 - if (checkAPIVersion(env, jdevice, au_notzed_zcl_CLPlatform_VERSION_2_1)) { - FAIL_clGetHostTimer_RET(0); - - cl_device_id device = GETP(env, jdevice); - cl_int res; - cl_ulong ts; - - res = clGetHostTimer(device, &ts); - THROW_RTERROR_RET(res, 0); - - return ts; - } else -#endif - throwException(env, "java/lang/UnsupportedOperationException", "Requires OpenCL 2.1"); - return 0; -} - -JNIEXPORT jobjectArray JNICALL Java_au_notzed_zcl_CLDevice_createSubDevices -(JNIEnv *env, jobject jdevice, jobjectArray jprops, jint count) { -#ifdef CL_VERSION_1_2 - FAIL_clCreateSubDevices_RET(NULL); - - cl_device_id device = GETP(env, jdevice); - cl_int res; - cl_device_partition_property *props = fromPropertyArray(env, jprops); - cl_device_id *devices; - cl_uint dcount; - - if ((*env)->ExceptionCheck(env)) return NULL; - - devices = alloca(sizeof(*devices) * count); - - res = clCreateSubDevices(device, props, count, devices, &dcount); - free(props); - - THROW_ERROR_RET(res, NULL); - - return toCLObjectArray(env, au_notzed_zcl_CLObject_CTYPE_DEVICE, dcount, (void **)devices); -#else - throwException(env, "java/lang/UnsupportedOperationException", "Requires OpenCL 1.2"); - return NULL; -#endif -} - -JNIEXPORT jobjectArray JNICALL Java_au_notzed_zcl_CLDevice_getPartitionProperties -(JNIEnv *env, jobject jcontext) { -#ifdef CL_VERSION_1_2 - return getInfoProperties(env, jcontext, au_notzed_zcl_CLObject_TYPE_DEVICE, CL_DEVICE_PARTITION_PROPERTIES, - CLDeviceProperty_classid, - CLDeviceProperty_TagValue_classid, CLDeviceProperty_TagValue_new_jj); -#else - throwException(env, "java/lang/UnsupportedOperationException", "Requires OpenCL 1.2"); - return NULL; -#endif -} - -JNIEXPORT jobjectArray JNICALL Java_au_notzed_zcl_CLDevice_getPartitionType -(JNIEnv *env, jobject jcontext) { -#ifdef CL_VERSION_1_2 - return getInfoProperties(env, jcontext, au_notzed_zcl_CLObject_TYPE_DEVICE, CL_DEVICE_PARTITION_TYPE, - CLDeviceProperty_classid, - CLDeviceProperty_TagValue_classid, CLDeviceProperty_TagValue_new_jj); -#else - throwException(env, "java/lang/UnsupportedOperationException", "Requires OpenCL 1.2"); - return NULL; -#endif -} - -/* ********************************************************************** */ -/* CLContext */ - -JNIEXPORT void JNICALL Java_au_notzed_zcl_CLContext_release -(JNIEnv *env, jclass jc, jlong jp) { - cl_int res; - - FAIL_clReleaseContext(); - if ((res = clReleaseContext((cl_context)jp)) != CL_SUCCESS) - throwCLRuntimeException(env, res); -} - -/** - * Bounces the context notify callback to java - */ -static void context_notify_hook(const char *error_info, const void *private_info, size_t private_size, void *data) { - JNIEnv *env; - jobject jnotify = data; - jobject jerror_info; - jobject jprivate_info = NULL; - - D(printf("context notify: %s\n", error_info)); - - if (!(env = nativez_AttachCurrentThreadAsDaemon())) { - fprintf(stderr, "Unable to attach java environment\n"); - return; - } - - jnotify = (*env)->NewLocalRef(env, jnotify); - if (!jnotify) { - fprintf(stderr, "cl_context notify called after object death\n"); - return; - } - - jerror_info = (*env)->NewStringUTF(env, error_info); - - if (private_info && private_size) - jprivate_info = nativez_NewDirectBuffer(env, (void *)private_info, private_size); - - jvalue args[2] = { - { .l = jerror_info }, - { .l = jprivate_info } - }; - - (*env)->CallVoidMethodA(env, jnotify, CLContextNotify_notify_ll, args); -} - -JNIEXPORT jobject JNICALL Java_au_notzed_zcl_CLContext_createContext -(JNIEnv *env, jclass jc, jobjectArray jprops, jobjectArray jdevices, jobject jnotify) { - FAIL_clCreateContext_RET(NULL); - - cl_context_properties *props = fromPropertyArray(env, jprops); - cl_device_id *devices; - cl_int res; - cl_context ret; - int dlen; - void (CL_CALLBACK* notify)(const char *, const void *, size_t, void *); - void *data; - - if ((*env)->ExceptionCheck(env)) return NULL; - - if (jdevices) { - dlen = (*env)->GetArrayLength(env, jdevices); - devices = alloca(dlen * sizeof(*devices)); - fromObjectArray(env, jdevices, (void **)devices, dlen); - } else { - devices = NULL; - dlen = 0; - } - - if (jnotify) { - // Note: solid reference is handled by constructor - notify = context_notify_hook; - data = (*env)->NewWeakGlobalRef(env, jnotify); - } else { - notify = NULL; - data = NULL; - } - - ret = clCreateContext(props, dlen, devices, notify, data, &res); - free(props); - THROW_RTERROR_RET(res, NULL); - - return NativeZ_register(env, (*env)->NewObject(env, classid[au_notzed_zcl_CLObject_CTYPE_CONTEXT], CLContext_new_pn, C2J(ret), jnotify)); -} - -JNIEXPORT jobject JNICALL Java_au_notzed_zcl_CLContext_createContextFromType -(JNIEnv *env, jclass jc, jobjectArray jprops, jlong type, jobject jnotify) { - FAIL_clCreateContextFromType_RET(NULL); - - cl_context_properties *props = fromPropertyArray(env, jprops); - cl_int res; - cl_context ret; - void (CL_CALLBACK * notify)(const char *, const void *, size_t, void *); - void *data; - - if ((*env)->ExceptionCheck(env)) return NULL; - - if (jnotify) { - // Note: solid reference is handled by constructor - notify = context_notify_hook; - data = (*env)->NewWeakGlobalRef(env, jnotify); - } else { - notify = NULL; - data = NULL; - } - - ret = clCreateContextFromType(props, type, notify, data, &res); - free(props); - THROW_RTERROR_RET(res, NULL); - - return NativeZ_register(env, (*env)->NewObject(env, classid[au_notzed_zcl_CLObject_CTYPE_CONTEXT], CLContext_new_pn, C2J(ret), jnotify)); -} - -JNIEXPORT jobject JNICALL Java_au_notzed_zcl_CLContext_createCommandQueue__Lau_notzed_zcl_CLDevice_2J -(JNIEnv *env, jobject jcontext, jobject jdevice, jlong properties) { - FAIL_clCreateCommandQueue_RET(NULL); - - cl_context context = GETP(env, jcontext); - cl_device_id device = GETP(env, jdevice); - cl_int res; - cl_command_queue ret; - - ret = clCreateCommandQueue(context, - device, - properties, - &res); - THROW_RTERROR_RET(res, NULL); - - return toCLObject(env, au_notzed_zcl_CLObject_CTYPE_COMMAND_QUEUE, ret); -} - -JNIEXPORT jobject JNICALL Java_au_notzed_zcl_CLContext_createCommandQueue__Lau_notzed_zcl_CLDevice_2_3Lau_notzed_zcl_CLQueueProperty_2 -(JNIEnv *env, jobject jcontext, jobject jdevice, jobjectArray jprops) { -#ifdef CL_VERSION_2_0 - if (getAPIVersion(env, jcontext) < au_notzed_zcl_CLPlatform_VERSION_2_0) { - cl_command_queue_properties properties = 0; - - printf("Warning: Calling OpenCL 2.0 CreateCommandQueueWithProperties, using fallback\n"); - fflush(stdout); - - if (jprops) { - cl_queue_properties *props = fromPropertyArray(env, jprops); - - if ((*env)->ExceptionCheck(env)) - return NULL; - - for (int i=0;props[i] != 0;i+=2) { - if (CL_QUEUE_PROPERTIES == props[i]) { - properties = props[i+1]; - break; - } - } - free(props); - } - return Java_au_notzed_zcl_CLContext_createCommandQueue__Lau_notzed_zcl_CLDevice_2J(env, jcontext, jdevice, properties); - } - - FAIL_clCreateCommandQueueWithProperties_RET(NULL); - - cl_context context = GETP(env, jcontext); - cl_device_id device = GETP(env, jdevice); - cl_int res; - cl_command_queue ret; - cl_queue_properties *props = fromPropertyArray(env, jprops); - - if ((*env)->ExceptionCheck(env)) return NULL; - - ret = clCreateCommandQueueWithProperties(context, - device, - props, - &res); - free(props); - THROW_RTERROR_RET(res, NULL); - - return toCLObject(env, au_notzed_zcl_CLObject_CTYPE_COMMAND_QUEUE, ret); -#else - throwException(env, "java/lang/UnsupportedOperationException", "Requires OpenCL 2.0"); - return NULL; -#endif -} - -JNIEXPORT void JNICALL Java_au_notzed_zcl_CLContext_setDefaultDeviceCommandQueue -(JNIEnv *env, jobject jcontext, jobject jdevice, jobject jqueue) -{ -#ifdef CL_VERSION_2_1 - if (checkAPIVersion(env, jcontext, au_notzed_zcl_CLPlatform_VERSION_2_1)) { - FAIL_clSetDefaultDeviceCommandQueue(); - - cl_context context = GETP(env, jcontext); - cl_device_id device = GETP(env, jdevice); - cl_command_queue queue = GETP(env, jqueue); - cl_int res; - - res = clSetDefaultDeviceCommandQueue(context, device, queue); - THROW_ERROR(res); - } else -#endif - throwException(env, "java/lang/UnsupportedOperationException", "Requires OpenCL 2.1"); -} - -JNIEXPORT jobject JNICALL Java_au_notzed_zcl_CLContext_createBuffer__JJLjava_nio_ByteBuffer_2 -(JNIEnv *env, jobject jcontext, jlong flags, jlong size, jobject jhost_ptr) { - FAIL_clCreateBuffer_RET(NULL); - - cl_context context = GETP(env, jcontext); - cl_int res; - cl_mem ret; - void *host_ptr = NULL; - - D(printf("createBuffer(%08lx, %ld, %p)\n", flags, size, jhost_ptr)); - - if (jhost_ptr) { - jlong jhost_size; - - // TODO: an aligned allocator may be necessary - - host_ptr = (*env)->GetDirectBufferAddress(env, jhost_ptr); - jhost_size = (*env)->GetDirectBufferCapacity(env, jhost_ptr); - if (jhost_size < size) { - throwCLException(env, CL_INVALID_HOST_PTR); - return NULL; - } - } - - ret = clCreateBuffer(context, - flags, - size, - host_ptr, - &res); - - THROW_RTERROR_RET(res, NULL); - - if (jhost_ptr && (flags & CL_MEM_USE_HOST_PTR)) { - jvalue args[] = { - { .j = (uintptr_t)ret }, - { .l = jhost_ptr } - }; - - return NativeZ_register(env, (*env)->NewObjectA(env, classid[au_notzed_zcl_CLObject_CTYPE_BUFFER], CLBuffer_new_jb, args)); - } else - return toCLObject(env, au_notzed_zcl_CLObject_CTYPE_BUFFER, ret); -} - -/* The convenience is worth it */ - -static jobject -createBufferPrimitive(JNIEnv *env, jobject jcontext, jlong flags, jarray jhost_ptr, int elshift) { - FAIL_clCreateBuffer_RET(NULL); - - cl_context context = GETP(env, jcontext); - cl_int res; - cl_mem ret; - void *host_ptr; - - // No way to implement this with java arrays currently - if (flags & CL_MEM_USE_HOST_PTR) { - throwCLException(env, CL_INVALID_VALUE); - return NULL; - } - - if (!jhost_ptr) { - throwException(env, "java/lang/NullPointerException", "null array"); - return NULL; - } - - jsize size = (*env)->GetArrayLength(env, jhost_ptr); - - host_ptr = (*env)->GetPrimitiveArrayCritical(env, jhost_ptr, NULL); - - ret = clCreateBuffer(context, - flags, - size << elshift, - host_ptr, - &res); - - (*env)->ReleasePrimitiveArrayCritical(env, jhost_ptr, host_ptr, 0); - - THROW_RTERROR_RET(res, NULL); - - return toCLObject(env, au_notzed_zcl_CLObject_CTYPE_BUFFER, ret); -} - -JNIEXPORT jobject JNICALL Java_au_notzed_zcl_CLContext_createBuffer__J_3B -(JNIEnv *env, jobject jcontext, jlong flags, jbyteArray jhost_ptr) { - return createBufferPrimitive(env, jcontext, flags, jhost_ptr, 0); -} - -JNIEXPORT jobject JNICALL Java_au_notzed_zcl_CLContext_createBuffer__J_3S -(JNIEnv *env, jobject jcontext, jlong flags, jbyteArray jhost_ptr) { - return createBufferPrimitive(env, jcontext, flags, jhost_ptr, 1); -} - -JNIEXPORT jobject JNICALL Java_au_notzed_zcl_CLContext_createBuffer__J_3I -(JNIEnv *env, jobject jcontext, jlong flags, jbyteArray jhost_ptr) { - return createBufferPrimitive(env, jcontext, flags, jhost_ptr, 2); -} - -JNIEXPORT jobject JNICALL Java_au_notzed_zcl_CLContext_createBuffer__J_3F -(JNIEnv *env, jobject jcontext, jlong flags, jfloatArray jhost_ptr) { - return createBufferPrimitive(env, jcontext, flags, jhost_ptr, 2); -} - -JNIEXPORT jobject JNICALL Java_au_notzed_zcl_CLContext_createBuffer__J_3D -(JNIEnv *env, jobject jcontext, jlong flags, jfloatArray jhost_ptr) { - return createBufferPrimitive(env, jcontext, flags, jhost_ptr, 2); -} - -/* ********************************************************************** */ - -// fmt = unmarshall(jfmt) -// returns size of 1 element in bytes -static size_t marshal_image_format(JNIEnv *env, cl_image_format *fmt, jobject jfmt) { - size_t nc, ds; - - fmt->image_channel_order = (*env)->GetIntField(env, jfmt, CLImageFormat_channelOrder); - fmt->image_channel_data_type = (*env)->GetIntField(env, jfmt, CLImageFormat_channelDataType); - - switch (fmt->image_channel_order) { - case CL_R: - case CL_A: - case CL_INTENSITY: - case CL_LUMINANCE: - case CL_DEPTH: - case CL_DEPTH_STENCIL: // ??? - nc = 1; - break; - case CL_RG: - case CL_RA: - case CL_Rx: - nc = 2; - break; - case CL_RGB: - case CL_RGx: - case CL_sRGB: // ?? - nc = 3; - break; - case CL_RGBA: - case CL_BGRA: - case CL_ARGB: - case CL_RGBx: - case CL_sRGBx: - case CL_sRGBA: - case CL_sBGRA: - case CL_ABGR: - default: - nc = 4; - break; - } - - switch (fmt->image_channel_data_type) { - case CL_SNORM_INT8: - case CL_UNORM_INT8: - case CL_SIGNED_INT8: - case CL_UNSIGNED_INT8: - ds = 1; - break; - case CL_SNORM_INT16: - case CL_UNORM_INT16: - case CL_UNORM_SHORT_565: - case CL_UNORM_SHORT_555: - case CL_UNORM_INT_101010: - case CL_SIGNED_INT16: - case CL_UNSIGNED_INT16: - case CL_HALF_FLOAT: - ds = 2; - break; - case CL_UNORM_INT24: - ds = 3; - break; - case CL_SIGNED_INT32: - case CL_UNSIGNED_INT32: - case CL_FLOAT: - case CL_UNORM_INT_101010_2: // ?? - default: - ds = 4; - break; - } - - return nc * ds; -} - -static size_t get_row_pitch(cl_image_desc *desc, size_t elsize) { - return desc->image_row_pitch != 0 - ? desc->image_row_pitch - : elsize * desc->image_width; -} - -static size_t get_slice_pitch(cl_image_desc *desc, size_t elsize) { - return desc->image_slice_pitch != 0 - ? desc->image_slice_pitch - : desc->image_height * get_row_pitch(desc, elsize); -} - -static size_t get_transfer_size(size_t region[3], size_t row_pitch, size_t slice_pitch, size_t elsize) { - if (slice_pitch == 0) { - if (row_pitch != 0) - row_pitch = region[0] * elsize; - slice_pitch = row_pitch * region[1]; - } - return slice_pitch * region[2]; -} - -// desc = unmarshall(jdesc) -// returns required bytes -static size_t marshal_image_desc(JNIEnv *env, cl_image_desc *desc, jobject jdesc, size_t elsize) { - desc->image_type = (*env)->GetIntField(env, jdesc, CLImageDesc_imageType); - desc->image_width = (*env)->GetIntField(env, jdesc, CLImageDesc_imageWidth); - desc->image_height = (*env)->GetIntField(env, jdesc, CLImageDesc_imageHeight); - desc->image_depth = (*env)->GetIntField(env, jdesc, CLImageDesc_imageDepth); - desc->image_array_size = (*env)->GetIntField(env, jdesc, CLImageDesc_imageArraySize); - desc->image_row_pitch = (*env)->GetIntField(env, jdesc, CLImageDesc_imageRowPitch); - desc->image_slice_pitch = (*env)->GetIntField(env, jdesc, CLImageDesc_imageSlicePitch); - desc->num_mip_levels = (*env)->GetIntField(env, jdesc, CLImageDesc_numMipLevels); - desc->num_samples = (*env)->GetIntField(env, jdesc, CLImageDesc_numSamples); - jobject jmemObject = (*env)->GetObjectField(env, jdesc, CLImageDesc_memObject); - desc->mem_object = jmemObject ? GETP(env, jmemObject) : NULL; - - switch (desc->image_type) { - case CL_MEM_OBJECT_IMAGE2D: - return get_row_pitch(desc, elsize) * desc->image_height; - case CL_MEM_OBJECT_IMAGE3D: - return get_slice_pitch(desc, elsize) * desc->image_depth; -#ifdef CL_VERSION_1_2 - case CL_MEM_OBJECT_IMAGE1D: - case CL_MEM_OBJECT_IMAGE1D_BUFFER: - return get_row_pitch(desc, elsize); - case CL_MEM_OBJECT_IMAGE1D_ARRAY: - case CL_MEM_OBJECT_IMAGE2D_ARRAY: - return get_slice_pitch(desc, elsize) * desc->image_array_size; -#endif - default: - return ~0; - } -} - -static jobject createImage(JNIEnv *env, cl_context context, jlong flags, cl_image_format *fmt, cl_image_desc *desc, void *host_ptr) { - - int res = 0; - cl_mem ret; - -#ifdef CL_VERSION_1_2 - if (CHECK_clCreateImage()) { - ret = clCreateImage(context, flags, fmt, desc, host_ptr, &res); - } else { - switch (desc->image_type) { - case CL_MEM_OBJECT_IMAGE2D: - FAIL_clCreateImage2D_RET(NULL); - D(printf("createImage2D(%dx%d stride=%d host=%p)\n", desc->image_width, desc->image_height, desc->image_row_pitch, host_ptr)); - ret = clCreateImage2D(context, flags, fmt, desc->image_width, desc->image_height, desc->image_row_pitch, host_ptr, &res); - break; - case CL_MEM_OBJECT_IMAGE3D: - FAIL_clCreateImage3D_RET(NULL); - ret = clCreateImage3D(context, flags, fmt, desc->image_width, desc->image_height, desc->image_depth, - desc->image_row_pitch, desc->image_slice_pitch, host_ptr, &res); - break; - default: - throwException(env, "java/lang/UnsupportedOperationException", "Requires OpenCL 1.2"); - return NULL; - } - } -#else - switch (desc->image_type) { - case CL_MEM_OBJECT_IMAGE2D: - FAIL_clCreateImage2D_RET(NULL); - D(printf("createImage2D(%dx%d stride=%d host=%p)\n", desc->image_width, desc->image_height, desc->image_row_pitch, host_ptr)); - ret = clCreateImage2D(context, flags, fmt, desc->image_width, desc->image_height, desc->image_row_pitch, host_ptr, &res); - break; - case CL_MEM_OBJECT_IMAGE3D: - FAIL_clCreateImage3D_RET(NULL); - ret = clCreateImage3D(context, flags, fmt, desc->image_width, desc->image_height, desc->image_depth, - desc->image_row_pitch, desc->image_slice_pitch, host_ptr, &res); - break; - default: - throwException(env, "java/lang/UnsupportedOperationException", "Requires OpenCL 1.2"); - return NULL; - } -#endif - THROW_RTERROR_RET(res, NULL); - - return toCLObject(env, au_notzed_zcl_CLObject_CTYPE_IMAGE, ret); -} - -JNIEXPORT jobject JNICALL Java_au_notzed_zcl_CLContext_createImage__JLau_notzed_zcl_CLImageFormat_2Lau_notzed_zcl_CLImageDesc_2Ljava_nio_ByteBuffer_2 -(JNIEnv *env, jobject jcontext, jlong flags, jobject jfmt, jobject jdesc, jobject jhost_ptr) { - cl_context context = GETP(env, jcontext); - cl_image_format fmt = { 0 }; - cl_image_desc desc = { 0 }; - void *host_ptr = NULL; - size_t required, elsize; - - elsize = marshal_image_format(env, &fmt, jfmt); - required = marshal_image_desc(env, &desc, jdesc, elsize); - - if (jhost_ptr) { - jsize jhost_size = (*env)->GetDirectBufferCapacity(env, jhost_ptr); - - if (jhost_size < required) { - throwCLException(env, CL_INVALID_HOST_PTR); - return NULL; - } - - host_ptr = (*env)->GetDirectBufferAddress(env, jhost_ptr); - } - - return createImage(env, context, flags, &fmt, &desc, host_ptr); -} - -static jobject createImagePrimitive -(JNIEnv *env, jobject jcontext, jlong flags, jobject jfmt, jobject jdesc, jarray jhost_ptr, int elshift) { - cl_context context = GETP(env, jcontext); - cl_image_format fmt = { 0 }; - cl_image_desc desc = { 0 }; - jobject ret; - void *host_ptr = NULL; - size_t required, elsize; - - // No way to implement this with java arrays currently - if (flags & CL_MEM_USE_HOST_PTR) { - throwCLException(env, CL_INVALID_VALUE); - return NULL; - } - - if (!jhost_ptr) { - throwException(env, "java/lang/NullPointerException", "null array"); - return NULL; - } - - elsize = marshal_image_format(env, &fmt, jfmt); - required = marshal_image_desc(env, &desc, jdesc, elsize); - - jsize size = (*env)->GetArrayLength(env, jhost_ptr) << elshift; - - if (size < required) { - throwCLException(env, CL_INVALID_HOST_PTR); - return NULL; - } - - host_ptr = (*env)->GetPrimitiveArrayCritical(env, jhost_ptr, NULL); - - ret = createImage(env, context, flags, &fmt, &desc, host_ptr); - - (*env)->ReleasePrimitiveArrayCritical(env, jhost_ptr, host_ptr, 0); - - return ret; -} - - -JNIEXPORT jobject JNICALL Java_au_notzed_zcl_CLContext_createImage__JLau_notzed_zcl_CLImageFormat_2Lau_notzed_zcl_CLImageDesc_2_3B -(JNIEnv *env, jobject jcontext, jlong flags, jobject jfmt, jobject jdesc, jbyteArray jhost_ptr) { - return createImagePrimitive(env, jcontext, flags, jfmt, jdesc, jhost_ptr, 0); -} - -JNIEXPORT jobject JNICALL Java_au_notzed_zcl_CLContext_createImage__JLau_notzed_zcl_CLImageFormat_2Lau_notzed_zcl_CLImageDesc_2_3S -(JNIEnv *env, jobject jcontext, jlong flags, jobject jfmt, jobject jdesc, jbyteArray jhost_ptr) { - return createImagePrimitive(env, jcontext, flags, jfmt, jdesc, jhost_ptr, 1); -} - -JNIEXPORT jobject JNICALL Java_au_notzed_zcl_CLContext_createImage__JLau_notzed_zcl_CLImageFormat_2Lau_notzed_zcl_CLImageDesc_2_3I -(JNIEnv *env, jobject jcontext, jlong flags, jobject jfmt, jobject jdesc, jbyteArray jhost_ptr) { - return createImagePrimitive(env, jcontext, flags, jfmt, jdesc, jhost_ptr, 2); -} - -JNIEXPORT jobject JNICALL Java_au_notzed_zcl_CLContext_createImage__JLau_notzed_zcl_CLImageFormat_2Lau_notzed_zcl_CLImageDesc_2_3F -(JNIEnv *env, jobject jcontext, jlong flags, jobject jfmt, jobject jdesc, jbyteArray jhost_ptr) { - return createImagePrimitive(env, jcontext, flags, jfmt, jdesc, jhost_ptr, 2); -} - -/* ********************************************************************** */ - -JNIEXPORT jobject JNICALL Java_au_notzed_zcl_CLContext_createPipe -(JNIEnv *env, jobject jcontext, jlong flags, jint packetSize, jint maxPackets, jobjectArray jprops) { -#ifdef CL_VERSION_2_0 - if (checkAPIVersion(env, jcontext, au_notzed_zcl_CLPlatform_VERSION_2_0)) { - FAIL_clCreatePipe_RET(NULL); - - cl_context context = GETP(env, jcontext); - cl_int res; - cl_mem ret; - cl_pipe_properties *props = fromPropertyArray(env, jprops); - - if ((*env)->ExceptionCheck(env)) return NULL; - - ret = clCreatePipe(context, - flags, - packetSize, - maxPackets, - props, - &res); - free(props); - THROW_RTERROR_RET(res, NULL); - - return toCLObject(env, au_notzed_zcl_CLObject_CTYPE_PIPE, ret); - } else -#endif - throwException(env, "java/lang/UnsupportedOperationException", "Requires OpenCL 2.0"); - return NULL; -} - -JNIEXPORT jobjectArray JNICALL Java_au_notzed_zcl_CLContext_getSupportedImageFormats -(JNIEnv *env, jobject jcontext, jlong flags, jint type) { - FAIL_clGetSupportedImageFormats_RET(NULL); - - cl_context context = GETP(env, jcontext); - cl_uint count; - cl_image_format *formats; - jobjectArray jformats; - cl_int res; - - res = clGetSupportedImageFormats(context, - flags, - type, - 0, NULL, &count); - THROW_RTERROR_RET(res, NULL); - - formats = alloca(sizeof(*formats) * count); - res = clGetSupportedImageFormats(context, - flags, - type, - count, formats, NULL); - THROW_RTERROR_RET(res, NULL); - - jformats = (*env)->NewObjectArray(env, count, CLImageFormat_classid, NULL); - if (!jformats) - return NULL; - - for (int i=0;iNewObject(env, CLImageFormat_classid, CLImageFormat_new_ii, - formats[i].image_channel_order, - formats[i].image_channel_data_type); - (*env)->SetObjectArrayElement(env, jformats, i, o); - } - - return jformats; -} - -JNIEXPORT jobject JNICALL Java_au_notzed_zcl_CLContext_SVMAlloc -(JNIEnv *env, jobject jcontext, jlong flags, jlong size, jint alignment) { -#ifdef CL_VERSION_2_0 - if (checkAPIVersion(env, jcontext, au_notzed_zcl_CLPlatform_VERSION_2_0)) { - FAIL_clSVMAlloc_RET(NULL); - - cl_context context = GETP(env, jcontext); - void *svm; - - svm = clSVMAlloc(context, flags, size, alignment); - if (!svm) { - // This isn't necessarily correct but there's no other return code - // and it's a bunch of work to look up what it might be. - throwCLRuntimeException(env, CL_OUT_OF_RESOURCES); - return NULL; - } - - return nativez_NewDirectBuffer(env, svm, size); - } else -#endif - throwException(env, "java/lang/UnsupportedOperationException", "Requires OpenCL 2.0"); - return NULL; -} - -JNIEXPORT void JNICALL Java_au_notzed_zcl_CLContext_SVMFree -(JNIEnv *env, jobject jcontext, jobject jsvm) { -#ifdef CL_VERSION_2_0 - if (checkAPIVersion(env, jcontext, au_notzed_zcl_CLPlatform_VERSION_2_0)) { - FAIL_clSVMFree(); - - cl_context context = GETP(env, jcontext); - - // NULL is ok & ignored - if (jsvm) { - void *svm = (*env)->GetDirectBufferAddress(env, jsvm); - - clSVMFree(context, svm); - } - } else -#endif - throwException(env, "java/lang/UnsupportedOperationException", "Requires OpenCL 2.0"); -} - - -JNIEXPORT jobject JNICALL Java_au_notzed_zcl_CLContext_createSampler__ZII -(JNIEnv *env, jobject jcontext, jboolean norm, jint addr_mode, jint filter_mode) { - FAIL_clCreateSampler_RET(NULL); - - cl_context context = GETP(env, jcontext); - cl_sampler ret; - cl_int res; - - ret = clCreateSampler(context, norm, addr_mode, filter_mode, &res); - THROW_RTERROR_RET(res, NULL); - - return toCLObject(env, au_notzed_zcl_CLObject_CTYPE_SAMPLER, ret); -} - -JNIEXPORT jobject JNICALL Java_au_notzed_zcl_CLContext_createSampler___3Lau_notzed_zcl_CLSamplerProperty_2 -(JNIEnv *env, jobject jcontext, jobjectArray jprops) { -#ifdef CL_VERSION_2_0 - if (checkAPIVersion(env, jcontext, au_notzed_zcl_CLPlatform_VERSION_2_0)) { - FAIL_clCreateSamplerWithProperties_RET(NULL); - - cl_context context = GETP(env, jcontext); - cl_sampler ret; - cl_int res; - cl_sampler_properties *props = fromPropertyArray(env, jprops); - - if ((*env)->ExceptionCheck(env)) return NULL; - - ret = clCreateSamplerWithProperties(context, props, &res); - free(props); - THROW_RTERROR_RET(res, NULL); - - return toCLObject(env, au_notzed_zcl_CLObject_CTYPE_SAMPLER, ret); - } else -#endif - throwException(env, "java/lang/UnsupportedOperationException", "Requires OpenCL 2.0"); - return NULL; -} - -JNIEXPORT jobject JNICALL Java_au_notzed_zcl_CLContext_createProgramWithSource -(JNIEnv *env, jobject jcontext, jobjectArray jstrings) { - FAIL_clCreateProgramWithSource_RET(NULL); - - cl_context context = GETP(env, jcontext); - int count; - const char **strings; - size_t *lengths; - cl_int res; - cl_program ret; - - count = (*env)->GetArrayLength(env, jstrings); - strings = alloca(sizeof(*strings) * count); - lengths = alloca(sizeof(*lengths) * count); - for (int i=0;iGetObjectArrayElement(env, jstrings, i); - - lengths[i] = (*env)->GetArrayLength(env, jo); - strings[i] = (*env)->GetPrimitiveArrayCritical(env, jo, NULL); - } - - ret = clCreateProgramWithSource(context, - count, - strings, - lengths, - &res); - for (int i=0;iGetObjectArrayElement(env, jstrings, i); - - (*env)->ReleasePrimitiveArrayCritical(env, jo, (void *)strings[i], 0); - } - - THROW_ERROR_RET(res, NULL); - - return toCLObject(env, au_notzed_zcl_CLObject_CTYPE_PROGRAM, ret); -} - -JNIEXPORT jobject JNICALL Java_au_notzed_zcl_CLContext_createProgramWithIL -(JNIEnv *env, jobject jcontext, jbyteArray jil) { -#ifdef CL_VERSION_2_1 - if (checkAPIVersion(env, jcontext, au_notzed_zcl_CLPlatform_VERSION_2_1)) { - FAIL_clCreateProgramWithIL_RET(NULL); - - cl_context context = GETP(env, jcontext); - void *il; - size_t length; - cl_int res; - cl_program ret; - - length = (*env)->GetArrayLength(env, jil); - il = (*env)->GetPrimitiveArrayCritical(env, jil, NULL); - - ret = clCreateProgramWithIL(context, - il, - length, - &res); - - (*env)->ReleasePrimitiveArrayCritical(env, jil, il, 0); - THROW_ERROR_RET(res, NULL); - - return toCLObject(env, au_notzed_zcl_CLObject_CTYPE_PROGRAM, ret); - } else -#endif - throwException(env, "java/lang/UnsupportedOperationException", "Requires OpenCL 2.1"); - return NULL; -} - -JNIEXPORT jobject JNICALL Java_au_notzed_zcl_CLContext_createProgramWithBinary -(JNIEnv *env, jobject jcontext, jobjectArray jdevices, jobjectArray jbinaries, jintArray jstatus) { - FAIL_clCreateProgramWithBinary_RET(NULL); - - cl_context context = GETP(env, jcontext); - int dlen, blen, slen; - cl_device_id *devices; - size_t *lengths; - const unsigned char **binaries; - cl_int *status; - cl_int res; - cl_program ret; - - if (!jdevices) { - throwException(env, "java/lang/NullPointerException", "device_list must not be null"); - return NULL; - } - - if (!jbinaries) { - throwException(env, "java/lang/NullPointerException", "binaries must not be null"); - return NULL; - } - - dlen = (*env)->GetArrayLength(env, jdevices); - blen = (*env)->GetArrayLength(env, jbinaries); - slen = jstatus ? (*env)->GetArrayLength(env, jbinaries) : 0; - - if (slen > 0 && slen != blen) { - throwException(env, "java/lang/ArrayIndexOutOfBoundsException", "binary_status.length != binaries.length"); - return NULL; - } - - devices = alloca(dlen * sizeof(*devices)); - fromObjectArray(env, jdevices, (void **)devices, dlen); - - binaries = alloca(blen * sizeof(*binaries)); - lengths = alloca(blen * sizeof(*lengths)); - status = alloca(blen * sizeof(*status)); - - for (int i=0;iGetObjectArrayElement(env, jbinaries, i); - - lengths[i] = (*env)->GetArrayLength(env, jo); - binaries[i] = (*env)->GetPrimitiveArrayCritical(env, jo, NULL); - } - - ret = clCreateProgramWithBinary(context, - dlen, - devices, - lengths, - binaries, - status, - &res); - - for (int i=0;iGetObjectArrayElement(env, jbinaries, i); - - (*env)->ReleasePrimitiveArrayCritical(env, jo, (void *)binaries[i], 0); - } - THROW_ERROR_RET(res, NULL); - - if (jstatus) - (*env)->SetIntArrayRegion(env, jstatus, 0, blen, status); - - return toCLObject(env, au_notzed_zcl_CLObject_CTYPE_PROGRAM, ret); -} - -JNIEXPORT jobject JNICALL Java_au_notzed_zcl_CLContext_createProgramWithBuiltInKernels -(JNIEnv *env, jobject jcontext, jobjectArray jdevices, jstring jnames) { -#ifdef CL_VERSION_1_2 - FAIL_clCreateProgramWithBuiltInKernels_RET(NULL); - - cl_context context = GETP(env, jcontext); - int dlen; - cl_device_id *devices; - const char *names; - cl_int res; - cl_program ret; - - if (!jdevices) { - throwException(env, "java/lang/NullPointerException", "device_list must not be null"); - return NULL; - } - - dlen = (*env)->GetArrayLength(env, jdevices); - devices = alloca(dlen * sizeof(*devices)); - fromObjectArray(env, jdevices, (void **)devices, dlen); - - names = (*env)->GetStringUTFChars(env, jnames, NULL); - if (!names) - return NULL; - - ret = clCreateProgramWithBuiltInKernels(context, - dlen, - devices, - names, - &res); - (*env)->ReleaseStringUTFChars(env, jnames, names); - - THROW_ERROR_RET(res, NULL); - - return toCLObject(env, au_notzed_zcl_CLObject_CTYPE_PROGRAM, ret); -#else - throwException(env, "java/lang/UnsupportedOperationException", "Requires OpenCL 1.2"); - return NULL; -#endif -} - -JNIEXPORT jobject JNICALL Java_au_notzed_zcl_CLContext_linkProgram -(JNIEnv *env, jobject jcontext, jobjectArray jdevices, jstring joptions, jobjectArray jprograms, jobject jnotify) { -#ifdef CL_VERSION_1_2 - FAIL_clLinkProgram_RET(NULL); - - cl_context context = GETP(env, jcontext); - int dlen = 0, plen; - cl_device_id *devices = NULL; - cl_program *programs; - const char *options; - cl_int res; - cl_program ret = NULL; - void (CL_CALLBACK *notify)(cl_program /* program */, void * /* user_data */) = NULL; - struct build_notify_info *data = NULL; - - if (!jprograms) { - throwException(env, "java/lang/NullPointerException", "device_list must not be null"); - return NULL; - } - - plen = (*env)->GetArrayLength(env, jprograms); - programs = alloca(plen * sizeof(*programs)); - fromObjectArray(env, jprograms, (void **)programs, plen); - - if (jdevices) { - dlen = (*env)->GetArrayLength(env, jdevices); - devices = alloca(dlen * sizeof(*devices)); - fromObjectArray(env, jdevices, (void **)devices, dlen); - } - - options = (*env)->GetStringUTFChars(env, joptions, NULL); - - if (jnotify) { - // Note: build_notify_hook deletes the global ref - notify = build_notify_hook; - data = build_notify_alloc(env, NULL, NULL, jnotify); - if (!data) { - res = CL_OUT_OF_HOST_MEMORY; - goto fail; - } - } - - ret = clLinkProgram(context, - dlen, - devices, - options, - plen, - programs, - notify, - data, - &res); - - fail: - (*env)->ReleaseStringUTFChars(env, joptions, options); - - THROW_ERROR_RET(res, NULL); - - return toCLObject(env, au_notzed_zcl_CLObject_CTYPE_PROGRAM, ret); -#else - throwException(env, "java/lang/UnsupportedOperationException", "Requires OpenCL 1.2"); - return NULL; -#endif -} - -JNIEXPORT jobject JNICALL Java_au_notzed_zcl_CLContext_createUserEvent -(JNIEnv *env, jobject jcontext) { -#ifdef CL_VERSION_1_1 - FAIL_clCreateUserEvent_RET(NULL); - - cl_context context = GETP(env, jcontext); - cl_event ret; - cl_int res; - - ret = clCreateUserEvent(context, &res); - THROW_RTERROR_RET(res, NULL); - - return toCLObject(env, au_notzed_zcl_CLObject_CTYPE_EVENT, ret); -#else - throwException(env, "java/lang/UnsupportedOperationException", "Requires OpenCL 1.1"); - return NULL; -#endif -} - -JNIEXPORT jobjectArray JNICALL Java_au_notzed_zcl_CLContext_getProperties -(JNIEnv *env, jobject jcontext) { - return getInfoProperties(env, jcontext, au_notzed_zcl_CLObject_TYPE_CONTEXT, CL_CONTEXT_PROPERTIES, - CLContextProperty_classid, - CLContextProperty_TagValue_classid, CLContextProperty_TagValue_new_jj); -} - -/* ********************************************************************** */ -/* CLMemory */ - -JNIEXPORT void JNICALL Java_au_notzed_zcl_CLMemory_release -(JNIEnv *env, jclass jc, jlong jp) { - cl_int res; - - FAIL_clReleaseMemObject(); - res = clReleaseMemObject((cl_mem)jp); - if (res != CL_SUCCESS) - throwCLRuntimeException(env, res); -} - -#ifdef CL_VERSION_1_1 -struct destroy_notify_info { - cl_mem mem; - jobject jnotify; - jobject jmem; -}; - -static void destroy_notify_hook(cl_mem mem, void *data) { - struct destroy_notify_info *info = data; - JNIEnv *env; - - D(printf("destroy notify()\n")); - - if (!(env = nativez_AttachCurrentThreadAsDaemon())) { - // NB: can't do anything here - fprintf(stderr, "Unable to attach java environment\n"); - free(data); - return; - } - - if (info->mem == mem) { - jvalue arg = { .l = info->jmem }; - - (*env)->CallVoidMethodA(env, info->jnotify, CLNotify_notify_l, &arg); - } else - fprintf(stderr, "destroy_notify_hook given wrong cl_mem\n"); - - (*env)->DeleteGlobalRef(env, info->jnotify); - (*env)->DeleteGlobalRef(env, info->jmem); - - free(info); -} -#endif - -JNIEXPORT void JNICALL Java_au_notzed_zcl_CLMemory_setMemObjectDestructorCallback -(JNIEnv *env, jobject jmem, jobject jnotify) { -#ifdef CL_VERSION_1_1 - FAIL_clSetMemObjectDestructorCallback(); - - cl_mem mem = GETP(env, jmem); - struct destroy_notify_info *info; - - if (!jnotify) - return; - - info = malloc(sizeof(*info)); - if (!info) - return; - - info->mem = mem; - info->jnotify = (*env)->NewGlobalRef(env, jnotify); - info->jmem = (*env)->NewGlobalRef(env, jmem); - - THROW_RTERROR(clSetMemObjectDestructorCallback(mem, destroy_notify_hook, info)); -#else - throwException(env, "java/lang/UnsupportedOperationException", "Requires OpenCL 1.1"); -#endif -} - -JNIEXPORT jobject JNICALL Java_au_notzed_zcl_CLMemory_getHostPtr -(JNIEnv *env, jobject jmem) { - FAIL_clGetMemObjectInfo_RET(NULL); - - cl_mem mem = GETP(env, jmem); - cl_int res; - void *host_ptr; - size_t host_size; - - res = clGetMemObjectInfo(mem, CL_MEM_HOST_PTR, sizeof(host_ptr), &host_ptr, NULL); - THROW_RTERROR_RET(res, NULL); - - res = clGetMemObjectInfo(mem, CL_MEM_SIZE, sizeof(host_size), &host_size, NULL); - THROW_RTERROR_RET(res, NULL); - - return nativez_NewDirectBuffer(env, host_ptr, host_size); -} - -/* ********************************************************************** */ -/* CLBuffer */ - -JNIEXPORT jobject JNICALL Java_au_notzed_zcl_CLBuffer_createSubBuffer -(JNIEnv *env, jobject jmem, jlong flags, jobject jinfo) { -#ifdef CL_VERSION_1_1 - FAIL_clCreateSubBuffer_RET(NULL); - - cl_mem mem = GETP(env, jmem); - cl_mem ret; - cl_int res; - cl_buffer_create_type type; - union { - cl_buffer_region region; - } info; - - if ((*env)->IsInstanceOf(env, jinfo, CLBufferInfoRegion_classid)) { - type = CL_BUFFER_CREATE_TYPE_REGION; - info.region.origin = (size_t)(*env)->GetLongField(env, jinfo, CLBufferInfoRegion_origin); - info.region.size = (size_t)(*env)->GetLongField(env, jinfo, CLBufferInfoRegion_size); - } else { - throwCLException(env, CL_INVALID_VALUE); - return NULL; - } - - ret = clCreateSubBuffer(mem, - flags, - type, - &info, - &res); - - THROW_RTERROR_RET(res, NULL); - - return toCLObject(env, au_notzed_zcl_CLObject_CTYPE_BUFFER, ret); -#else - throwException(env, "java/lang/UnsupportedOperationException", "Requires OpenCL 1.1"); - return NULL; -#endif -} - -/* ********************************************************************** */ -/* CLProgram */ - -JNIEXPORT jobject JNICALL Java_au_notzed_zcl_CLProgram_getBuildInfoAny -(JNIEnv *env, jobject jprogram, jobject jdevice, jint ctype, jint param) { - FAIL_clGetProgramBuildInfo_RET(NULL); - - cl_program program = GETP(env, jprogram); - cl_device_id device = GETP(env, jdevice); - void *value; - size_t size = ctype_sizes[ctype]; - cl_int res; - - value = alloca(size); - res = clGetProgramBuildInfo(program, device, param, size, value, NULL); - THROW_RTERROR_RET(res, NULL); - - return toObject(env, ctype, size, value); -} - -JNIEXPORT jobject JNICALL Java_au_notzed_zcl_CLProgram_getBuildInfoAnyV -(JNIEnv *env, jobject jprogram, jobject jdevice, jint ctype, jint param) { - FAIL_clGetProgramBuildInfo_RET(NULL); - - cl_program program = GETP(env, jprogram); - cl_device_id device = GETP(env, jdevice); - void *value; - size_t size = 0; - cl_int res; - - res = clGetProgramBuildInfo(program, device, param, 0, NULL, &size); - THROW_RTERROR_RET(res, NULL); - - value = alloca(size); - - res = clGetProgramBuildInfo(program, device, param, size, value, NULL); - THROW_RTERROR_RET(res, NULL); - - return toArray(env, ctype, size, value); -} - -JNIEXPORT void JNICALL Java_au_notzed_zcl_CLProgram_buildProgram -(JNIEnv *env, jobject jprogram, jobjectArray jdevices, jstring joptions, jobject jnotify) { - FAIL_clBuildProgram(); - - cl_program program = GETP(env, jprogram); - cl_device_id *devices = NULL; - int devcount = 0; - const char *options = NULL; - cl_int res; - void (CL_CALLBACK *notify)(cl_program /* program */, void * /* user_data */) = NULL; - struct build_notify_info *data = NULL; - - if (jdevices) { - devcount = (*env)->GetArrayLength(env, jdevices); - devices = alloca(sizeof(*devices) * devcount); - fromObjectArray(env, jdevices, (void **)devices, devcount); - } - - if (joptions) { - options = (*env)->GetStringUTFChars(env, joptions, NULL); - } - - if (jnotify) { - // Note: build_notify_hook deletes the global ref - notify = build_notify_hook; - data = build_notify_alloc(env, program, jprogram, jnotify); - if (!data) { - res = CL_OUT_OF_HOST_MEMORY; - goto fail; - } - } - - res = clBuildProgram(program, devcount, devices, options, notify, data); - fail: - if (options) - (*env)->ReleaseStringUTFChars(env, joptions, options); - - THROW_ERROR(res); -} - -JNIEXPORT void JNICALL Java_au_notzed_zcl_CLProgram_compileProgram -(JNIEnv *env, jobject jprogram, jobjectArray jdevices, jstring joptions, jobjectArray jheaders, jobjectArray jheadernames, jobject jnotify) { -#ifdef CL_VERSION_1_2 - FAIL_clCompileProgram(); - - cl_program program = GETP(env, jprogram); - cl_device_id *devices = NULL; - int devcount = 0; - cl_int res; - const char *options = NULL; - void (CL_CALLBACK *notify)(cl_program /* program */, void * /* user_data */) = NULL; - struct build_notify_info *data = NULL; - int hlen = 0; - cl_program *headers = NULL; - const char **names = NULL; - - if (jdevices) { - devcount = (*env)->GetArrayLength(env, jdevices); - devices = alloca(sizeof(*devices) * devcount); - fromObjectArray(env, jdevices, (void **)devices, devcount); - } - - if (joptions) { - options = (*env)->GetStringUTFChars(env, joptions, NULL); - } - - if (jheaders) { - hlen = (*env)->GetArrayLength(env, jheaders); - - if (hlen != (*env)->GetArrayLength(env, jheadernames)) { - res = CL_INVALID_VALUE; - goto fail; - } - - headers = alloca(sizeof(*headers) * hlen); - names = alloca(sizeof(*names) * hlen); - - for (int i=0;iGetObjectArrayElement(env, jheaders, i); - jobject jname = (*env)->GetObjectArrayElement(env, jheadernames, i); - - headers[i] = GETP(env, jheader); - names[i] = (*env)->GetStringUTFChars(env, jname, NULL); - } - } - - if (jnotify) { - // Note: build_notify_hook deletes the global ref - notify = build_notify_hook; - data = build_notify_alloc(env, program, jprogram, jnotify); - if (!data) { - res = CL_OUT_OF_HOST_MEMORY; - goto fail; - } - } - - res = clCompileProgram(program, devcount, devices, options, hlen, headers, names, notify, data); - fail: - if (options) - (*env)->ReleaseStringUTFChars(env, joptions, options); - - if (names) { - for (int i=0;iGetObjectArrayElement(env, jheadernames, i); - - (*env)->ReleaseStringUTFChars(env, jname, names[i]); - } - } - - THROW_ERROR(res); -#else - throwException(env, "java/lang/UnsupportedOperationException", "Requires OpenCL 1.2"); -#endif -} - -JNIEXPORT jobject JNICALL Java_au_notzed_zcl_CLProgram_createKernel -(JNIEnv *env, jobject jprogram, jstring jname) { - FAIL_clCreateKernel_RET(NULL); - - cl_program program = GETP(env, jprogram); - const char *name; - cl_kernel ret; - cl_int res; - - name = (*env)->GetStringUTFChars(env, jname, NULL); - - ret = clCreateKernel(program, name, &res); - - (*env)->ReleaseStringUTFChars(env, jname, name); - THROW_RTERROR_RET(res, NULL); - - return toCLObject(env, au_notzed_zcl_CLObject_CTYPE_KERNEL, ret); -} - -JNIEXPORT jobjectArray JNICALL Java_au_notzed_zcl_CLProgram_createKernelsInProgram -(JNIEnv *env, jobject jprogram) { - FAIL_clCreateKernelsInProgram_RET(NULL); - - cl_program program = GETP(env, jprogram); - cl_int res; - cl_uint kcount; - cl_kernel *kernels; - - res = clCreateKernelsInProgram(program, 0, NULL, &kcount); - THROW_RTERROR_RET(res, NULL); - - kernels = alloca(sizeof(*kernels) * kcount); - - res = clCreateKernelsInProgram(program, kcount, kernels, NULL); - THROW_RTERROR_RET(res, NULL); - - return toCLObjectArray(env, au_notzed_zcl_CLObject_CTYPE_KERNEL, kcount, (void **)kernels); -} - -JNIEXPORT jobjectArray JNICALL Java_au_notzed_zcl_CLProgram_getBinaries -(JNIEnv *env, jobject jprogram) { - FAIL_clGetProgramInfo_RET(NULL); - - cl_program program = GETP(env, jprogram); - cl_uint count; - size_t *sizes; - unsigned char **binaries; - cl_int res; - jobjectArray ret; - - res = clGetProgramInfo(program, CL_PROGRAM_NUM_DEVICES, sizeof(count), &count, NULL); - THROW_RTERROR_RET(res, NULL); - - sizes = alloca(sizeof(*sizes) * count); - res = clGetProgramInfo(program, CL_PROGRAM_BINARY_SIZES, sizeof(*sizes) * count, sizes, NULL); - THROW_RTERROR_RET(res, NULL); - - binaries = alloca(sizeof(*binaries) * count); - memset(binaries, 0, sizeof(*binaries) * count); - for (int i=0;iNewObjectArray(env, count, byte_a_classid, NULL); - if (!ret) - goto fail; - - for (int i=0;iNewByteArray(env, sizes[i]); - - if (!jo) - goto fail; - - (*env)->SetByteArrayRegion(env, jo, 0, sizes[i], (const jbyte *)binaries[i]); - (*env)->SetObjectArrayElement(env, ret, i, jo); - } - for (int i=0;iGetArrayLength(env, jinput); - - *input_size = sizeof(*input) * ilen; - *input = alloca(sizeof(*input) * ilen); - getSizeTA(env, jinput, *input, ilen); - } else { - *input = NULL; - *input_size = 0; - } -} - -JNIEXPORT jobject JNICALL Java_au_notzed_zcl_CLKernel_getSubGroupInfoAny -(JNIEnv *env, jobject jkernel, jobject jdevice, jint ctype, jint param, jlongArray jinput) { - FAIL_clGetKernelSubGroupInfo_RET(NULL); - - cl_kernel kernel = GETP(env, jkernel); - cl_device_id device = GETP(env, jdevice); - void *value; - size_t size = ctype_sizes[ctype]; - cl_int res; - void *input; - size_t input_size; - - getInputSizeTA(env, jinput, &input, &input_size); - - value = alloca(size); - res = clGetKernelSubGroupInfo(kernel, device, param, input_size, input, size, value, NULL); - THROW_RTERROR_RET(res, NULL); - - return toObject(env, ctype, size, value); -} - -JNIEXPORT jobject JNICALL Java_au_notzed_zcl_CLKernel_getSubGroupInfoAnyV -(JNIEnv *env, jobject jkernel, jobject jdevice, jint ctype, jint param, jlongArray jinput) { - FAIL_clGetKernelSubGroupInfo_RET(NULL); - - cl_kernel kernel = GETP(env, jkernel); - cl_device_id device = GETP(env, jdevice); - void *value; - size_t size = ctype_sizes[ctype]; - cl_int res; - void *input; - size_t input_size; - - getInputSizeTA(env, jinput, &input, &input_size); - - res = clGetKernelSubGroupInfo(kernel, device, param, input_size, input, 0, NULL, &size); - THROW_RTERROR_RET(res, NULL); - - value = alloca(size); - - res = clGetKernelSubGroupInfo(kernel, device, param, input_size, input, size, value, NULL); - THROW_RTERROR_RET(res, NULL); - - return toArray(env, ctype, size, value); -} - -JNIEXPORT jobject JNICALL Java_au_notzed_zcl_CLKernel_getArgInfoAny -(JNIEnv *env, jobject jkernel, jint index, jint ctype, jint param) { - FAIL_clGetKernelArgInfo_RET(NULL); - - cl_kernel kernel = GETP(env, jkernel); - void *value; - size_t size = ctype_sizes[ctype]; - cl_int res; - - value = alloca(size); - res = clGetKernelArgInfo(kernel, index, param, size, value, NULL); - THROW_RTERROR_RET(res, NULL); - - return toObject(env, ctype, size, value); -} - -JNIEXPORT jobject JNICALL Java_au_notzed_zcl_CLKernel_getArgInfoAnyV -(JNIEnv *env, jobject jkernel, jint index, jint ctype, jint param) { - FAIL_clGetKernelArgInfo_RET(NULL); - - cl_kernel kernel = GETP(env, jkernel); - void *value; - size_t size = ctype_sizes[ctype]; - cl_int res; - - res = clGetKernelArgInfo(kernel, index, param, 0, NULL, &size); - THROW_RTERROR_RET(res, NULL); - - value = alloca(size); - - res = clGetKernelArgInfo(kernel, index, param, size, value, NULL); - THROW_RTERROR_RET(res, NULL); - - return toArray(env, ctype, size, value); -} - -JNIEXPORT jobject JNICALL Java_au_notzed_zcl_CLKernel_cloneKernel -(JNIEnv *env, jobject jkernel) { - // Note: no runtime version check, see CLKernel.java -#ifdef CL_VERSION_2_1 - FAIL_clCloneKernel_RET(NULL); - - cl_kernel kernel = GETP(env, jkernel); - cl_int res; - cl_kernel ret; - - ret = clCloneKernel(kernel, &res); - THROW_RTERROR_RET(res, NULL); - - return toCLObject(env, au_notzed_zcl_CLObject_CTYPE_KERNEL, ret); -#else - throwException(env, "java/lang/UnsupportedOperationException", "Requires OpenCL 2.1"); - - return NULL; -#endif -} - -JNIEXPORT void JNICALL Java_au_notzed_zcl_CLKernel_setArg__IJLjava_nio_Buffer_2J -(JNIEnv *env, jobject jkernel, jint index, jlong size, jobject jbuffer, jlong offset) { - FAIL_clSetKernelArg(); - - cl_kernel kernel = GETP(env, jkernel); - cl_int res; - - if (jbuffer) { - void *buffer = (*env)->GetDirectBufferAddress(env, jbuffer); - jlong bsize = (*env)->GetDirectBufferCapacity(env, jbuffer); - - if (offset + size > bsize) { - throwCLException(env, CL_INVALID_VALUE); - return; - } - - res = clSetKernelArg(kernel, index, size, buffer+offset); - } else { - res = clSetKernelArg(kernel, index, size, NULL); - } - THROW_ERROR(res); -} - -static void zclSetKernelArg(JNIEnv *env, cl_kernel kernel, jint index, size_t size, void *valuep) { - FAIL_clSetKernelArg(); - THROW_ERROR(clSetKernelArg(kernel, index, size, valuep)); -} - -JNIEXPORT void JNICALL Java_au_notzed_zcl_CLKernel_setArg__ILau_notzed_zcl_CLObject_2 -(JNIEnv *env, jobject jkernel, jint index, jobject jvalue) { - cl_kernel kernel = GETP(env, jkernel); - void *value = jvalue ? GETP(env, jvalue) : NULL; - - zclSetKernelArg(env, kernel, index, sizeof(value), &value); -} - -JNIEXPORT void JNICALL Java_au_notzed_zcl_CLKernel_setArg__IB -(JNIEnv *env, jobject jkernel, jint index, jbyte value) { - cl_kernel kernel = GETP(env, jkernel); - zclSetKernelArg(env, kernel, index, sizeof(value), &value); -} - -JNIEXPORT void JNICALL Java_au_notzed_zcl_CLKernel_setArg__IS -(JNIEnv *env, jobject jkernel, jint index, jshort value) { - cl_kernel kernel = GETP(env, jkernel); - zclSetKernelArg(env, kernel, index, sizeof(value), &value); -} - -JNIEXPORT void JNICALL Java_au_notzed_zcl_CLKernel_setArg__II -(JNIEnv *env, jobject jkernel, jint index, jint value) { - cl_kernel kernel = GETP(env, jkernel); - zclSetKernelArg(env, kernel, index, sizeof(value), &value); -} - -JNIEXPORT void JNICALL Java_au_notzed_zcl_CLKernel_setArg__IJ -(JNIEnv *env, jobject jkernel, jint index, jlong value) { - cl_kernel kernel = GETP(env, jkernel); - zclSetKernelArg(env, kernel, index, sizeof(value), &value); -} - -JNIEXPORT void JNICALL Java_au_notzed_zcl_CLKernel_setArg__IF -(JNIEnv *env, jobject jkernel, jint index, jfloat value) { - cl_kernel kernel = GETP(env, jkernel); - zclSetKernelArg(env, kernel, index, sizeof(value), &value); -} - -JNIEXPORT void JNICALL Java_au_notzed_zcl_CLKernel_setArg__ID -(JNIEnv *env, jobject jkernel, jint index, jdouble value) { - cl_kernel kernel = GETP(env, jkernel); - zclSetKernelArg(env, kernel, index, sizeof(value), &value); -} - -JNIEXPORT void JNICALL Java_au_notzed_zcl_CLKernel_setArg__ILjava_nio_ByteBuffer_2 -(JNIEnv *env, jobject jkernel, jint index, jobject jsvm) { -#ifdef CL_VERSION_2_0 - // Note: no runtime version check, see CLKernel.java - FAIL_clSetKernelArgSVMPointer(); - - cl_kernel kernel = GETP(env, jkernel); - void *svm = jsvm ? (*env)->GetDirectBufferAddress(env, jsvm) : NULL; - - THROW_ERROR(clSetKernelArgSVMPointer(kernel, index, svm)); -#else - throwException(env, "java/lang/UnsupportedOperationException", "Requires OpenCL 2.0"); -#endif -} - -JNIEXPORT void JNICALL Java_au_notzed_zcl_CLKernel_setArg__I_3B -(JNIEnv *env, jobject jkernel, jint index, jbyteArray jvalue) { - cl_kernel kernel = GETP(env, jkernel); - jsize count = (*env)->GetArrayLength(env, jvalue); - jbyte *value = alloca(count * sizeof(*value)); - - (*env)->GetByteArrayRegion(env, jvalue, 0, count, value); - zclSetKernelArg(env, kernel, index, sizeof(*value) * count, value); -} - -JNIEXPORT void JNICALL Java_au_notzed_zcl_CLKernel_setArg__I_3S -(JNIEnv *env, jobject jkernel, jint index, jshortArray jvalue) { - cl_kernel kernel = GETP(env, jkernel); - jsize count = (*env)->GetArrayLength(env, jvalue); - jshort *value = alloca(count * sizeof(*value)); - - (*env)->GetShortArrayRegion(env, jvalue, 0, count, value); - zclSetKernelArg(env, kernel, index, sizeof(*value) * count, value); -} - -JNIEXPORT void JNICALL Java_au_notzed_zcl_CLKernel_setArg__I_3I -(JNIEnv *env, jobject jkernel, jint index, jintArray jvalue) { - cl_kernel kernel = GETP(env, jkernel); - jsize count = (*env)->GetArrayLength(env, jvalue); - jint *value = alloca(count * sizeof(*value)); - - (*env)->GetIntArrayRegion(env, jvalue, 0, count, value); - zclSetKernelArg(env, kernel, index, sizeof(*value) * count, value); -} - -JNIEXPORT void JNICALL Java_au_notzed_zcl_CLKernel_setArg__I_3J -(JNIEnv *env, jobject jkernel, jint index, jlongArray jvalue) { - cl_kernel kernel = GETP(env, jkernel); - jsize count = (*env)->GetArrayLength(env, jvalue); - jlong *value = alloca(count * sizeof(*value)); - - (*env)->GetLongArrayRegion(env, jvalue, 0, count, value); - zclSetKernelArg(env, kernel, index, sizeof(*value) * count, value); -} - -JNIEXPORT void JNICALL Java_au_notzed_zcl_CLKernel_setArg__I_3F -(JNIEnv *env, jobject jkernel, jint index, jfloatArray jvalue) { - cl_kernel kernel = GETP(env, jkernel); - jsize count = (*env)->GetArrayLength(env, jvalue); - jfloat *value = alloca(count * sizeof(*value)); - - (*env)->GetFloatArrayRegion(env, jvalue, 0, count, value); - zclSetKernelArg(env, kernel, index, sizeof(*value) * count, value); -} - -JNIEXPORT void JNICALL Java_au_notzed_zcl_CLKernel_setArg__I_3D -(JNIEnv *env, jobject jkernel, jint index, jfloatArray jvalue) { - cl_kernel kernel = GETP(env, jkernel); - jsize count = (*env)->GetArrayLength(env, jvalue); - jdouble *value = alloca(count * sizeof(*value)); - - (*env)->GetDoubleArrayRegion(env, jvalue, 0, count, value); - zclSetKernelArg(env, kernel, index, sizeof(*value) * count, value); -} - -/* ********************************************************************** */ -/* CLEvent */ - -JNIEXPORT void JNICALL Java_au_notzed_zcl_CLEvent_release -(JNIEnv *env, jclass jc, jlong jp) { - cl_int res; - FAIL_clReleaseEvent(); - res = clReleaseEvent((cl_event)jp); - if (res != CL_SUCCESS) - throwCLRuntimeException(env, res); -} - -#ifdef CL_VERSION_1_1 -struct event_notify_info { - cl_event event; - jobject jnotify; - jobject jevent; -}; - -static void event_notify_hook(cl_event event, cl_int status, void *data) { - struct event_notify_info *info = data; - JNIEnv *env; - - D(printf("event notify()\n")); - - if (!(env = nativez_AttachCurrentThreadAsDaemon())) { - // NB: can't do anything here - fprintf(stderr, "Unable to attach java environment\n"); - free(data); - return; - } - - if (info->event == event) { - jvalue args[2] = { - { .l = info->jevent }, - { .i = status } - }; - (*env)->CallVoidMethodA(env, info->jnotify, CLEventNotify_notify_li, args); - } else - fprintf(stderr, "destroy_notify_hook given wrong cl_mem\n"); - - (*env)->DeleteGlobalRef(env, info->jnotify); - (*env)->DeleteGlobalRef(env, info->jevent); - - free(info); -} -#endif - -JNIEXPORT void JNICALL Java_au_notzed_zcl_CLEvent_setUserEventStatus -(JNIEnv *env, jobject jevent, jint status) { -#ifdef CL_VERSION_1_1 - FAIL_clSetUserEventStatus(); - - cl_event event = GETP(env, jevent); - THROW_RTERROR(clSetUserEventStatus(event, status)); -#else - throwException(env, "java/lang/UnsupportedOperationException", "Requires OpenCL 1.1"); -#endif -} - -JNIEXPORT void JNICALL Java_au_notzed_zcl_CLEvent_setEventCallback -(JNIEnv *env, jobject jevent, jint type, jobject jnotify) { -#ifdef CL_VERSION_1_1 - FAIL_clSetEventCallback(); - - cl_event event = GETP(env, jevent); - struct event_notify_info *info; - - if (!jnotify) - return; - - info = malloc(sizeof(*info)); - if (!info) - return; - - info->event = event; - info->jnotify = (*env)->NewGlobalRef(env, jnotify); - info->jevent = (*env)->NewGlobalRef(env, jevent); - - THROW_RTERROR(clSetEventCallback(event, type, event_notify_hook, info)); -#else - throwException(env, "java/lang/UnsupportedOperationException", "Requires OpenCL 1.1"); -#endif -} - -/* ********************************************************************** */ -/* CLEventList */ - -JNIEXPORT void JNICALL Java_au_notzed_zcl_CLEventList_waitForEvents -(JNIEnv *env, jobject jevent) { - FAIL_clWaitForEvents(); - - jint count = (*env)->GetIntField(env, jevent, CLEventList_index); - jlongArray jevents = (*env)->GetObjectField(env, jevent, CLEventList_events); - cl_event *events = alloca(sizeof(*events) * count); - cl_int res; - - if (sizeof(cl_event) == sizeof(jlong)) { - (*env)->GetLongArrayRegion(env, jevents, 0, count, (jlong *)events); - } else { - jlong *levents = alloca(count * sizeof(*levents)); - (*env)->GetLongArrayRegion(env, jevents, 0, count, levents); - for (int i=0;iGetDirectBufferAddress(env, jbuffer); - jint position = nativez_BufferPosition(env, jbuffer); - jint limit = nativez_BufferLimit(env, jbuffer); - struct events_info einfo; - cl_int res; - - if (memsize > limit - position) { - throwException(env, ex, what); - return; - } - - GET_P(env, jmem, mem,, "mem must not be null"); - - if (events_init(env, &einfo, jwaiters, jevents)) - return; - - res = (*op)(queue, - mem, - blocking, - memoffset, - memsize, - buffer + position, - einfo.wait_count, - einfo.waitersp, - einfo.eventp); - - THROW_ERROR(res); - - events_post(env, &einfo, jevents); -} - - -JNIEXPORT void JNICALL -Java_au_notzed_zcl_CLCommandQueue_enqueueReadBuffer__Lau_notzed_zcl_CLBuffer_2ZJJLjava_nio_ByteBuffer_2Lau_notzed_zcl_CLEventList_2Lau_notzed_zcl_CLEventList_2 -(JNIEnv *env, jobject jqueue, jobject jmem, jboolean blocking, jlong memoffset, jlong memsize, jobject jbuffer, jobject jwaiters, jobject jevents) { - enqueueBuffer(env, jqueue, jmem, blocking, memoffset, memsize, jbuffer, jwaiters, jevents, clEnqueueReadBuffer, - "java/nio/BufferOverflowException", "target buffer too small"); -} - -JNIEXPORT void JNICALL -Java_au_notzed_zcl_CLCommandQueue_enqueueWriteBuffer__Lau_notzed_zcl_CLBuffer_2ZJJLjava_nio_ByteBuffer_2Lau_notzed_zcl_CLEventList_2Lau_notzed_zcl_CLEventList_2 -(JNIEnv *env, jobject jqueue, jobject jmem, jboolean blocking, jlong memoffset, jlong memsize, jobject jbuffer, jobject jwaiters, jobject jevents) { - enqueueBuffer(env, jqueue, jmem, blocking, memoffset, memsize, jbuffer, jwaiters, jevents, (enqueueReadWriteBuffer_t)clEnqueueWriteBuffer, - "java/nio/BufferUnderflowException", "source buffer too small"); -} - -/* ********************************************************************** */ - -static void enqueueBufferRect -(JNIEnv *env, jobject jqueue, jobject jmem, jboolean blocking, - jlongArray jbuf_origin, jlongArray jhost_origin, jlongArray jregion, - jlong buf_row_pitch, jlong buf_slice_pitch, jlong host_row_pitch, jlong host_slice_pitch, - jbyteArray jbuffer, jobject jwaiters, jobject jevents, - enqueueReadWriteBufferRect_t op) { -#ifdef CL_VERSION_1_1 - if (!op) { - throwException(env, "java/lang/UnsupportedOperationException", "Buffer read/write"); - return; - } - - cl_command_queue queue = GETP(env, jqueue); - cl_mem mem; - void *buffer = (*env)->GetDirectBufferAddress(env, jbuffer); - jlong bsize = (*env)->GetDirectBufferCapacity(env, jbuffer); - struct events_info einfo; - cl_int res; - size_t buf_origin[3]; - size_t host_origin[3]; - size_t region[3]; - - CHECK_ARRAY_MIN(env, jbuf_origin, 3,, "buf origin must be 3-elements long"); - CHECK_ARRAY_MIN(env, jhost_origin, 3,, "host origin must be 3-elements long"); - CHECK_ARRAY_MIN(env, jregion, 3,, "region must be 3-elements long"); - - getSizeTA(env, jbuf_origin, buf_origin, 3); - getSizeTA(env, jhost_origin, host_origin, 3); - getSizeTA(env, jregion, region, 3); - - size_t stride = (host_row_pitch == 0 ? region[0] : host_row_pitch); - size_t slice = (host_slice_pitch == 0 ? region[1] * stride : host_slice_pitch); - - if (host_origin[0] + host_origin[1] * stride + host_origin[2] * slice - + region[0] + (region[1]-1) * stride + (region[2]-1) * slice - > bsize) { - throwException(env, "java/lang/ArrayIndexOutOfBoundsException", "Target buffer over/overflow"); - return; - } - - GET_P(env, jmem, mem,, "mem must not be null"); - - if (events_init(env, &einfo, jwaiters, jevents)) - return; - - res = (*op)(queue, - mem, - blocking, - buf_origin, - host_origin, - region, - buf_row_pitch, - buf_slice_pitch, - host_row_pitch, - host_slice_pitch, - buffer, - einfo.wait_count, - einfo.waitersp, - einfo.eventp); - - THROW_ERROR(res); - - events_post(env, &einfo, jevents); -#else - throwException(env, "java/lang/UnsupportedOperationException", "Requires OpenCL 1.1"); -#endif -} - - -JNIEXPORT void JNICALL Java_au_notzed_zcl_CLCommandQueue_enqueueReadBufferRect__Lau_notzed_zcl_CLBuffer_2Z_3J_3J_3JJJJJLjava_nio_ByteBuffer_2Lau_notzed_zcl_CLEventList_2Lau_notzed_zcl_CLEventList_2 -(JNIEnv *env, jobject jqueue, jobject jmem, jboolean blocking, - jlongArray jbuf_origin, jlongArray jhost_origin, jlongArray jregion, - jlong buf_row_pitch, jlong buf_slice_pitch, jlong host_row_pitch, jlong host_slice_pitch, - jobject jbuffer, - jobject jwaiters, jobject jevents) { - enqueueBufferRect(env, jqueue, jmem, blocking, jbuf_origin, jhost_origin, jregion, - buf_row_pitch, buf_slice_pitch, host_row_pitch, host_slice_pitch, - jbuffer, jwaiters, jevents, - clEnqueueReadBufferRect); -} - -JNIEXPORT void JNICALL Java_au_notzed_zcl_CLCommandQueue_enqueueWriteBufferRect__Lau_notzed_zcl_CLBuffer_2Z_3J_3J_3JJJJJLjava_nio_ByteBuffer_2Lau_notzed_zcl_CLEventList_2Lau_notzed_zcl_CLEventList_2 -(JNIEnv *env, jobject jqueue, jobject jmem, jboolean blocking, - jlongArray jbuf_origin, jlongArray jhost_origin, jlongArray jregion, - jlong buf_row_pitch, jlong buf_slice_pitch, jlong host_row_pitch, jlong host_slice_pitch, - jobject jbuffer, - jobject jwaiters, jobject jevents) { - enqueueBufferRect(env, jqueue, jmem, blocking, jbuf_origin, jhost_origin, jregion, - buf_row_pitch, buf_slice_pitch, host_row_pitch, host_slice_pitch, - jbuffer, jwaiters, jevents, - (enqueueReadWriteBufferRect_t)clEnqueueWriteBufferRect); -} - -/* ********************************************************************** */ - -static void enqueueFillBuffer -(JNIEnv *env, jobject jqueue, - jobject jbuffer, jobject jpattern, jlong offset, jlong size, - jobject jwaiters, jobject jevents, getArrayRegion_t getArray, int elsize) { -#ifdef CL_VERSION_1_2 - FAIL_clEnqueueFillBuffer(); - - cl_command_queue queue = GETP(env, jqueue); - cl_mem buffer; - void *pattern; - size_t pattern_size; - struct events_info einfo; - cl_int res; - - GET_P(env, jbuffer, buffer,, "buffer must not be null"); - CHECK_NULL(env, jpattern,, "pattern must not be null"); - - pattern_size = (*env)->GetArrayLength(env, jpattern); - // complex double16 is maximum possible size? - if (pattern_size * elsize > 16*16) { - throwCLException(env, CL_INVALID_VALUE); - return; - } - pattern = alloca(pattern_size * elsize); - getArray(env, jpattern, 0, pattern_size, pattern); - - D(printf("enqueue fill buffer( off=%d size=%d patternsize=%d\n", - (int)(offset * pattern_size * elsize), - (int)(size * pattern_size * elsize), - (int)(pattern_size * elsize))); - - if (events_init(env, &einfo, jwaiters, jevents)) - return; - - res = clEnqueueFillBuffer(queue, - buffer, - pattern, - pattern_size * elsize, - offset * pattern_size * elsize, - size * pattern_size * elsize, - einfo.wait_count, - einfo.waitersp, - einfo.eventp); - THROW_ERROR(res); - - events_post(env, &einfo, jevents); -#else - throwException(env, "java/lang/UnsupportedOperationException", "Requires OpenCL 1.2"); -#endif -} - -JNIEXPORT void JNICALL Java_au_notzed_zcl_CLCommandQueue_enqueueFillBuffer__Lau_notzed_zcl_CLBuffer_2_3BJJLau_notzed_zcl_CLEventList_2Lau_notzed_zcl_CLEventList_2 -(JNIEnv *env, jobject jqueue, - jobject jbuffer, jbyteArray jpattern, jlong offset, jlong size, - jobject jwaiters, jobject jevents) { - enqueueFillBuffer(env, jqueue, jbuffer, jpattern, offset, size, jwaiters, jevents, (getArrayRegion_t)(*env)->GetByteArrayRegion, 1); -} - -JNIEXPORT void JNICALL Java_au_notzed_zcl_CLCommandQueue_enqueueFillBuffer__Lau_notzed_zcl_CLBuffer_2_3SJJLau_notzed_zcl_CLEventList_2Lau_notzed_zcl_CLEventList_2 -(JNIEnv *env, jobject jqueue, - jobject jbuffer, jshortArray jpattern, jlong offset, jlong size, - jobject jwaiters, jobject jevents) { - enqueueFillBuffer(env, jqueue, jbuffer, jpattern, offset, size, jwaiters, jevents, (getArrayRegion_t)(*env)->GetByteArrayRegion, 2); -} - -JNIEXPORT void JNICALL Java_au_notzed_zcl_CLCommandQueue_enqueueFillBuffer__Lau_notzed_zcl_CLBuffer_2_3IJJLau_notzed_zcl_CLEventList_2Lau_notzed_zcl_CLEventList_2 -(JNIEnv *env, jobject jqueue, - jobject jbuffer, jintArray jpattern, jlong offset, jlong size, - jobject jwaiters, jobject jevents) { - enqueueFillBuffer(env, jqueue, jbuffer, jpattern, offset, size, jwaiters, jevents, (getArrayRegion_t)(*env)->GetIntArrayRegion, sizeof(cl_int)); -} - -JNIEXPORT void JNICALL Java_au_notzed_zcl_CLCommandQueue_enqueueFillBuffer__Lau_notzed_zcl_CLBuffer_2_3JJJLau_notzed_zcl_CLEventList_2Lau_notzed_zcl_CLEventList_2 -(JNIEnv *env, jobject jqueue, - jobject jbuffer, jlongArray jpattern, jlong offset, jlong size, - jobject jwaiters, jobject jevents) { - enqueueFillBuffer(env, jqueue, jbuffer, jpattern, offset, size, jwaiters, jevents, (getArrayRegion_t)(*env)->GetLongArrayRegion, sizeof(cl_long)); -} - -JNIEXPORT void JNICALL Java_au_notzed_zcl_CLCommandQueue_enqueueFillBuffer__Lau_notzed_zcl_CLBuffer_2_3FJJLau_notzed_zcl_CLEventList_2Lau_notzed_zcl_CLEventList_2 -(JNIEnv *env, jobject jqueue, - jobject jbuffer, jfloatArray jpattern, jlong offset, jlong size, - jobject jwaiters, jobject jevents) { - enqueueFillBuffer(env, jqueue, jbuffer, jpattern, offset, size, jwaiters, jevents, (getArrayRegion_t)(*env)->GetFloatArrayRegion, sizeof(cl_float)); -} - -JNIEXPORT void JNICALL Java_au_notzed_zcl_CLCommandQueue_enqueueFillBuffer__Lau_notzed_zcl_CLBuffer_2_3DJJLau_notzed_zcl_CLEventList_2Lau_notzed_zcl_CLEventList_2 -(JNIEnv *env, jobject jqueue, - jobject jbuffer, jdoubleArray jpattern, jlong offset, jlong size, - jobject jwaiters, jobject jevents) { - enqueueFillBuffer(env, jqueue, jbuffer, jpattern, offset, size, jwaiters, jevents, (getArrayRegion_t)(*env)->GetDoubleArrayRegion, sizeof(cl_double)); -} - -/* ********************************************************************** */ - -JNIEXPORT void JNICALL Java_au_notzed_zcl_CLCommandQueue_enqueueCopyBuffer -(JNIEnv *env, jobject jqueue, jobject jsrc, jobject jdst, jlong srcoff, jlong dstoff, jlong size, - jobject jwaiters, jobject jevents) { - FAIL_clEnqueueCopyBuffer(); - - cl_command_queue queue = GETP(env, jqueue); - cl_mem src; - cl_mem dst; - struct events_info einfo; - cl_int res; - - GET_P(env, jsrc, src,, "src must not be null"); - GET_P(env, jdst, dst,, "dst must not be null"); - - if (events_init(env, &einfo, jwaiters, jevents)) - return; - - res = clEnqueueCopyBuffer(queue, - src, - dst, - srcoff, - dstoff, - size, - einfo.wait_count, - einfo.waitersp, - einfo.eventp); - THROW_ERROR(res); - - events_post(env, &einfo, jevents); -} - -JNIEXPORT void JNICALL Java_au_notzed_zcl_CLCommandQueue_enqueueCopyBufferRect -(JNIEnv *env, jobject jqueue, jobject jsrc, jobject jdst, jlongArray jsrc_origin, jlongArray jdst_origin, jlongArray jregion, - jlong src_row_pitch, jlong src_slice_pitch, jlong dst_row_pitch, jlong dst_slice_pitch, - jobject jwaiters, jobject jevents) { -#ifdef CL_VERSION_1_1 - FAIL_clEnqueueCopyBufferRect(); - - cl_command_queue queue = GETP(env, jqueue); - cl_mem src; - cl_mem dst; - size_t src_origin[3]; - size_t dst_origin[3]; - size_t region[3]; - struct events_info einfo; - cl_int res; - - GET_P(env, jsrc, src,, "src must not be null"); - GET_P(env, jdst, dst,, "dst must not be null"); - - CHECK_ARRAY_MIN(env, jsrc_origin, 3,, "src origin must be 3-elements long"); - CHECK_ARRAY_MIN(env, jdst_origin, 3,, "dst origin must be 3-elements long"); - CHECK_ARRAY_MIN(env, jregion, 3,, "region must be 3-elements long"); - - if (events_init(env, &einfo, jwaiters, jevents)) - return; - - getSizeTA(env, jsrc_origin, src_origin, 3); - getSizeTA(env, jdst_origin, dst_origin, 3); - getSizeTA(env, jregion, region, 3); - -#if 0 - printf("CopyBufferRect[ src={ %d, %d, %d }/stride=%d slice=%d dstt={ %d, %d, %d }/stride=%d slice=%d region={ %d, %d, %d }\n", - (int)src_origin[0], (int)src_origin[1], (int)src_origin[2], (int)src_row_pitch, (int)src_slice_pitch, - (int)dst_origin[0], (int)dst_origin[1], (int)dst_origin[2], (int)dst_row_pitch, (int)dst_slice_pitch, - (int)region[0], (int)region[1], (int)region[2]); - fflush(stdout); -#endif - - res = clEnqueueCopyBufferRect(queue, - src, - dst, - src_origin, - dst_origin, - region, - src_row_pitch, - src_slice_pitch, - dst_row_pitch, - dst_slice_pitch, - einfo.wait_count, - einfo.waitersp, - einfo.eventp); - THROW_ERROR(res); - - events_post(env, &einfo, jevents); -#else - throwException(env, "java/lang/UnsupportedOperationException", "Requires OpenCL 1.1"); -#endif -} - -/* ********************************************************************** */ - -/* Common driver for image read/write from/to byte buffer */ -static void enqueueImageBuffer -(JNIEnv *env, jobject jqueue, jobject jimage, jboolean blocking, jlongArray jorigin, jlongArray jregion, - jlong row_pitch, jlong slice_pitch, - jarray jbuffer, - jobject jwaiters, jobject jevents, - enqueueReadWriteImage_t op) { - if (!op) { - throwException(env, "java/lang/UnsupportedOperationException", "Image read/write"); - return; - } - cl_command_queue queue = GETP(env, jqueue); - cl_mem image; - void *buffer = (*env)->GetDirectBufferAddress(env, jbuffer); - jint position = nativez_BufferPosition(env, jbuffer); - jint limit = nativez_BufferLimit(env, jbuffer); - size_t origin[3]; - size_t region[3]; - size_t elsize, tsize; - struct events_info einfo; - cl_int res; - - GET_P(env, jimage, image,, "image must not be null"); - - CHECK_ARRAY_MIN(env, jorigin, 3,, "origin must be 3-elements long"); - CHECK_ARRAY_MIN(env, jregion, 3,, "region must be 3-elements long"); - - getSizeTA(env, jorigin, origin, 3); - getSizeTA(env, jregion, region, 3); - - // Needed to check transfer size - clGetImageInfo(image, CL_IMAGE_ELEMENT_SIZE, sizeof(elsize), &elsize, NULL); - - // Calculate what OpenCL will actually transfer based on parameters. - tsize = get_transfer_size(region, row_pitch, slice_pitch, elsize); - - if (tsize > limit - position) { - // FIXME: overflow exception for read - throwException(env, "java/nio/BufferUnderflowExcetion", "source buffer too small"); - return; - } - - if (events_init(env, &einfo, jwaiters, jevents)) - return; - - res = op(queue, - image, - blocking, - origin, - region, - row_pitch, - slice_pitch, - buffer + position, - einfo.wait_count, - einfo.waitersp, - einfo.eventp); - THROW_ERROR(res); - - events_post(env, &einfo, jevents); -} - -JNIEXPORT void JNICALL -Java_au_notzed_zcl_CLCommandQueue_enqueueReadImage__Lau_notzed_zcl_CLImage_2Z_3J_3JJJLjava_nio_ByteBuffer_2Lau_notzed_zcl_CLEventList_2Lau_notzed_zcl_CLEventList_2 -(JNIEnv *env, jobject jqueue, jobject jimage, jboolean blocking, jlongArray jorigin, jlongArray jregion, - jlong row_pitch, jlong slice_pitch, - jobject jbuffer, - jobject jwaiters, jobject jevents) { - FAIL_clEnqueueReadImage(); - enqueueImageBuffer(env, jqueue, jimage, blocking, jorigin, jregion, row_pitch, slice_pitch, jbuffer, - jwaiters, jevents, clEnqueueReadImage); -} -JNIEXPORT void JNICALL -Java_au_notzed_zcl_CLCommandQueue_enqueueWriteImage__Lau_notzed_zcl_CLImage_2Z_3J_3JJJLjava_nio_ByteBuffer_2Lau_notzed_zcl_CLEventList_2Lau_notzed_zcl_CLEventList_2 -(JNIEnv *env, jobject jqueue, jobject jimage, jboolean blocking, jlongArray jorigin, jlongArray jregion, - jlong row_pitch, jlong slice_pitch, - jobject jbuffer, - jobject jwaiters, jobject jevents) { - FAIL_clEnqueueWriteImage(); - - // Cast is for a harmless const warning - enqueueImageBuffer(env, jqueue, jimage, blocking, jorigin, jregion, row_pitch, slice_pitch, jbuffer, - jwaiters, jevents, - (enqueueReadWriteImage_t)clEnqueueWriteImage); -} - -static void enqueueFillImage -(JNIEnv *env, jobject jqueue, - jobject jimage, void *colour, jlongArray jorigin, jlongArray jregion, - jobject jwaiters, jobject jevents) { -#ifdef CL_VERSION_1_2 - FAIL_clEnqueueFillImage(); - - cl_command_queue queue = GETP(env, jqueue); - cl_mem image; - size_t origin[3]; - size_t region[3]; - struct events_info einfo; - cl_int res; - - GET_P(env, jimage, image,, "image must not be null"); - - CHECK_ARRAY_MIN(env, jorigin, 3,, "origin must be 3-elements long"); - CHECK_ARRAY_MIN(env, jregion, 3,, "region must be 3-elements long"); - - if (events_init(env, &einfo, jwaiters, jevents)) - return; - - getSizeTA(env, jorigin, origin, 3); - getSizeTA(env, jregion, region, 3); - - D(printf("enqueue fill image( [ %d,%d,%d] [%d,%d,%d] )\n", - (int)origin[0], (int)origin[1], (int)origin[2], - (int)region[0], (int)region[1], (int)region[2])); - - res = clEnqueueFillImage(queue, - image, - colour, - origin, - region, - einfo.wait_count, - einfo.waitersp, - einfo.eventp); - THROW_ERROR(res); - - events_post(env, &einfo, jevents); -#else - throwException(env, "java/lang/UnsupportedOperationException", "Requires OpenCL 1.2"); -#endif -} - -JNIEXPORT void JNICALL Java_au_notzed_zcl_CLCommandQueue_enqueueFillImage__Lau_notzed_zcl_CLImage_2_3I_3J_3JLau_notzed_zcl_CLEventList_2Lau_notzed_zcl_CLEventList_2 -(JNIEnv *env, jobject jqueue, jobject jimage, jintArray jcolour, jlongArray jorigin, jlongArray jregion, - jobject jwaiters, jobject jevents) { - jint colour[4]; - - CHECK_ARRAY_MIN(env, jcolour, 4,, "colour must be 4-elements long"); - (*env)->GetIntArrayRegion(env, jcolour, 0, 4, colour); - - enqueueFillImage(env, jqueue, jimage, colour, jorigin, jregion, jwaiters, jevents); -} - -JNIEXPORT void JNICALL Java_au_notzed_zcl_CLCommandQueue_enqueueFillImage__Lau_notzed_zcl_CLImage_2_3F_3J_3JLau_notzed_zcl_CLEventList_2Lau_notzed_zcl_CLEventList_2 -(JNIEnv *env, jobject jqueue, jobject jimage, jfloatArray jcolour, jlongArray jorigin, jlongArray jregion, - jobject jwaiters, jobject jevents) { - jfloat colour[4]; - - CHECK_ARRAY_MIN(env, jcolour, 4,, "colour must be 4-elements long"); - (*env)->GetFloatArrayRegion(env, jcolour, 0, 4, colour); - - enqueueFillImage(env, jqueue, jimage, colour, jorigin, jregion, jwaiters, jevents); -} - -JNIEXPORT void JNICALL Java_au_notzed_zcl_CLCommandQueue_enqueueCopyImage -(JNIEnv *env, jobject jqueue, jobject jsrc, jobject jdst, jlongArray jsrc_origin, jlongArray jdst_origin, jlongArray jregion, - jobject jwaiters, jobject jevents) { - FAIL_clEnqueueCopyImage(); - - cl_command_queue queue = GETP(env, jqueue); - cl_mem src; - cl_mem dst; - size_t src_origin[3]; - size_t dst_origin[3]; - size_t region[3]; - struct events_info einfo; - cl_int res; - - GET_P(env, jsrc, src,, "src must not be null"); - GET_P(env, jdst, dst,, "dst must not be null"); - - CHECK_ARRAY_MIN(env, jsrc_origin, 3,, "src origin must be 3-elements long"); - CHECK_ARRAY_MIN(env, jdst_origin, 3,, "dst origin must be 3-elements long"); - CHECK_ARRAY_MIN(env, jregion, 3,, "region must be 3-elements long"); - - if (events_init(env, &einfo, jwaiters, jevents)) - return; - - getSizeTA(env, jsrc_origin, src_origin, 3); - getSizeTA(env, jdst_origin, dst_origin, 3); - getSizeTA(env, jregion, region, 3); - - res = clEnqueueCopyImage(queue, - src, - dst, - src_origin, - dst_origin, - region, - einfo.wait_count, - einfo.waitersp, - einfo.eventp); - THROW_ERROR(res); - - events_post(env, &einfo, jevents); -} - -JNIEXPORT void JNICALL Java_au_notzed_zcl_CLCommandQueue_enqueueCopyImageToBuffer -(JNIEnv *env, jobject jqueue, - jobject jsrc, jobject jdst, - jlongArray jsrc_origin, jlongArray jregion, jlong dst_offset, - jobject jwaiters, jobject jevents) { - FAIL_clEnqueueCopyImageToBuffer(); - - cl_command_queue queue = GETP(env, jqueue); - cl_mem src; - cl_mem dst; - size_t src_origin[3]; - size_t region[3]; - struct events_info einfo; - cl_int res; - - GET_P(env, jsrc, src,, "src must not be null"); - GET_P(env, jdst, dst,, "dst must not be null"); - - CHECK_ARRAY_MIN(env, jsrc_origin, 3,, "src origin must be 3-elements long"); - CHECK_ARRAY_MIN(env, jregion, 3,, "region must be 3-elements long"); - - if (events_init(env, &einfo, jwaiters, jevents)) - return; - - getSizeTA(env, jsrc_origin, src_origin, 3); - getSizeTA(env, jregion, region, 3); - - res = clEnqueueCopyImageToBuffer(queue, - src, - dst, - src_origin, - region, - dst_offset, - einfo.wait_count, - einfo.waitersp, - einfo.eventp); - THROW_ERROR(res); - - events_post(env, &einfo, jevents); -} - -JNIEXPORT void JNICALL Java_au_notzed_zcl_CLCommandQueue_enqueueCopyBufferToImage -(JNIEnv *env, jobject jqueue, - jobject jsrc, jobject jdst, - jlong src_offset, jlongArray jdst_origin, jlongArray jregion, - jobject jwaiters, jobject jevents) { - FAIL_clEnqueueCopyBufferToImage(); - - cl_command_queue queue = GETP(env, jqueue); - cl_mem src; - cl_mem dst; - size_t dst_origin[3]; - size_t region[3]; - struct events_info einfo; - cl_int res; - - GET_P(env, jsrc, src,, "src must not be null"); - GET_P(env, jdst, dst,, "dst must not be null"); - - CHECK_ARRAY_MIN(env, jdst_origin, 3,, "dst origin must be 3-elements long"); - CHECK_ARRAY_MIN(env, jregion, 3,, "region must be 3-elements long"); - - if (events_init(env, &einfo, jwaiters, jevents)) - return; - - getSizeTA(env, jdst_origin, dst_origin, 3); - getSizeTA(env, jregion, region, 3); - - res = clEnqueueCopyBufferToImage(queue, - src, - dst, - src_offset, - dst_origin, - region, - einfo.wait_count, - einfo.waitersp, - einfo.eventp); - THROW_ERROR(res); - - events_post(env, &einfo, jevents); -} - -JNIEXPORT jobject JNICALL Java_au_notzed_zcl_CLCommandQueue_enqueueMapBuffer -(JNIEnv *env, jobject jqueue, jobject jmem, jboolean blocking, jlong flags, jlong offset, jlong size, jobject jwaiters, jobject jevents) { - FAIL_clEnqueueMapBuffer_RET(NULL); - - cl_command_queue queue = GETP(env, jqueue); - cl_mem mem; - struct events_info einfo; - cl_int res; - void *ret; - - GET_P(env, jmem, mem, NULL, "mem must not be null"); - - if (events_init(env, &einfo, jwaiters, jevents)) - return NULL; - - ret = clEnqueueMapBuffer(queue, - mem, - blocking, - flags, - offset, - size, - einfo.wait_count, - einfo.waitersp, - einfo.eventp, - &res); - THROW_ERROR_RET(res, NULL); - - events_post(env, &einfo, jevents); - - return nativez_NewDirectBuffer(env, ret, size); -} - -JNIEXPORT jobject JNICALL Java_au_notzed_zcl_CLCommandQueue_enqueueMapImage -(JNIEnv *env, jobject jqueue, jobject jimage, jboolean blocking, jlong flags, - jlongArray jorigin, jlongArray jregion, jlongArray jrow_pitch, jlongArray jslice_pitch, - jobject jwaiters, jobject jevents) { - FAIL_clEnqueueMapImage_RET(NULL); - - cl_command_queue queue = GETP(env, jqueue); - cl_mem image; - struct events_info einfo; - size_t origin[3]; - size_t region[3]; - size_t row_pitch; - size_t slice_pitch; - cl_int res; - void *ret; - - GET_P(env, jimage, image, NULL, "image must not be null"); - - CHECK_ARRAY_MIN(env, jorigin, 3, NULL, "origin must be 3-elements long"); - CHECK_ARRAY_MIN(env, jregion, 3, NULL, "region must be 3-elements long"); - - if (events_init(env, &einfo, jwaiters, jevents)) - return NULL; - - getSizeTA(env, jorigin, origin, 3); - getSizeTA(env, jregion, region, 3); - - ret = clEnqueueMapImage(queue, - image, - blocking, - flags, - origin, - region, - &row_pitch, - &slice_pitch, - einfo.wait_count, - einfo.waitersp, - einfo.eventp, - &res); - THROW_ERROR_RET(res, NULL); - - if (jrow_pitch) { - jlong value = (jlong)row_pitch; - (*env)->SetLongArrayRegion(env, jrow_pitch, 0, 1, &value); - } - if (jslice_pitch) { - jlong value = (jlong)slice_pitch; - (*env)->SetLongArrayRegion(env, jslice_pitch, 0, 1, &value); - } - - events_post(env, &einfo, jevents); - - // TODO: check these, not sure how it works. - - jlong size; - - size = slice_pitch * region[2] + row_pitch * region[1] + region[0]; - - return nativez_NewDirectBuffer(env, ret, size); -} - -JNIEXPORT void JNICALL Java_au_notzed_zcl_CLCommandQueue_enqueueUnmapMemObject -(JNIEnv *env, jobject jqueue, jobject jmem, jobject jbuffer, jobject jwaiters, jobject jevents) { - FAIL_clEnqueueUnmapMemObject(); - - cl_command_queue queue = GETP(env, jqueue); - cl_mem mem; - void *buffer = (*env)->GetDirectBufferAddress(env, jbuffer); - struct events_info einfo; - cl_int res; - - GET_P(env, jmem, mem,, "mem must not be null"); - - if (events_init(env, &einfo, jwaiters, jevents)) - return; - - res = clEnqueueUnmapMemObject(queue, mem, buffer, - einfo.wait_count, - einfo.waitersp, - einfo.eventp); - THROW_ERROR(res); - events_post(env, &einfo, jevents); -} - -JNIEXPORT void JNICALL Java_au_notzed_zcl_CLCommandQueue_enqueueMigrateMemObjects -(JNIEnv *env, jobject jqueue, jobjectArray jmems, jlong flags, jobject jwaiters, jobject jevents) { -#ifdef CL_VERSION_1_2 - FAIL_clEnqueueMigrateMemObjects(); - - cl_command_queue queue = GETP(env, jqueue); - jsize mlen = (*env)->GetArrayLength(env, jmems); - cl_mem *mems = alloca(mlen * sizeof(*mems)); - struct events_info einfo; - cl_int res; - - if (fromObjectArray(env, jmems, (void **)mems, mlen)) - return; - - if (events_init(env, &einfo, jwaiters, jevents)) - return; - - res = clEnqueueMigrateMemObjects(queue, - mlen, - mems, - flags, - einfo.wait_count, - einfo.waitersp, - einfo.eventp); - THROW_ERROR(res); - - events_post(env, &einfo, jevents); -#else - throwException(env, "java/lang/UnsupportedOperationException", "Requires OpenCL 1.2"); -#endif -} - -JNIEXPORT void JNICALL Java_au_notzed_zcl_CLCommandQueue_enqueueNDRangeKernel -(JNIEnv *env, jobject jqueue, jobject jkernel, jint dim, - jlongArray jgwo, jlongArray jgws, jlongArray jlws, - jobject jwaiters, jobject jevents) { - FAIL_clEnqueueNDRangeKernel(); - - cl_command_queue queue = GETP(env, jqueue); - cl_kernel kernel; - struct events_info einfo; - cl_int res; - size_t gwo[3]; - size_t gws[3]; - size_t lws[3]; - - if (dim > 3 || dim < 1) { - throwCLException(env, CL_INVALID_WORK_DIMENSION); - return; - } - - GET_P(env, jkernel, kernel,, "kernel must not be null"); - - if (!jgws) { - throwException(env, "java/lang/NullPointerException", "global_size must not be null"); - return; - } - - if (events_init(env, &einfo, jwaiters, jevents)) - return; - - getSizeTA(env, jgwo, gwo, dim); - getSizeTA(env, jgws, gws, dim); - getSizeTA(env, jlws, lws, dim); - - D(printf("enqueue( dim=%d off=%d,%d,%d gws=%d,%d,%d lws=%d,%d,%d (%p)\n", - dim, - (int)gwo[0], (int)gwo[1], (int)gwo[2], - (int)gws[0], (int)gws[1], (int)gws[2], - (int)lws[0], (int)lws[1], (int)lws[2], jlws)); - - res = clEnqueueNDRangeKernel(queue, - kernel, - dim, - jgwo ? gwo : NULL, - gws, - jlws ? lws : NULL, - einfo.wait_count, - einfo.waitersp, - einfo.eventp); - THROW_ERROR(res); - - if (debug_sync) { - char kname[64]; - size_t size_ret; - - clGetKernelInfo(kernel, CL_KERNEL_FUNCTION_NAME, 64, kname, &size_ret); - (printf("zcl:enqueue('%s' dim=%d off=%d,%d,%d gws=%d,%d,%d lws=%d,%d,%d (%p)\n", - kname, - dim, - (int)gwo[0], (int)gwo[1], (int)gwo[2], - (int)gws[0], (int)gws[1], (int)gws[2], - (int)lws[0], (int)lws[1], (int)lws[2], jlws)); - fflush(stdout); - - clFlush(queue); - clFinish(queue); - } - - - events_post(env, &einfo, jevents); -} - -JNIEXPORT void JNICALL Java_au_notzed_zcl_CLCommandQueue_enqueueTask -(JNIEnv *env, jobject jqueue, jobject jkernel, - jobject jwaiters, jobject jevents) { - FAIL_clEnqueueTask(); - - cl_command_queue queue = GETP(env, jqueue); - cl_kernel kernel; - struct events_info einfo; - cl_int res; - - GET_P(env, jkernel, kernel,, "kernel must not be null"); - - if (events_init(env, &einfo, jwaiters, jevents)) - return; - - res = clEnqueueTask(queue, - kernel, - einfo.wait_count, - einfo.waitersp, - einfo.eventp); - THROW_ERROR(res); - - events_post(env, &einfo, jevents); -} - -/** - * This interrogates the argument array and provides the appropriate arguments - * for the clEnqueueNativeKernel call. - * - * The first argument to the JNI hook is native_kernel_info which is used - * to re-map the data back to Java objects. - */ - -struct native_kernel_info { - // Original kernel / args from caller (for reference) - jobject jkernel; - jobjectArray jargs; - - // Actual arguments passed to clEnqueueNativeKernel - // args[0] points to 'this' - // arguments follow - jobject *args; - int argslen; - - cl_mem *mems; - const void **memsloc; - int memslen; -}; - -static void native_kernel_free(JNIEnv *env, struct native_kernel_info *info) { - (*env)->DeleteGlobalRef(env, info->jargs); - (*env)->DeleteGlobalRef(env, info->jkernel); - free(info->args); - free(info->mems); - free(info->memsloc); - - free(info); -} - -static void native_kernel_hook(void *data) { - JNIEnv *env; - jobject *args = data; - struct native_kernel_info *info = (void *)args[0]; - jobjectArray kargs; - int argslen = info->argslen-1; - - if (!(env = nativez_AttachCurrentThreadAsDaemon())) { - // NB: can't do anything here - fprintf(stderr, "Unable to attach java environment\n"); - free(data); - return; - } - - kargs = (*env)->NewObjectArray(env, argslen, Object_classid, NULL); - - for (int i=0;iGetObjectArrayElement(env, info->jargs, i); - - if ((*env)->IsInstanceOf(env, jo, CLMemory_classid)) { - cl_mem mem = GETP(env, jo); - size_t memsize; - - clGetMemObjectInfo(mem, CL_MEM_SIZE, sizeof(memsize), &memsize, NULL); - - jo = nativez_NewDirectBuffer(env, args[i+1], memsize); - } - - (*env)->SetObjectArrayElement(env, kargs, i, jo); - } - - jvalue arg = { .l = kargs }; - (*env)->CallVoidMethodA(env, info->jkernel, CLNativeKernel_invoke__l, &arg); - - native_kernel_free(env, info); -} - -JNIEXPORT void Java_au_notzed_zcl_CLCommandQueue_enqueueNativeKernel -(JNIEnv *env, jobject jqueue, jobject jkernel, jobject jwaiters, jobject jevents, jobjectArray jargs) { - FAIL_clEnqueueNativeKernel(); - - cl_command_queue queue = GETP(env, jqueue); - int argslen = (*env)->GetArrayLength(env, jargs); - struct native_kernel_info *info; - struct events_info einfo; - cl_int res; - - // TODO: check if it could use more checks - - if (events_init(env, &einfo, jwaiters, jevents)) - return; - - info = malloc(sizeof(*info)); - - info->jargs = (*env)->NewGlobalRef(env, jargs); - info->jkernel = (*env)->NewGlobalRef(env, jkernel); - - info->args = malloc(sizeof(*info->args) * (argslen+1)); - info->argslen = argslen + 1; - info->mems = malloc(sizeof(*info->mems) * (argslen)); - info->memsloc = malloc(sizeof(*info->memsloc) * (argslen)); - info->memslen = 0; - - info->args[0] = (jobject)info; - - for (int i=0;iGetObjectArrayElement(env, jargs, i); - - if ((*env)->IsInstanceOf(env, jo, CLMemory_classid)) { - info->mems[info->memslen] = GETP(env, jo); - info->memsloc[info->memslen] = &info->args[i+1]; - info->memslen++; - info->args[i+1] = NULL; - } else { - info->args[i+1] = jo; - } - } - - res = clEnqueueNativeKernel(queue, - native_kernel_hook, - info->args, - sizeof(*info->args) * info->argslen, - info->memslen, - info->mems, - info->memsloc, - einfo.wait_count, - einfo.waitersp, - einfo.eventp); - if (res != CL_SUCCESS) { - native_kernel_free(env, info); - throwCLException(env, res); - return; - } - - events_post(env, &einfo, jevents); -} - -JNIEXPORT void JNICALL Java_au_notzed_zcl_CLCommandQueue_enqueueMarkerWithWaitList -(JNIEnv *env, jobject jqueue, jobject jwaiters, jobject jevents) { - /* As this emulates the 1.2 interface always, must fallback */ -#ifdef CL_VERSION_1_2 - if (CHECK_clEnqueueMarkerWithWaitList()) { - cl_command_queue queue = GETP(env, jqueue); - struct events_info einfo; - cl_int res; - - if (events_init(env, &einfo, jwaiters, jevents)) - return; - - res = clEnqueueMarkerWithWaitList(queue, - einfo.wait_count, - einfo.waitersp, - einfo.eventp); - THROW_ERROR(res); - - events_post(env, &einfo, jevents); - } else { - FAIL_clEnqueueWaitForEvents(); - FAIL_clEnqueueMarker(); - - cl_command_queue queue = GETP(env, jqueue); - struct events_info einfo; - cl_int res; - - if (events_init(env, &einfo, jwaiters, jevents)) - return; - - res = clEnqueueWaitForEvents(queue, - einfo.wait_count, - einfo.waitersp); - THROW_ERROR(res); - - res = clEnqueueMarker(queue, - einfo.eventp); - THROW_ERROR(res); - - events_post(env, &einfo, jevents); - } -#else - cl_command_queue queue = GETP(env, jqueue); - struct events_info einfo; - cl_int res; - - if (events_init(env, &einfo, jwaiters, jevents)) - return; - - res = clEnqueueWaitForEvents(queue, - einfo.wait_count, - einfo.waitersp); - THROW_ERROR(res); - - res = clEnqueueMarker(queue, - einfo.eventp); - THROW_ERROR(res); - - events_post(env, &einfo, jevents); -#endif -} - -JNIEXPORT void JNICALL Java_au_notzed_zcl_CLCommandQueue_enqueueBarrierWithWaitList -(JNIEnv *env, jobject jqueue, jobject jwaiters, jobject jevents) { -#ifdef CL_VERSION_1_2 - if (checkAPIVersion(env, jqueue, au_notzed_zcl_CLPlatform_VERSION_1_2)) { - cl_command_queue queue = GETP(env, jqueue); - struct events_info einfo; - cl_int res; - - if (events_init(env, &einfo, jwaiters, jevents)) - return; - - res = clEnqueueBarrierWithWaitList(queue, - einfo.wait_count, - einfo.waitersp, - einfo.eventp); - THROW_ERROR(res); - - events_post(env, &einfo, jevents); - return; - } -#endif - FAIL_clEnqueueWaitForEvents(); - FAIL_clEnqueueBarrier(); - FAIL_clEnqueueMarker(); - - cl_command_queue queue = GETP(env, jqueue); - struct events_info einfo; - cl_int res; - - if (events_init(env, &einfo, jwaiters, jevents)) - return; - - res = clEnqueueWaitForEvents(queue, - einfo.wait_count, - einfo.waitersp); - THROW_ERROR(res); - - res = clEnqueueBarrier(queue); - THROW_ERROR(res); - - res = clEnqueueMarker(queue, - einfo.eventp); - THROW_ERROR(res); - - events_post(env, &einfo, jevents); -} - -JNIEXPORT void JNICALL Java_au_notzed_zcl_CLCommandQueue_enqueueSVMFree -(JNIEnv *env, jobject jqueue, jobjectArray jptrs, jobject jwaiters, jobject jevents) { -#ifdef CL_VERSION_2_0 - if (checkAPIVersion(env, jqueue, au_notzed_zcl_CLPlatform_VERSION_2_0)) { - FAIL_clEnqueueSVMFree(); - - cl_command_queue queue = GETP(env, jqueue); - struct events_info einfo; - cl_int res; - void **ptrs; - size_t size; - - if (events_init(env, &einfo, jwaiters, jevents)) - return; - - size = (*env)->GetArrayLength(env, jptrs); - ptrs = alloca(sizeof(*ptrs) * size); - for (int i=0;iGetObjectArrayElement(env, jptrs, i); - - ptrs[i] = (*env)->GetDirectBufferAddress(env, jo); - } - - res = clEnqueueSVMFree(queue, - size, - ptrs, - NULL, // free_func - NULL, // user_data - einfo.wait_count, - einfo.waitersp, - einfo.eventp); - THROW_ERROR(res); - - events_post(env, &einfo, jevents); - } else -#endif - throwException(env, "java/lang/UnsupportedOperationException", "Requires OpenCL 2.0"); -} - -JNIEXPORT void JNICALL Java_au_notzed_zcl_CLCommandQueue_enqueueSVMMemcpy -(JNIEnv *env, jobject jqueue, jboolean blocking, jobject jdst, jlong doffset, jobject jsrc, jlong soffset, jlong size, jobject jwaiters, jobject jevents) { -#ifdef CL_VERSION_2_0 - if (checkAPIVersion(env, jqueue, au_notzed_zcl_CLPlatform_VERSION_2_0)) { - FAIL_clEnqueueSVMMemcpy(); - - cl_command_queue queue = GETP(env, jqueue); - void *dst, *src; - struct events_info einfo; - cl_int res; - - CHECK_NULL(env, jdst,, "dst must not be null"); - CHECK_NULL(env, jsrc,, "src must not be null"); - - dst = (*env)->GetDirectBufferAddress(env, jdst); - src = (*env)->GetDirectBufferAddress(env, jsrc); - - res = clEnqueueSVMMemcpy(queue, - blocking, - dst + doffset, - src + soffset, - size, - einfo.wait_count, - einfo.waitersp, - einfo.eventp); - THROW_ERROR(res); - - events_post(env, &einfo, jevents); - } else -#endif - throwException(env, "java/lang/UnsupportedOperationException", "Requires OpenCL 2.0"); -} - -static void enqueueSVMMemFill -(JNIEnv *env, jobject jqueue, - jobject jbuffer, jobject jpattern, jlong offset, jlong size, - jobject jwaiters, jobject jevents, getArrayRegion_t getArray, int elsize) { -#ifdef CL_VERSION_2_0 - if (checkAPIVersion(env, jqueue, au_notzed_zcl_CLPlatform_VERSION_2_0)) { - FAIL_clEnqueueSVMMemFill(); - - cl_command_queue queue = GETP(env, jqueue); - void *buffer; - void *pattern; - size_t pattern_size; - struct events_info einfo; - cl_int res; - - CHECK_NULL(env, jbuffer,, "pattern must not be null"); - CHECK_NULL(env, jpattern,, "pattern must not be null"); - - buffer = (*env)->GetDirectBufferAddress(env, jbuffer); - - pattern_size = (*env)->GetArrayLength(env, jpattern); - // complex double16 is maximum possible size? - if (pattern_size * elsize > 16*16) { - throwCLException(env, CL_INVALID_VALUE); - return; - } - pattern = alloca(pattern_size * elsize); - getArray(env, jpattern, 0, pattern_size, pattern); - - D(printf("enqueue svm memfill( off=%d size=%d patternsize=%d\n", - (int)(offset * pattern_size * elsize), - (int)(size * pattern_size * elsize), - (int)(pattern_size * elsize))); - - if (events_init(env, &einfo, jwaiters, jevents)) - return; - - res = clEnqueueSVMMemFill(queue, - buffer + offset * pattern_size * elsize, - pattern, - pattern_size * elsize, - size * pattern_size * elsize, - einfo.wait_count, - einfo.waitersp, - einfo.eventp); - THROW_ERROR(res); - - events_post(env, &einfo, jevents); - } else -#endif - throwException(env, "java/lang/UnsupportedOperationException", "Requires OpenCL 2.0"); -} - -JNIEXPORT void JNICALL Java_au_notzed_zcl_CLCommandQueue_enqueueSVMMemFill__Ljava_nio_ByteBuffer_2_3BJJLau_notzed_zcl_CLEventList_2Lau_notzed_zcl_CLEventList_2 -(JNIEnv *env, jobject jqueue, jobject jdst, jbyteArray jpattern, jlong offset, jlong size, jobject jwaiters, jobject jevents) { - enqueueSVMMemFill(env, jqueue, jdst, jpattern, offset, size, jwaiters, jevents, (getArrayRegion_t)(*env)->GetByteArrayRegion, 1); -} - -JNIEXPORT void JNICALL Java_au_notzed_zcl_CLCommandQueue_enqueueSVMMemFill__Ljava_nio_ByteBuffer_2_3SJJLau_notzed_zcl_CLEventList_2Lau_notzed_zcl_CLEventList_2 -(JNIEnv *env, jobject jqueue, jobject jdst, jshortArray jpattern, jlong offset, jlong size, jobject jwaiters, jobject jevents) { - enqueueSVMMemFill(env, jqueue, jdst, jpattern, offset, size, jwaiters, jevents, (getArrayRegion_t)(*env)->GetShortArrayRegion, 2); -} - -JNIEXPORT void JNICALL Java_au_notzed_zcl_CLCommandQueue_enqueueSVMMemFill__Ljava_nio_ByteBuffer_2_3IJJLau_notzed_zcl_CLEventList_2Lau_notzed_zcl_CLEventList_2 -(JNIEnv *env, jobject jqueue, jobject jdst, jintArray jpattern, jlong offset, jlong size, jobject jwaiters, jobject jevents) { - enqueueSVMMemFill(env, jqueue, jdst, jpattern, offset, size, jwaiters, jevents, (getArrayRegion_t)(*env)->GetIntArrayRegion, 4); -} - -JNIEXPORT void JNICALL Java_au_notzed_zcl_CLCommandQueue_enqueueSVMMemFill__Ljava_nio_ByteBuffer_2_3JJJLau_notzed_zcl_CLEventList_2Lau_notzed_zcl_CLEventList_2 -(JNIEnv *env, jobject jqueue, jobject jdst, jlongArray jpattern, jlong offset, jlong size, jobject jwaiters, jobject jevents) { - enqueueSVMMemFill(env, jqueue, jdst, jpattern, offset, size, jwaiters, jevents, (getArrayRegion_t)(*env)->GetLongArrayRegion, 8); -} - -JNIEXPORT void JNICALL Java_au_notzed_zcl_CLCommandQueue_enqueueSVMMemFill__Ljava_nio_ByteBuffer_2_3FJJLau_notzed_zcl_CLEventList_2Lau_notzed_zcl_CLEventList_2 -(JNIEnv *env, jobject jqueue, jobject jdst, jfloatArray jpattern, jlong offset, jlong size, jobject jwaiters, jobject jevents) { - enqueueSVMMemFill(env, jqueue, jdst, jpattern, offset, size, jwaiters, jevents, (getArrayRegion_t)(*env)->GetFloatArrayRegion, 4); -} - -JNIEXPORT void JNICALL Java_au_notzed_zcl_CLCommandQueue_enqueueSVMMemFill__Ljava_nio_ByteBuffer_2_3DJJLau_notzed_zcl_CLEventList_2Lau_notzed_zcl_CLEventList_2 -(JNIEnv *env, jobject jqueue, jobject jdst, jdoubleArray jpattern, jlong offset, jlong size, jobject jwaiters, jobject jevents) { - enqueueSVMMemFill(env, jqueue, jdst, jpattern, offset, size, jwaiters, jevents, (getArrayRegion_t)(*env)->GetDoubleArrayRegion, 8); -} - -JNIEXPORT void JNICALL Java_au_notzed_zcl_CLCommandQueue_enqueueSVMMap -(JNIEnv *env, jobject jqueue, jboolean blocking, jlong flags, jobject jsvm, jlong offset, jlong size, jobject jwaiters, jobject jevents) { -#ifdef CL_VERSION_2_0 - if (checkAPIVersion(env, jqueue, au_notzed_zcl_CLPlatform_VERSION_2_0)) { - FAIL_clEnqueueSVMMap(); - - cl_command_queue queue = GETP(env, jqueue); - void *svm; - struct events_info einfo; - cl_int res; - - CHECK_NULL(env, jsvm,, "svm pointer must not be null"); - - svm = (*env)->GetDirectBufferAddress(env, jsvm); - - if (events_init(env, &einfo, jwaiters, jevents)) - return; - - res = clEnqueueSVMMap(queue, - blocking, - flags, - svm + offset, - size, - einfo.wait_count, - einfo.waitersp, - einfo.eventp); - THROW_ERROR(res); - - events_post(env, &einfo, jevents); - } else -#endif - throwException(env, "java/lang/UnsupportedOperationException", "Requires OpenCL 2.0"); -} - -JNIEXPORT void JNICALL Java_au_notzed_zcl_CLCommandQueue_enqueueSVMUnmap -(JNIEnv *env, jobject jqueue, jobject jsvm, jlong offset, jobject jwaiters, jobject jevents) { -#ifdef CL_VERSION_2_0 - if (checkAPIVersion(env, jqueue, au_notzed_zcl_CLPlatform_VERSION_2_0)) { - FAIL_clEnqueueSVMUnmap(); - - cl_command_queue queue = GETP(env, jqueue); - void *svm; - struct events_info einfo; - cl_int res; - - CHECK_NULL(env, jsvm,, "svm pointer must not be null"); - - svm = (*env)->GetDirectBufferAddress(env, jsvm); - - if (events_init(env, &einfo, jwaiters, jevents)) - return; - - res = clEnqueueSVMUnmap(queue, - svm + offset, - einfo.wait_count, - einfo.waitersp, - einfo.eventp); - THROW_ERROR(res); - - events_post(env, &einfo, jevents); - } else -#endif - throwException(env, "java/lang/UnsupportedOperationException", "Requires OpenCL 2.0"); -} - -JNIEXPORT void JNICALL Java_au_notzed_zcl_CLCommandQueue_enqueueSVMMigrateMem -(JNIEnv *env, jobject jqueue, jobjectArray jmems, jlongArray joffsets, jlongArray jsizes, jlong flags, jobject jwaiters, jobject jevents) { -#ifdef CL_VERSION_2_1 - if (checkAPIVersion(env, jqueue, au_notzed_zcl_CLPlatform_VERSION_2_1)) { - FAIL_clEnqueueSVMMigrateMem(); - - cl_command_queue queue = GETP(env, jqueue); - jsize mlen = (*env)->GetArrayLength(env, jmems); - void **mems = alloca(mlen * sizeof(*mems)); - struct events_info einfo; - cl_int res; - size_t *sizes = NULL; - - if (fromObjectArray(env, jmems, (void **)mems, mlen)) - return; - - if (joffsets) { - size_t *offsets = alloca(sizeof(size_t) * mlen); - - getSizeTA(env, joffsets, offsets, mlen); - for (int i=0;iNewObject(env, CLImageFormat_classid, CLImageFormat_new_ii, - value.image_channel_order, - value.image_channel_data_type); -} - - -/* ********************************************************************** */ -/* Primitive array Buffer read/writes */ - -/* - For simplicity reasons only blocking operations are implemented. - */ - -static void enqueueBufferPrimitive -(JNIEnv *env, jobject jqueue, jobject jmem, jboolean blocking, jlong memoffset, jlong memsize, - jarray jbuffer, jlong bufoffset, - jobject jwaiters, jobject jevents, - int elshift, - enqueueReadWriteBuffer_t op) { - cl_command_queue queue = GETP(env, jqueue); - cl_mem mem; - void *buffer; - jsize bsize = (*env)->GetArrayLength(env, jbuffer); - struct events_info einfo; - cl_int res; - - //blocking = PRIMITIVE_BLOCKING(blocking); - blocking = CL_TRUE; - - //memoffset <<= elshift; - //memsize <<= elshift; - //bufoffset <<= elshift; - //bsize <<= elshift; - - if (memsize > bsize - bufoffset) { - throwException(env, "java/lang/ArrayIndexOutOfBoundsException", "target array too small"); - return; - } - - GET_P(env, jmem, mem,, "mem must not be null"); - - if (events_init(env, &einfo, jwaiters, jevents)) - return; - - buffer = (*env)->GetPrimitiveArrayCritical(env, jbuffer, NULL); - - res = op(queue, - mem, - blocking, - (memoffset << elshift), - (memsize << elshift), - buffer + (bufoffset << elshift), - einfo.wait_count, - einfo.waitersp, - einfo.eventp); - - (*env)->ReleasePrimitiveArrayCritical(env, jbuffer, buffer, 0); - THROW_ERROR(res); - - events_post(env, &einfo, jevents); -} - -JNIEXPORT void JNICALL Java_au_notzed_zcl_CLCommandQueue_enqueueReadBuffer__Lau_notzed_zcl_CLBuffer_2ZJJ_3BJLau_notzed_zcl_CLEventList_2Lau_notzed_zcl_CLEventList_2 -(JNIEnv *env, jobject jqueue, jobject jmem, jboolean blocking, jlong memoffset, jlong memsize, - jbyteArray jbuffer, jlong bufoffset, - jobject jwaiters, jobject jevents) { - enqueueBufferPrimitive(env, jqueue, jmem, blocking, memoffset, memsize, - jbuffer, bufoffset, - jwaiters, jevents, 0, - clEnqueueReadBuffer); -} - -JNIEXPORT void JNICALL Java_au_notzed_zcl_CLCommandQueue_enqueueReadBuffer__Lau_notzed_zcl_CLBuffer_2ZJJ_3SJLau_notzed_zcl_CLEventList_2Lau_notzed_zcl_CLEventList_2 -(JNIEnv *env, jobject jqueue, jobject jmem, jboolean blocking, jlong memoffset, jlong memsize, - jshortArray jbuffer, jlong bufoffset, - jobject jwaiters, jobject jevents) { - enqueueBufferPrimitive(env, jqueue, jmem, blocking, memoffset, memsize, - jbuffer, bufoffset, - jwaiters, jevents, 1, - clEnqueueReadBuffer); - -} - -JNIEXPORT void JNICALL Java_au_notzed_zcl_CLCommandQueue_enqueueReadBuffer__Lau_notzed_zcl_CLBuffer_2ZJJ_3IJLau_notzed_zcl_CLEventList_2Lau_notzed_zcl_CLEventList_2 -(JNIEnv *env, jobject jqueue, jobject jmem, jboolean blocking, jlong memoffset, jlong memsize, - jintArray jbuffer, jlong bufoffset, - jobject jwaiters, jobject jevents) { - enqueueBufferPrimitive(env, jqueue, jmem, blocking, memoffset, memsize, - jbuffer, bufoffset, - jwaiters, jevents, 2, - clEnqueueReadBuffer); -} - -JNIEXPORT void JNICALL Java_au_notzed_zcl_CLCommandQueue_enqueueReadBuffer__Lau_notzed_zcl_CLBuffer_2ZJJ_3JJLau_notzed_zcl_CLEventList_2Lau_notzed_zcl_CLEventList_2 -(JNIEnv *env, jobject jqueue, jobject jmem, jboolean blocking, jlong memoffset, jlong memsize, - jlongArray jbuffer, jlong bufoffset, - jobject jwaiters, jobject jevents) { - enqueueBufferPrimitive(env, jqueue, jmem, blocking, memoffset, memsize, - jbuffer, bufoffset, - jwaiters, jevents, 3, - clEnqueueReadBuffer); -} - -JNIEXPORT void JNICALL Java_au_notzed_zcl_CLCommandQueue_enqueueReadBuffer__Lau_notzed_zcl_CLBuffer_2ZJJ_3FJLau_notzed_zcl_CLEventList_2Lau_notzed_zcl_CLEventList_2 -(JNIEnv *env, jobject jqueue, jobject jmem, jboolean blocking, jlong memoffset, jlong memsize, - jfloatArray jbuffer, jlong bufoffset, - jobject jwaiters, jobject jevents) { - enqueueBufferPrimitive(env, jqueue, jmem, blocking, memoffset, memsize, - jbuffer, bufoffset, - jwaiters, jevents, 2, - clEnqueueReadBuffer); - -} - -JNIEXPORT void JNICALL Java_au_notzed_zcl_CLCommandQueue_enqueueReadBuffer__Lau_notzed_zcl_CLBuffer_2ZJJ_3DJLau_notzed_zcl_CLEventList_2Lau_notzed_zcl_CLEventList_2 -(JNIEnv *env, jobject jqueue, jobject jmem, jboolean blocking, jlong memoffset, jlong memsize, - jdoubleArray jbuffer, jlong bufoffset, - jobject jwaiters, jobject jevents) { - enqueueBufferPrimitive(env, jqueue, jmem, blocking, memoffset, memsize, - jbuffer, bufoffset, - jwaiters, jevents, 3, - clEnqueueReadBuffer); -} - -/* * * * */ - -JNIEXPORT void JNICALL Java_au_notzed_zcl_CLCommandQueue_enqueueWriteBuffer__Lau_notzed_zcl_CLBuffer_2ZJJ_3BJLau_notzed_zcl_CLEventList_2Lau_notzed_zcl_CLEventList_2 -(JNIEnv *env, jobject jqueue, jobject jmem, jboolean blocking, jlong memoffset, jlong memsize, - jbyteArray jbuffer, jlong bufoffset, - jobject jwaiters, jobject jevents) { - enqueueBufferPrimitive(env, jqueue, jmem, blocking, memoffset, memsize, - jbuffer, bufoffset, - jwaiters, jevents, 0, - (enqueueReadWriteBuffer_t)clEnqueueWriteBuffer); -} - -JNIEXPORT void JNICALL Java_au_notzed_zcl_CLCommandQueue_enqueueWriteBuffer__Lau_notzed_zcl_CLBuffer_2ZJJ_3SJLau_notzed_zcl_CLEventList_2Lau_notzed_zcl_CLEventList_2 -(JNIEnv *env, jobject jqueue, jobject jmem, jboolean blocking, jlong memoffset, jlong memsize, - jshortArray jbuffer, jlong bufoffset, - jobject jwaiters, jobject jevents) { - enqueueBufferPrimitive(env, jqueue, jmem, blocking, memoffset, memsize, - jbuffer, bufoffset, - jwaiters, jevents, 1, - (enqueueReadWriteBuffer_t)clEnqueueWriteBuffer); -} - -JNIEXPORT void JNICALL Java_au_notzed_zcl_CLCommandQueue_enqueueWriteBuffer__Lau_notzed_zcl_CLBuffer_2ZJJ_3IJLau_notzed_zcl_CLEventList_2Lau_notzed_zcl_CLEventList_2 -(JNIEnv *env, jobject jqueue, jobject jmem, jboolean blocking, jlong memoffset, jlong memsize, - jintArray jbuffer, jlong bufoffset, - jobject jwaiters, jobject jevents) { - enqueueBufferPrimitive(env, jqueue, jmem, blocking, memoffset, memsize, - jbuffer, bufoffset, - jwaiters, jevents, 2, - (enqueueReadWriteBuffer_t)clEnqueueWriteBuffer); -} - -JNIEXPORT void JNICALL Java_au_notzed_zcl_CLCommandQueue_enqueueWriteBuffer__Lau_notzed_zcl_CLBuffer_2ZJJ_3JJLau_notzed_zcl_CLEventList_2Lau_notzed_zcl_CLEventList_2 -(JNIEnv *env, jobject jqueue, jobject jmem, jboolean blocking, jlong memoffset, jlong memsize, - jlongArray jbuffer, jlong bufoffset, - jobject jwaiters, jobject jevents) { - enqueueBufferPrimitive(env, jqueue, jmem, blocking, memoffset, memsize, - jbuffer, bufoffset, - jwaiters, jevents, 3, - (enqueueReadWriteBuffer_t)clEnqueueWriteBuffer); - -} - -JNIEXPORT void JNICALL Java_au_notzed_zcl_CLCommandQueue_enqueueWriteBuffer__Lau_notzed_zcl_CLBuffer_2ZJJ_3FJLau_notzed_zcl_CLEventList_2Lau_notzed_zcl_CLEventList_2 -(JNIEnv *env, jobject jqueue, jobject jmem, jboolean blocking, jlong memoffset, jlong memsize, - jfloatArray jbuffer, jlong bufoffset, - jobject jwaiters, jobject jevents) { - enqueueBufferPrimitive(env, jqueue, jmem, blocking, memoffset, memsize, - jbuffer, bufoffset, - jwaiters, jevents, 2, - (enqueueReadWriteBuffer_t)clEnqueueWriteBuffer); -} - -JNIEXPORT void JNICALL Java_au_notzed_zcl_CLCommandQueue_enqueueWriteBuffer__Lau_notzed_zcl_CLBuffer_2ZJJ_3DJLau_notzed_zcl_CLEventList_2Lau_notzed_zcl_CLEventList_2 -(JNIEnv *env, jobject jqueue, jobject jmem, jboolean blocking, jlong memoffset, jlong memsize, - jdoubleArray jbuffer, jlong bufoffset, - jobject jwaiters, jobject jevents) { - enqueueBufferPrimitive(env, jqueue, jmem, blocking, memoffset, memsize, - jbuffer, bufoffset, - jwaiters, jevents, 3, - (enqueueReadWriteBuffer_t)clEnqueueWriteBuffer); - -} - -/* ********************************************************************** */ - -/* 2D/3D Buffer primitive array read/write operations */ - -/* - For simplicity reasons only blocking operations are implemented. - */ - -static void enqueueBufferRectPrimitive -(JNIEnv *env, jobject jqueue, jobject jmem, jboolean blocking, - jlongArray jbuf_origin, jlongArray jhost_origin, jlongArray jregion, - jlong buf_row_pitch, jlong buf_slice_pitch, jlong host_row_pitch, jlong host_slice_pitch, - jbyteArray jbuffer, jobject jwaiters, jobject jevents, int elshift, - enqueueReadWriteBufferRect_t op) { -#ifdef CL_VERSION_1_1 - if (!op) { - throwException(env, "java/lang/UnsupportedOperationException", "Buffer read/write"); - return; - } - - cl_command_queue queue = GETP(env, jqueue); - cl_mem mem; - void *buffer; - jsize bsize = (*env)->GetArrayLength(env, jbuffer); - struct events_info einfo; - cl_int res; - size_t buf_origin[3]; - size_t host_origin[3]; - size_t region[3]; - - blocking = CL_TRUE; - - CHECK_ARRAY_MIN(env, jbuf_origin, 3,, "buf origin must be 3-elements long"); - CHECK_ARRAY_MIN(env, jhost_origin, 3,, "host origin must be 3-elements long"); - CHECK_ARRAY_MIN(env, jregion, 3,, "region must be 3-elements long"); - - getSizeTA(env, jbuf_origin, buf_origin, 3); - getSizeTA(env, jhost_origin, host_origin, 3); - getSizeTA(env, jregion, region, 3); - - buf_origin[0] <<= elshift; - host_origin[0] <<= elshift; - region[0] <<= elshift; - buf_row_pitch <<= elshift; - buf_slice_pitch <<= elshift; - host_row_pitch <<= elshift; - host_slice_pitch <<= elshift; - - size_t stride = (host_row_pitch == 0 ? region[0] : host_row_pitch); - size_t slice = (host_slice_pitch == 0 ? region[1] * stride : host_slice_pitch); - -#if 0 - printf("*BufferRect[ dev={ %d, %d, %d }/stride=%d slice=%d host={ %d, %d, %d }/stride=%d slice=%d region={ %d, %d, %d } bsize=%d dstride=%d dslice=%d dorigin=%d dsize=%d\n", - (int)buf_origin[0], (int)buf_origin[1], (int)buf_origin[2], (int)buf_row_pitch, (int)buf_slice_pitch, - (int)host_origin[0], (int)host_origin[1], (int)host_origin[2], (int)host_row_pitch, (int)host_slice_pitch, - (int)region[0], (int)region[1], (int)region[2], - (int)(bsize << elshift), - (int)stride, (int)slice, - (int)(host_origin[0] + host_origin[1] * stride + host_origin[2] * slice), - (int)(region[0] + (region[1]-1) * stride + (region[2]-1) * slice)); - fflush(stdout); -#endif - - if (host_origin[0] + host_origin[1] * stride + host_origin[2] * slice - + region[0] + (region[1]-1) * stride + (region[2]-1) * slice - > bsize << elshift) { - throwException(env, "java/lang/ArrayIndexOutOfBoundsException", "Target buffer overflow"); - return; - } - - GET_P(env, jmem, mem,, "mem must not be null"); - - if (events_init(env, &einfo, jwaiters, jevents)) - return; - - buffer = (*env)->GetPrimitiveArrayCritical(env, jbuffer, NULL); - res = (*op)(queue, - mem, - blocking, - buf_origin, - host_origin, - region, - buf_row_pitch, - buf_slice_pitch, - host_row_pitch, - host_slice_pitch, - buffer, - einfo.wait_count, - einfo.waitersp, - einfo.eventp); - (*env)->ReleasePrimitiveArrayCritical(env, jbuffer, buffer, 0); - - THROW_ERROR(res); - - events_post(env, &einfo, jevents); -#else - throwException(env, "java/lang/UnsupportedOperationException", "Requires OpenCL 1.1"); -#endif -} - -JNIEXPORT void JNICALL Java_au_notzed_zcl_CLCommandQueue_enqueueReadBufferRect__Lau_notzed_zcl_CLBuffer_2Z_3J_3J_3JJJJJ_3BLau_notzed_zcl_CLEventList_2Lau_notzed_zcl_CLEventList_2 -(JNIEnv *env, jobject jqueue, jobject jmem, jboolean blocking, - jlongArray jbuf_origin, jlongArray jhost_origin, jlongArray jregion, - jlong buf_row_pitch, jlong buf_slice_pitch, jlong host_row_pitch, jlong host_slice_pitch, - jbyteArray jbuffer, jobject jwaiters, jobject jevents) { - enqueueBufferRectPrimitive(env, jqueue, jmem, blocking, jbuf_origin, jhost_origin, jregion, - buf_row_pitch, buf_slice_pitch, host_row_pitch, host_slice_pitch, - jbuffer, jwaiters, jevents, 0, - clEnqueueReadBufferRect); -} - -JNIEXPORT void JNICALL Java_au_notzed_zcl_CLCommandQueue_enqueueReadBufferRect__Lau_notzed_zcl_CLBuffer_2Z_3J_3J_3JJJJJ_3SLau_notzed_zcl_CLEventList_2Lau_notzed_zcl_CLEventList_2 -(JNIEnv *env, jobject jqueue, jobject jmem, jboolean blocking, - jlongArray jbuf_origin, jlongArray jhost_origin, jlongArray jregion, - jlong buf_row_pitch, jlong buf_slice_pitch, jlong host_row_pitch, jlong host_slice_pitch, - jshortArray jbuffer, jobject jwaiters, jobject jevents) { - enqueueBufferRectPrimitive(env, jqueue, jmem, blocking, jbuf_origin, jhost_origin, jregion, - buf_row_pitch, buf_slice_pitch, host_row_pitch, host_slice_pitch, - jbuffer, jwaiters, jevents, 1, - clEnqueueReadBufferRect); -} - -JNIEXPORT void JNICALL Java_au_notzed_zcl_CLCommandQueue_enqueueReadBufferRect__Lau_notzed_zcl_CLBuffer_2Z_3J_3J_3JJJJJ_3ILau_notzed_zcl_CLEventList_2Lau_notzed_zcl_CLEventList_2 -(JNIEnv *env, jobject jqueue, jobject jmem, jboolean blocking, - jlongArray jbuf_origin, jlongArray jhost_origin, jlongArray jregion, - jlong buf_row_pitch, jlong buf_slice_pitch, jlong host_row_pitch, jlong host_slice_pitch, - jintArray jbuffer, jobject jwaiters, jobject jevents) { - enqueueBufferRectPrimitive(env, jqueue, jmem, blocking, jbuf_origin, jhost_origin, jregion, - buf_row_pitch, buf_slice_pitch, host_row_pitch, host_slice_pitch, - jbuffer, jwaiters, jevents, 2, - clEnqueueReadBufferRect); -} - -JNIEXPORT void JNICALL Java_au_notzed_zcl_CLCommandQueue_enqueueReadBufferRect__Lau_notzed_zcl_CLBuffer_2Z_3J_3J_3JJJJJ_3JLau_notzed_zcl_CLEventList_2Lau_notzed_zcl_CLEventList_2 -(JNIEnv *env, jobject jqueue, jobject jmem, jboolean blocking, - jlongArray jbuf_origin, jlongArray jhost_origin, jlongArray jregion, - jlong buf_row_pitch, jlong buf_slice_pitch, jlong host_row_pitch, jlong host_slice_pitch, - jlongArray jbuffer, jobject jwaiters, jobject jevents) { - enqueueBufferRectPrimitive(env, jqueue, jmem, blocking, jbuf_origin, jhost_origin, jregion, - buf_row_pitch, buf_slice_pitch, host_row_pitch, host_slice_pitch, - jbuffer, jwaiters, jevents, 3, - clEnqueueReadBufferRect); -} - -JNIEXPORT void JNICALL Java_au_notzed_zcl_CLCommandQueue_enqueueReadBufferRect__Lau_notzed_zcl_CLBuffer_2Z_3J_3J_3JJJJJ_3FLau_notzed_zcl_CLEventList_2Lau_notzed_zcl_CLEventList_2 -(JNIEnv *env, jobject jqueue, jobject jmem, jboolean blocking, - jlongArray jbuf_origin, jlongArray jhost_origin, jlongArray jregion, - jlong buf_row_pitch, jlong buf_slice_pitch, jlong host_row_pitch, jlong host_slice_pitch, - jfloatArray jbuffer, jobject jwaiters, jobject jevents) { - enqueueBufferRectPrimitive(env, jqueue, jmem, blocking, jbuf_origin, jhost_origin, jregion, - buf_row_pitch, buf_slice_pitch, host_row_pitch, host_slice_pitch, - jbuffer, jwaiters, jevents, 2, - clEnqueueReadBufferRect); -} - -JNIEXPORT void JNICALL Java_au_notzed_zcl_CLCommandQueue_enqueueReadBufferRect__Lau_notzed_zcl_CLBuffer_2Z_3J_3J_3JJJJJ_3DLau_notzed_zcl_CLEventList_2Lau_notzed_zcl_CLEventList_2 -(JNIEnv *env, jobject jqueue, jobject jmem, jboolean blocking, - jlongArray jbuf_origin, jlongArray jhost_origin, jlongArray jregion, - jlong buf_row_pitch, jlong buf_slice_pitch, jlong host_row_pitch, jlong host_slice_pitch, - jdoubleArray jbuffer, jobject jwaiters, jobject jevents) { - enqueueBufferRectPrimitive(env, jqueue, jmem, blocking, jbuf_origin, jhost_origin, jregion, - buf_row_pitch, buf_slice_pitch, host_row_pitch, host_slice_pitch, - jbuffer, jwaiters, jevents, 3, - clEnqueueReadBufferRect); -} - -/* * * * */ - -JNIEXPORT void JNICALL Java_au_notzed_zcl_CLCommandQueue_enqueueWriteBufferRect__Lau_notzed_zcl_CLBuffer_2Z_3J_3J_3JJJJJ_3BLau_notzed_zcl_CLEventList_2Lau_notzed_zcl_CLEventList_2 -(JNIEnv *env, jobject jqueue, jobject jmem, jboolean blocking, - jlongArray jbuf_origin, jlongArray jhost_origin, jlongArray jregion, - jlong buf_row_pitch, jlong buf_slice_pitch, jlong host_row_pitch, jlong host_slice_pitch, - jbyteArray jbuffer, jobject jwaiters, jobject jevents) { - enqueueBufferRectPrimitive(env, jqueue, jmem, blocking, jbuf_origin, jhost_origin, jregion, - buf_row_pitch, buf_slice_pitch, host_row_pitch, host_slice_pitch, - jbuffer, jwaiters, jevents, 0, - (enqueueReadWriteBufferRect_t)clEnqueueWriteBufferRect); -} - -JNIEXPORT void JNICALL Java_au_notzed_zcl_CLCommandQueue_enqueueWriteBufferRect__Lau_notzed_zcl_CLBuffer_2Z_3J_3J_3JJJJJ_3SLau_notzed_zcl_CLEventList_2Lau_notzed_zcl_CLEventList_2 -(JNIEnv *env, jobject jqueue, jobject jmem, jboolean blocking, - jlongArray jbuf_origin, jlongArray jhost_origin, jlongArray jregion, - jlong buf_row_pitch, jlong buf_slice_pitch, jlong host_row_pitch, jlong host_slice_pitch, - jshortArray jbuffer, jobject jwaiters, jobject jevents) { - enqueueBufferRectPrimitive(env, jqueue, jmem, blocking, jbuf_origin, jhost_origin, jregion, - buf_row_pitch, buf_slice_pitch, host_row_pitch, host_slice_pitch, - jbuffer, jwaiters, jevents, 1, - (enqueueReadWriteBufferRect_t)clEnqueueWriteBufferRect); -} - -JNIEXPORT void JNICALL Java_au_notzed_zcl_CLCommandQueue_enqueueWriteBufferRect__Lau_notzed_zcl_CLBuffer_2Z_3J_3J_3JJJJJ_3ILau_notzed_zcl_CLEventList_2Lau_notzed_zcl_CLEventList_2 -(JNIEnv *env, jobject jqueue, jobject jmem, jboolean blocking, - jlongArray jbuf_origin, jlongArray jhost_origin, jlongArray jregion, - jlong buf_row_pitch, jlong buf_slice_pitch, jlong host_row_pitch, jlong host_slice_pitch, - jintArray jbuffer, jobject jwaiters, jobject jevents) { - enqueueBufferRectPrimitive(env, jqueue, jmem, blocking, jbuf_origin, jhost_origin, jregion, - buf_row_pitch, buf_slice_pitch, host_row_pitch, host_slice_pitch, - jbuffer, jwaiters, jevents, 2, - (enqueueReadWriteBufferRect_t)clEnqueueWriteBufferRect); -} - -JNIEXPORT void JNICALL Java_au_notzed_zcl_CLCommandQueue_enqueueWriteBufferRect__Lau_notzed_zcl_CLBuffer_2Z_3J_3J_3JJJJJ_3JLau_notzed_zcl_CLEventList_2Lau_notzed_zcl_CLEventList_2 -(JNIEnv *env, jobject jqueue, jobject jmem, jboolean blocking, - jlongArray jbuf_origin, jlongArray jhost_origin, jlongArray jregion, - jlong buf_row_pitch, jlong buf_slice_pitch, jlong host_row_pitch, jlong host_slice_pitch, - jlongArray jbuffer, jobject jwaiters, jobject jevents) { - enqueueBufferRectPrimitive(env, jqueue, jmem, blocking, jbuf_origin, jhost_origin, jregion, - buf_row_pitch, buf_slice_pitch, host_row_pitch, host_slice_pitch, - jbuffer, jwaiters, jevents, 3, - (enqueueReadWriteBufferRect_t)clEnqueueWriteBufferRect); -} - -JNIEXPORT void JNICALL Java_au_notzed_zcl_CLCommandQueue_enqueueWriteBufferRect__Lau_notzed_zcl_CLBuffer_2Z_3J_3J_3JJJJJ_3FLau_notzed_zcl_CLEventList_2Lau_notzed_zcl_CLEventList_2 -(JNIEnv *env, jobject jqueue, jobject jmem, jboolean blocking, - jlongArray jbuf_origin, jlongArray jhost_origin, jlongArray jregion, - jlong buf_row_pitch, jlong buf_slice_pitch, jlong host_row_pitch, jlong host_slice_pitch, - jfloatArray jbuffer, jobject jwaiters, jobject jevents) { - enqueueBufferRectPrimitive(env, jqueue, jmem, blocking, jbuf_origin, jhost_origin, jregion, - buf_row_pitch, buf_slice_pitch, host_row_pitch, host_slice_pitch, - jbuffer, jwaiters, jevents, 2, - (enqueueReadWriteBufferRect_t)clEnqueueWriteBufferRect); -} - -JNIEXPORT void JNICALL Java_au_notzed_zcl_CLCommandQueue_enqueueWriteBufferRect__Lau_notzed_zcl_CLBuffer_2Z_3J_3J_3JJJJJ_3DLau_notzed_zcl_CLEventList_2Lau_notzed_zcl_CLEventList_2 -(JNIEnv *env, jobject jqueue, jobject jmem, jboolean blocking, - jlongArray jbuf_origin, jlongArray jhost_origin, jlongArray jregion, - jlong buf_row_pitch, jlong buf_slice_pitch, jlong host_row_pitch, jlong host_slice_pitch, - jbyteArray jbuffer, jobject jwaiters, jobject jevents) { - enqueueBufferRectPrimitive(env, jqueue, jmem, blocking, jbuf_origin, jhost_origin, jregion, - buf_row_pitch, buf_slice_pitch, host_row_pitch, host_slice_pitch, - jbuffer, jwaiters, jevents, 3, - (enqueueReadWriteBufferRect_t)clEnqueueWriteBufferRect); -} - -/* ********************************************************************** */ -/* Primitive array Image read/writes */ - -static void enqueueImagePrimitive -(JNIEnv *env, jobject jqueue, jobject jimage, jboolean blocking, jlongArray jorigin, jlongArray jregion, - jlong row_pitch, jlong slice_pitch, - jarray jbuffer, jlong bufoffset, - jobject jwaiters, jobject jevents, - int elshift, - enqueueReadWriteImage_t op) { - if (!op) { - throwException(env, "java/lang/UnsupportedOperationException", "Image read/write"); - return; - } - - cl_command_queue queue = GETP(env, jqueue); - cl_mem image; - void *buffer; - size_t origin[3]; - size_t region[3]; - size_t elsize, tsize; - struct events_info einfo; - cl_int res; - - GET_P(env, jimage, image,, "image must not be null"); - - CHECK_ARRAY_MIN(env, jorigin, 3,, "origin must be 3-elements long"); - CHECK_ARRAY_MIN(env, jregion, 3,, "region must be 3-elements long"); - - getSizeTA(env, jorigin, origin, 3); - getSizeTA(env, jregion, region, 3); - - // Needed to check transfer size - clGetImageInfo(image, CL_IMAGE_ELEMENT_SIZE, sizeof(elsize), &elsize, NULL); - - //blocking = PRIMITIVE_BLOCKING(blocking); - blocking = CL_TRUE; - - // Map to java primitive type. - bufoffset <<= elshift; - row_pitch <<= elshift; - slice_pitch <<= elshift; - - tsize = get_transfer_size(region, row_pitch, slice_pitch, elsize); - - CHECK_ARRAY_MIN(env, jbuffer, tsize >> elshift,, "array too small"); - - if (events_init(env, &einfo, jwaiters, jevents)) - return; - - buffer = (*env)->GetPrimitiveArrayCritical(env, jbuffer, NULL); - - res = op(queue, - image, - blocking, - origin, - region, - row_pitch, - slice_pitch, - buffer + bufoffset, - einfo.wait_count, - einfo.waitersp, - einfo.eventp); - - (*env)->ReleasePrimitiveArrayCritical(env, jbuffer, buffer, 0); - - THROW_ERROR(res); - - events_post(env, &einfo, jevents); -} - -JNIEXPORT void JNICALL Java_au_notzed_zcl_CLCommandQueue_enqueueReadImage__Lau_notzed_zcl_CLImage_2Z_3J_3JJJ_3BJLau_notzed_zcl_CLEventList_2Lau_notzed_zcl_CLEventList_2 -(JNIEnv *env, jobject jqueue, jobject jimage, jboolean blocking, jlongArray jorigin, jlongArray jregion, - jlong row_pitch, jlong slice_pitch, - jbyteArray jbuffer, jlong bufoffset, - jobject jwaiters, jobject jevents) { - enqueueImagePrimitive(env, jqueue, jimage, blocking, jorigin, jregion, row_pitch, slice_pitch, - jbuffer, bufoffset, jwaiters, jevents, 0, - clEnqueueReadImage); -} - -JNIEXPORT void JNICALL Java_au_notzed_zcl_CLCommandQueue_enqueueReadImage__Lau_notzed_zcl_CLImage_2Z_3J_3JJJ_3SJLau_notzed_zcl_CLEventList_2Lau_notzed_zcl_CLEventList_2 -(JNIEnv *env, jobject jqueue, jobject jimage, jboolean blocking, jlongArray jorigin, jlongArray jregion, - jlong row_pitch, jlong slice_pitch, - jshortArray jbuffer, jlong bufoffset, - jobject jwaiters, jobject jevents) { - enqueueImagePrimitive(env, jqueue, jimage, blocking, jorigin, jregion, row_pitch, slice_pitch, - jbuffer, bufoffset, jwaiters, jevents, 1, - clEnqueueReadImage); -} - -JNIEXPORT void JNICALL Java_au_notzed_zcl_CLCommandQueue_enqueueReadImage__Lau_notzed_zcl_CLImage_2Z_3J_3JJJ_3IJLau_notzed_zcl_CLEventList_2Lau_notzed_zcl_CLEventList_2 -(JNIEnv *env, jobject jqueue, jobject jimage, jboolean blocking, jlongArray jorigin, jlongArray jregion, - jlong row_pitch, jlong slice_pitch, - jintArray jbuffer, jlong bufoffset, - jobject jwaiters, jobject jevents) { - enqueueImagePrimitive(env, jqueue, jimage, blocking, jorigin, jregion, row_pitch, slice_pitch, - jbuffer, bufoffset, jwaiters, jevents, 2, - clEnqueueReadImage); -} - -JNIEXPORT void JNICALL Java_au_notzed_zcl_CLCommandQueue_enqueueReadImage__Lau_notzed_zcl_CLImage_2Z_3J_3JJJ_3JJLau_notzed_zcl_CLEventList_2Lau_notzed_zcl_CLEventList_2 -(JNIEnv *env, jobject jqueue, jobject jimage, jboolean blocking, jlongArray jorigin, jlongArray jregion, - jlong row_pitch, jlong slice_pitch, - jlongArray jbuffer, jlong bufoffset, - jobject jwaiters, jobject jevents) { - enqueueImagePrimitive(env, jqueue, jimage, blocking, jorigin, jregion, row_pitch, slice_pitch, - jbuffer, bufoffset, jwaiters, jevents, 3, - clEnqueueReadImage); -} - -JNIEXPORT void JNICALL Java_au_notzed_zcl_CLCommandQueue_enqueueReadImage__Lau_notzed_zcl_CLImage_2Z_3J_3JJJ_3FJLau_notzed_zcl_CLEventList_2Lau_notzed_zcl_CLEventList_2 -(JNIEnv *env, jobject jqueue, jobject jimage, jboolean blocking, jlongArray jorigin, jlongArray jregion, - jlong row_pitch, jlong slice_pitch, - jfloatArray jbuffer, jlong bufoffset, - jobject jwaiters, jobject jevents) { - enqueueImagePrimitive(env, jqueue, jimage, blocking, jorigin, jregion, row_pitch, slice_pitch, - jbuffer, bufoffset, jwaiters, jevents, 2, - clEnqueueReadImage); -} - -JNIEXPORT void JNICALL Java_au_notzed_zcl_CLCommandQueue_enqueueReadImage__Lau_notzed_zcl_CLImage_2Z_3J_3JJJ_3DJLau_notzed_zcl_CLEventList_2Lau_notzed_zcl_CLEventList_2 -(JNIEnv *env, jobject jqueue, jobject jimage, jboolean blocking, jlongArray jorigin, jlongArray jregion, - jlong row_pitch, jlong slice_pitch, - jdoubleArray jbuffer, jlong bufoffset, - jobject jwaiters, jobject jevents) { - enqueueImagePrimitive(env, jqueue, jimage, blocking, jorigin, jregion, row_pitch, slice_pitch, - jbuffer, bufoffset, jwaiters, jevents, 3, - clEnqueueReadImage); -} - -/* * * * */ - -JNIEXPORT void JNICALL Java_au_notzed_zcl_CLCommandQueue_enqueueWriteImage__Lau_notzed_zcl_CLImage_2Z_3J_3JJJ_3BJLau_notzed_zcl_CLEventList_2Lau_notzed_zcl_CLEventList_2 -(JNIEnv *env, jobject jqueue, jobject jimage, jboolean blocking, jlongArray jorigin, jlongArray jregion, - jlong row_pitch, jlong slice_pitch, - jbyteArray jbuffer, jlong bufoffset, - jobject jwaiters, jobject jevents) { - enqueueImagePrimitive(env, jqueue, jimage, blocking, jorigin, jregion, row_pitch, slice_pitch, - jbuffer, bufoffset, jwaiters, jevents, 0, - (enqueueReadWriteImage_t)clEnqueueWriteImage); -} - -JNIEXPORT void JNICALL Java_au_notzed_zcl_CLCommandQueue_enqueueWriteImage__Lau_notzed_zcl_CLImage_2Z_3J_3JJJ_3SJLau_notzed_zcl_CLEventList_2Lau_notzed_zcl_CLEventList_2 -(JNIEnv *env, jobject jqueue, jobject jimage, jboolean blocking, jlongArray jorigin, jlongArray jregion, - jlong row_pitch, jlong slice_pitch, - jshortArray jbuffer, jlong bufoffset, - jobject jwaiters, jobject jevents) { - enqueueImagePrimitive(env, jqueue, jimage, blocking, jorigin, jregion, row_pitch, slice_pitch, - jbuffer, bufoffset, jwaiters, jevents, 1, - (enqueueReadWriteImage_t)clEnqueueWriteImage); -} - -JNIEXPORT void JNICALL Java_au_notzed_zcl_CLCommandQueue_enqueueWriteImage__Lau_notzed_zcl_CLImage_2Z_3J_3JJJ_3IJLau_notzed_zcl_CLEventList_2Lau_notzed_zcl_CLEventList_2 -(JNIEnv *env, jobject jqueue, jobject jimage, jboolean blocking, jlongArray jorigin, jlongArray jregion, - jlong row_pitch, jlong slice_pitch, - jintArray jbuffer, jlong bufoffset, - jobject jwaiters, jobject jevents) { - enqueueImagePrimitive(env, jqueue, jimage, blocking, jorigin, jregion, row_pitch, slice_pitch, - jbuffer, bufoffset, jwaiters, jevents, 2, - (enqueueReadWriteImage_t)clEnqueueWriteImage); -} - -JNIEXPORT void JNICALL Java_au_notzed_zcl_CLCommandQueue_enqueueWriteImage__Lau_notzed_zcl_CLImage_2Z_3J_3JJJ_3JJLau_notzed_zcl_CLEventList_2Lau_notzed_zcl_CLEventList_2 -(JNIEnv *env, jobject jqueue, jobject jimage, jboolean blocking, jlongArray jorigin, jlongArray jregion, - jlong row_pitch, jlong slice_pitch, - jlongArray jbuffer, jlong bufoffset, - jobject jwaiters, jobject jevents) { - enqueueImagePrimitive(env, jqueue, jimage, blocking, jorigin, jregion, row_pitch, slice_pitch, - jbuffer, bufoffset, jwaiters, jevents, 3, - (enqueueReadWriteImage_t)clEnqueueWriteImage); -} - -JNIEXPORT void JNICALL Java_au_notzed_zcl_CLCommandQueue_enqueueWriteImage__Lau_notzed_zcl_CLImage_2Z_3J_3JJJ_3FJLau_notzed_zcl_CLEventList_2Lau_notzed_zcl_CLEventList_2 -(JNIEnv *env, jobject jqueue, jobject jimage, jboolean blocking, jlongArray jorigin, jlongArray jregion, - jlong row_pitch, jlong slice_pitch, - jfloatArray jbuffer, jlong bufoffset, - jobject jwaiters, jobject jevents) { - enqueueImagePrimitive(env, jqueue, jimage, blocking, jorigin, jregion, row_pitch, slice_pitch, - jbuffer, bufoffset, jwaiters, jevents, 2, - (enqueueReadWriteImage_t)clEnqueueWriteImage); -} - -JNIEXPORT void JNICALL Java_au_notzed_zcl_CLCommandQueue_enqueueWriteImage__Lau_notzed_zcl_CLImage_2Z_3J_3JJJ_3DJLau_notzed_zcl_CLEventList_2Lau_notzed_zcl_CLEventList_2 -(JNIEnv *env, jobject jqueue, jobject jimage, jboolean blocking, jlongArray jorigin, jlongArray jregion, - jlong row_pitch, jlong slice_pitch, - jdoubleArray jbuffer, jlong bufoffset, - jobject jwaiters, jobject jevents) { - enqueueImagePrimitive(env, jqueue, jimage, blocking, jorigin, jregion, row_pitch, slice_pitch, - jbuffer, bufoffset, jwaiters, jevents, 3, - (enqueueReadWriteImage_t)clEnqueueWriteImage); -} diff --git a/src/notzed.zcl/jni/zcl-jni.def b/src/notzed.zcl/jni/zcl-jni.def deleted file mode 100644 index 4b58795..0000000 --- a/src/notzed.zcl/jni/zcl-jni.def +++ /dev/null @@ -1,73 +0,0 @@ -java CLExtendable au/notzed/zcl/CLExtendable { - apiVersion, I -} -java CLMemory au/notzed/zcl/CLMemory { -} - -java Object java/lang/Object { -} -java Long java/lang/Long { - static valueOf, (J)Ljava/lang/Long; -} -java Integer java/lang/Integer { - static valueOf, (I)Ljava/lang/Integer; -} -java byte_a [B { -} - -java CLProperty au/notzed/zcl/CLProperty { - static toInt, ([Ljava/lang/Object;)[I - static toLong, ([Ljava/lang/Object;)[J -} -java CLContextProperty au/notzed/zcl/CLContextProperty { -} -java CLContextProperty_TagValue au/notzed/zcl/CLContextProperty$TagValue { - , (JJ)V -} -java CLDeviceProperty au/notzed/zcl/CLDeviceProperty { -} -java CLDeviceProperty_TagValue au/notzed/zcl/CLDeviceProperty$TagValue { - , (JJ)V -} -java CLDeviceProperty_PartitionByCounts au/notzed/zcl/CLDeviceProperty$PartitionByCounts { - , ([I)V -} -java CLImageDesc au/notzed/zcl/CLImageDesc { - imageType, I - imageWidth, I - imageHeight, I - imageDepth, I - imageArraySize, I - imageRowPitch, I - imageSlicePitch, I - numMipLevels, I - numSamples, I - memObject, Lau/notzed/zcl/CLMemory; -} -java CLImageFormat au/notzed/zcl/CLImageFormat { - , (II)V - channelOrder, I - channelDataType, I -} -java CLBufferInfoRegion au/notzed/zcl/CLBufferInfo$Region { - origin, J - size, J -} -java CLEventList au/notzed/zcl/CLEventList { - add, (J)V - index, I - events, [J -} -java CLContextNotify au/notzed/zcl/CLContextNotify { - notify, (Ljava/lang/String;Ljava/nio/ByteBuffer;)V -} -java CLEventNotify au/notzed/zcl/CLEventNotify { - notify, (Lau/notzed/zcl/CLEvent;I)V -} -java CLNotify au/notzed/zcl/CLNotify { - notify, (Ljava/lang/Object;)V -} -java CLNativeKernel au/notzed/zcl/CLNativeKernel { - invoke, ([Ljava/lang/Object;)V -} - diff --git a/src/notzed.zcl/jni/zcl-khr-gl-event.c b/src/notzed.zcl/jni/zcl-khr-gl-event.c deleted file mode 100644 index 7795209..0000000 --- a/src/notzed.zcl/jni/zcl-khr-gl-event.c +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright (C) 2015 Michael Zucchi - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -/* - Binding handler for gl event extension. - */ - -#include "au_notzed_zcl_khr_GLEvent.h" -#include "au_notzed_zcl_CLObject.h" - -#include - -#include "zcl-extension.h" - -#include "nativez.h" - -extern jfieldID CLNative_p; -#define GETP(env, o) NativeZ_getP(env, o) - -#ifndef CL_COMMAND_GL_FENCE_SYNC_OBJECT_KHR -jobject createExtension_cl_khr_gl_event(JNIEnv *env, cl_platform_id platform) { - // throw new? - fprintf(stderr, "extension cl_khr_gl_event unavailable at build time\n"); - fflush(stderr); - return NULL; -} -#else -struct ext_cl_khr_gl_event { - cl_event (*clCreateEventFromGLsyncKHR)(cl_context, cl_GLsync, cl_int *); -}; - -jobject createExtension_cl_khr_gl_event(JNIEnv *env, cl_platform_id platform) { - struct ext_cl_khr_gl_event *p; - - p = malloc(sizeof(*p)); - - p->clCreateEventFromGLsyncKHR = getExtensionAddress(platform, "clCreateEventFromGLsyncKHR"); - // FIXME: check they are there - - jobject jo = createExtension(env, p, "au/notzed/zcl/khr/GLEvent"); - - if (!jo) - free(p); - - return jo; -} - -JNIEXPORT void JNICALL Java_au_notzed_zcl_khr_GLEvent_release -(JNIEnv *env, jclass jc, jlong jp) { - free((void *)jp); -} - -JNIEXPORT jobject JNICALL Java_au_notzed_zcl_khr_GLEvent_clCreateEventFromGLsync -(JNIEnv *env, jobject jext, jobject jcontext, jlong glsync) { - struct ext_cl_khr_gl_event *ext = GETP(env, jext); - cl_context context = GETP(env, jcontext); - cl_int res = 0; - cl_event mo; - - THROW_UNSUPPORTED_RET(ext->clCreateEventFromGLsyncKHR, "clCreateEventFromGLsyncKHR", NULL); - - printf("createEventFromGLsync(%ld)\n", (long int)glsync); - fflush(stdout); - - mo = ext->clCreateEventFromGLsyncKHR(context, (cl_GLsync)(intptr_t)glsync, &res); - - printf("mo = %p, res = %d\n", mo, res); - fflush(stdout); - - THROW_ERROR_RET(res, NULL); - - return toCLObject(env, au_notzed_zcl_CLObject_CTYPE_EVENT, mo); -} - -#endif // have extension diff --git a/src/notzed.zcl/jni/zcl-khr-gl-sharing.c b/src/notzed.zcl/jni/zcl-khr-gl-sharing.c deleted file mode 100644 index cb8b548..0000000 --- a/src/notzed.zcl/jni/zcl-khr-gl-sharing.c +++ /dev/null @@ -1,278 +0,0 @@ -/* - * Copyright (C) 2015 Michael Zucchi - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -/* - Binding handler for gl sharing extension. - - This is just proof of concept/expriments and not complete. - */ - -#include "au_notzed_zcl_khr_GLSharing.h" -#include "au_notzed_zcl_CLObject.h" - -#include - -#include "zcl-extension.h" -#include "nativez.h" - -extern jfieldID CLNative_p; -#define GETP(env, o) NativeZ_getP(env, o) -extern size_t const ctype_sizes[]; - -#ifdef cl_khr_gl_sharing -struct ext_cl_khr_gl_sharing { - cl_mem (*clCreateFromGLBuffer)(cl_context, cl_mem_flags, cl_GLuint, int *); - cl_mem (*clCreateFromGLTexture)(cl_context, cl_mem_flags, cl_GLenum, cl_GLint, cl_GLuint, cl_int *); - cl_mem (*clCreateFromGLRenderbuffer)(cl_context /* context */, - cl_mem_flags /* flags */, - cl_GLuint /* renderbuffer */, - cl_int * /* errcode_ret */); - cl_int (*clEnqueueAcquireGLObjects)(cl_command_queue /* command_queue */, - cl_uint /* num_objects */, - const cl_mem * /* mem_objects */, - cl_uint /* num_events_in_wait_list */, - const cl_event * /* event_wait_list */, - cl_event * /* event */); - - cl_int (*clEnqueueReleaseGLObjects)(cl_command_queue /* command_queue */, - cl_uint /* num_objects */, - const cl_mem * /* mem_objects */, - cl_uint /* num_events_in_wait_list */, - const cl_event * /* event_wait_list */, - cl_event * /* event */); - clGetGLContextInfoKHR_fn clGetGLContextInfoKHR; - cl_int (*clGetGLObjectInfo)(cl_mem, cl_gl_object_type *, cl_GLuint *); - cl_int (*clGetGLTextureInfo)(cl_mem, cl_gl_texture_info, size_t, void *, size_t *); -}; - -static jclass GLObjectInfo_classid; -static jmethodID GLObjectInfo_new_ii; - -jobject createExtension_cl_khr_gl_sharing(JNIEnv *env, cl_platform_id platform) { - struct ext_cl_khr_gl_sharing *p; - - if (!GLObjectInfo_classid) { - jclass jc; - jc = (*env)->FindClass(env, "au/notzed/zcl/khr/GLSharing$GLObjectInfo"); - if (jc == NULL) - return NULL; - - GLObjectInfo_classid = jc = (*env)->NewGlobalRef(env, jc); - GLObjectInfo_new_ii = (*env)->GetMethodID(env, jc, "", "(II)V"); - } - - //cl_khr_gl_sharing - - p = malloc(sizeof(*p)); - - p->clCreateFromGLBuffer = getExtensionAddress(platform, "clCreateFromGLBuffer"); - p->clCreateFromGLTexture = getExtensionAddress(platform, "clCreateFromGLTexture"); - p->clCreateFromGLRenderbuffer = getExtensionAddress(platform, "clCreateFromGLRenderbuffer"); - p->clEnqueueAcquireGLObjects = getExtensionAddress(platform, "clEnqueueAcquireGLObjects"); - p->clEnqueueReleaseGLObjects = getExtensionAddress(platform, "clEnqueueReleaseGLObjects"); - p->clGetGLContextInfoKHR = getExtensionAddress(platform, "clGetGLContextInfoKHR"); - p->clGetGLObjectInfo = getExtensionAddress(platform, "clGetGLObjectInfo"); - p->clGetGLTextureInfo = getExtensionAddress(platform, "clGetGLTextureInfo"); - // FIXME: check they are there - - jobject jo = createExtension(env, p, "au/notzed/zcl/khr/GLSharing"); - - if (!jo) - free(p); - - return jo; -} -#else -jobject createExtension_cl_khr_gl_sharing(JNIEnv *env, cl_platform_id platform) { - // throw new? - return NULL; -} -#endif - - -JNIEXPORT void JNICALL Java_au_notzed_zcl_khr_GLSharing_release -(JNIEnv *env, jclass jc, jlong jp) { - free((void *)jp); -} - -JNIEXPORT jobject JNICALL Java_au_notzed_zcl_khr_GLSharing_createFromGLBuffer -(JNIEnv *env, jobject jext, jobject jcontext, jlong flags, jint bufobj) { - struct ext_cl_khr_gl_sharing *ext = GETP(env, jext); - cl_context context = GETP(env, jcontext); - cl_int res; - cl_mem mo; - - mo = ext->clCreateFromGLBuffer(context, flags, bufobj, &res); - THROW_ERROR_RET(res, NULL); - - return toCLObject(env, au_notzed_zcl_CLObject_CTYPE_BUFFER, mo); -} - -JNIEXPORT jobject JNICALL Java_au_notzed_zcl_khr_GLSharing_createFromGLTexture -(JNIEnv *env, jobject jext, jobject jcontext, jlong flags, jint target, jint miplevel, jint texture) { - struct ext_cl_khr_gl_sharing *ext = GETP(env, jext); - cl_context context = GETP(env, jcontext); - cl_int res; - cl_mem mo; - - mo = ext->clCreateFromGLTexture(context, flags, target, miplevel, texture, &res); - THROW_ERROR_RET(res, NULL); - - return toCLObject(env, au_notzed_zcl_CLObject_CTYPE_IMAGE, mo); -} - -JNIEXPORT jobject JNICALL Java_au_notzed_zcl_khr_GLSharing_createFromGLRenderbuffer -(JNIEnv *env, jobject jext, jobject jcontext, jlong flags, jint renderbuffer) { - struct ext_cl_khr_gl_sharing *ext = GETP(env, jext); - cl_context context = GETP(env, jcontext); - cl_int res; - cl_mem mo; - - mo = ext->clCreateFromGLRenderbuffer(context, flags, renderbuffer, &res); - THROW_ERROR_RET(res, NULL); - - return toCLObject(env, au_notzed_zcl_CLObject_CTYPE_IMAGE, mo); -} - -JNIEXPORT jobject JNICALL Java_au_notzed_zcl_khr_GLSharing_getGLObjectInfo -(JNIEnv *env, jobject jext, jobject jmem) { - struct ext_cl_khr_gl_sharing *ext = GETP(env, jext); - cl_mem mem = GETP(env, jmem); - cl_gl_object_type type; - cl_GLuint name; - cl_int res; - - res = ext->clGetGLObjectInfo(mem, &type, &name); - THROW_ERROR_RET(res, NULL); - - jvalue args[] = { - { .i = type }, - { .i = name } - }; - - return (*env)->NewObjectA(env, GLObjectInfo_classid, GLObjectInfo_new_ii, args); -} - -JNIEXPORT jint JNICALL Java_au_notzed_zcl_khr_GLSharing_getGLTextureInfoInt -(JNIEnv *env, jobject jext, jobject jmem, jint param) { - struct ext_cl_khr_gl_sharing *ext = GETP(env, jext); - cl_mem mem = GETP(env, jmem); - cl_int res; - cl_GLuint value; - - res = ext->clGetGLTextureInfo(mem, param, sizeof(value), &value, NULL); - THROW_ERROR_RET(res, 0); - - return value; -} - -JNIEXPORT void JNICALL Java_au_notzed_zcl_khr_GLSharing_enqueueAcquireGLObjects -(JNIEnv *env, jobject jext, jobject jqueue, jobjectArray jmemlist, jobject jwaiters, jobject jevents) { - struct ext_cl_khr_gl_sharing *ext = GETP(env, jext); - cl_command_queue queue = GETP(env, jqueue); - struct events_info einfo; - cl_int res; - cl_mem *memlist; - cl_uint mlen; - - if (events_init(env, &einfo, jwaiters, jevents)) - return; - - if (jmemlist) { - mlen = (*env)->GetArrayLength(env, jmemlist); - memlist = alloca(mlen * sizeof(*memlist)); - fromObjectArray(env, jmemlist, (void **)memlist, mlen); - } else { - memlist = NULL; - mlen = 0; - } - - res = ext->clEnqueueAcquireGLObjects(queue, - mlen, memlist, - einfo.wait_count, - einfo.waitersp, - einfo.eventp); - - THROW_ERROR(res); - - events_post(env, &einfo, jevents); -} - -JNIEXPORT void JNICALL Java_au_notzed_zcl_khr_GLSharing_enqueueReleaseGLObjects -(JNIEnv *env, jobject jext, jobject jqueue, jobjectArray jmemlist, jobject jwaiters, jobject jevents) { - struct ext_cl_khr_gl_sharing *ext = GETP(env, jext); - cl_command_queue queue = GETP(env, jqueue); - struct events_info einfo; - cl_int res; - cl_mem *memlist; - cl_uint mlen; - - if (events_init(env, &einfo, jwaiters, jevents)) - return; - - if (jmemlist) { - mlen = (*env)->GetArrayLength(env, jmemlist); - memlist = alloca(mlen * sizeof(*memlist)); - fromObjectArray(env, jmemlist, (void **)memlist, mlen); - } else { - memlist = NULL; - mlen = 0; - } - - res = ext->clEnqueueReleaseGLObjects(queue, - mlen, memlist, - einfo.wait_count, - einfo.waitersp, - einfo.eventp); - - THROW_ERROR(res); - - events_post(env, &einfo, jevents); -} - -JNIEXPORT jobject JNICALL Java_au_notzed_zcl_khr_GLSharing_getGLContextInfoKHRAny -(JNIEnv *env, jobject jext, jobjectArray jprops, jint ctype, jint param) { - struct ext_cl_khr_gl_sharing *ext = GETP(env, jext); - cl_context_properties *props = fromPropertyArray(env, jprops); - size_t size = ctype_sizes[ctype]; - void *value = alloca(size); - cl_int res; - - if ((*env)->ExceptionCheck(env)) return NULL; - - value = alloca(size); - res = ext->clGetGLContextInfoKHR(props, param, size, value, NULL); - free(props); - THROW_RTERROR_RET(res, NULL); - - return toObject(env, ctype, size, value); -} - -JNIEXPORT jobject JNICALL Java_au_notzed_zcl_khr_GLSharing_getGLContextInfoKHRAnyV -(JNIEnv *env, jobject jext, jobjectArray jprops, jint ctype, jint param) { - struct ext_cl_khr_gl_sharing *ext = GETP(env, jext); - cl_context_properties *props = fromPropertyArray(env, jprops); - size_t size = ctype_sizes[ctype] * 32; - void *value = alloca(size); - cl_int res; - - res = ext->clGetGLContextInfoKHR(props, param, size, value, &size); - free(props); - THROW_RTERROR_RET(res, NULL); - - return toArray(env, ctype, size, value); -} -- 2.39.5