Move api version to CLObject and a constructor try-copy-apiversion
authorNot Zed <notzed@gmail.com>
Mon, 27 Jan 2020 09:40:20 +0000 (20:10 +1030)
committerNot Zed <notzed@gmail.com>
Mon, 27 Jan 2020 09:40:20 +0000 (20:10 +1030)
19 files changed:
src/notzed.zcl/classes/au/notzed/zcl/CLBuffer.java
src/notzed.zcl/classes/au/notzed/zcl/CLCommandQueue.java
src/notzed.zcl/classes/au/notzed/zcl/CLContext.java
src/notzed.zcl/classes/au/notzed/zcl/CLDevice.java
src/notzed.zcl/classes/au/notzed/zcl/CLEvent.java
src/notzed.zcl/classes/au/notzed/zcl/CLEventList.java
src/notzed.zcl/classes/au/notzed/zcl/CLEventNotify.java
src/notzed.zcl/classes/au/notzed/zcl/CLExtendable.java
src/notzed.zcl/classes/au/notzed/zcl/CLExtension.java
src/notzed.zcl/classes/au/notzed/zcl/CLImage.java
src/notzed.zcl/classes/au/notzed/zcl/CLKernel.java
src/notzed.zcl/classes/au/notzed/zcl/CLMemory.java
src/notzed.zcl/classes/au/notzed/zcl/CLObject.java
src/notzed.zcl/classes/au/notzed/zcl/CLPipe.java
src/notzed.zcl/classes/au/notzed/zcl/CLPlatform.java
src/notzed.zcl/classes/au/notzed/zcl/CLProgram.java
src/notzed.zcl/classes/au/notzed/zcl/CLSampler.java
src/notzed.zcl/classes/au/notzed/zcl/khr/GLEvent.java
src/notzed.zcl/classes/au/notzed/zcl/khr/GLSharing.java

index a24c794..6397f0f 100644 (file)
@@ -25,12 +25,12 @@ import java.nio.ByteBuffer;
  */
 public class CLBuffer extends CLMemory {
 
-       public CLBuffer(MemoryAddress p) {
-               this(p, null);
+       public CLBuffer(MemoryAddress p, int apiVersion) {
+               this(p, apiVersion, null);
        }
 
-       CLBuffer(MemoryAddress p, MemorySegment seg) {
-               super(p, seg);
+       CLBuffer(MemoryAddress p, int apiVersion, MemorySegment seg) {
+               super(p, apiVersion, seg);
        }
 
        static void release(MemoryAddress p) {
index 063b480..3530e85 100644 (file)
@@ -54,12 +54,8 @@ import java.util.function.Function;
  */
 public class CLCommandQueue extends CLExtendable {
 
-       public CLCommandQueue(MemoryAddress p) {
-               super(p);
-       }
-
-       static CLCommandQueue create(MemoryAddress p) {
-               return Native.resolve(p, CLCommandQueue::new);
+       public CLCommandQueue(MemoryAddress p, int apiVersion) {
+               super(p, apiVersion);
        }
 
        private static void release(MemoryAddress p) {
@@ -1895,11 +1891,11 @@ public class CLCommandQueue extends CLExtendable {
        }
 
        public CLContext getContext() {
-               return getInfoAny(CL_QUEUE_CONTEXT, clGetCommandQueueInfo, CLContext::new);
+               return getInfoAny(CL_QUEUE_CONTEXT, clGetCommandQueueInfo, (c) -> new CLContext(c, getAPIVersion()));
        }
 
        public CLDevice getDevice() {
-               return getInfoAny(CL_QUEUE_DEVICE, clGetCommandQueueInfo, CLDevice::new);
+               return getInfoAny(CL_QUEUE_DEVICE, clGetCommandQueueInfo, (d) -> new CLDevice(d, apiVersion));
        }
 
        public long getProperties() {
@@ -1915,8 +1911,8 @@ public class CLCommandQueue extends CLExtendable {
        }
 
        @Override
-       protected CLPlatform initPlatform() {
-               return getDevice().platform;
+       protected CLPlatform findPlatform() {
+               return getDevice().getPlatform();
        }
 
        //protected GLSharing getGLSharing() {
index 564964c..8125fe3 100644 (file)
@@ -41,20 +41,16 @@ public class CLContext extends CLExtendable {
         */
        final Callback<CLContextNotify> notify;
 
-       public CLContext(MemoryAddress p) {
-               super(p);
+       public CLContext(MemoryAddress p, int apiVersion) {
+               super(p, apiVersion);
                this.notify = null;
        }
 
-       CLContext(MemoryAddress p, Callback<CLContextNotify> notify) {
-               super(p);
+       CLContext(MemoryAddress p, int apiVersion, Callback<CLContextNotify> notify) {
+               super(p, apiVersion);
                this.notify = notify;
        }
 
-       static CLContext create(MemoryAddress p) {
-               return Native.resolve(p, CLContext::new);
-       }
-
        private static void release(MemoryAddress p) {
                try {
                        clReleaseContext(p);
@@ -80,6 +76,11 @@ public class CLContext extends CLExtendable {
                return clGetContextInfo;
        }
 
+       @Override
+       protected CLPlatform findPlatform() {
+               return getDevices()[0].getPlatform();
+       }
+
        /**
         * Creates a property representing CL_CONTEXT_PLATFORM.
         *
@@ -128,7 +129,7 @@ public class CLContext extends CLExtendable {
                        if (res != 0)
                                throw new CLRuntimeException(res);
 
-                       return Native.resolve(cl, CLContext::new);
+                       return Native.resolve(cl, (c) -> new CLContext(c, devices[0].getAPIVersion()));
                } catch (RuntimeException | Error t) {
                        throw t;
                } catch (Throwable t) {
@@ -167,7 +168,7 @@ public class CLContext extends CLExtendable {
                        if (res != 0)
                                throw new CLRuntimeException(res);
 
-                       return Native.resolve(cl, (p) -> new CLContext(p, call));
+                       return Native.resolve(cl, (p) -> new CLContext(p, 0, call));
                } catch (RuntimeException | Error t) {
                        throw t;
                } catch (Throwable t) {
@@ -197,7 +198,7 @@ public class CLContext extends CLExtendable {
                        if (res != 0)
                                throw new CLRuntimeException(res);
 
-                       return Native.resolve(q, CLCommandQueue::new);
+                       return Native.resolve(q, (c) -> new CLCommandQueue(c, dev.getAPIVersion()));
                } catch (RuntimeException | Error t) {
                        throw t;
                } catch (Throwable t) {
@@ -230,7 +231,7 @@ public class CLContext extends CLExtendable {
                        if (res != 0)
                                throw new CLRuntimeException(res);
 
-                       return Native.resolve(q, CLCommandQueue::new);
+                       return Native.resolve(q, (c) -> new CLCommandQueue(c, getAPIVersion()));
                } catch (RuntimeException | Error t) {
                        throw t;
                } catch (Throwable t) {
@@ -303,9 +304,9 @@ public class CLContext extends CLExtendable {
                                throw new CLRuntimeException(res);
 
                        if (hostseg != null && (flags & CL_MEM_USE_HOST_PTR) != 0)
-                               return resolve(pbuffer, (x) -> new CLBuffer(x, hostseg));
+                               return resolve(pbuffer, (x) -> new CLBuffer(x, getAPIVersion(), hostseg));
                        else
-                               return resolve(pbuffer, CLBuffer::new);
+                               return resolve(pbuffer, (x) -> new CLBuffer(x, getAPIVersion()));
                } catch (RuntimeException | Error t) {
                        throw t;
                } catch (Throwable t) {
@@ -467,9 +468,9 @@ public class CLContext extends CLExtendable {
                                throw new CLRuntimeException(res);
 
                        if (hostseg != null && (flags & CL_MEM_USE_HOST_PTR) != 0)
-                               return resolve(ci, (x) -> new CLImage(x, hostseg));
+                               return resolve(ci, (x) -> new CLImage(x, getAPIVersion(), hostseg));
                        else
-                               return resolve(ci, CLImage::new);
+                               return resolve(ci, (x) -> new CLImage(x, getAPIVersion()));
                } catch (RuntimeException | Error t) {
                        throw t;
                } catch (Throwable t) {
@@ -554,7 +555,7 @@ public class CLContext extends CLExtendable {
                        if (res != 0)
                                throw new CLRuntimeException(res);
 
-                       return resolve(cp, CLPipe::new);
+                       return resolve(cp, (p) -> new CLPipe(p, getAPIVersion()));
                } catch (RuntimeException | Error t) {
                        throw t;
                } catch (Throwable t) {
@@ -650,7 +651,7 @@ public class CLContext extends CLExtendable {
                        if (res != 0)
                                throw new CLRuntimeException(res);
 
-                       return resolve(cs, CLSampler::new);
+                       return resolve(cs, (s) -> new CLSampler(s, getAPIVersion()));
                } catch (RuntimeException | Error t) {
                        throw t;
                } catch (Throwable t) {
@@ -681,7 +682,7 @@ public class CLContext extends CLExtendable {
                        if (res != 0)
                                throw new CLRuntimeException(res);
 
-                       return resolve(cs, CLSampler::new);
+                       return resolve(cs, (s) -> new CLSampler(s, getAPIVersion()));
                } catch (RuntimeException | Error t) {
                        throw t;
                } catch (Throwable t) {
@@ -740,7 +741,7 @@ public class CLContext extends CLExtendable {
                        if (res != 0)
                                throw new CLException(res);
 
-                       return resolve(cp, CLProgram::new);
+                       return resolve(cp, (p) -> new CLProgram(p, getAPIVersion()));
                } catch (CLException | RuntimeException | Error t) {
                        throw t;
                } catch (Throwable t) {
@@ -795,7 +796,7 @@ public class CLContext extends CLExtendable {
                        if (res != 0)
                                throw new CLException(res);
 
-                       return resolve(cp, CLProgram::new);
+                       return resolve(cp, (p) -> new CLProgram(p, getAPIVersion()));
                } catch (CLException | RuntimeException | Error t) {
                        throw t;
                } catch (Throwable t) {
@@ -847,7 +848,7 @@ public class CLContext extends CLExtendable {
                                        status[i] = getInt(cstatus, i);
                        }
 
-                       return resolve(cp, CLProgram::new);
+                       return resolve(cp, (p) -> new CLProgram(p, getAPIVersion()));
                } catch (CLException | RuntimeException | Error t) {
                        throw t;
                } catch (Throwable t) {
@@ -881,7 +882,7 @@ public class CLContext extends CLExtendable {
                        if (res != 0)
                                throw new CLException(res);
 
-                       return resolve(cp, CLProgram::new);
+                       return resolve(cp, (p) -> new CLProgram(p, getAPIVersion()));
                } catch (CLException | RuntimeException | Error t) {
                        throw t;
                } catch (Throwable t) {
@@ -906,7 +907,7 @@ public class CLContext extends CLExtendable {
                requireAPIVersion(CLPlatform.VERSION_1_2);
 
                try (Allocator frame = Memory.stack();
-                    Callback<CLNotify<CLProgram>> cnotify = CLNotify.call(notify, CLProgram::new)) {
+                       Callback<CLNotify<CLProgram>> cnotify = CLNotify.call(notify, (p)-> new CLProgram(p, devices[0].getAPIVersion()))) {
                        MemoryAddress cdevs = toAddrV(frame, devices);
                        MemoryAddress coptions = toByteV(frame, options);
                        MemoryAddress cprogs = toAddrV(frame, programs);
@@ -920,7 +921,7 @@ public class CLContext extends CLExtendable {
                        if (res != 0)
                                throw new CLException(res);
 
-                       return resolve(cp, CLProgram::new);
+                       return resolve(cp, (p) -> new CLProgram(p, getAPIVersion()));
                } catch (CLException | RuntimeException | Error t) {
                        throw t;
                } catch (Throwable t) {
@@ -950,7 +951,7 @@ public class CLContext extends CLExtendable {
                        if (res != 0)
                                throw new CLException(res);
 
-                       return resolve(ce, CLEvent::new);
+                       return resolve(ce, (c) -> new CLEvent(c, getAPIVersion()));
                } catch (CLException | RuntimeException | Error t) {
                        throw t;
                } catch (Throwable t) {
@@ -973,7 +974,7 @@ public class CLContext extends CLExtendable {
         * @return List of devices.
         */
        public CLDevice[] getDevices() {
-               return getInfoAnyV(CL_CONTEXT_DEVICES, clGetContextInfo, CLDevice::new, CLDevice[]::new);
+               return getInfoAnyV(CL_CONTEXT_DEVICES, clGetContextInfo, (d) -> new CLDevice(d, apiVersion), CLDevice[]::new);
        }
 
        /**
@@ -985,11 +986,6 @@ public class CLContext extends CLExtendable {
                return getInfoPropertyV(CL_CONTEXT_PROPERTIES, clGetContextInfo, CLContextProperty.TagValue::new, CLContextProperty[]::new);
        }
 
-       @Override
-       protected CLPlatform initPlatform() {
-               return getDevices()[0].platform;
-       }
-
        //protected GLSharing getGLSharing() {
        //      return getExtension(GLSharing.class, CLPlatform.cl_khr_gl_sharing);
        //}
index c97d51c..c43ece8 100644 (file)
@@ -26,8 +26,8 @@ import static au.notzed.zcl.CLLib.*;
  */
 public class CLDevice extends CLExtendable {
 
-       public CLDevice(MemoryAddress p) {
-               super(p);
+       public CLDevice(MemoryAddress p, int apiVersion) {
+               super(p, apiVersion);
        }
 
        private static void release(MemoryAddress p) {
@@ -48,7 +48,7 @@ public class CLDevice extends CLExtendable {
        }
 
        @Override
-       protected CLPlatform initPlatform() {
+       protected CLPlatform findPlatform() {
                return getPlatform();
        }
 
@@ -392,7 +392,7 @@ public class CLDevice extends CLExtendable {
        }
 
        public CLDevice getParentDevice() {
-               return getInfoAny(CL_DEVICE_PARENT_DEVICE, clGetDeviceInfo, CLDevice::new);
+               return getInfoAny(CL_DEVICE_PARENT_DEVICE, clGetDeviceInfo, (d) -> new CLDevice(d, getAPIVersion()));
        }
 
        public int getPartitionMaxSubDevices() {
index 201c35c..4e1d280 100644 (file)
@@ -28,25 +28,14 @@ import java.util.ArrayList;
  */
 public class CLEvent extends CLObject {
 
-       /**
-        * Cached and used for api version check
-        */
-       final int apiVersion;
-
        /**
         * This is used to retain a reference for any callback set.
         * There may be multiple.
         */
        ArrayList<Callback<CLEventNotify>> callbacks;
 
-       public CLEvent(MemoryAddress p) {
-               super(p);
-
-               apiVersion = getContext().getAPIVersion();
-       }
-
-       static CLEvent create(MemoryAddress p) {
-               return Native.resolve(p, CLEvent::new);
+       public CLEvent(MemoryAddress p, int apiVersion) {
+               super(p, apiVersion);
        }
 
        private static void release(MemoryAddress p) {
@@ -70,6 +59,11 @@ public class CLEvent extends CLObject {
                return clGetEventInfo;
        }
 
+       @Override
+       protected CLPlatform findPlatform() {
+               return getContext().getDevices()[0].getPlatform();
+       }
+
        /**
         * Call clSetUserEventStatus(this, status).
         * <p>
@@ -80,7 +74,7 @@ public class CLEvent extends CLObject {
         * @since OpenCL 1.1
         */
        public void setUserEventStatus(int status) throws CLRuntimeException {
-               CLPlatform.requireAPIVersion(apiVersion, CLPlatform.VERSION_1_1);
+               requireAPIVersion(CLPlatform.VERSION_1_1);
                try {
                        int res = clSetUserEventStatus(addr(), status);
 
@@ -104,7 +98,7 @@ public class CLEvent extends CLObject {
         * @since OpenCL 1.1
         */
        public void setEventCallback(int type, CLEventNotify notify) throws CLRuntimeException {
-               CLPlatform.requireAPIVersion(apiVersion, CLPlatform.VERSION_1_1);
+               requireAPIVersion(CLPlatform.VERSION_1_1);
 
                Callback<CLEventNotify> callback = CLEventNotify.call(notify);
 
@@ -132,7 +126,7 @@ public class CLEvent extends CLObject {
         * @return
         */
        public CLCommandQueue getCommandQueue() {
-               return getInfoAny(CL_EVENT_COMMAND_QUEUE, clGetEventInfo, CLCommandQueue::new);
+               return getInfoAny(CL_EVENT_COMMAND_QUEUE, clGetEventInfo, (c) -> new CLCommandQueue(c, getAPIVersion()));
        }
 
        /**
@@ -143,7 +137,7 @@ public class CLEvent extends CLObject {
         * @return
         */
        public CLContext getContext() {
-               return getInfoAny(CL_EVENT_CONTEXT, clGetEventInfo, CLContext::new);
+               return getInfoAny(CL_EVENT_CONTEXT, clGetEventInfo, (c) -> new CLContext(c, apiVersion));
        }
 
        /**
index 21a30f8..b99fc78 100644 (file)
@@ -154,7 +154,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(Native.getAddr(cevents, i), (e) -> new CLEvent(e, 0));
                        return ev;
                } else
                        throw new ArrayIndexOutOfBoundsException();
index 95331d1..301097e 100644 (file)
@@ -37,7 +37,7 @@ public interface CLEventNotify {
        static Callback<CLEventNotify> call(CLEventNotify notify) {
                if (notify != null) {
                        return Native.resolve(
-                               Call_pLIpv_v.stub((cevent, status, dummy) -> notify.notify(Native.resolve(cevent, CLEvent::new), status)),
+                               Call_pLIpv_v.stub((cevent, status, dummy) -> notify.notify(Native.resolve(cevent, (e) -> new CLEvent(e, 0)), status)),
                                (p) -> new Callback<>(p, notify));
                } else {
                        return Callback.NULL;
index 44837df..cf3e962 100644 (file)
@@ -21,20 +21,17 @@ import jdk.incubator.foreign.MemoryAddress;
 /**
  * Extendable object. These keep track of the platform and api revision to be
  * able to lookup extension pointers efficiently.
+ * TODO: probably delete this
  */
 public abstract class CLExtendable extends CLObject {
 
-       protected final CLPlatform platform;
-       /**
-        * Copy of platform.apiVersion, cached for faster lookup
-        */
-       final int apiVersion;
+       private CLPlatform platform;
 
-       public CLExtendable(MemoryAddress p) {
-               super(p);
+       public CLExtendable(MemoryAddress p, int apiVersion) {
+               super(p, apiVersion);
 
-               platform = initPlatform();
-               apiVersion = platform.apiVersion;
+               platform = null;
+               //platform = initPlatform();
        }
 
        /**
@@ -43,23 +40,11 @@ public abstract class CLExtendable extends CLObject {
         *
         * @return
         */
-       protected abstract CLPlatform initPlatform();
+       //protected abstract CLPlatform initPlatform();
 
-       public CLPlatform getPlatform() {
-               return platform;
-       }
-
-       public int getAPIVersion() {
-               return apiVersion;
-       }
-
-       public void requireAPIVersion(int version) throws UnsupportedOperationException {
-               CLPlatform.requireAPIVersion(apiVersion, version);
-       }
-
-       public boolean haveAPIVersion(int version) {
-               return apiVersion >= version;
-       }
+       //public CLPlatform findPlatform() {
+       //      return platform;
+       //}
 
        /**
         * Retrieve an extension interface for this object.Used by implementors of
index e4e165e..6f99d77 100644 (file)
@@ -33,8 +33,8 @@ import java.lang.invoke.MethodHandle;
  */
 public abstract class CLExtension extends CLObject {
 
-       protected CLExtension(MemoryAddress p) {
-               super(p);
+       protected CLExtension(MemoryAddress p, int apiVersion) {
+               super(p, apiVersion);
        }
 
        public abstract String getName();
index b255444..bdea4e9 100644 (file)
@@ -24,17 +24,15 @@ import java.lang.invoke.MethodHandle;
 
 /**
  * Interface for cl_image.
- *
- * @param <T> Not used, yet?
  */
-public class CLImage<T> extends CLMemory {
+public class CLImage extends CLMemory {
 
-       public CLImage(MemoryAddress p) {
-               this(p, null);
+       public CLImage(MemoryAddress p, int apiVersion) {
+               this(p, apiVersion, null);
        }
 
-       public CLImage(MemoryAddress p, MemorySegment seg) {
-               super(p, seg);
+       public CLImage(MemoryAddress p, int apiVersion, MemorySegment seg) {
+               super(p, apiVersion, seg);
        }
 
        static void release(MemoryAddress p) {
@@ -79,7 +77,7 @@ public class CLImage<T> extends CLMemory {
        }
 
        public CLBuffer getBuffer() {
-               return getInfoAny(CL_IMAGE_BUFFER, clGetImageInfo, CLBuffer::new);
+               return getInfoAny(CL_IMAGE_BUFFER, clGetImageInfo, (b) -> new CLBuffer(b, getAPIVersion()));
        }
 
        public int getNumMipLevels() {
index 5565491..fc65915 100644 (file)
@@ -27,22 +27,11 @@ import java.lang.invoke.MethodHandle;
 
 /**
  * Interface for cl_kernel.
- * <p>
- * Note although this has api versioning it does not extend CLExtendable for
- * efficiency reasons. There is therefore no run-time checking of api.
  */
 public class CLKernel extends CLObject {
 
-       int apiVersion;
-       
-       CLKernel(MemoryAddress p) {
-               super(p);
-               
-               apiVersion = getContext().getAPIVersion();
-       }
-
-       static CLKernel create(MemoryAddress p) {
-               return Native.resolve(p, CLKernel::new);
+       CLKernel(MemoryAddress p, int apiVersion) {
+               super(p, apiVersion);
        }
 
        private static void release(MemoryAddress p) {
@@ -57,6 +46,11 @@ public class CLKernel extends CLObject {
                return clGetKernelInfo;
        }
 
+       @Override
+       protected CLPlatform findPlatform() {
+               return getContext().getDevices()[0].getPlatform();
+       }
+
        /**
         * Calls clCloneKernel.
         *
@@ -65,17 +59,17 @@ public class CLKernel extends CLObject {
         * @since OpenCL 2.1
         */
        public CLKernel cloneKernel() throws CLRuntimeException {
-               CLPlatform.requireAPIVersion(apiVersion, CLPlatform.VERSION_2_1);
-               
+               requireAPIVersion(CLPlatform.VERSION_2_1);
+
                try (Allocator a = Memory.stack()) {
                        MemoryAddress cres = a.alloca(8);
                        MemoryAddress ck = clCloneKernel(addr(), cres);
                        int res = getInt(cres);
-                       
+
                        if (res != 0)
                                throw new CLRuntimeException(res);
 
-                       return Native.resolve(ck, CLKernel::new);                       
+                       return Native.resolve(ck, (c) -> new CLKernel(c, getAPIVersion()));
                } catch (CLRuntimeException | Error t) {
                        throw t;
                } catch (Throwable t) {
@@ -392,11 +386,11 @@ public class CLKernel extends CLObject {
        }
 
        public CLContext getContext() {
-               return getInfoAny(CL_KERNEL_CONTEXT, clGetKernelInfo, CLContext::new);
+               return getInfoAny(CL_KERNEL_CONTEXT, clGetKernelInfo, (c) -> new CLContext(c, apiVersion));
        }
 
        public CLProgram getProgram() {
-               return getInfoAny(CL_KERNEL_PROGRAM, clGetKernelInfo, CLProgram::new);
+               return getInfoAny(CL_KERNEL_PROGRAM, clGetKernelInfo, (p) -> new CLProgram(p, getAPIVersion()));
        }
 
        public String getAttributes() {
index 0625cbf..707daaf 100644 (file)
@@ -77,8 +77,8 @@ public abstract class CLMemory extends CLObject {
         */
        Callback<CLNotify<CLMemory>> destroyCallback;
 
-       CLMemory(MemoryAddress p, MemorySegment seg) {
-               super(p);
+       CLMemory(MemoryAddress p, int apiVersion, MemorySegment seg) {
+               super(p, apiVersion);
 
                this.seg = seg;
        }
@@ -88,7 +88,7 @@ public abstract class CLMemory extends CLObject {
                return clGetMemObjectInfo;
        }
 
-       public static CLMemory create(MemoryAddress p) {
+       public static CLMemory create(MemoryAddress p, int apiVersion) {
                if (p.offset() == 0)
                        return null;
 
@@ -102,16 +102,16 @@ public abstract class CLMemory extends CLObject {
 
                        switch (type) {
                        case CL_MEM_OBJECT_BUFFER:
-                               return Native.resolve(p, CLBuffer::new);
+                               return Native.resolve(p, (b) -> new CLBuffer(b, apiVersion));
                        case CL_MEM_OBJECT_IMAGE2D:
                        case CL_MEM_OBJECT_IMAGE3D:
                        case CL_MEM_OBJECT_IMAGE2D_ARRAY:
                        case CL_MEM_OBJECT_IMAGE1D:
                        case CL_MEM_OBJECT_IMAGE1D_ARRAY:
                        case CL_MEM_OBJECT_IMAGE1D_BUFFER:
-                               return Native.resolve(p, CLImage::new);
+                               return Native.resolve(p, (b) -> new CLImage(b, apiVersion));
                        case CL_MEM_OBJECT_PIPE:
-                               return Native.resolve(p, CLPipe::new);
+                               return Native.resolve(p, (b) -> new CLPipe(b, apiVersion));
                        default:
                                throw new UnsupportedOperationException();
                        }
@@ -120,7 +120,6 @@ public abstract class CLMemory extends CLObject {
 
        static void release(MemoryAddress p) {
                // note: no way to free the hostSegment, even if we could
-               System.out.println("*** release clmemory");
                try {
                        clReleaseMemObject(p);
                } catch (Throwable t) {
@@ -141,6 +140,10 @@ public abstract class CLMemory extends CLObject {
                super.release();
        }
 
+       protected CLPlatform findPlatform() {
+               return getContext().getDevices()[0].getPlatform();
+       }
+
        /**
         * Call clSetMemObjectDestructorCallback.
         *
@@ -150,12 +153,12 @@ public abstract class CLMemory extends CLObject {
         * @since OpenCL 1.1
         */
        public void setMemObjectDestructorCallback(CLNotify<CLMemory> notify) throws CLException, UnsupportedOperationException {
-               //a bit costly perhaps
-               getContext().requireAPIVersion(CLPlatform.VERSION_1_1);
+               requireAPIVersion(CLPlatform.VERSION_1_1);
 
+               // FIXME: i think this is 'add' not 'set'
                Native.release(destroyCallback);
                if (notify != null) {
-                       destroyCallback = CLNotify.call(notify, CLMemory::create);
+                       destroyCallback = CLNotify.call(notify, (m) -> CLMemory.create(m, getAPIVersion()));
 
                        try {
                                int res = clSetMemObjectDestructorCallback(addr(), destroyCallback.addr(), MemoryAddress.NULL);
@@ -216,7 +219,7 @@ public abstract class CLMemory extends CLObject {
         * @return An interface to the context this memory was created on.
         */
        public CLContext getContext() {
-               return getInfoAny(CL_MEM_CONTEXT, clGetMemObjectInfo, CLContext::new);
+               return getInfoAny(CL_MEM_CONTEXT, clGetMemObjectInfo, (c) -> new CLContext(c, apiVersion));
        }
 
        /**
@@ -225,7 +228,7 @@ public abstract class CLMemory extends CLObject {
         * @return
         */
        public CLBuffer getAssociatedMemObject() {
-               return getInfoAny(CL_MEM_ASSOCIATED_MEMOBJECT, clGetMemObjectInfo, CLBuffer::new);
+               return getInfoAny(CL_MEM_ASSOCIATED_MEMOBJECT, clGetMemObjectInfo, (b) -> new CLBuffer(b, getAPIVersion()));
        }
 
        /**
index ba54975..40127e1 100644 (file)
@@ -45,8 +45,22 @@ import api.Memory;
  */
 public abstract class CLObject extends Native {
 
-       protected CLObject(MemoryAddress p) {
+       /**
+        * Cached copy of platform api version (zcl format)
+        * for any subclasses to quickly determine function
+        * availability.
+        * TODO: maybe it shoud just cache CLPlatform or it's 'parent' object instead?
+        */
+       int apiVersion;
+
+//     protected CLObject(MemoryAddress p) {
+//             super(p);
+//     }
+
+       protected CLObject(MemoryAddress p, int apiVersion) {
                super(p);
+
+               this.apiVersion = apiVersion;
        }
 
        // for now ... mirror the native ones so native isn't exposed?
@@ -60,6 +74,32 @@ public abstract class CLObject extends Native {
                        release(o);
        }
 
+       /**
+        * Get the platform api versiom.
+        *
+        * This may be compared to the version constants
+        * {@link CLPlatform#VERSION_1_0}, {@link CLPlatform#VERSION_1_1}, and so on.
+        *
+        * @return platform api version.
+        */
+       public int getAPIVersion() {
+               return apiVersion != 0 ? apiVersion : findPlatform().getAPIVersion();
+       }
+
+       public void requireAPIVersion(int version) throws UnsupportedOperationException {
+               if (getAPIVersion() < version)
+                       throw new UnsupportedOperationException("Requires version " + ((apiVersion >> 8) & 0xff) + "." + (apiVersion & 0xff));
+       }
+
+       public boolean haveAPIVersion(int version) {
+               return getAPIVersion() >= version;
+       }
+
+       /**
+        * Find the platform this object belongs to.
+        */
+       protected abstract CLPlatform findPlatform();
+
        // new 5-param version
        // this one is static so it can be accessed at creation time
        protected static MemoryAddress getInfo(MemoryAddress self, int id, MethodHandle getInfo, Allocator frame, long size) throws CLRuntimeException {
@@ -108,19 +148,19 @@ public abstract class CLObject extends Native {
        }
 
        // new 5-param version for get any
-       protected MemorySegment getInfoAny(int id, MethodHandle getInfo, Allocator a) throws CLRuntimeException {
+       protected static MemorySegment getInfoAny(MemoryAddress addr, int id, MethodHandle getInfo, Allocator a) throws CLRuntimeException {
                try {
                        MemoryAddress sizep = a.alloca(8);
                        MemorySegment valp;
                        long size;
                        int res;
 
-                       res = (int)getInfo.invokeExact(addr(), id, 0L, MemoryAddress.NULL, sizep);
+                       res = (int)getInfo.invokeExact(addr, id, 0L, MemoryAddress.NULL, sizep);
 
                        size = getLong(sizep);
                        valp = a.allocs(size);
 
-                       res = (int)getInfo.invokeExact(addr(), id, size, valp.baseAddress(), sizep);
+                       res = (int)getInfo.invokeExact(addr, id, size, valp.baseAddress(), sizep);
 
                        if (res != 0)
                                throw new CLRuntimeException(res);
@@ -135,31 +175,31 @@ public abstract class CLObject extends Native {
 
        protected byte[] getInfoByteV(int id, MethodHandle getInfo) {
                try (Allocator a = Memory.stack()) {
-                       return getInfoAny(id, getInfo, a).toByteArray();
+                       return getInfoAny(addr(), id, getInfo, a).toByteArray();
                }
        }
 
        protected String getInfoString(int id, MethodHandle getInfo) {
                try (Allocator a = Memory.stack()) {
-                       return infoToString(getInfoAny(id, getInfo, a));
+                       return infoToString(getInfoAny(addr(), id, getInfo, a));
                }
        }
 
        protected <T extends CLProperty> T[] getInfoPropertyV(int id, MethodHandle getInfo, BiFunction<Long, Long, T> create, IntFunction<T[]> createArray) {
                try (Allocator a = Memory.stack()) {
-                       return CLProperty.fromNative(getInfoAny(id, getInfo, a), create, createArray);
+                       return CLProperty.fromNative(getInfoAny(addr(), id, getInfo, a), create, createArray);
                }
        }
 
        protected long[] getInfoLongV(int id, MethodHandle getInfo) {
                try (Allocator a = Memory.stack()) {
-                       return Native.toLongV(getInfoAny(id, getInfo, a));
+                       return Native.toLongV(getInfoAny(addr(), id, getInfo, a));
                }
        }
 
        protected <T extends CLObject> T[] getInfoAnyV(int id, MethodHandle getInfo, Function<MemoryAddress, T> create, IntFunction<T[]> createArray) {
                try (Allocator a = Memory.stack()) {
-                       return Native.toObjectV(getInfoAny(id, getInfo, a), create, createArray);
+                       return Native.toObjectV(getInfoAny(addr(), id, getInfo, a), create, createArray);
                } catch (RuntimeException | Error t) {
                        throw t;
                } catch (Throwable t) {
@@ -235,7 +275,7 @@ public abstract class CLObject extends Native {
        }
 
        // clGet*Info includes terminating 0
-       static String infoToString(MemorySegment seg) {
+       static protected String infoToString(MemorySegment seg) {
                if (false) {
                        MemoryAddress valp = seg.baseAddress();
                        byte[] val = new byte[(int)(seg.byteSize() - 1)];
index 5f2c613..99d510f 100644 (file)
@@ -24,16 +24,15 @@ import java.lang.invoke.MethodHandle;
 /**
  * Interface for pipes.
  *
- * @param <T> Not used - yet?
  */
-public class CLPipe<T> extends CLMemory {
+public class CLPipe extends CLMemory {
 
-       public CLPipe(MemoryAddress p) {
-               this(p, null);
+       public CLPipe(MemoryAddress p, int apiVersion) {
+               this(p, apiVersion, null);
        }
 
-       public CLPipe(MemoryAddress p, MemorySegment seg) {
-               super(p, seg);
+       public CLPipe(MemoryAddress p, int apiVersion, MemorySegment seg) {
+               super(p, apiVersion, seg);
        }
 
        @Override
index 9b11165..426a0bb 100644 (file)
@@ -37,20 +37,20 @@ public class CLPlatform extends CLObject {
        public final static int VERSION_2_0 = 0x200;
        public final static int VERSION_2_1 = 0x201;
 
-       final int apiVersion;
-
        public CLPlatform(MemoryAddress p) {
-               super(p);
+               super(p, getZCLVersion(p));
+       }
 
-               String v = getVersion();
-               try {
+       private static int getZCLVersion(MemoryAddress p) {
+               try (Allocator a = Memory.stack()) {
+                       String v = infoToString(getInfoAny(p, CL_PLATFORM_VERSION, clGetPlatformInfo, a));
                        int dot = v.indexOf('.', 7);
                        int space = v.indexOf(' ', dot);
                        int major = Integer.parseInt(v.substring(7, dot));
                        int minor = Integer.parseInt(v.substring(dot + 1, space));
-                       apiVersion = (major << 8) | minor;
+                       return (major << 8) | minor;
                } catch (NullPointerException | NumberFormatException | IndexOutOfBoundsException ex) {
-                       throw new RuntimeException(String.format("Unable to parse version string `%s'", v));
+                       throw new RuntimeException("Unable to parse version string");
                }
        }
 
@@ -69,9 +69,8 @@ public class CLPlatform extends CLObject {
                return clGetPlatformInfo;
        }
 
-       public static void requireAPIVersion(int apiVersion, int required) throws UnsupportedOperationException {
-               if (apiVersion < required)
-                       throw new UnsupportedOperationException("Requires version " + ((apiVersion >> 8) & 0xff) + "." + (apiVersion & 0xff));
+       protected CLPlatform findPlatform() {
+               return this;
        }
 
        /**
@@ -131,7 +130,7 @@ public class CLPlatform extends CLObject {
 
                        res = (int)clGetDeviceIDs.invokeExact(addr(), type, len, list, lenp);
 
-                       return toObjectV(list, new CLDevice[len], CLDevice::new);
+                       return toObjectV(list, new CLDevice[len], (d) -> new CLDevice(d, getAPIVersion()));
                } catch (RuntimeException | Error t) {
                        throw t;
                } catch (Throwable t) {
@@ -195,18 +194,6 @@ 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.
-        *
-        * @return platform api version.
-        */
-       public int getAPIVersion() {
-               return apiVersion;
-       }
-
        /**
         * get CL_PLATFORM_PROFILE.
         *
index ef63a40..e052bc0 100644 (file)
@@ -31,12 +31,8 @@ import java.util.stream.LongStream;
  */
 public class CLProgram extends CLObject {
 
-       CLProgram(MemoryAddress p) {
-               super(p);
-       }
-
-       public static CLProgram create(MemoryAddress p) {
-               return Native.resolve(p, CLProgram::new);
+       CLProgram(MemoryAddress p, int apiVersion) {
+               super(p, apiVersion);
        }
 
        private static void release(MemoryAddress p) {
@@ -52,6 +48,11 @@ public class CLProgram extends CLObject {
                return clGetProgramInfo;
        }
 
+       @Override
+       protected CLPlatform findPlatform() {
+               return getContext().getDevices()[0].getPlatform();
+       }
+
        /**
         * Call clBuildProgram.
         *
@@ -62,7 +63,7 @@ public class CLProgram extends CLObject {
         */
        public void buildProgram(CLDevice[] devices, String options, CLNotify<CLProgram> notify) throws CLException {
                try (Allocator frame = Memory.stack();
-                       Callback<CLNotify<CLProgram>> call = CLNotify.call(notify, CLProgram::new)) {
+                       Callback<CLNotify<CLProgram>> call = CLNotify.call(notify, (p) -> new CLProgram(p, getAPIVersion()))) {
                        MemoryAddress pdevs = toAddrV(frame, devices);
                        MemoryAddress poptions = toByteV(frame, options);
                        int res;
@@ -110,6 +111,8 @@ public class CLProgram extends CLObject {
         * @since OpenCL 1.2
         */
        public void compileProgram(CLDevice[] devices, String options, CLProgram[] headers, String[] header_names, CLNotify<CLProgram> notify) throws CLException, UnsupportedOperationException {
+               requireAPIVersion(CLPlatform.VERSION_1_2);
+
                int nheaders = 0;
                if (headers != null && header_names != null) {
                        if (headers.length != header_names.length)
@@ -120,7 +123,7 @@ public class CLProgram extends CLObject {
                }
 
                try (Allocator frame = Memory.stack();
-                       Callback<CLNotify<CLProgram>> call = CLNotify.call(notify, CLProgram::new)) {
+                       Callback<CLNotify<CLProgram>> call = CLNotify.call(notify, (p) -> new CLProgram(p, getAPIVersion()))) {
                        MemoryAddress cdevs = toAddrV(frame, devices);
                        MemoryAddress coptions = toByteV(frame, options);
                        MemoryAddress cheaders = toAddrV(frame, headers);
@@ -158,7 +161,7 @@ public class CLProgram extends CLObject {
                        res = getInt(pres);
                        if (res != 0)
                                throw new CLException(res);
-                       return resolve(ck, CLKernel::new);
+                       return resolve(ck, (k) -> new CLKernel(k, getAPIVersion()));
                } catch (CLException | RuntimeException | Error t) {
                        throw t;
                } catch (Throwable t) {
@@ -185,7 +188,7 @@ public class CLProgram extends CLObject {
                                throw new CLRuntimeException();
 
                        size = getInt(csize);
-                       return Native.toObjectV(ckern, new CLKernel[size], CLKernel::new);
+                       return Native.toObjectV(ckern, new CLKernel[size], (k) -> new CLKernel(k, getAPIVersion()));
                } catch (RuntimeException | Error t) {
                        throw t;
                } catch (Throwable t) {
@@ -194,7 +197,7 @@ public class CLProgram extends CLObject {
        }
 
        public CLContext getContext() {
-               return getInfoAny(CL_PROGRAM_CONTEXT, clGetProgramInfo, CLContext::new);
+               return getInfoAny(CL_PROGRAM_CONTEXT, clGetProgramInfo, (c) -> new CLContext(c, apiVersion));
        }
 
        public int getNumDevices() {
@@ -202,7 +205,7 @@ public class CLProgram extends CLObject {
        }
 
        public CLDevice[] getDevices() {
-               return getInfoAnyV(CL_PROGRAM_DEVICES, clGetProgramInfo, CLDevice::new, CLDevice[]::new);
+               return getInfoAnyV(CL_PROGRAM_DEVICES, clGetProgramInfo, (d) -> new CLDevice(d, getAPIVersion()), CLDevice[]::new);
        }
 
        public String getSource() {
index 736f9d1..8082a14 100644 (file)
@@ -26,8 +26,8 @@ import java.lang.invoke.MethodHandle;
  */
 public class CLSampler extends CLObject {
 
-       public CLSampler(MemoryAddress p) {
-               super(p);
+       public CLSampler(MemoryAddress p, int apiVersion) {
+               super(p, apiVersion);
        }
 
        @Override
@@ -35,6 +35,11 @@ public class CLSampler extends CLObject {
                return clGetSamplerInfo;
        }
 
+       @Override
+       protected CLPlatform findPlatform() {
+               return getContext().getDevices()[0].getPlatform();
+       }
+
        private static void release(MemoryAddress p) {
                try {
                        clReleaseSampler(p);
@@ -56,7 +61,7 @@ public class CLSampler extends CLObject {
        }
 
        public CLContext getContext() {
-               return getInfoAny(CL_SAMPLER_CONTEXT, clGetSamplerInfo, CLContext::new);
+               return getInfoAny(CL_SAMPLER_CONTEXT, clGetSamplerInfo, (c) -> new CLContext(c, apiVersion));
        }
 
        public boolean getNormalisedCoords() {
index 449da72..a1f5f67 100644 (file)
@@ -19,6 +19,8 @@ package au.notzed.zcl.khr;
 import au.notzed.zcl.CLContext;
 import au.notzed.zcl.CLEvent;
 import au.notzed.zcl.CLExtension;
+import au.notzed.zcl.CLExtension;
+import au.notzed.zcl.CLPlatform;
 
 import jdk.incubator.foreign.MemoryAddress;
 
@@ -28,11 +30,15 @@ import jdk.incubator.foreign.MemoryAddress;
 public class GLEvent extends CLExtension {
 
        public GLEvent(MemoryAddress p) {
-               super(p);
+               super(p, 0);
        }
 
        private native static void release(long p);
 
+       protected CLPlatform findPlatform() {
+               throw new UnsupportedOperationException();
+       }
+
        @Override
        public String getName() {
                return NAME;
index 245c907..a116078 100644 (file)
@@ -25,6 +25,7 @@ import au.notzed.zcl.CLExtension;
 import au.notzed.zcl.CLImage;
 import au.notzed.zcl.CLMemory;
 import au.notzed.zcl.CLRuntimeException;
+import au.notzed.zcl.CLPlatform;
 
 import jdk.incubator.foreign.MemoryAddress;
 
@@ -34,11 +35,15 @@ import jdk.incubator.foreign.MemoryAddress;
 public class GLSharing extends CLExtension {
 
        public GLSharing(MemoryAddress p) {
-               super(p);
+               super(p, 0);
        }
 
        private native static void release(long p);
 
+       protected CLPlatform findPlatform() {
+               throw new UnsupportedOperationException();
+       }
+
        @Override
        public String getName() {
                return NAME;