From: Not Zed Date: Wed, 8 Dec 2021 08:17:00 +0000 (+1030) Subject: WIP converting to openjdk 17 incubator version of foreign api. X-Git-Url: https://code.zedzone.au/cvs?a=commitdiff_plain;h=34cd0eaeeb11502c53ce6f563154f5ab689fad3e;p=zcl WIP converting to openjdk 17 incubator version of foreign api. --- diff --git a/Makefile b/Makefile index eeca8da..4047315 100644 --- a/Makefile +++ b/Makefile @@ -71,7 +71,7 @@ $(foreach host,$(maven_HOSTS),\ # TODO: module deps? # TODO: JAVAFLAGS / DEMOFLAGS / TESTFLAGS? -TESTFLAGS=--add-exports jdk.incubator.foreign/jdk.incubator.foreign.unsafe=notzed.zcl +TESTFLAGS=--enable-native-access=notzed.zcl -Djava.library.path=/usr/lib64 #central_JARS+=junit:junit:4.12 \ # org.hamcrest:hamcrest-core:1.3 diff --git a/config.make.in b/config.make.in index 64bf34f..628f6d8 100644 --- a/config.make.in +++ b/config.make.in @@ -1,10 +1,9 @@ TARGET ?= linux-amd64 -JAVA_HOME ?= /usr/local/jdk-13+33 -JAVAFX_HOME ?= /home/notzed/src/jfx/build/sdk +JAVA_HOME ?= /usr/local/jdk +JAVAFX_HOME ?= /usr/local/javafx-sdk -JAVACFLAGS += -source 13 JAVACFLAGS += --add-exports jdk.incubator.foreign/jdk.incubator.foreign.unsafe=notzed.zcl JAVA ?= $(JAVA_HOME)/bin/java diff --git a/src/notzed.zcl.demo/classes/au/notzed/zcl/test/TestCopies.java b/src/notzed.zcl.demo/classes/au/notzed/zcl/test/TestCopies.java index a4b02e4..570c802 100644 --- a/src/notzed.zcl.demo/classes/au/notzed/zcl/test/TestCopies.java +++ b/src/notzed.zcl.demo/classes/au/notzed/zcl/test/TestCopies.java @@ -15,7 +15,8 @@ import static java.lang.Math.*; public class TestCopies { final static VarHandle longHandle = MemoryHandles.varHandle(long.class, ByteOrder.nativeOrder()); - final static VarHandle longVHandle = MemoryHandles.withStride(longHandle, 8); + final static SequenceLayout longVLayout = MemoryLayout.sequenceLayout(CLinker.C_LONG); + final static VarHandle longVHandle = longVLayout.varHandle(long.class, MemoryLayout.PathElement.sequenceElement()); public static long getLong(MemoryAddress p) { return (long)longHandle.get(p); @@ -33,15 +34,15 @@ public class TestCopies { longVHandle.set(p, i, v); } - - static void copyLoop(long[] src, MemoryAddress dst) { - for (int i=0;i results = new HashMap<>(); + 256,}; + HashMap results = new HashMap<>(); - int X = 1024*1024; + int X = 1024 * 1024; for (int c = 0; c < 5; c++) { for (int len: lengths) { long[] data = new long[len]; @@ -67,25 +67,25 @@ public class TestCopies { now = System.nanoTime(); for (int l = 0; l < X; l++) { - try (MemorySegment seg = MemorySegment.allocateNative(data.length * 8)) { - MemoryAddress add = seg.baseAddress(); - copyLoop(data, add); + try ( ResourceScope scope = ResourceScope.newConfinedScope()) { + MemorySegment seg = MemorySegment.allocateNative(data.length * 8, scope); + copyLoop(data, seg); } } long t = System.nanoTime() - now; System.out.printf(" %12.9f %3d copyLoop\n", t * 1E-9, len); - results.compute(String.format("%3d copyLoop", len), (k, v)-> v == null ? t : min(v, t)); + results.compute(String.format("%3d copyLoop", len), (k, v) -> v == null ? t : min(v, t)); now = System.nanoTime(); for (int l = 0; l < X; l++) { - try (MemorySegment seg = MemorySegment.allocateNative(data.length * 8)) { - MemoryAddress add = seg.baseAddress(); - copyBulk(data, add); + try ( ResourceScope scope = ResourceScope.newConfinedScope()) { + MemorySegment seg = MemorySegment.allocateNative(data.length * 8, scope); + copyBulk(data, seg); } } long s = System.nanoTime() - now; System.out.printf(" %12.9f %3d copyBulk\n", s * 1E-9, len); - results.compute(String.format("%3d copyBulk", len), (k, v)-> v == null ? s : min(v, s)); + results.compute(String.format("%3d copyBulk", len), (k, v) -> v == null ? s : min(v, s)); } for (int len: lengths) { @@ -93,26 +93,26 @@ public class TestCopies { long now; now = System.nanoTime(); - try (MemorySegment seg = MemorySegment.allocateNative(data.length * 8)) { - MemoryAddress add = seg.baseAddress(); + try ( ResourceScope scope = ResourceScope.newConfinedScope()) { + MemorySegment seg = MemorySegment.allocateNative(data.length * 8, scope); for (int l = 0; l < X; l++) { - copyLoop(data, add); + copyLoop(data, seg); } } long t = System.nanoTime() - now; System.out.printf(" %12.9f %3d copyLoop pre-alloc\n", t * 1E-9, len); - results.compute(String.format("%3d copyLoop pre-alloc", len), (k, v)-> v == null ? t : min(v, t)); + results.compute(String.format("%3d copyLoop pre-alloc", len), (k, v) -> v == null ? t : min(v, t)); now = System.nanoTime(); - try (MemorySegment seg = MemorySegment.allocateNative(data.length * 8)) { - MemoryAddress add = seg.baseAddress(); + try ( ResourceScope scope = ResourceScope.newConfinedScope()) { + MemorySegment seg = MemorySegment.allocateNative(data.length * 8, scope); for (int l = 0; l < X; l++) { - copyBulk(data, add); + copyBulk(data, seg); } } long s = System.nanoTime() - now; System.out.printf(" %12.9f %3d copyBulk pre-alloc\n", s * 1E-9, len); - results.compute(String.format("%3d copyBulk pre-alloc", len), (k, v)-> v == null ? s : min(v, s)); + results.compute(String.format("%3d copyBulk pre-alloc", len), (k, v) -> v == null ? s : min(v, s)); } // if have stack allocator: @@ -122,32 +122,32 @@ public class TestCopies { now = System.nanoTime(); for (int l = 0; l < X; l++) { - try (Allocator a = api.Memory.stack()) { - MemoryAddress add = a.alloca(data.length * 8); - copyLoop(data, add); + try ( Allocator a = api.Memory.stack()) { + MemorySegment seg = a.allocs(data.length * 8); + copyLoop(data, seg); } } long t = System.nanoTime() - now; System.out.printf(" %12.9f %3d copyLoop stack\n", t * 1E-9, len); - results.compute(String.format("%3d copyLoop stack", len), (k, v)-> v == null ? t : min(v, t)); + results.compute(String.format("%3d copyLoop stack", len), (k, v) -> v == null ? t : min(v, t)); now = System.nanoTime(); for (int l = 0; l < X; l++) { - try (Allocator a = api.Memory.stack()) { - MemoryAddress add = a.alloca(data.length * 8); - copyBulk(data, add); + try ( Allocator a = api.Memory.stack()) { + MemorySegment seg = a.allocs(data.length * 8); + copyBulk(data, seg); } } long s = System.nanoTime() - now; System.out.printf(" %12.9f %3d copyBulk stack\n", s * 1E-9, len); - results.compute(String.format("%3d copyBulk stack", len), (k, v)-> v == null ? s : min(v, s)); + results.compute(String.format("%3d copyBulk stack", len), (k, v) -> v == null ? s : min(v, s)); } System.out.println(); } results.entrySet().stream().map((e) -> { - return String.format("%s %12.9f %s", e.getKey().substring(0, 3), 1E-9 * e.getValue(), e.getKey().substring(4)); - }).sorted().forEach(System.out::println); + return String.format("%s %12.9f %s", e.getKey().substring(0, 3), 1E-9 * e.getValue(), e.getKey().substring(4)); + }).sorted().forEach(System.out::println); } } diff --git a/src/notzed.zcl.demo/classes/au/notzed/zcl/test/TestMemory.java b/src/notzed.zcl.demo/classes/au/notzed/zcl/test/TestMemory.java index 9a5145a..9d5c5a6 100644 --- a/src/notzed.zcl.demo/classes/au/notzed/zcl/test/TestMemory.java +++ b/src/notzed.zcl.demo/classes/au/notzed/zcl/test/TestMemory.java @@ -9,6 +9,7 @@ import java.nio.ByteOrder; import java.nio.FloatBuffer; import jdk.incubator.foreign.MemoryAddress; import jdk.incubator.foreign.MemorySegment; +import jdk.incubator.foreign.ResourceScope; /** * Some memory tests. @@ -19,7 +20,7 @@ public class TestMemory { int len = (int)(seg.byteSize() >>> 2); float sum = 0; - MemoryAddress add = seg.baseAddress(); + MemoryAddress add = seg.address(); for (int i = 0; i < len; i++) sum += Native.getFloat(add, i); Native.setFloat(add, sum); @@ -65,7 +66,7 @@ public class TestMemory { for (int i = 0; i < sizes.length; i++) { arrays[i] = new float[sizes[i]]; - segments[i] = MemorySegment.allocateNative(sizes[i] * 4, 16); + segments[i] = MemorySegment.allocateNative(sizes[i] * 4, 16, ResourceScope.globalScope()); buffers[i] = ByteBuffer.allocateDirect(sizes[i] * 4).order(ByteOrder.nativeOrder()); } diff --git a/src/notzed.zcl.demo/classes/au/notzed/zcl/test/TestMemoryLong.java b/src/notzed.zcl.demo/classes/au/notzed/zcl/test/TestMemoryLong.java index 55e1c50..5193abb 100644 --- a/src/notzed.zcl.demo/classes/au/notzed/zcl/test/TestMemoryLong.java +++ b/src/notzed.zcl.demo/classes/au/notzed/zcl/test/TestMemoryLong.java @@ -9,6 +9,7 @@ import java.nio.ByteOrder; import java.nio.LongBuffer; import jdk.incubator.foreign.MemoryAddress; import jdk.incubator.foreign.MemorySegment; +import jdk.incubator.foreign.ResourceScope; /** * Some memory tests. @@ -19,7 +20,7 @@ public class TestMemoryLong { int len = (int)(seg.byteSize() >>> 3); long sum = 0; - MemoryAddress add = seg.baseAddress(); + MemoryAddress add = seg.address(); for (int i = 0; i < len; i++) sum += Native.getLong(add, i); Native.setLong(add, sum); @@ -65,7 +66,7 @@ public class TestMemoryLong { for (int i = 0; i < sizes.length; i++) { arrays[i] = new long[sizes[i]]; - segments[i] = MemorySegment.allocateNative(sizes[i] * 8, 16); + segments[i] = MemorySegment.allocateNative(sizes[i] * 8, 16, ResourceScope.globalScope()); buffers[i] = ByteBuffer.allocateDirect(sizes[i] * 8).order(ByteOrder.nativeOrder()); } diff --git a/src/notzed.zcl.demo/classes/module-info.java b/src/notzed.zcl.demo/classes/module-info.java index d9922ca..e9b21e9 100644 --- a/src/notzed.zcl.demo/classes/module-info.java +++ b/src/notzed.zcl.demo/classes/module-info.java @@ -22,6 +22,7 @@ */ module notzed.zcl.demo { requires notzed.zcl; + requires jdk.incubator.foreign; exports au.notzed.zcl.tools; } diff --git a/src/notzed.zcl/classes/api/Memory.java b/src/notzed.zcl/classes/api/Memory.java index 63cd351..68080e6 100644 --- a/src/notzed.zcl/classes/api/Memory.java +++ b/src/notzed.zcl/classes/api/Memory.java @@ -14,7 +14,6 @@ * 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.*; @@ -24,13 +23,13 @@ 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. - * + * 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. */ @@ -40,12 +39,10 @@ public class Memory { 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. + * Alloc memory in the current frame. The size is not enforced. */ /* public static MemoryAddress alloca(long size) { @@ -53,11 +50,10 @@ public class Memory { throw new UnsupportedOperationException("Must have a frame"); return stack().alloca(size); }*/ - /** - * Allocate a segment in the current frame. The segment must not be closed. + * 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"); @@ -81,8 +77,9 @@ public class Memory { @Override public void close(); } -*/ + */ static class Stack extends Native { + final MemorySegment stack; final MemoryAddress base; long sp; @@ -92,8 +89,8 @@ public class Memory { super(p); // TODO: use cleanup stuff, perhaps owner thread - stack = MemorySegment.ofNativeRestricted(addr(), size, null, null, null); - base = stack.baseAddress(); + stack = MemorySegment.globalNativeSegment().asSlice(addr(), size); + base = stack.address(); sp = size; origin = Thread.currentThread(); @@ -109,17 +106,17 @@ public class Memory { } public MemoryAddress alloca(long size) { - sp -= (size + 7 ) & ~7; + sp -= (size + 7) & ~7; return base.addOffset(sp); } public MemorySegment allocs(long size) { - sp -= (size + 7 ) & ~7; + sp -= (size + 7) & ~7; return stack.asSlice(sp, size); } public MemorySegment slicea(long size) { - sp -= (size + 7 ) & ~7; + sp -= (size + 7) & ~7; return stack.asSlice(sp, size); } } @@ -129,7 +126,6 @@ public class Memory { 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. @@ -142,47 +138,47 @@ public class Memory { 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); - } - }; + 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.getSystemABI(); - MethodHandles.Lookup lookup = MethodHandles.lookup(); - LibraryLookup libc = LibraryLookup.ofDefault(); + CLinker abi = CLinker.getInstance(); + SymbolLookup libc = CLinker.systemLookup(); try { - malloc = abi.downcallHandle(libc.lookup("malloc"), - MethodType.methodType(MemoryAddress.class, - long.class), - FunctionDescriptor.of(MemoryLayouts.SysV.C_POINTER, - MemoryLayouts.SysV.C_ULONG)); - free = abi.downcallHandle(libc.lookup("free"), - MethodType.methodType(void.class, - MemoryAddress.class), - FunctionDescriptor.ofVoid(MemoryLayouts.SysV.C_POINTER)); - } catch (NoSuchMethodException x) { + malloc = abi.downcallHandle(libc.lookup("malloc").get(), + MethodType.methodType(MemoryAddress.class, + long.class), + FunctionDescriptor.of(CLinker.C_POINTER, + CLinker.C_LONG)); + free = abi.downcallHandle(libc.lookup("free").get(), + MethodType.methodType(void.class, + MemoryAddress.class), + FunctionDescriptor.ofVoid(CLinker.C_POINTER)); + } catch (Exception x) { throw new RuntimeException(x); } } @@ -192,11 +188,11 @@ public class Memory { * 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 MemorySegment.ofNativeRestricted(addr, size, null, null, null); + return MemorySegment.globalNativeSegment().asSlice(addr, size); } /** - * Get the physical address. I mean how is this an "offset"? + * Get the physical address. I mean how is this an "offset"? */ public static long toLong(MemoryAddress addr) { return addr.toRawLongValue(); diff --git a/src/notzed.zcl/classes/api/Native.java b/src/notzed.zcl/classes/api/Native.java index f2f3d39..6d81f00 100644 --- a/src/notzed.zcl/classes/api/Native.java +++ b/src/notzed.zcl/classes/api/Native.java @@ -14,7 +14,6 @@ * 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; @@ -35,16 +34,17 @@ import java.lang.System.Logger.Level; /** * Base class for all native objects. - * + *

* Handles instantiation and provides helper functions for native access. - * + *

* Work in progress. - * + *

* For better safety the 'p' field should be the CHandle, and addr() would - * call get(). Otherwise one must not release ANY object which might ever - * be used again - including any objects returned by the getInfo(). However ... + * call get(). Otherwise one must not release ANY object which might ever + * be used again - including any objects returned by the getInfo(). However ... * it's a trade-off and it's a lot of code to change. - * + *

+ * FIXME: there are MemorySegment based accessors for primitive types now, use those */ public class Native { @@ -52,21 +52,30 @@ public class Native { 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.asAddressVarHandle(MemoryHandles.varHandle(long.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); + public final static VarHandle byteHandle = MemoryHandles.varHandle(byte.class, ByteOrder.nativeOrder()); + public final static VarHandle shortHandle = MemoryHandles.varHandle(short.class, ByteOrder.nativeOrder()); + //final static VarHandle intHandle = MemoryHandles.varHandle(int.class, ByteOrder.nativeOrder()); + public final static VarHandle intHandle = CLinker.C_INT.varHandle(int.class); + public final static VarHandle longHandle = MemoryHandles.varHandle(long.class, ByteOrder.nativeOrder()); + public final static VarHandle floatHandle = MemoryHandles.varHandle(float.class, ByteOrder.nativeOrder()); + public final static VarHandle doubleHandle = MemoryHandles.varHandle(double.class, ByteOrder.nativeOrder()); + public final static VarHandle addrHandle = MemoryHandles.asAddressVarHandle(MemoryHandles.varHandle(long.class, ByteOrder.nativeOrder())); + + final static SequenceLayout byteVLayout = MemoryLayout.sequenceLayout(CLinker.C_CHAR); + final static SequenceLayout shortVLayout = MemoryLayout.sequenceLayout(CLinker.C_SHORT); + final static SequenceLayout intVLayout = MemoryLayout.sequenceLayout(CLinker.C_INT); + final static SequenceLayout longVLayout = MemoryLayout.sequenceLayout(CLinker.C_LONG); + final static SequenceLayout floatVLayout = MemoryLayout.sequenceLayout(CLinker.C_FLOAT); + final static SequenceLayout doubleVLayout = MemoryLayout.sequenceLayout(CLinker.C_DOUBLE); + final static SequenceLayout addrVLayout = MemoryLayout.sequenceLayout(CLinker.C_POINTER); + + public final static VarHandle byteVHandle = byteVLayout.varHandle(byte.class, MemoryLayout.PathElement.sequenceElement()); + public final static VarHandle shortVHandle = shortVLayout.varHandle(short.class, MemoryLayout.PathElement.sequenceElement()); + public final static VarHandle intVHandle = intVLayout.varHandle(int.class, MemoryLayout.PathElement.sequenceElement()); + public final static VarHandle longVHandle = longVLayout.varHandle(long.class, MemoryLayout.PathElement.sequenceElement()); + public final static VarHandle floatVHandle = floatVLayout.varHandle(float.class, MemoryLayout.PathElement.sequenceElement()); + public final static VarHandle doubleVHandle = doubleVLayout.varHandle(double.class, MemoryLayout.PathElement.sequenceElement()); + public final static VarHandle addrVHandle = addrVLayout.varHandle(long.class, MemoryLayout.PathElement.sequenceElement()); protected Native(MemoryAddress p) { this.p = p; @@ -85,7 +94,7 @@ public class Native { } public static MemoryAddress addr(MemorySegment o) { - return o != null ? o.baseAddress() : MemoryAddress.NULL; + return o != null ? o.address() : MemoryAddress.NULL; } public static byte getByte(MemoryAddress p) { @@ -197,46 +206,84 @@ public class Native { } /* helpers - java to native */ - public static MemoryAddress toAddrV(Allocator frame, T[]array, int len) { + public static MemoryAddress toAddrV(Allocator frame, T[] array, int len) { MemoryAddress list = frame.alloca(8 * len); - for (int i=0;i MemoryAddress toAddrV(Allocator frame, T[]array) { + public static MemoryAddress toAddrV(Allocator frame, T[] array) { return toAddrV(frame, array, array.length); } - public static MemoryAddress toAddrV(Allocator frame, String[]array) { - if (array != null) { - MemoryAddress list = frame.alloca(8 * array.length); + public static 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) { + public static MemoryAddress toLongV(Allocator frame, long[] array) { MemoryAddress list = frame.alloca(8 * array.length); - for (int i=0;i MemorySegment toAddrV(ResourceScope frame, T[] array, int len) { + MemorySegment list = MemorySegment.allocateNative(CLinker.C_POINTER.byteSize() * len, CLinker.C_POINTER.byteAlignment(), frame); + + for (int i = 0; i < len; i++) + MemoryAccess.setAddressAtIndex(list, i, array[i].addr()); + + return list; + } + + public static MemorySegment toAddrV(ResourceScope frame, T[] array) { + return toAddrV(frame, array, array.length); + } + + public static MemorySegment toLongV(ResourceScope frame, long[] array) { + MemorySegment list = MemorySegment.allocateNative(CLinker.C_LONG.byteSize() * array.length, CLinker.C_LONG.byteAlignment(), frame); + + for (int i = 0; i < array.length; i++) + MemoryAccess.setLongAtIndex(list, i, array[i]); + + return list; + } + + public static MemorySegment toCStringV(String[]array, ResourceScope frame) { + MemorySegment list = MemorySegment.allocateNative(CLinker.C_POINTER.byteSize() * array.length, CLinker.C_POINTER.byteAlignment(), frame); + 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 T[] toObjectV(MemoryAddress list, T[] array, Function create) { - for (int i=0;i T[] toObjectV(MemorySegment list, T[] array, Function create) { + for (int i = 0; i < array.length; i++) + array[i] = Native.resolve(MemoryAccess.getAddressAtIndex(list, i), create); return array; } - public static T[] toObjectV(MemorySegment list, Function create, IntFunction createArray) { - return toObjectV(list.baseAddress(), createArray.apply((int)(list.byteSize() >>> 3)), create); + public static T[] toObjectV(MemorySegment list, Function create, IntFunction createArray) { + return toObjectV(list, createArray.apply((int)(list.byteSize() >>> 3)), create); } public static String toString(MemoryAddress cstr) { - MemorySegment seg = MemorySegment.ofNativeRestricted(cstr, Integer.MAX_VALUE, null, null, null); - 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, Arrays.copyOf(sig.layouts, n-1))); - } catch (NoSuchMethodException x) { - } + Class resClass = sig.classes[n - 1]; + MemoryLayout resLayout = sig.layouts[n - 1]; + + if (resLayout != null) { + return lib.lookup(name).map(addr -> abi.downcallHandle(addr, + MethodType.methodType(resClass, Arrays.copyOf(sig.classes, n - 1)), + FunctionDescriptor.of(resLayout, Arrays.copyOf(sig.layouts, n - 1)))) + .get(); + } else { + return lib.lookup(name).map(addr -> abi.downcallHandle(addr, + MethodType.methodType(resClass, Arrays.copyOf(sig.classes, n - 1)), + FunctionDescriptor.ofVoid(Arrays.copyOf(sig.layouts, n - 1)))) + .get(); } - // or use some 'unsupportedoperation' one? - System.err.println("not found: "+ name); - - return null; } - public static MethodHandle downcallHandle(Function find, String name, String signature) { + public static MethodHandle downcallHandle(Function find, String name, String signature) { return downcallHandle(find.apply(name), signature); } public static MethodHandle downcallHandle(MemoryAddress addr, String signature) { Signature sig = Signature.parse(signature); int n = sig.classes.length; - SystemABI abi = SystemABI.getSystemABI(); + CLinker abi = CLinker.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]; + 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, Arrays.copyOf(sig.layouts, n-1))); + MethodType.methodType(resClass, Arrays.copyOf(sig.classes, n - 1)), + FunctionDescriptor.of(resLayout, 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.getSystemABI(); + CLinker abi = CLinker.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]; - + 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()); + // FIXME: ResourceScope usage is broken here //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, Arrays.copyOf(sig.layouts, n-1))); + if (resLayout != null) { + return abi.upcallStub(lookup.findVirtual( + m.getDeclaringClass(), + m.getName(), + mt) + .bindTo(instance), + FunctionDescriptor.of(resLayout, Arrays.copyOf(sig.layouts, n - 1)), + ResourceScope.newSharedScope()); + } else { + return abi.upcallStub(lookup.findVirtual( + m.getDeclaringClass(), + m.getName(), + mt) + .bindTo(instance), + FunctionDescriptor.ofVoid(Arrays.copyOf(sig.layouts, n - 1)), + ResourceScope.newSharedScope()); + } } catch (NoSuchMethodException | IllegalAccessException x) { throw new RuntimeException(x); } } public static void freeUpcallStub(MemoryAddress addr) { - SystemABI.getSystemABI().freeUpcallStub(addr); + // NOOP? } - public static LibraryLookup[] loadLibraries(String... libraries) { - LibraryLookup[] libs = new LibraryLookup[libraries.length]; - MethodHandles.Lookup lookup = MethodHandles.lookup(); - for (int i=0;i 0) { argClass.add(MemoryAddress.class); - argLayout.add(MemoryLayouts.SysV.C_POINTER); + argLayout.add(CLinker.C_POINTER); } else { switch (c) { case 'u': switch (size) { case 8: argClass.add(byte.class); - argLayout.add(MemoryLayouts.SysV.C_UCHAR); + argLayout.add(CLinker.C_CHAR); break; case 16: // char.class? argClass.add(short.class); - argLayout.add(MemoryLayouts.SysV.C_USHORT); + argLayout.add(CLinker.C_SHORT); break; case 32: argClass.add(int.class); - argLayout.add(MemoryLayouts.SysV.C_UINT); + argLayout.add(CLinker.C_INT); break; case 64: argClass.add(long.class); - argLayout.add(MemoryLayouts.SysV.C_ULONG); + argLayout.add(CLinker.C_LONG); break; } break; @@ -502,19 +542,19 @@ public class Native { switch (size) { case 8: argClass.add(byte.class); - argLayout.add(MemoryLayouts.SysV.C_SCHAR); + argLayout.add(CLinker.C_CHAR); break; case 16: argClass.add(short.class); - argLayout.add(MemoryLayouts.SysV.C_SHORT); + argLayout.add(CLinker.C_SHORT); break; case 32: argClass.add(int.class); - argLayout.add(MemoryLayouts.SysV.C_INT); + argLayout.add(CLinker.C_INT); break; case 64: argClass.add(long.class); - argLayout.add(MemoryLayouts.SysV.C_LONG); + argLayout.add(CLinker.C_LONG); break; } break; @@ -522,11 +562,11 @@ public class Native { switch (size) { case 32: argClass.add(float.class); - argLayout.add(MemoryLayouts.SysV.C_FLOAT); + argLayout.add(CLinker.C_FLOAT); break; case 64: argClass.add(double.class); - argLayout.add(MemoryLayouts.SysV.C_DOUBLE); + argLayout.add(CLinker.C_DOUBLE); break; } break; @@ -558,7 +598,7 @@ public class Native { //System.out.printf("void *=%d\n", pointerDepth); if (pointerDepth > 0) { argClass.add(MemoryAddress.class); - argLayout.add(MemoryLayouts.SysV.C_POINTER); + argLayout.add(CLinker.C_POINTER); } else { // can only be return value argClass.add(void.class); @@ -586,7 +626,7 @@ public class Native { //System.out.printf(" type: *=%d %s\n", pointerDepth, sb); if (pointerDepth > 0) { argClass.add(MemoryAddress.class); - argLayout.add(MemoryLayouts.SysV.C_POINTER); + argLayout.add(CLinker.C_POINTER); } else { argClass.add(MemorySegment.class); try { @@ -623,14 +663,13 @@ public class Native { } return new Signature(argClass.stream().toArray(Class[]::new), - argLayout.stream().toArray(MemoryLayout[]::new)); + argLayout.stream().toArray(MemoryLayout[]::new)); } } /* ********************************************************************** */ - /* GC handling */ - /* ********************************************************************** */ - + /* GC handling */ + /* ********************************************************************** */ /** * Resource index. */ @@ -675,20 +714,18 @@ public class Native { } return o; }*/ - - public static T resolve(MemoryAddress p, Function create) { + 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)); - if (Memory.toLong(p) == 0) return null; // Instantiation needs to be synchronized for obvious reasons. synchronized (map) { - CHandle h = (CHandle) map.get(p); + CHandle h = (CHandle)map.get(p); String fmt; @@ -735,7 +772,6 @@ public class Native { return o; }*/ - public void release() { WeakReference ref; @@ -757,7 +793,7 @@ public class Native { } public static void release(Native... list) { - for (Native o : list) + for (Native o: list) release(o); } @@ -770,7 +806,7 @@ public class Native { private static void cleanerStep() { try { - CHandle stale = (CHandle) references.poll(); + CHandle stale = (CHandle)references.poll(); if (stale != null) { synchronized (map) { map.remove(stale.p); @@ -792,7 +828,7 @@ public class Native { log().log(Level.DEBUG, "Native finaliser started"); try { while (true) { - CHandle stale = (CHandle) references.remove(); + CHandle stale = (CHandle)references.remove(); do { try { synchronized (map) { @@ -801,7 +837,7 @@ public class Native { stale.release(); } catch (Throwable ex) { } - stale = (CHandle) references.poll(); + stale = (CHandle)references.poll(); } while (stale != null); } } catch (InterruptedException ex) { @@ -809,6 +845,7 @@ public class Native { } private static class CHandle extends WeakReference { + protected MemoryAddress p; final Class jtype; CHandle next; @@ -838,7 +875,7 @@ public class Native { @Override public boolean equals(Object obj) { - return (obj instanceof CHandle) && ((CHandle) obj).p == p; + return (obj instanceof CHandle) && ((CHandle)obj).p == p; } @Override @@ -858,7 +895,7 @@ public class Native { * @return */ public static final int hashCode(long p) { - return (int) p >>> 4; + return (int)p >>> 4; } /** @@ -870,13 +907,13 @@ public class Native { } public static void debugFlushAll() { - for (int i=0;i<3;i++) { + for (int i = 0; i < 3; i++) { try { System.gc(); Thread.sleep(100); } catch (InterruptedException x) { } - CHandle stale = (CHandle) references.poll(); + CHandle stale = (CHandle)references.poll(); while (stale != null) { try { synchronized (map) { @@ -885,7 +922,7 @@ public class Native { stale.release(); } catch (Throwable ex) { } - stale = (CHandle) references.poll(); + stale = (CHandle)references.poll(); } } } diff --git a/src/notzed.zcl/classes/au/notzed/zcl/CLCommandQueue.java b/src/notzed.zcl/classes/au/notzed/zcl/CLCommandQueue.java index 531282c..26464dd 100644 --- a/src/notzed.zcl/classes/au/notzed/zcl/CLCommandQueue.java +++ b/src/notzed.zcl/classes/au/notzed/zcl/CLCommandQueue.java @@ -20,7 +20,6 @@ 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 api.Callback; @@ -132,7 +131,7 @@ public class CLCommandQueue extends CLObject { * @param blocking * @param mem_offset source memory offset in bytes. * @param size memory transfer size in bytes. - * @param buffer destination buffer. It must be a native segment. + * @param buffer destination buffer. It must be a native segment. * @param wait * @param event * @throws CLException @@ -145,13 +144,13 @@ public class CLCommandQueue extends CLObject { if (size > buffer.byteSize()) throw new BufferOverflowException(); - try (Allocator frame = Memory.stack()) { + try (ResourceScope frame = ResourceScope.newConfinedScope()) { EventInfo info = new EventInfo(frame, wait, event); int res; res = clEnqueueReadBuffer(addr(), mem.addr(), blocking ? 1 : 0, mem_offset, size, - buffer.baseAddress(), + buffer.address(), info.nwait, info.wait, info.event); if (res != 0) throw new CLException(res); @@ -169,17 +168,16 @@ public class CLCommandQueue extends CLObject { ByteBuffer buffer, CLEventList wait, CLEventList event) throws CLException { - try (MemorySegment seg = MemorySegment.ofByteBuffer(buffer)) { - enqueueReadBuffer(mem, blocking, - mem_offset, size, - seg, - wait, event); - } + 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 @@ -197,7 +195,8 @@ public class CLCommandQueue extends CLObject { byte[] buffer, int buf_offset, CLEventList wait, CLEventList event) throws CLException { - try (MemorySegment seg = MemorySegment.allocateNative(size)) { + try (ResourceScope scope = ResourceScope.newConfinedScope()) { + MemorySegment seg = MemorySegment.allocateNative(size, scope); enqueueReadBuffer(mem, true, mem_offset, size, seg, wait, event); seg.asByteBuffer().order(ByteOrder.nativeOrder()).get(buffer, buf_offset, size); } @@ -205,7 +204,7 @@ public class CLCommandQueue extends CLObject { /** * Calls clEnqueueReadBuffer for a short array. - * + *

* Note that mem_offset and size are in terms of the buffer element size. * * @param mem @@ -223,7 +222,8 @@ public class CLCommandQueue extends CLObject { short[] buffer, int buf_offset, CLEventList wait, CLEventList event) throws CLException { - try (MemorySegment seg = MemorySegment.allocateNative(size * 2)) { + try (ResourceScope scope = ResourceScope.newConfinedScope()) { + MemorySegment seg = MemorySegment.allocateNative(size * 2, scope); enqueueReadBuffer(mem, true, mem_offset * 2, size * 2, seg, wait, event); seg.asByteBuffer().order(ByteOrder.nativeOrder()).asShortBuffer().get(buffer, buf_offset, size); } @@ -234,7 +234,8 @@ public class CLCommandQueue extends CLObject { int[] buffer, int buf_offset, CLEventList wait, CLEventList event) throws CLException { - try (MemorySegment seg = MemorySegment.allocateNative(size * 4)) { + try (ResourceScope scope = ResourceScope.newConfinedScope()) { + MemorySegment seg = MemorySegment.allocateNative(size * 4, scope); enqueueReadBuffer(mem, true, mem_offset * 4, size * 4, seg, wait, event); seg.asByteBuffer().order(ByteOrder.nativeOrder()).asIntBuffer().get(buffer, buf_offset, size); } @@ -245,7 +246,8 @@ public class CLCommandQueue extends CLObject { long[] buffer, int buf_offset, CLEventList wait, CLEventList event) throws CLException { - try (MemorySegment seg = MemorySegment.allocateNative(size * 8)) { + try (ResourceScope scope = ResourceScope.newConfinedScope()) { + MemorySegment seg = MemorySegment.allocateNative(size * 8, scope); enqueueReadBuffer(mem, true, mem_offset * 8, size * 8, seg, wait, event); seg.asByteBuffer().order(ByteOrder.nativeOrder()).asLongBuffer().get(buffer, buf_offset, size); } @@ -256,7 +258,8 @@ public class CLCommandQueue extends CLObject { float[] buffer, int buf_offset, CLEventList wait, CLEventList event) throws CLException { - try (MemorySegment seg = MemorySegment.allocateNative(size * 4)) { + try (ResourceScope scope = ResourceScope.newConfinedScope()) { + MemorySegment seg = MemorySegment.allocateNative(size * 4, scope); enqueueReadBuffer(mem, true, mem_offset * 4, size * 4, seg, wait, event); seg.asByteBuffer().order(ByteOrder.nativeOrder()).asFloatBuffer().get(buffer, buf_offset, size); } @@ -267,7 +270,8 @@ public class CLCommandQueue extends CLObject { double[] buffer, int buf_offset, CLEventList wait, CLEventList event) throws CLException { - try (MemorySegment seg = MemorySegment.allocateNative(size * 8)) { + try (ResourceScope scope = ResourceScope.newConfinedScope()) { + MemorySegment seg = MemorySegment.allocateNative(size * 8, scope); enqueueReadBuffer(mem, true, mem_offset * 8, size * 8, seg, wait, event); seg.asByteBuffer().order(ByteOrder.nativeOrder()).asDoubleBuffer().get(buffer, buf_offset, size); } @@ -278,16 +282,16 @@ public class CLCommandQueue extends CLObject { 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) + || 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) + + region[0] + (region[1] - 1) * stride + (region[2] - 1) * slice + > limit) throw new BufferOverflowException(); } @@ -319,21 +323,21 @@ public class CLCommandQueue extends CLObject { buffer_row_pitch, buffer_slice_pitch, host_row_pitch, host_slice_pitch, buffer.byteSize()); - try (Allocator frame = Memory.stack()) { + try (ResourceScope frame = ResourceScope.newConfinedScope()) { 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); + MemorySegment cbuffer_origin = toLongV(frame, buffer_origin); + MemorySegment chost_origin = toLongV(frame, host_origin); + MemorySegment cregion = toLongV(frame, region); int res; res = clEnqueueReadBufferRect( addr(), mem.addr(), blocking ? 1 : 0, - cbuffer_origin, chost_origin, cregion, + cbuffer_origin.address(), chost_origin.address(), cregion.address(), buffer_row_pitch, buffer_slice_pitch, host_row_pitch, host_slice_pitch, - buffer.baseAddress(), + buffer.address(), info.nwait, info.wait, info.event); if (res != 0) @@ -353,13 +357,12 @@ public class CLCommandQueue extends CLObject { ByteBuffer buffer, 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); - } + 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 void enqueueReadBufferRect(CLBuffer mem, boolean blocking, @@ -373,7 +376,8 @@ public class CLCommandQueue extends CLObject { long slice = region[1] * stride; long size = slice * region[2]; - try (MemorySegment seg = MemorySegment.allocateNative(size)) { + try (ResourceScope scope = ResourceScope.newConfinedScope()) { + MemorySegment seg = MemorySegment.allocateNative(size, scope); enqueueReadBufferRect(mem, blocking, buffer_origin, OFFSET_0x0x0, region, buffer_row_pitch, buffer_slice_pitch, stride, slice, @@ -431,13 +435,13 @@ public class CLCommandQueue extends CLObject { if (size > buffer.byteSize()) throw new BufferUnderflowException(); - try (Allocator frame = Memory.stack()) { + try (ResourceScope frame = ResourceScope.newConfinedScope()) { EventInfo info = new EventInfo(frame, wait, event); int res; res = clEnqueueWriteBuffer(addr(), mem.addr(), blocking ? 1 : 0, mem_offset, size, - buffer.baseAddress(), + buffer.address(), info.nwait, info.wait, info.event); if (res != 0) throw new CLException(res); @@ -455,12 +459,11 @@ public class CLCommandQueue extends CLObject { ByteBuffer buffer, CLEventList wait, CLEventList event) throws CLException { - try (MemorySegment seg = MemorySegment.ofByteBuffer(buffer)) { - enqueueWriteBuffer(mem, blocking, - mem_offset, size, - seg, - wait, event); - } + MemorySegment seg = MemorySegment.ofByteBuffer(buffer); + enqueueWriteBuffer(mem, blocking, + mem_offset, size, + seg, + wait, event); } public void enqueueWriteBuffer(CLBuffer mem, boolean blocking, @@ -468,7 +471,8 @@ public class CLCommandQueue extends CLObject { byte[] buffer, int buf_offset, CLEventList wait, CLEventList event) throws CLException { - try (MemorySegment seg = MemorySegment.allocateNative(size)) { + try (ResourceScope scope = ResourceScope.newConfinedScope()) { + MemorySegment seg = MemorySegment.allocateNative(size, scope); seg.asByteBuffer().order(ByteOrder.nativeOrder()).put(buffer, buf_offset, size); enqueueWriteBuffer(mem, true, mem_offset, size, seg, wait, event); } @@ -479,7 +483,8 @@ public class CLCommandQueue extends CLObject { short[] buffer, int buf_offset, CLEventList wait, CLEventList event) throws CLException { - try (MemorySegment seg = MemorySegment.allocateNative(size * 2L)) { + try (ResourceScope scope = ResourceScope.newConfinedScope()) { + MemorySegment seg = MemorySegment.allocateNative(size * 2L, scope); seg.asByteBuffer().order(ByteOrder.nativeOrder()).asShortBuffer().put(buffer, buf_offset, size); enqueueWriteBuffer(mem, true, mem_offset * 2, size * 2L, seg, wait, event); } @@ -490,7 +495,8 @@ public class CLCommandQueue extends CLObject { int[] buffer, int buf_offset, CLEventList wait, CLEventList event) throws CLException { - try (MemorySegment seg = MemorySegment.allocateNative(size * 4L)) { + try (ResourceScope scope = ResourceScope.newConfinedScope()) { + MemorySegment seg = MemorySegment.allocateNative(size * 4L, scope); seg.asByteBuffer().order(ByteOrder.nativeOrder()).asIntBuffer().put(buffer, buf_offset, size); enqueueWriteBuffer(mem, true, mem_offset * 4, size * 4L, seg, wait, event); } @@ -501,7 +507,8 @@ public class CLCommandQueue extends CLObject { long[] buffer, int buf_offset, CLEventList wait, CLEventList event) throws CLException { - try (MemorySegment seg = MemorySegment.allocateNative(size * 8L)) { + try (ResourceScope scope = ResourceScope.newConfinedScope()) { + MemorySegment seg = MemorySegment.allocateNative(size * 8L, scope); seg.asByteBuffer().order(ByteOrder.nativeOrder()).asLongBuffer().put(buffer, buf_offset, size); enqueueWriteBuffer(mem, true, mem_offset * 8, size * 8L, seg, wait, event); } @@ -512,7 +519,8 @@ public class CLCommandQueue extends CLObject { float[] buffer, int buf_offset, CLEventList wait, CLEventList event) throws CLException { - try (MemorySegment seg = MemorySegment.allocateNative(size * 4L)) { + try (ResourceScope scope = ResourceScope.newConfinedScope()) { + MemorySegment seg = MemorySegment.allocateNative(size * 4L, scope); seg.asByteBuffer().order(ByteOrder.nativeOrder()).asFloatBuffer().put(buffer, buf_offset, size); enqueueWriteBuffer(mem, true, mem_offset * 4, size * 4L, seg, wait, event); } @@ -523,7 +531,8 @@ public class CLCommandQueue extends CLObject { double[] buffer, int buf_offset, CLEventList wait, CLEventList event) throws CLException { - try (MemorySegment seg = MemorySegment.allocateNative(size * 8L)) { + try (ResourceScope scope = ResourceScope.newConfinedScope()) { + MemorySegment seg = MemorySegment.allocateNative(size * 8L, scope); seg.asByteBuffer().order(ByteOrder.nativeOrder()).asDoubleBuffer().put(buffer, buf_offset, size); enqueueWriteBuffer(mem, true, mem_offset * 8, size * 8L, seg, wait, event); } @@ -560,21 +569,21 @@ public class CLCommandQueue extends CLObject { buffer_row_pitch, buffer_slice_pitch, host_row_pitch, host_slice_pitch, buffer.byteSize()); - try (Allocator frame = Memory.stack()) { + try (ResourceScope frame = ResourceScope.newConfinedScope()) { 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); + MemorySegment cbuffer_origin = toLongV(frame, buffer_origin); + MemorySegment chost_origin = toLongV(frame, host_origin); + MemorySegment cregion = toLongV(frame, region); int res; res = clEnqueueWriteBufferRect( addr(), mem.addr(), blocking ? 1 : 0, - cbuffer_origin, chost_origin, cregion, + cbuffer_origin.address(), chost_origin.address(), cregion.address(), buffer_row_pitch, buffer_slice_pitch, host_row_pitch, host_slice_pitch, - buffer.baseAddress(), + buffer.address(), info.nwait, info.wait, info.event); if (res != 0) @@ -593,13 +602,12 @@ public class CLCommandQueue extends CLObject { 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 { - 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); - } + 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, @@ -640,8 +648,8 @@ public class CLCommandQueue extends CLObject { /** * Calls clEnqueueFillBuffer. - * - * This fills the buffer with a pattern. The offset and size + *

+ * This fills the buffer with a pattern. The offset and size * is in multiples of the pattern size. * * @param buffer @@ -654,19 +662,19 @@ public class CLCommandQueue extends CLObject { * @throws CLException */ public void enqueueFillBuffer(CLBuffer buffer, - MemorySegment pattern, - long offset, - long size, - CLEventList wait, - CLEventList event) throws CLException { + MemorySegment pattern, + long offset, + long size, + CLEventList wait, + CLEventList event) throws CLException { requireAPIVersion(CLPlatform.VERSION_1_2); - try (Allocator frame = Memory.stack()) { + try (ResourceScope frame = ResourceScope.newConfinedScope()) { EventInfo info = new EventInfo(frame, wait, event); int res; res = clEnqueueFillBuffer( addr(), buffer.addr(), - pattern.baseAddress(), pattern.byteSize(), + pattern.address(), pattern.byteSize(), offset * pattern.byteSize(), size * pattern.byteSize(), info.nwait, info.wait, info.event); @@ -681,18 +689,18 @@ public class CLCommandQueue extends CLObject { throw new RuntimeException(t); } } + public void enqueueFillBuffer(CLBuffer buffer, ByteBuffer pattern, long offset, long size, CLEventList wait, CLEventList event) throws CLException { - try (MemorySegment seg = MemorySegment.ofByteBuffer(pattern)) { - enqueueFillBuffer(buffer, - pattern, - offset, size, - wait, event); - } + MemorySegment seg = MemorySegment.ofByteBuffer(pattern); + enqueueFillBuffer(buffer, + pattern, + offset, size, + wait, event); } /** @@ -708,15 +716,16 @@ public class CLCommandQueue extends CLObject { * @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;i call = Native.resolve( Call_pv_v.stub((MemoryAddress memargs) -> { - int xmem = 0; + 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); + res = clEnqueueNativeKernel(addr(), call.addr(), memstage.address(), nmem * 8, nmem, memstage.address(), memptrs.address(), info.nwait, info.wait, info.event); if (res != 0) throw new CLException(res); @@ -1620,7 +1634,7 @@ public class CLCommandQueue extends CLObject { public void enqueueMarkerWithWaitList( CLEventList waiters, CLEventList events) throws CLException { - try (Allocator frame = Memory.stack()) { + try (ResourceScope frame = ResourceScope.newConfinedScope()) { EventInfo info = new EventInfo(frame, waiters, events); if (haveAPIVersion(CLPlatform.VERSION_1_2)) { clEnqueueMarkerWithWaitList(addr(), info.nwait, info.wait, info.event); @@ -1647,10 +1661,10 @@ public class CLCommandQueue extends CLObject { * @param events * @throws CLException */ - public void enqueueBarrierWithWaitList( + public void enqueueBarrierWithWaitList( CLEventList waiters, CLEventList events) throws CLException { - try (Allocator frame = Memory.stack()) { + try (ResourceScope frame = ResourceScope.newConfinedScope()) { EventInfo info = new EventInfo(frame, waiters, events); if (haveAPIVersion(CLPlatform.VERSION_1_2)) { clEnqueueBarrierWithWaitList(addr(), info.nwait, info.wait, info.event); @@ -1885,7 +1899,6 @@ public class CLCommandQueue extends CLObject { } /* ********************************************************************** */ - protected GLext getGLext() { return getObjectPlatform() .getExtension(CLPlatform.cl_gl_ext, (p) @@ -1900,12 +1913,12 @@ public class CLCommandQueue extends CLObject { CLEventList wait, CLEventList event) { GLext gl = getGLext(); - try (Allocator frame = Memory.stack()) { + try (ResourceScope frame = ResourceScope.newConfinedScope()) { EventInfo info = new EventInfo(frame, wait, event); - MemoryAddress cmem_objects = Native.toAddrV(frame, mem_objects); + MemorySegment cmem_objects = Native.toAddrV(frame, mem_objects); int res; - res = gl.clEnqueueAcquireGLObjects(addr(), mem_objects.length, cmem_objects, + res = gl.clEnqueueAcquireGLObjects(addr(), mem_objects.length, cmem_objects.address(), info.nwait, info.wait, info.event); if (res != 0) throw new CLRuntimeException(res); @@ -1923,12 +1936,12 @@ public class CLCommandQueue extends CLObject { CLEventList wait, CLEventList event) { GLext gl = getGLext(); - try (Allocator frame = Memory.stack()) { + try (ResourceScope frame = ResourceScope.newConfinedScope()) { EventInfo info = new EventInfo(frame, wait, event); - MemoryAddress cmem_objects = Native.toAddrV(frame, mem_objects); + MemorySegment cmem_objects = Native.toAddrV(frame, mem_objects); int res; - res = gl.clEnqueueReleaseGLObjects(addr(), mem_objects.length, cmem_objects, + res = gl.clEnqueueReleaseGLObjects(addr(), mem_objects.length, cmem_objects.address(), info.nwait, info.wait, info.event); if (res != 0) throw new CLRuntimeException(res); @@ -1942,7 +1955,6 @@ public class CLCommandQueue extends CLObject { } /* ********************************************************************** */ - /** * 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 116f46b..f1b84f4 100644 --- a/src/notzed.zcl/classes/au/notzed/zcl/CLContext.java +++ b/src/notzed.zcl/classes/au/notzed/zcl/CLContext.java @@ -68,7 +68,7 @@ public class CLContext extends CLObject { @Override public String toString() { StringBuilder sb = new StringBuilder("CLContext["); - for (CLDevice d : getDevices()) { + for (CLDevice d: getDevices()) { sb.append(d); sb.append(' '); } @@ -113,19 +113,19 @@ public class CLContext extends CLObject { * @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); + try (ResourceScope frame = ResourceScope.newConfinedScope()) { + MemorySegment pprops = CLProperty.toNative(frame, properties); + MemorySegment pdevs = MemorySegment.allocateNative(devices.length * CLinker.C_POINTER.byteSize(), CLinker.C_POINTER.byteAlignment(), frame); + MemorySegment pres = MemorySegment.allocateNative(CLinker.C_INT, frame); Callback call = CLContextNotify.call(notify); MemoryAddress cl; int res; - for (int i=0;i call = CLContextNotify.call(notify); int res; - cl = clCreateContextFromType(pprops, device_type, call.addr(), MemoryAddress.NULL, pres); - res = getInt(pres); + cl = clCreateContextFromType(pprops.address(), device_type, call.addr(), MemoryAddress.NULL, pres.address()); + res = MemoryAccess.getInt(pres); if (res != 0) throw new CLRuntimeException(res); @@ -204,13 +204,13 @@ public class CLContext extends CLObject { * deprecated as of OpenCL 2.0 */ public CLCommandQueue createCommandQueue(CLDevice dev, long properties) throws CLRuntimeException { - try (Allocator frame = Memory.stack()) { - MemoryAddress pres = frame.alloca(8); + try (ResourceScope frame = ResourceScope.newConfinedScope()) { + MemorySegment pres = MemorySegment.allocateNative(CLinker.C_INT, frame); MemoryAddress q; int res; - q = clCreateCommandQueue(addr(), dev.addr(), properties, pres); - res = getInt(pres); + q = clCreateCommandQueue(addr(), dev.addr(), properties, pres.address()); + res = MemoryAccess.getInt(pres); if (res != 0) throw new CLRuntimeException(res); @@ -236,14 +236,14 @@ public class CLContext extends CLObject { // 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); + try (ResourceScope frame = ResourceScope.newConfinedScope()) { + MemorySegment pprops = CLProperty.toNative(frame, properties); + MemorySegment pres = MemorySegment.allocateNative(CLinker.C_INT, frame); MemoryAddress q; int res; - q = clCreateCommandQueueWithProperties(addr(), dev.addr(), pprops, pres); - res = getInt(pres); + q = clCreateCommandQueueWithProperties(addr(), dev.addr(), pprops.address(), pres.address()); + res = MemoryAccess.getInt(pres); if (res != 0) throw new CLRuntimeException(res); @@ -280,7 +280,6 @@ public class CLContext extends CLObject { } /* ********************************************************************** */ - /** * Calls clCreateBuffer with an empty host pointer. * @@ -294,9 +293,9 @@ public class CLContext extends CLObject { /** * Calls clCreateBuffer. - * + *

* If flags contains CL_MEM_USE_HOST_PTR then hostp must not - * be null. Currently in this case the CLBuffer must be + * be null. Currently in this case the CLBuffer must be * explicitly released() on the caller thread. * * @param flags CL_MEM_* flags. @@ -309,15 +308,13 @@ public class CLContext extends CLObject { if (hostseg != null && hostseg.byteSize() < size) throw new CLRuntimeException(CL_INVALID_HOST_PTR); - try (Allocator frame = Memory.stack()) { - MemoryAddress pres = frame.alloca(8); + try (ResourceScope frame = ResourceScope.newConfinedScope()) { + MemorySegment pres = MemorySegment.allocateNative(CLinker.C_INT, frame); MemoryAddress pbuffer; int res; - pbuffer = clCreateBuffer(addr(), flags, size, addr(hostseg), pres); - res = getInt(pres); - - if (res != 0) + pbuffer = clCreateBuffer(addr(), flags, size, addr(hostseg), pres.address()); + if ((res = MemoryAccess.getInt(pres)) != 0) throw new CLRuntimeException(res); if (hostseg != null && (flags & CL_MEM_USE_HOST_PTR) != 0) @@ -333,9 +330,9 @@ public class CLContext extends CLObject { /** * Calls clCreateBuffer. - * + *

* If flags contains CL_MEM_USE_HOST_PTR then hostp must not - * be null. Currently the CLBuffer must be explicitly + * be null. Currently the CLBuffer must be explicitly * released() on the caller thread. * * @param flags CL_MEM_* flags. @@ -350,13 +347,12 @@ public class CLContext extends CLObject { try { CLBuffer buffer = createBuffer(flags, size, hostseg); - if ((flags & CL_MEM_USE_HOST_PTR) != 0) - hostseg = null; - + //if ((flags & CL_MEM_USE_HOST_PTR) != 0) + // hostseg = null; return buffer; } finally { - if (hostseg != null) - hostseg.close(); + //if (hostseg != null) + // hostseg.close(); } } else { return createBuffer(flags, size, (MemorySegment)null); @@ -407,16 +403,15 @@ public class CLContext extends CLObject { throw new NullPointerException(); // Must copy. - try (MemorySegment mem = MemorySegment.allocateNative(hostp.length, 16)) { + try (ResourceScope scope = ResourceScope.newConfinedScope()) { + MemorySegment mem = MemorySegment.allocateNative(hostp.length, 16, scope); mem.asByteBuffer().order(ByteOrder.nativeOrder()).put(hostp); return createBuffer(flags, hostp.length, mem); } } //native public CLBuffer createBuffer(long flags, short[] hostp) throws CLRuntimeException; - //native public CLBuffer createBuffer(long flags, int[] 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); @@ -425,20 +420,19 @@ public class CLContext extends CLObject { throw new NullPointerException(); // Must copy. - try (MemorySegment mem = MemorySegment.allocateNative(hostp.length, 16)) { + try (ResourceScope scope = ResourceScope.newConfinedScope()) { + MemorySegment mem = MemorySegment.allocateNative(hostp.length, 16, scope); 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; - // FIXME: clCreateSubBuffer /* ********************************************************************** */ - public CLImage createImage(long flags, CLImageFormat fmt, CLImageDesc desc) throws CLRuntimeException, UnsupportedOperationException { - return createImage(flags, fmt, desc, (MemorySegment) null); + return createImage(flags, fmt, desc, (MemorySegment)null); } /** @@ -461,7 +455,6 @@ public class CLContext extends CLObject { int res; // FIXME: perform range checks - if (haveAPIVersion(CLPlatform.VERSION_1_2)) { MemoryAddress cdesc = CLImageDesc.toNative(frame, desc); @@ -473,7 +466,7 @@ public class CLContext extends CLObject { break; case CL_MEM_OBJECT_IMAGE3D: ci = clCreateImage3D(addr(), flags, cfmt, desc.imageWidth, desc.imageHeight, desc.imageDepth, - desc.imageRowPitch, desc.imageSlicePitch, addr(hostseg), cres); + desc.imageRowPitch, desc.imageSlicePitch, addr(hostseg), cres); break; default: throw new UnsupportedOperationException("Requires OpenCL 1.2"); @@ -501,13 +494,12 @@ public class CLContext extends CLObject { try { CLImage image = createImage(flags, fmt, desc, hostseg); - if ((flags & CL_MEM_USE_HOST_PTR) != 0) - hostseg = null; - + //if ((flags & CL_MEM_USE_HOST_PTR) != 0) + // hostseg = null; return image; } finally { - if (hostseg != null) - hostseg.close(); + //if (hostseg != null) + // hostseg.close(); } } else { return createImage(flags, fmt, desc, (MemorySegment)null); @@ -522,16 +514,15 @@ public class CLContext extends CLObject { throw new NullPointerException(); // Must copy. - try (MemorySegment mem = MemorySegment.allocateNative(hostp.length, 16)) { - mem.asByteBuffer().order(ByteOrder.nativeOrder()).put(hostp); + try (ResourceScope scope = ResourceScope.newConfinedScope()) { + MemorySegment mem = MemorySegment.allocateNative(hostp.length, 16, scope); + mem.copyFrom(MemorySegment.ofArray(hostp)); return createImage(flags, fmt, desc, mem); } } //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); @@ -540,8 +531,9 @@ public class CLContext extends CLObject { throw new NullPointerException(); // Must copy. - try (MemorySegment mem = MemorySegment.allocateNative(hostp.length * 4, 16)) { - mem.asByteBuffer().order(ByteOrder.nativeOrder()).asFloatBuffer().put(hostp); + try (ResourceScope scope = ResourceScope.newConfinedScope()) { + MemorySegment mem = MemorySegment.allocateNative(hostp.length * 4, 16, scope); + mem.copyFrom(MemorySegment.ofArray(hostp)); return createImage(flags, fmt, desc, mem); } } @@ -561,15 +553,14 @@ public class CLContext extends CLObject { 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); + try (ResourceScope frame = ResourceScope.newConfinedScope()) { + MemorySegment pprops = CLProperty.toNative(frame, properties); + MemorySegment pres = MemorySegment.allocateNative(CLinker.C_INT, frame); int res; MemoryAddress cp; - cp = clCreatePipe(addr(), flags, packetSize, maxPackets, cprops, cres); - res = getInt(cres); - if (res != 0) + cp = clCreatePipe(addr(), flags, packetSize, maxPackets, pprops.address(), pres.address()); + if ((res = MemoryAccess.getInt(pres)) != 0) throw new CLRuntimeException(res); return resolve(cp, (x) -> new CLPipe(x, getObjectPlatform())); @@ -605,7 +596,7 @@ public class CLContext extends CLObject { res = clGetSupportedImageFormats(addr(), flags, type, num, list, cnum); CLImageFormat[] out = new CLImageFormat[num]; - for (int i=0;i new CLSampler(x, getObjectPlatform())); @@ -710,23 +700,20 @@ public class CLContext extends CLObject { static long length(byte[][] strings) { long len = 0; - for (int i=0;i new CLProgram(x, getObjectPlatform())); @@ -798,19 +783,16 @@ public class CLContext extends CLObject { public CLProgram createProgramWithIL(byte[] il) throws CLException { requireAPIVersion(CLPlatform.VERSION_2_1); - try (Allocator frame = Memory.stack(); - MemorySegment buffer = MemorySegment.allocateNative(il.length, 1)) { - MemoryAddress cret = frame.alloca(8); - MemoryAddress base = buffer.baseAddress(); + try (ResourceScope frame = ResourceScope.newConfinedScope()) { + MemorySegment buffer = MemorySegment.allocateNative(il.length, 1, frame); + MemorySegment pres = MemorySegment.allocateNative(CLinker.C_INT, frame); MemoryAddress cp; int res; - copy(base, il); - - cp = clCreateProgramWithIL(addr(), base, il.length, cret); + copy(buffer, il); - res = getInt(cret); - if (res != 0) + cp = clCreateProgramWithIL(addr(), buffer.address(), il.length, pres.address()); + if ((res = MemoryAccess.getInt(pres)) != 0) throw new CLException(res); return resolve(cp, (x) -> new CLProgram(x, getObjectPlatform())); @@ -833,36 +815,33 @@ public class CLContext extends CLObject { */ public CLProgram createProgramWithBinary(CLDevice[] devices, byte[][] binaries, int[] status) throws CLException { long size = length(binaries); - try (Allocator frame = Memory.stack(); - MemorySegment buffer = MemorySegment.allocateNative(size, 1)) { - MemoryAddress cdevs = toAddrV(frame, devices); - MemoryAddress barray = frame.alloca(8 * binaries.length); - MemoryAddress larray = frame.alloca(8 * binaries.length); - MemoryAddress cstatus = status != null ? frame.alloca(4 * devices.length) : MemoryAddress.NULL; - MemoryAddress cret = frame.alloca(8); - MemoryAddress base = buffer.baseAddress(); + try (ResourceScope frame = ResourceScope.newConfinedScope()) { + MemorySegment buffer = MemorySegment.allocateNative(size, 1, frame); + MemorySegment cdevs = toAddrV(frame, devices); + MemorySegment barray = Native.allocAddrV(frame, binaries.length); + MemorySegment larray = Native.allocV(frame, CLinker.C_LONG, binaries.length); + MemorySegment cstatus = status != null ? MemorySegment.allocateNative(4 * status.length, 4, frame) : MemorySegment.globalNativeSegment(); + MemorySegment pres = MemorySegment.allocateNative(CLinker.C_INT, frame); MemoryAddress cp; int res; - for (int i=0, o=0;i new CLProgram(x, getObjectPlatform())); @@ -957,15 +936,13 @@ public class CLContext extends CLObject { public CLEvent createUserEvent() throws CLException { requireAPIVersion(CLPlatform.VERSION_1_1); - try (Allocator frame = Memory.stack()) { - MemoryAddress cret = frame.alloca(8); + try (ResourceScope frame = ResourceScope.newConfinedScope()) { + MemorySegment pres = MemorySegment.allocateNative(CLinker.C_INT, frame); MemoryAddress ce; int res; - ce = clCreateUserEvent(addr(), cret); - - res = getInt(cret); - if (res != 0) + ce = clCreateUserEvent(addr(), pres.address()); + if ((res = MemoryAccess.getInt(pres)) != 0) throw new CLException(res); return resolve(ce, (x) -> new CLEvent(x, getObjectPlatform())); @@ -1004,7 +981,6 @@ public class CLContext extends CLObject { } /* ********************************************************************** */ - protected GLext getGLext() { return getObjectPlatform() .getExtension(CLPlatform.cl_gl_ext, (p) @@ -1014,7 +990,6 @@ public class CLContext extends CLObject { /* ********************************************************************** * cl_khr_sharing extension */ - public static CLContextProperty GL_CONTEXT_KHR(long id) { return new CLContextProperty.TagValue(CL_GL_CONTEXT_KHR, id); } @@ -1119,8 +1094,8 @@ public class CLContext extends CLObject { CLContextProperty[] properties int ctype, int param_name) throws CLRuntimeException; - */ - /* + */ + /* public CLDevice getCurrendDeviceForGLConextKHR(CLContextProperty[] properties) throws CLRuntimeException { return getGLContextInfoKHRAny(properties, CLObject.CTYPE_DEVICE, CL_CURRENT_DEVICE_FOR_GL_CONTEXT_KHR); } @@ -1128,12 +1103,9 @@ public class CLContext extends CLObject { public CLDevice[] getDevicesForGLConextKHR(CLContextProperty[] properties) throws CLRuntimeException { return getGLContextInfoKHRAnyV(properties, CLObject.CTYPE_DEVICE, CL_DEVICES_FOR_GL_CONTEXT_KHR); }*/ - - - /* ********************************************************************** + /* ********************************************************************** * cl_khr_gl_event extension */ - /** * @since cl_khr_gl_event extension */ diff --git a/src/notzed.zcl/classes/au/notzed/zcl/CLDeviceProperty.java b/src/notzed.zcl/classes/au/notzed/zcl/CLDeviceProperty.java index 08b8813..e3c8f32 100644 --- a/src/notzed.zcl/classes/au/notzed/zcl/CLDeviceProperty.java +++ b/src/notzed.zcl/classes/au/notzed/zcl/CLDeviceProperty.java @@ -17,7 +17,8 @@ package au.notzed.zcl; import api.Native; -import jdk.incubator.foreign.MemoryAddress; +import jdk.incubator.foreign.MemoryAccess; +import jdk.incubator.foreign.MemorySegment; /** * Properties for CLDevice sub-device creation. @@ -47,20 +48,20 @@ public interface CLDeviceProperty extends CLProperty { } @Override - public int toInt(MemoryAddress dst, int o) { - Native.setInt(dst, o++, CL.CL_DEVICE_PARTITION_BY_COUNTS); + public int toInt(MemorySegment dst, int o) { + MemoryAccess.setIntAtIndex(dst, o++, CL.CL_DEVICE_PARTITION_BY_COUNTS); for (int c : counts) - Native.setInt(dst, o++, c); - Native.setInt(dst, o++, CL.CL_DEVICE_PARTITION_BY_COUNTS_LIST_END); + MemoryAccess.setIntAtIndex(dst, o++, c); + MemoryAccess.setIntAtIndex(dst, o++, CL.CL_DEVICE_PARTITION_BY_COUNTS_LIST_END); return o; } @Override - public int toLong(MemoryAddress dst, int o) { - Native.setLong(dst, o++, CL.CL_DEVICE_PARTITION_BY_COUNTS); + public int toLong(MemorySegment dst, int o) { + MemoryAccess.setLongAtIndex(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); + MemoryAccess.setLongAtIndex(dst, o++, c); + MemoryAccess.setLongAtIndex(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 a91d7c3..fd2f283 100644 --- a/src/notzed.zcl/classes/au/notzed/zcl/CLEvent.java +++ b/src/notzed.zcl/classes/au/notzed/zcl/CLEvent.java @@ -75,8 +75,8 @@ public class CLEvent extends CLObject { * This goes via the context - every one must have a context? */ static CLPlatform findPlatform(MemoryAddress cevent) { - try (Allocator a = Memory.stack()) { - MemoryAddress ccl = getAddr(getInfo(cevent, CL_EVENT_CONTEXT, clGetEventInfo, a, 8)); + try (ResourceScope a = ResourceScope.newConfinedScope()) { + MemoryAddress ccl = MemoryAccess.getAddress(getInfo(cevent, CL_EVENT_CONTEXT, clGetEventInfo, a, 8)); return CLContext.findPlatform(ccl); } catch (RuntimeException | Error t) { diff --git a/src/notzed.zcl/classes/au/notzed/zcl/CLEventList.java b/src/notzed.zcl/classes/au/notzed/zcl/CLEventList.java index a633bc1..811ade2 100644 --- a/src/notzed.zcl/classes/au/notzed/zcl/CLEventList.java +++ b/src/notzed.zcl/classes/au/notzed/zcl/CLEventList.java @@ -18,10 +18,10 @@ package au.notzed.zcl; import jdk.incubator.foreign.MemoryAddress; import jdk.incubator.foreign.MemorySegment; -import api.Memory; -import api.Allocator; import api.Native; import static au.notzed.zcl.CLLib.*; +import jdk.incubator.foreign.MemoryAccess; +import jdk.incubator.foreign.ResourceScope; /** * Manages a list of cl_events. @@ -44,10 +44,12 @@ import static au.notzed.zcl.CLLib.*; */ public final class CLEventList implements AutoCloseable { + // FIXME: pass scope in instead of being autocloseable + final ResourceScope scope = ResourceScope.newConfinedScope(); /** * Raw event values. */ - final MemoryAddress cevents; + final MemorySegment cevents; /** * Event references? @@ -65,7 +67,7 @@ public final class CLEventList implements AutoCloseable { */ public CLEventList(int capacity) { this.jevents = new CLEvent[capacity]; - this.cevents = MemorySegment.allocateNative(8 * capacity, 8).baseAddress(); + this.cevents = MemorySegment.allocateNative(8 * capacity, 8, scope); } /** @@ -79,14 +81,14 @@ public final class CLEventList implements AutoCloseable { if (ev == null) { try { - clReleaseEvent(Native.getAddr(cevents, i)); + clReleaseEvent(MemoryAccess.getAddressAtIndex(cevents, i)); } catch (Throwable t) { } } else { ev.release(); jevents[i] = null; } - Native.setAddr(cevents, i, MemoryAddress.NULL); + MemoryAccess.setAddressAtIndex(cevents, i, MemoryAddress.NULL); } index = 0; } @@ -99,7 +101,7 @@ public final class CLEventList implements AutoCloseable { */ public void release() { reset(); - cevents.segment().close(); + scope.close(); } @Override @@ -113,7 +115,7 @@ public final class CLEventList implements AutoCloseable { * This is used internally by CLCommandQueue.EventInfo to write directly to the event list. */ public MemoryAddress slots() { - return cevents; + return cevents.address(); } /** @@ -126,11 +128,11 @@ public final class CLEventList implements AutoCloseable { */ public MemoryAddress currentSlot() { if (index < jevents.length) { - MemoryAddress addr = cevents.addOffset(index * 8); + MemorySegment addr = cevents.asSlice(index * 8); // This should already be null, but this performs a range check - Native.setAddr(addr, MemoryAddress.NULL); - return addr; + MemoryAccess.setAddress(addr, MemoryAddress.NULL); + return addr.address(); } else throw new ArrayIndexOutOfBoundsException(); } @@ -154,7 +156,7 @@ public final class CLEventList implements AutoCloseable { if (i < index) { CLEvent ev = jevents[i]; if (ev == null) - jevents[i] = ev = Native.resolve(Native.getAddr(cevents, i), CLEvent::new); + jevents[i] = ev = Native.resolve(MemoryAccess.getAddressAtIndex(cevents, i), CLEvent::new); return ev; } else throw new ArrayIndexOutOfBoundsException(); @@ -166,7 +168,7 @@ public final class CLEventList implements AutoCloseable { * @param event */ public void add(CLEvent event) { - Native.setAddr(cevents, index, event.addr()); + MemoryAccess.setAddressAtIndex(cevents, index, event.addr()); jevents[index++] = event; } @@ -187,7 +189,7 @@ public final class CLEventList implements AutoCloseable { public void waitForEvents() throws CLException { if (size() > 0) { try { - int res = clWaitForEvents(size(), cevents); + int res = clWaitForEvents(size(), cevents.address()); if (res != 0) throw new CLException(res); } catch (CLException | RuntimeException | Error t) { diff --git a/src/notzed.zcl/classes/au/notzed/zcl/CLImageFormat.java b/src/notzed.zcl/classes/au/notzed/zcl/CLImageFormat.java index 4503305..e702637 100644 --- a/src/notzed.zcl/classes/au/notzed/zcl/CLImageFormat.java +++ b/src/notzed.zcl/classes/au/notzed/zcl/CLImageFormat.java @@ -110,7 +110,7 @@ public class CLImageFormat { } static CLImageFormat fromNative(MemorySegment addr) { - return fromNative(addr.baseAddress()); + return fromNative(addr.address()); } 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/CLMemory.java b/src/notzed.zcl/classes/au/notzed/zcl/CLMemory.java index cff5f69..5ca3409 100644 --- a/src/notzed.zcl/classes/au/notzed/zcl/CLMemory.java +++ b/src/notzed.zcl/classes/au/notzed/zcl/CLMemory.java @@ -98,9 +98,9 @@ public abstract class CLMemory extends CLObject { return null; - try (Allocator a = Memory.stack()) { - MemoryAddress addr = getInfo(p, CL_MEM_TYPE, clGetMemObjectInfo, a, 4); - int type = getInt(addr); + try (ResourceScope a = ResourceScope.newConfinedScope()) { + MemorySegment addr = getInfo(p, CL_MEM_TYPE, clGetMemObjectInfo, a, 4); + int type = MemoryAccess.getInt(addr); switch (type) { case CL_MEM_OBJECT_BUFFER: @@ -135,10 +135,11 @@ public abstract class CLMemory extends CLObject { */ @Override public void release() { - if (seg != null) { - seg.close(); - seg = null; - } + // ?? + //if (seg != null) { + // seg.close(); + // seg = null; + //} super.release(); } @@ -284,8 +285,8 @@ public abstract class CLMemory extends CLObject { * @since cl_khr_gl_sharing */ public int getGLTextureInfoInt(int param) { - try (Allocator frame = Memory.stack()) { - return Native.getInt(getInfo(addr(), CL_GL_TEXTURE_TARGET, getGLext().clGetGLTextureInfo, frame, 4)); + try (ResourceScope frame = ResourceScope.newConfinedScope()) { + return MemoryAccess.getInt(getInfo(addr(), CL_GL_TEXTURE_TARGET, getGLext().clGetGLTextureInfo, frame, 4)); } } diff --git a/src/notzed.zcl/classes/au/notzed/zcl/CLObject.java b/src/notzed.zcl/classes/au/notzed/zcl/CLObject.java index a037012..5987e12 100644 --- a/src/notzed.zcl/classes/au/notzed/zcl/CLObject.java +++ b/src/notzed.zcl/classes/au/notzed/zcl/CLObject.java @@ -22,8 +22,6 @@ import java.util.function.IntFunction; import java.util.function.BiFunction; import jdk.incubator.foreign.*; import api.Native; -import api.Allocator; -import api.Memory; /** * Base class for all OpenCL types which can be represented as objects. @@ -47,7 +45,7 @@ public abstract class CLObject extends Native { /** * Cache the platform this object belongs to, for api checking. - * Classes can use getObjectPlatform to look it up. If + * Classes can use getObjectPlatform to look it up. If * they need to support null platform at createion (e.g. clevent) * they must override it. */ @@ -56,7 +54,7 @@ public abstract class CLObject extends Native { /** * Instantiate a new CLObject. * - * @param p address of object. May be MemoryAddress.NULL if required. + * @param p address of object. May be MemoryAddress.NULL if required. * @param platform This must not be null. */ protected CLObject(MemoryAddress p, CLPlatform platform) { @@ -100,14 +98,13 @@ public abstract class CLObject extends Native { } // some are static for access before object instantiation - // new 5-param version - static MemoryAddress getInfo(MemoryAddress self, int id, MethodHandle getInfo, Allocator frame, long size) throws CLRuntimeException { + static MemorySegment getInfo(MemoryAddress self, int id, MethodHandle getInfo, ResourceScope frame, long size) throws CLRuntimeException { try { - MemoryAddress addr = frame.alloca(size); + MemorySegment addr = MemorySegment.allocateNative(size, 8, frame); int res; - res = (int)getInfo.invokeExact(self, id, size, addr, MemoryAddress.NULL); + res = (int)getInfo.invokeExact(self, id, size, addr.address(), MemoryAddress.NULL); if (res != 0) throw new CLRuntimeException(res); @@ -120,14 +117,14 @@ public abstract class CLObject extends Native { } protected int getInfoInt(int id, MethodHandle getInfo) { - try (Allocator a = Memory.stack()) { - return getInt(getInfo(addr(), id, getInfo, a, 4)); + try (ResourceScope a = ResourceScope.newConfinedScope()) { + return MemoryAccess.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)); + try (ResourceScope a = ResourceScope.newConfinedScope()) { + return MemoryAccess.getLong(getInfo(addr(), id, getInfo, a, 8)); } } @@ -136,31 +133,31 @@ public abstract class CLObject extends Native { } 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); + try (ResourceScope a = ResourceScope.newConfinedScope()) { + return Native.resolve(MemoryAccess.getAddress(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))); + try (ResourceScope a = ResourceScope.newConfinedScope()) { + return create.apply(MemoryAccess.getAddress(getInfo(addr(), id, getInfo, a, 8))); } } // new 5-param version for get any - static MemorySegment getInfoAny(MemoryAddress addr, int id, MethodHandle getInfo, Allocator a) throws CLRuntimeException { + static MemorySegment getInfoAny(MemoryAddress addr, int id, MethodHandle getInfo, ResourceScope a) throws CLRuntimeException { try { - MemoryAddress sizep = a.alloca(8); + MemorySegment sizep = MemorySegment.allocateNative(8, 8, a); MemorySegment valp; long size; int res; - res = (int)getInfo.invokeExact(addr, id, 0L, MemoryAddress.NULL, sizep); + res = (int)getInfo.invokeExact(addr, id, 0L, MemoryAddress.NULL, sizep.address()); - size = getLong(sizep); - valp = a.allocs(size); + size = MemoryAccess.getLong(sizep); + valp = MemorySegment.allocateNative(size, a); - res = (int)getInfo.invokeExact(addr, id, size, valp.baseAddress(), sizep); + res = (int)getInfo.invokeExact(addr, id, size, valp.address(), sizep.address()); if (res != 0) throw new CLRuntimeException(res); @@ -174,31 +171,31 @@ public abstract class CLObject extends Native { } protected byte[] getInfoByteV(int id, MethodHandle getInfo) { - try (Allocator a = Memory.stack()) { + try (ResourceScope a = ResourceScope.newConfinedScope()) { return getInfoAny(addr(), id, getInfo, a).toByteArray(); } } protected String getInfoString(int id, MethodHandle getInfo) { - try (Allocator a = Memory.stack()) { + try (ResourceScope a = ResourceScope.newConfinedScope()) { return infoToString(getInfoAny(addr(), id, getInfo, a)); } } protected T[] getInfoPropertyV(int id, MethodHandle getInfo, BiFunction create, IntFunction createArray) { - try (Allocator a = Memory.stack()) { + try (ResourceScope a = ResourceScope.newConfinedScope()) { return CLProperty.fromNative(getInfoAny(addr(), id, getInfo, a), create, createArray); } } protected long[] getInfoLongV(int id, MethodHandle getInfo) { - try (Allocator a = Memory.stack()) { + try (ResourceScope a = ResourceScope.newConfinedScope()) { return Native.toLongV(getInfoAny(addr(), id, getInfo, a)); } } protected T[] getInfoAnyV(int id, MethodHandle getInfo, Function create, IntFunction createArray) { - try (Allocator a = Memory.stack()) { + try (ResourceScope a = ResourceScope.newConfinedScope()) { return Native.toObjectV(getInfoAny(addr(), id, getInfo, a), create, createArray); } catch (RuntimeException | Error t) { throw t; @@ -208,12 +205,13 @@ public abstract class CLObject extends Native { } // new 6-param version - protected MemoryAddress getInfo(T ctx, int id, MethodHandle getInfo, Allocator a, long size) throws CLRuntimeException { + protected MemorySegment getInfo(T ctx, int id, MethodHandle getInfo, ResourceScope a, long size) throws CLRuntimeException { try { - MemoryAddress addr = a.alloca(size); + // TODO: use ... ValueLayout? + MemorySegment addr = MemorySegment.allocateNative(size, 16, a); int res; - res = (int)getInfo.invokeExact(addr(), ctx.addr(), id, size, addr, MemoryAddress.NULL); + res = (int)getInfo.invokeExact(addr(), ctx.addr(), id, size, addr.address(), MemoryAddress.NULL); if (res != 0) throw new CLRuntimeException(res); @@ -226,14 +224,14 @@ public abstract class CLObject extends Native { } protected int getInfoInt(T ctx, int id, MethodHandle getInfo) { - try (Allocator a = Memory.stack()) { - return getInt(getInfo(ctx, id, getInfo, a, 4)); + try (ResourceScope a = ResourceScope.newConfinedScope()) { + return MemoryAccess.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)); + try (ResourceScope a = ResourceScope.newConfinedScope()) { + return MemoryAccess.getLong(getInfo(ctx, id, getInfo, a, 8)); } } @@ -242,19 +240,20 @@ public abstract class CLObject extends Native { } // new 6-param get-any - protected MemorySegment getInfoAny(T ctx, int id, MethodHandle getInfo, Allocator a) throws CLRuntimeException { + // TODO: pass type descriptor for alignment + protected MemorySegment getInfoAny(T ctx, int id, MethodHandle getInfo, ResourceScope a) throws CLRuntimeException { try { - MemoryAddress sizep = a.alloca(8); + MemorySegment sizep = MemorySegment.allocateNative(CLinker.C_LONG, a); MemorySegment valp; long size; int res; - res = (int)getInfo.invokeExact(addr(), ctx.addr(), id, 0L, MemoryAddress.NULL, sizep); + res = (int)getInfo.invokeExact(addr(), ctx.addr(), id, 0L, MemoryAddress.NULL, sizep.address()); - size = getLong(sizep); - valp = a.allocs(size); + size = MemoryAccess.getLong(sizep); + valp = MemorySegment.allocateNative(size, 16, a); - res = (int)getInfo.invokeExact(addr(), ctx.addr(), id, size, valp.baseAddress(), sizep); + res = (int)getInfo.invokeExact(addr(), ctx.addr(), id, size, valp.address(), sizep.address()); if (res != 0) throw new CLRuntimeException(res); @@ -268,7 +267,7 @@ public abstract class CLObject extends Native { } protected byte[] getInfoByteV(T ctx, int id, MethodHandle getInfo) { - try (Allocator a = Memory.stack()) { + try (ResourceScope a = ResourceScope.newConfinedScope()) { MemorySegment seg = getInfoAny(ctx, id, getInfo, a); return seg.toByteArray(); } @@ -276,8 +275,10 @@ public abstract class CLObject extends Native { // clGet*Info includes terminating 0 static String infoToString(MemorySegment seg) { - if (false) { - MemoryAddress valp = seg.baseAddress(); + if (true) { + return CLinker.toJavaString(seg); + } else if (false) { + MemoryAddress valp = seg.address(); byte[] val = new byte[(int)(seg.byteSize() - 1)]; for (int i = 0; i < val.length; i++) @@ -290,21 +291,19 @@ public abstract class CLObject extends Native { } protected String getInfoString(T ctx, int id, MethodHandle getInfo) { - try (Allocator a = Memory.stack()) { + try (ResourceScope a = ResourceScope.newConfinedScope()) { MemorySegment seg = getInfoAny(ctx, id, getInfo, a); return infoToString(seg); } } protected long[] getInfoLongV(T ctx, int id, MethodHandle getInfo) { - try (Allocator a = Memory.stack()) { + try (ResourceScope a = ResourceScope.newConfinedScope()) { 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 < list.length; i++) - list[i] = getLong(val, i); + MemorySegment.ofArray(list).copyFrom(valp); return list; } catch (RuntimeException | Error t) { @@ -315,9 +314,10 @@ public abstract class CLObject extends Native { } // indexed version - protected MemoryAddress getInfo(int index, int id, MethodHandle getInfo, Allocator a, long size) throws CLRuntimeException { + protected MemorySegment getInfo(int index, int id, MethodHandle getInfo, ResourceScope a, long size) throws CLRuntimeException { try { - MemoryAddress addr = a.alloca(size); + // TODO: type for alignment + MemorySegment addr = MemorySegment.allocateNative(size, 16, a); int res = (int)getInfo.invokeExact(addr(), index, id, size, addr, MemoryAddress.NULL); if (res != 0) @@ -332,30 +332,30 @@ public abstract class CLObject extends Native { } protected int getInfoInt(int index, int id, MethodHandle getInfo) { - try (Allocator a = Memory.stack()) { - return getInt(getInfo(index, id, getInfo, a, 4)); + try (ResourceScope a = ResourceScope.newConfinedScope()) { + return MemoryAccess.getInt(getInfo(index, id, getInfo, a, 4)); } } protected long getInfoLong(int index, int id, MethodHandle getInfo) { - try (Allocator a = Memory.stack()) { - return getLong(getInfo(index, id, getInfo, a, 8)); + try (ResourceScope a = ResourceScope.newConfinedScope()) { + return MemoryAccess.getLong(getInfo(index, id, getInfo, a, 8)); } } - protected MemorySegment getInfoAny(int index, int id, MethodHandle getInfo, Allocator a) throws CLRuntimeException { + protected MemorySegment getInfoAny(int index, int id, MethodHandle getInfo, ResourceScope a) throws CLRuntimeException { try { - MemoryAddress sizep = a.alloca(8); + MemorySegment sizep = MemorySegment.allocateNative(CLinker.C_LONG, a); MemorySegment valp; long size; int res; - res = (int)getInfo.invokeExact(addr(), index, id, 0L, MemoryAddress.NULL, sizep); + res = (int)getInfo.invokeExact(addr(), index, id, 0L, MemoryAddress.NULL, sizep.address()); - size = getLong(sizep); - valp = a.allocs(size); + size = MemoryAccess.getLong(sizep); + valp = MemorySegment.allocateNative(size, a); - res = (int)getInfo.invokeExact(addr(), index, id, size, valp.baseAddress(), sizep); + res = (int)getInfo.invokeExact(addr(), index, id, size, valp.address(), sizep.address()); if (res != 0) throw new CLRuntimeException(res); @@ -369,7 +369,7 @@ public abstract class CLObject extends Native { } protected String getInfoString(int index, int id, MethodHandle getInfo) { - try (Allocator a = Memory.stack()) { + try (ResourceScope a = ResourceScope.newConfinedScope()) { MemorySegment valp = getInfoAny(index, id, getInfo, a); return infoToString(valp); } diff --git a/src/notzed.zcl/classes/au/notzed/zcl/CLPlatform.java b/src/notzed.zcl/classes/au/notzed/zcl/CLPlatform.java index e6530ad..dec2b75 100644 --- a/src/notzed.zcl/classes/au/notzed/zcl/CLPlatform.java +++ b/src/notzed.zcl/classes/au/notzed/zcl/CLPlatform.java @@ -90,20 +90,22 @@ public class CLPlatform extends CLObject { * @throws CLRuntimeException */ public static CLPlatform[] getPlatforms() /*throws CLRuntimeException*/ { - try (Allocator frame = Memory.stack()) { - MemoryAddress lenp = frame.alloca(8); - MemoryAddress list; + try (ResourceScope scope = ResourceScope.newConfinedScope()) { + MemorySegment lenp = MemorySegment.allocateNative(CLinker.C_INT, scope); + MemorySegment list; int len; int res; - res = (int)clGetPlatformIDs.invokeExact(0, MemoryAddress.NULL, lenp); + res = (int)clGetPlatformIDs.invokeExact(0, MemoryAddress.NULL, lenp.address()); if (res != 0) throw new CLRuntimeException(res); - len = Native.getInt(lenp); - list = frame.alloca(8 * len); + len = MemoryAccess.getInt(lenp); + list = MemorySegment.allocateNative(MemoryLayout.sequenceLayout(len, CLinker.C_POINTER), scope); - res = (int)clGetPlatformIDs.invokeExact(len, list, lenp); + res = (int)clGetPlatformIDs.invokeExact(len, list.address(), lenp.address()); + if (res != 0) + throw new CLRuntimeException(res); return toObjectV(list, new CLPlatform[len], CLPlatform::new); } catch (RuntimeException | Error t) { @@ -122,23 +124,25 @@ public class CLPlatform extends CLObject { * @return List of matching devices in this platform. * @throws CLRuntimeException */ - public CLDevice []getDevices(long type) /*throws CLRuntimeException*/ { - try (Allocator frame = Memory.stack()) { - MemoryAddress lenp = frame.alloca(8); - MemoryAddress list; + public CLDevice[] getDevices(long type) /*throws CLRuntimeException*/ { + try (ResourceScope scope = ResourceScope.newConfinedScope()) { + MemorySegment lenp = MemorySegment.allocateNative(CLinker.C_INT, scope); + MemorySegment list; int res, len; - res = (int)clGetDeviceIDs.invokeExact(addr(), type, 0, MemoryAddress.NULL, lenp); + res = (int)clGetDeviceIDs.invokeExact(addr(), type, 0, MemoryAddress.NULL, lenp.address()); 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); + len = MemoryAccess.getInt(lenp); + list = MemorySegment.allocateNative(MemoryLayout.sequenceLayout(len, CLinker.C_POINTER), scope); - res = (int)clGetDeviceIDs.invokeExact(addr(), type, len, list, lenp); + res = (int)clGetDeviceIDs.invokeExact(addr(), type, len, list.address(), lenp.address()); + if (res != 0) + throw new CLRuntimeException(res); return toObjectV(list, new CLDevice[len], (d) -> new CLDevice(d, this)); } catch (RuntimeException | Error t) { @@ -160,10 +164,10 @@ public class CLPlatform extends CLObject { CLDevice best = null; double bestScore = 0; - for (CLPlatform p : platforms) { + for (CLPlatform p: platforms) { CLDevice[] devs = p.getDevices(type); - for (CLDevice d : devs) { + for (CLDevice d: devs) { double score = scoreFunc.applyAsDouble(d); if (best == null || score > bestScore) { @@ -207,6 +211,7 @@ public class CLPlatform extends CLObject { /** * Calls clGetExtensionFunctionAddressForPlatform.If not available then * it falls back to clGetExtensionFunctionAddress. + * * @param name extension function name * @return MemoryAddress of function entry point, or MemoryAddress.NULL. */ @@ -228,7 +233,7 @@ public class CLPlatform extends CLObject { /** * Get the platform api versiom. - * + *

* This may be compared to the version constants * {@link #VERSION_1_0}, {@link #VERSION_1_1}, and so on. * @@ -295,17 +300,17 @@ public class CLPlatform extends CLObject { /** * Retrieve an extension by extension id. - * + *

* The extension id must be one of the supported extensions. * This is called internally by the class/method to which the - * extension applies. It should check the published list of + * extension applies. It should check the published list of * extensions for validity and throw * UnsupportedOperationException if it isn't. - * + *

* TODO: pass the class, constructor.invoke? id = getfield()? */ @SuppressWarnings("unchecked") - T getExtension(int id, Function create) { + T getExtension(int id, Function create) { synchronized (extension) { T x = (T)extension[id]; @@ -315,4 +320,12 @@ public class CLPlatform extends CLObject { return x; } } + + public static void main(String[] args) { + + for (CLPlatform p: getPlatforms()) { + System.out.println(p.getName()); + p.getDevices(CL_DEVICE_TYPE_ALL); + } + } } diff --git a/src/notzed.zcl/classes/au/notzed/zcl/CLProgram.java b/src/notzed.zcl/classes/au/notzed/zcl/CLProgram.java index a5dc91f..b8104cd 100644 --- a/src/notzed.zcl/classes/au/notzed/zcl/CLProgram.java +++ b/src/notzed.zcl/classes/au/notzed/zcl/CLProgram.java @@ -21,7 +21,6 @@ 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; @@ -57,13 +56,13 @@ public class CLProgram extends CLObject { * @throws CLException */ public void buildProgram(CLDevice[] devices, String options, CLNotify notify) throws CLException { - try (Allocator frame = Memory.stack(); + try(ResourceScope frame = ResourceScope.newConfinedScope(); Callback> call = CLNotify.call(notify, (x) -> new CLProgram(x, getObjectPlatform()))) { - MemoryAddress pdevs = toAddrV(frame, devices); - MemoryAddress poptions = toByteV(frame, options); + MemorySegment pdevs = toAddrV(frame, devices); + MemorySegment poptions = options != null ? CLinker.toCString(options, frame) : MemorySegment.globalNativeSegment(); int res; - res = clBuildProgram(addr(), devices.length, pdevs, poptions, call.addr(), MemoryAddress.NULL); + res = clBuildProgram(addr(), devices.length, pdevs.address(), poptions.address(), call.addr(), MemoryAddress.NULL); if (res != 0) throw new CLException(res); } catch (CLException | RuntimeException | Error t) { @@ -75,7 +74,7 @@ public class CLProgram extends CLObject { public void buildProgram(CLDevice[] devices, String options) throws CLException { CLNotify notify = (CLProgram source) -> { - for (CLDevice d : devices) { + for (CLDevice d: devices) { int status = source.getBuildStatus(d); if (status != 0) { System.err.printf("Build status: %d\n", status); @@ -118,17 +117,15 @@ public class CLProgram extends CLObject { throw new IllegalArgumentException(); } - try (Allocator frame = Memory.stack(); + try(ResourceScope frame = ResourceScope.newConfinedScope(); Callback> call = CLNotify.call(notify, (x) -> new CLProgram(x, getObjectPlatform()))) { - 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); + MemorySegment cdevs = toAddrV(frame, devices); + MemorySegment poptions = CLinker.toCString(options, frame); + MemorySegment cheaders = toAddrV(frame, headers); + MemorySegment cnames = Native.toCStringV(header_names, frame); int res; - MemoryAddress ck; - res = clCompileProgram(addr(), devices.length, cdevs, coptions, nheaders, cheaders, cnames, call.addr(), MemoryAddress.NULL); + res = clCompileProgram(addr(), devices.length, cdevs.address(), poptions.address(), nheaders, cheaders.address(), cnames.address(), call.addr(), MemoryAddress.NULL); if (res != 0) throw new CLException(res); } catch (CLException | RuntimeException | Error t) { @@ -147,15 +144,14 @@ public class CLProgram extends CLObject { * @throws CLRuntimeException */ public CLKernel createKernel(String name) throws CLException { - try (Allocator frame = Memory.stack()) { - MemoryAddress pres = frame.alloca(8); - MemoryAddress pname = toByteV(frame, name); + try(ResourceScope frame = ResourceScope.newConfinedScope()) { + MemorySegment pres = MemorySegment.allocateNative(CLinker.C_INT, frame); + MemorySegment pname = CLinker.toCString(name, frame); int res; MemoryAddress ck; - ck = clCreateKernel(addr(), pname, pres); - res = getInt(pres); - if (res != 0) + ck = clCreateKernel(addr(), pname.address(), pres.address()); + if ((res = MemoryAccess.getInt(pres)) != 0) throw new CLException(res); return resolve(ck, (x) -> new CLKernel(x, getObjectPlatform())); } catch (CLException | RuntimeException | Error t) { @@ -174,16 +170,16 @@ public class CLProgram extends CLObject { 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); + try(ResourceScope frame = ResourceScope.newConfinedScope()) { + MemorySegment csize = MemorySegment.allocateNative(CLinker.C_INT, frame); + MemorySegment ckern = Native.allocAddrV(frame, size); int res; - res = clCreateKernelsInProgram(addr(), size, ckern, csize); + res = clCreateKernelsInProgram(addr(), size, ckern.address(), csize.address()); if (res != 0) throw new CLRuntimeException(); - size = getInt(csize); + size = MemoryAccess.getInt(csize); return Native.toObjectV(ckern, new CLKernel[size], (x) -> new CLKernel(x, getObjectPlatform())); } catch (RuntimeException | Error t) { throw t; @@ -210,31 +206,30 @@ public class CLProgram extends CLObject { /* This is unnecessary since getBinaries() is the only thing that needs it 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(sizes.length * 8); + try (ResourceScope frame = ResourceScope.newConfinedScope()) { + MemorySegment seg = MemorySegment.allocateNative(size, frame); + MemoryAddress data = seg.address(); + MemorySegment cptrs = Native.allocAddrV(frame, sizes.length); long off = 0; int res; - for (int i=0;i MemoryAddress toNative(Allocator frame, T[] properties) { + static MemorySegment toNative(ResourceScope frame, T[] properties) { if (properties != null && properties.length > 0) { - MemoryAddress addr = frame.alloca(getSize(properties) * 8); + MemorySegment addr = MemorySegment.allocateNative(getSize(properties) * 8, 8, frame); int i = 0; for (CLProperty p: properties) i = p.toLong(addr, i); - Native.setLong(addr, i, 0L); + MemoryAccess.setLongAtIndex(addr, i, 0L); return addr; } else { - MemoryAddress addr = frame.alloca(8); - Native.setLong(addr, 0L); + MemorySegment addr = MemorySegment.allocateNative(8, 8, frame); + MemoryAccess.setLong(addr, 0L); return addr; - - //return MemoryAddress.NULL; } } 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;) { + for (int i = 0;(tag = MemoryAccess.getLongAtIndex(seg, 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++); + long value = MemoryAccess.getLongAtIndex(seg, i++); list.add(create.apply(tag, value)); } diff --git a/src/notzed.zcl/classes/au/notzed/zcl/EventInfo.java b/src/notzed.zcl/classes/au/notzed/zcl/EventInfo.java index e6c68bf..4d59123 100644 --- a/src/notzed.zcl/classes/au/notzed/zcl/EventInfo.java +++ b/src/notzed.zcl/classes/au/notzed/zcl/EventInfo.java @@ -18,8 +18,6 @@ package au.notzed.zcl; import jdk.incubator.foreign.*; -import au.notzed.zcl.CLEventList; -import api.Allocator; /** * Simplify wait/event handling. @@ -34,7 +32,8 @@ class EventInfo { public final MemoryAddress wait; public final MemoryAddress event; - public EventInfo(Allocator frame, CLEventList waiters, CLEventList events) { + // TODO: frame isn't used, maybe it should be removed? if so check callers where scope isn't doing anyting + public EventInfo(ResourceScope frame, CLEventList waiters, CLEventList events) { nwait = waiters != null ? waiters.size() : 0; wait = nwait > 0 ? waiters.slots() : MemoryAddress.NULL; event = events != null ? events.currentSlot() : MemoryAddress.NULL; diff --git a/src/notzed.zcl/classes/module-info.java b/src/notzed.zcl/classes/module-info.java index 355b012..6483e0b 100644 --- a/src/notzed.zcl/classes/module-info.java +++ b/src/notzed.zcl/classes/module-info.java @@ -21,7 +21,7 @@ * Implements a java-friendly binding to OpenCL. */ module notzed.zcl { - requires transitive jdk.incubator.foreign; + requires jdk.incubator.foreign; exports au.notzed.zcl; diff --git a/src/notzed.zcl/gen/generate-api b/src/notzed.zcl/gen/generate-api index f713506..aaf6954 100755 --- a/src/notzed.zcl/gen/generate-api +++ b/src/notzed.zcl/gen/generate-api @@ -984,7 +984,8 @@ END if (@libs) { # static function handle init print $dst "\tstatic {\n"; - print $dst "\t\tLibraryLookup[] ctx = Native.loadLibraries(libraries);\n"; + print $dst "\t\tNative.loadLibraries(libraries);\n"; + print $dst "\t\tSymbolLookup ctx = SymbolLookup.loaderLookup();\n"; } else { # address factory handle init print $dst "\tpublic $class{name}(Function ctx) {\n"; diff --git a/src/notzed.zcl/tests/au/notzed/zcl/CLBufferTest.java b/src/notzed.zcl/tests/au/notzed/zcl/CLBufferTest.java index 2359ee0..5689eac 100644 --- a/src/notzed.zcl/tests/au/notzed/zcl/CLBufferTest.java +++ b/src/notzed.zcl/tests/au/notzed/zcl/CLBufferTest.java @@ -1,4 +1,3 @@ - package au.notzed.zcl; import org.junit.*; @@ -18,6 +17,7 @@ import java.nio.ByteOrder; */ public class CLBufferTest { + boolean haveCL() { CLPlatform[] list = CLPlatform.getPlatforms(); return list != null && list.length > 0; @@ -33,10 +33,11 @@ public class CLBufferTest { org.junit.Assume.assumeTrue(haveCL()); plat = CLPlatform.getPlatforms()[0]; - devs = new CLDevice[] { plat.getDevices(CL_DEVICE_TYPE_ALL)[0] }; + devs = new CLDevice[]{plat.getDevices(CL_DEVICE_TYPE_ALL)[0]}; cl = CLContext.createContext(null, devs); q = cl.createCommandQueue(devs[0], 0); } + @After public void shutdown() { CLObject.release(q, cl); @@ -79,8 +80,7 @@ public class CLBufferTest { long[] flags = { CL_MEM_READ_WRITE, CL_MEM_WRITE_ONLY, - CL_MEM_READ_ONLY, - }; + CL_MEM_READ_ONLY,}; for (long flag: flags) { CLBuffer b = cl.createBuffer(flag, 1024); @@ -96,28 +96,25 @@ public class CLBufferTest { byte[] filla = "opencl ftw!".getBytes(); static void fillSegment(MemorySegment seg, byte[] seq) { - MemoryAddress add = seg.baseAddress(); - for (long i=0;i= CLPlatform.VERSION_1_2); - byte[] data = new byte[] { 1, 2, 3, 4 }; + byte[] data = new byte[]{1, 2, 3, 4}; - try (MemorySegment seg = MemorySegment.allocateNative(1024, 8)) { + try (ResourceScope scope = ResourceScope.newConfinedScope()) { + MemorySegment seg = MemorySegment.allocateNative(1024, 8, scope); CLBuffer b = cl.createBuffer(0, 1024); q.enqueueFillBuffer(b, data, 0, 256, null, null); q.enqueueReadBuffer(b, true, 0, seg.byteSize(), seg, null, null); boolean same = true; - MemoryAddress add = seg.baseAddress(); - for (int i=0;same && i<1024;i++) { + MemoryAddress add = seg.address(); + for (int i = 0; same && i < 1024; i++) { same = Native.getByte(add, i) == data[i % data.length]; } diff --git a/src/notzed.zcl/tests/au/notzed/zcl/CLEventTest.java b/src/notzed.zcl/tests/au/notzed/zcl/CLEventTest.java index ad2118b..125e405 100644 --- a/src/notzed.zcl/tests/au/notzed/zcl/CLEventTest.java +++ b/src/notzed.zcl/tests/au/notzed/zcl/CLEventTest.java @@ -1,4 +1,3 @@ - package au.notzed.zcl; import org.junit.*; @@ -12,6 +11,7 @@ import api.*; CLEvent and CLEventList tests */ public class CLEventTest { + boolean haveCL() { CLPlatform[] list = CLPlatform.getPlatforms(); return list != null && list.length > 0; @@ -27,10 +27,11 @@ public class CLEventTest { org.junit.Assume.assumeTrue(haveCL()); plat = CLPlatform.getPlatforms()[0]; - devs = new CLDevice[] { plat.getDevices(CL_DEVICE_TYPE_ALL)[0] }; + devs = new CLDevice[]{plat.getDevices(CL_DEVICE_TYPE_ALL)[0]}; cl = CLContext.createContext(null, devs); q = cl.createCommandQueue(devs[0], 0); } + @After public void shutdown() { q.release(); @@ -63,7 +64,7 @@ public class CLEventTest { * I think this should pass but it times out on Mesa 19. */ @Ignore - @Test(timeout=1000) + @Test(timeout = 1000) public void testUserWait() throws Exception { org.junit.Assume.assumeTrue(plat.getAPIVersion() >= CLPlatform.VERSION_1_1); System.out.println("UserEvent wait"); @@ -71,9 +72,10 @@ public class CLEventTest { CLEvent ev = cl.createUserEvent(); CLBuffer mem = cl.createBuffer(0, 64); - try (MemorySegment seg = MemorySegment.allocateNative(64, 8)) { + try (ResourceScope scope = ResourceScope.newConfinedScope(); CLEventList list = new CLEventList(1); - CLEventList wait = new CLEventList(1); + CLEventList wait = new CLEventList(1)) { + MemorySegment seg = MemorySegment.allocateNative(64, 8, scope); wait.add(ev); assertEquals(ev, wait.get(0)); @@ -101,8 +103,9 @@ public class CLEventTest { System.out.println("event callback, state"); CLBuffer mem = cl.createBuffer(0, 64); - try (MemorySegment seg = MemorySegment.allocateNative(64, 8)) { - CLEventList list = new CLEventList(1); + try (ResourceScope scope = ResourceScope.newConfinedScope(); + CLEventList list = new CLEventList(1)) { + MemorySegment seg = MemorySegment.allocateNative(64, 8, scope); CLEvent ev; q.enqueueReadBuffer(mem, true, 0, 64, seg, null, list); @@ -113,17 +116,17 @@ public class CLEventTest { assertEquals(CL_COMMAND_READ_BUFFER, ev.getCommandType()); ev.setEventCallback(CL_SUBMITTED, (e, s) -> { - assertTrue(s <= CL_SUBMITTED); - count[0] += 1; - }); + assertTrue(s <= CL_SUBMITTED); + count[0] += 1; + }); ev.setEventCallback(CL_RUNNING, (e, s) -> { - assertTrue(s <= CL_RUNNING); - count[0] += 1; - }); + assertTrue(s <= CL_RUNNING); + count[0] += 1; + }); ev.setEventCallback(CL_COMPLETE, (e, s) -> { - assertTrue(s <= CL_COMPLETE); - count[0] += 1; - }); + assertTrue(s <= CL_COMPLETE); + count[0] += 1; + }); q.finish(); @@ -181,7 +184,8 @@ public class CLEventTest { assertEquals(IllegalStateException.class, x.getClass()); CLBuffer mem = cl.createBuffer(0, 64); - try (MemorySegment seg = MemorySegment.allocateNative(64, 8)) { + try (ResourceScope scope = ResourceScope.newConfinedScope()) { + MemorySegment seg = MemorySegment.allocateNative(64, 8, scope); x = null; q.enqueueReadBuffer(mem, false, 0, 64, seg, null, list); } catch (Throwable t) { @@ -194,9 +198,10 @@ public class CLEventTest { public void testMulti() throws Exception { System.out.println("multi"); CLBuffer mem = cl.createBuffer(0, 64); - try (MemorySegment seg = MemorySegment.allocateNative(64, 8); + try (ResourceScope scope = ResourceScope.newConfinedScope(); CLEventList list = new CLEventList(2); CLEventList last = new CLEventList(1)) { + MemorySegment seg = MemorySegment.allocateNative(64, 8, scope); q.enqueueReadBuffer(mem, false, 0, 64, seg, null, list); assertEquals(1, list.size()); @@ -220,12 +225,13 @@ public class CLEventTest { } } - @Test(timeout=1000) + @Test(timeout = 1000) public void testMultiWait() throws Exception { System.out.println("multi wait"); CLBuffer mem = cl.createBuffer(0, 64); - try (MemorySegment seg = MemorySegment.allocateNative(64, 8); + try (ResourceScope scope = ResourceScope.newConfinedScope(); CLEventList list = new CLEventList(3)) { + MemorySegment seg = MemorySegment.allocateNative(64, 8, scope); q.enqueueReadBuffer(mem, false, 0, 64, seg, null, list); assertEquals(1, list.size());