diff options
Diffstat (limited to 'src/com/mbien/opencl/CLProgram.java')
-rw-r--r-- | src/com/mbien/opencl/CLProgram.java | 257 |
1 files changed, 145 insertions, 112 deletions
diff --git a/src/com/mbien/opencl/CLProgram.java b/src/com/mbien/opencl/CLProgram.java index 70656373..ff2919e8 100644 --- a/src/com/mbien/opencl/CLProgram.java +++ b/src/com/mbien/opencl/CLProgram.java @@ -21,39 +21,6 @@ public class CLProgram { private final Map<String, CLKernel> kernels; - public enum Status { - - BUILD_SUCCESS(CL.CL_BUILD_SUCCESS), - BUILD_NONE(CL.CL_BUILD_NONE), - BUILD_IN_PROGRESS(CL.CL_BUILD_IN_PROGRESS), - BUILD_ERROR(CL.CL_BUILD_ERROR); - - /** - * Value of wrapped OpenCL device type. - */ - public final int CL_BUILD_STATUS; - - private Status(int CL_BUILD_STATUS) { - this.CL_BUILD_STATUS = CL_BUILD_STATUS; - } - - public static Status valueOf(int clBuildStatus) { - switch(clBuildStatus) { - case(CL.CL_BUILD_SUCCESS): - return BUILD_SUCCESS; - case(CL.CL_BUILD_NONE): - return BUILD_NONE; - case(CL.CL_BUILD_IN_PROGRESS): - return BUILD_IN_PROGRESS; - case(CL.CL_BUILD_ERROR): - return BUILD_ERROR; -// is this a standard state? -// case (CL.CL_BUILD_PROGRAM_FAILURE): -// return BUILD_PROGRAM_FAILURE; - } - return null; - } - } CLProgram(CLContext context, String src, long contextID) { @@ -68,6 +35,76 @@ public class CLProgram { checkForError(intArray[0], "can not create program with source"); } + private final void initKernels() { + + if(kernels.isEmpty()) { + int[] intArray = new int[1]; + int ret = cl.clCreateKernelsInProgram(ID, 0, null, 0, intArray, 0); + checkForError(ret, "can not create kernels for program"); + + long[] kernelIDs = new long[intArray[0]]; + ret = cl.clCreateKernelsInProgram(ID, kernelIDs.length, kernelIDs, 0, null, 0); + checkForError(ret, "can not create kernels for program"); + + for (int i = 0; i < intArray[0]; i++) { + CLKernel kernel = new CLKernel(this, kernelIDs[i]); + kernels.put(kernel.name, kernel); + } + } + } + + // TODO serialization, program build options + + private final String getBuildInfoString(long device, int flag) { + + long[] longArray = new long[1]; + + int ret = cl.clGetProgramBuildInfo(ID, device, flag, 0, null, longArray, 0); + checkForError(ret, "on clGetProgramBuildInfo"); + + ByteBuffer bb = ByteBuffer.allocate((int)longArray[0]).order(ByteOrder.nativeOrder()); + + ret = cl.clGetProgramBuildInfo(ID, device, flag, bb.capacity(), bb, null, 0); + checkForError(ret, "on clGetProgramBuildInfo"); + + return new String(bb.array(), 0, (int)longArray[0]); + } + + private final String getProgramInfoString(int flag) { + + long[] longArray = new long[1]; + + int ret = cl.clGetProgramInfo(ID, flag, 0, null, longArray, 0); + checkForError(ret, "on clGetProgramInfo"); + + ByteBuffer bb = ByteBuffer.allocate((int)longArray[0]).order(ByteOrder.nativeOrder()); + + ret = cl.clGetProgramInfo(ID, flag, bb.capacity(), bb, null, 0); + checkForError(ret, "on clGetProgramInfo"); + + return new String(bb.array(), 0, (int)longArray[0]); + } + +// private int getProgramInfoInt(int flag) { +// +// ByteBuffer bb = ByteBuffer.allocate(4).order(ByteOrder.nativeOrder()); +// +// int ret = cl.clGetProgramInfo(programID, flag, bb.capacity(), bb, null, 0); +// checkForError(ret, ""); +// +// return bb.getInt(); +// } + + private int getBuildInfoInt(long device, int flag) { + + ByteBuffer bb = ByteBuffer.allocate(4).order(ByteOrder.nativeOrder()); + + int ret = cl.clGetProgramBuildInfo(ID, device, flag, bb.capacity(), bb, null, 0); + checkForError(ret, "error on clGetProgramBuildInfo"); + + return bb.getInt(); + } + /** * Builds this program for all devices associated with the context and implementation specific build options. @@ -79,6 +116,15 @@ public class CLProgram { } /** + * Builds this program for all devices associated with the context using the specified build options. + * @return this + */ + public CLProgram build(String options) { + build(null, options); + return this; + } + + /** * Builds this program for the given devices and with the specified build options. * @return this * @param devices A list of devices this program should be build on or null for all devices of its context. @@ -100,30 +146,6 @@ public class CLProgram { return this; } - /** - * Returns all kernels of this program in a unmodifiable view of a map with the kernel function names as keys. - */ - public Map<String, CLKernel> getCLKernels() { - - if(kernels.isEmpty()) { - - int[] intArray = new int[1]; - int ret = cl.clCreateKernelsInProgram(ID, 0, null, 0, intArray, 0); - checkForError(ret, "can not create kernels for program"); - - long[] kernelIDs = new long[intArray[0]]; - ret = cl.clCreateKernelsInProgram(ID, kernelIDs.length, kernelIDs, 0, null, 0); - checkForError(ret, "can not create kernels for program"); - - for (int i = 0; i < intArray[0]; i++) { - CLKernel kernel = new CLKernel(this, kernelIDs[i]); - kernels.put(kernel.name, kernel); - } - } - - return Collections.unmodifiableMap(kernels); - } - void onKernelReleased(CLKernel kernel) { this.kernels.remove(kernel.name); } @@ -147,6 +169,24 @@ public class CLProgram { } /** + * Returns the kernel with the specified name or null if not found. + */ + public CLKernel getCLKernel(String kernelName) { + initKernels(); + return kernels.get(kernelName); + } + + + /** + * Returns all kernels of this program in a unmodifiable view of a map + * with the kernel function names as keys. + */ + public Map<String, CLKernel> getCLKernels() { + initKernels(); + return Collections.unmodifiableMap(kernels); + } + + /** * Returns all devices associated with this program. */ public CLDevice[] getCLDevices() { @@ -169,22 +209,34 @@ public class CLProgram { } + /** + * Returns the build log for this program. The contents of the log are + * implementation dependent log can be an empty String. + */ public String getBuildLog(CLDevice device) { return getBuildInfoString(device.ID, CL.CL_PROGRAM_BUILD_LOG); } + /** + * Returns the build status enum for this program on the specified device. + */ public Status getBuildStatus(CLDevice device) { int clStatus = getBuildInfoInt(device.ID, CL.CL_PROGRAM_BUILD_STATUS); return Status.valueOf(clStatus); } /** - * Returns the source code of this program. Note: sources are not cached, each call of this method calls into OpenCL. + * Returns the source code of this program. Note: sources are not cached, + * each call of this method calls into OpenCL. */ public String getSource() { return getProgramInfoString(CL.CL_PROGRAM_SOURCE); } + /** + * Returns the binaries for this program in a map containing the device as key + * and the byte array as value. + */ public Map<CLDevice, byte[]> getBinaries() { CLDevice[] devices = getCLDevices(); @@ -198,7 +250,7 @@ public class CLProgram { binarySize += (int)sizes.getLong(); ByteBuffer binaries = ByteBuffer.allocate(binarySize).order(ByteOrder.nativeOrder()); - ret = cl.clGetProgramInfo(ID, CL.CL_PROGRAM_BINARIES, binaries.capacity(), binaries, null, 0); // crash, driver bug? + ret = cl.clGetProgramInfo(ID, CL.CL_PROGRAM_BINARIES, binaries.capacity(), binaries, null, 0); // TODO crash, driver bug? checkForError(ret, "on clGetProgramInfo"); Map<CLDevice, byte[]> map = new HashMap<CLDevice, byte[]>(); @@ -212,59 +264,6 @@ public class CLProgram { return map; } - - // TODO serialization, program build options - - private final String getBuildInfoString(long device, int flag) { - - long[] longArray = new long[1]; - - int ret = cl.clGetProgramBuildInfo(ID, device, flag, 0, null, longArray, 0); - checkForError(ret, "on clGetProgramBuildInfo"); - - ByteBuffer bb = ByteBuffer.allocate((int)longArray[0]).order(ByteOrder.nativeOrder()); - - ret = cl.clGetProgramBuildInfo(ID, device, flag, bb.capacity(), bb, null, 0); - checkForError(ret, "on clGetProgramBuildInfo"); - - return new String(bb.array(), 0, (int)longArray[0]); - } - - private final String getProgramInfoString(int flag) { - - long[] longArray = new long[1]; - - int ret = cl.clGetProgramInfo(ID, flag, 0, null, longArray, 0); - checkForError(ret, "on clGetProgramInfo"); - - ByteBuffer bb = ByteBuffer.allocate((int)longArray[0]).order(ByteOrder.nativeOrder()); - - ret = cl.clGetProgramInfo(ID, flag, bb.capacity(), bb, null, 0); - checkForError(ret, "on clGetProgramInfo"); - - return new String(bb.array(), 0, (int)longArray[0]); - } - -// private int getProgramInfoInt(int flag) { -// -// ByteBuffer bb = ByteBuffer.allocate(4).order(ByteOrder.nativeOrder()); -// -// int ret = cl.clGetProgramInfo(programID, flag, bb.capacity(), bb, null, 0); -// checkForError(ret, ""); -// -// return bb.getInt(); -// } - - private int getBuildInfoInt(long device, int flag) { - - ByteBuffer bb = ByteBuffer.allocate(4).order(ByteOrder.nativeOrder()); - - int ret = cl.clGetProgramBuildInfo(ID, device, flag, bb.capacity(), bb, null, 0); - checkForError(ret, "error on clGetProgramBuildInfo"); - - return bb.getInt(); - } - @Override public boolean equals(Object obj) { if (obj == null) { @@ -290,5 +289,39 @@ public class CLProgram { hash = 37 * hash + (int) (this.ID ^ (this.ID >>> 32)); return hash; } + + public enum Status { + + BUILD_SUCCESS(CL.CL_BUILD_SUCCESS), + BUILD_NONE(CL.CL_BUILD_NONE), + BUILD_IN_PROGRESS(CL.CL_BUILD_IN_PROGRESS), + BUILD_ERROR(CL.CL_BUILD_ERROR); + + /** + * Value of wrapped OpenCL device type. + */ + public final int CL_BUILD_STATUS; + + private Status(int CL_BUILD_STATUS) { + this.CL_BUILD_STATUS = CL_BUILD_STATUS; + } + + public static Status valueOf(int clBuildStatus) { + switch(clBuildStatus) { + case(CL.CL_BUILD_SUCCESS): + return BUILD_SUCCESS; + case(CL.CL_BUILD_NONE): + return BUILD_NONE; + case(CL.CL_BUILD_IN_PROGRESS): + return BUILD_IN_PROGRESS; + case(CL.CL_BUILD_ERROR): + return BUILD_ERROR; +// is this a standard state? +// case (CL.CL_BUILD_PROGRAM_FAILURE): +// return BUILD_PROGRAM_FAILURE; + } + return null; + } + } } |